[FFmpeg-devel] [PATCH] SHOUTcast HTTP Support

Micah F. Galizia micahgalizia
Fri Apr 9 03:14:53 CEST 2010


On 10-04-06 09:40 PM, Michael Niedermayer wrote:
> On Tue, Apr 06, 2010 at 09:06:35PM -0400, Micah F. Galizia wrote:
>> On 10-04-06 06:37 PM, Michael Niedermayer wrote:
>>> On Wed, Mar 31, 2010 at 06:43:10PM -0400, Micah F. Galizia wrote:
>>>
>>
>> [...]
>>
>>>> +    /* there is no shoutcast in shoutcast */
>>>> +    if (!strcmp(sc->child->name, SHOUTCAST_DEMUXER_NAME)) {
>>>> +        av_log(s, AV_LOG_ERROR, "ERROR: Child demuxer is %s\n",
>>>> +               sc->child->name);
>>>> +        return AVERROR_IO;
>>>> +    }
>>>
>>> thats fragile, we just need a second shoutcast like demxuer and
>>> each with such check would not be enough
>>
>> I have observed the s->iformat and sc->child pointers values are the same
>> with when both are shoutcast demuxers.  Can I rely on that, or did you have
>> something else in mind?
>
> shoutcast(foobar(shoutcast(foobar(...))))
>
> checking the immedeate first child is not enough
> it depends on the non existence of a second shoutcast like demuxer.
> thats fragile as we would not consider that when we add such a demuxer
>

Perhaps we can add a new function pointer to AVInputFormat.  Something 
like AVInputFormat (*get_child)(char *name);. Any demuxer that has 
children can check the child name or recurse down until said demuxer is 
found or NULL is returned.

>>
>>>
>>>> +
>>>> +    if (!(sc->child_priv = av_mallocz(sc->child->priv_data_size))) {
>>>> +        av_log(s, AV_LOG_ERROR,
>>>> +               "Unable to allocate SHOUTcast child private data.\n");
>>>> +        return AVERROR_NOMEM;
>>>> +    }
>>>> +
>>>> +    /* read past the HTTP header (after probing the stream is reset) */
>>>> +    url_fseek(s->pb, offset, SEEK_CUR);
>>>> +
>>>
>>>> +    /* ensure that we set the data position ahead if the child demuxer
>>>> moves
>>>> +     * the buffer pointer forward. TODO Use pb->pos if possible. */
>>>> +    offset = (unsigned long)(s->pb->buf_ptr);
>>>
>>> whatever this is it has undefined behavior
>>>
>>
>> What I need is to know how the child demuxer has manipulated the buffer
>> (did it move the pointer forwards or backwards?). I need to know this
>
> url_ftell() ?

ty!

>
>> because it affects the  index within the actual data between metadata
>> chunks. If this is unacceptable and there isn't a preferred way getting
>> this information, I can try to seek back to the beginning of the stream and
>> failing that close, reopen, and seek beyond the http header to the start of
>> real data.
>>
>>>> +    s->priv_data = sc->child_priv;
>>>> +    ret = sc->child->read_header(s, ap);
>>>> +    s->priv_data = sc;
>>>> +    sc->datapos = (unsigned long)(s->pb->buf_ptr) - offset;
>>>> +
>>>> +    return ret;
>>>> +}
>>>> +
>>>
>>>> +static int shoutcast_read_packet(struct AVFormatContext *s, AVPacket
>>>> *pkt)
>>>> +{
>>>> +    int ret;
>>>> +    ByteIOContext *pb = s->pb;
>>>> +    SHOUTcast *sc = s->priv_data;
>>>> +
>>>> +    /* allow the child demuxer to read a packet. */
>>>> +    s->priv_data = sc->child_priv;
>>>> +    if ((ret = sc->child->read_packet(s, pkt))<   0) {
>>>> +        return ret;
>>>> +    }
>>>> +    s->priv_data = sc;
>>>
>>>> +    sc->datapos += pkt->size;
>>>
>>> what is datapos supposed to be?
>>> this just looks wrong, it surely is not the "file" position
>>
>> No, it is a counter of how much non-metadata data has been read.  When it
>> is greater than our metadata interval, we must strip the icy metadata out
>> before passing more non-metadata to the child demuxer.
>
> still sounds wrong, the sum or packet sizes is not the same as the num
> of bytes the child demuer consumed. These might match for mp3 but will
> not match for most other cases

The scast demuxer _needs_ to keep track of how far into the stream data 
has been read. And an absolute position wont work either (because the 
interleaved meatdata is variable sized) -- if the child reads past a 
segment of metadata, then the scast demuxer counts are totally invalid! 
Also, if the child demuxer is just consuming stream data without 
returning some sort of count that also wont work.

Is there a correct way to work around this problem? If not, can we 
restrict children to formats that do work? So far I have verified that 
vorbis and mp3 streams play nice.

[...]

One other question I have (the reference comment was cut in my previous 
email) is about chapter times. I understand that the start should be 
based purely on the data we have read up to the point where the metadata 
segment occurs. But I don't have any idea how this should done 
correctly, so a nudge in the right direction would be appreciated.

TIA
-- 
Micah F. Galizia
micahgalizia at gmail.com

"The mark of an immature man is that he wants to die nobly for a cause, 
while the mark of the mature man is that he wants to live humbly for 
one."   --W. Stekel



More information about the ffmpeg-devel mailing list