[FFmpeg-soc] [PATCH] xiph packetizer

Martin Storsjö martin at martin.st
Thu Aug 5 11:21:39 CEST 2010


On Thu, 5 Aug 2010, Josh Allmann wrote:

> >> @@ -135,6 +137,14 @@ static int rtp_write_header(AVFormatContext *s1)
> >>              s->nal_length_size = (st->codec->extradata[4] & 0x03) + 1;
> >>          }
> >>          break;
> >> +    case CODEC_ID_VORBIS:
> >> +    case CODEC_ID_THEORA:
> >> +        if (!s->max_frames_per_packet) s->max_frames_per_packet = 15;
> >> +        s->max_frames_per_packet = av_clip(s->max_frames_per_packet, 1, 15);
> >> +        s->max_payload_size -= 6; // ident+frag+tdt/vdt+pkt_num+pkt_length
> >> +        s->num_frames = 0;
> >> +        if (st->codec->codec_id == CODEC_ID_VORBIS) goto defaultcase;
> >> +        break;
> >
> > I think you could do this for both codecs - the default case sets buf_ptr,
> > which needs to be set for theora too.
> >
> 
> Fixed.


> @@ -135,6 +137,14 @@ static int rtp_write_header(AVFormatContext *s1)
>              s->nal_length_size = (st->codec->extradata[4] & 0x03) + 1;
>          }
>          break;
> +    case CODEC_ID_VORBIS:
> +    case CODEC_ID_THEORA:
> +        if (!s->max_frames_per_packet) s->max_frames_per_packet = 15;
> +        s->max_frames_per_packet = av_clip(s->max_frames_per_packet, 1, 15);
> +        s->max_payload_size -= 6; // ident+frag+tdt/vdt+pkt_num+pkt_length
> +        s->num_frames = 0;
> +        goto defaultcase;
> +        break;

In this case, when you have an unconditional goto, you could drop the break

> >> +
> >> +    if (!frag && !xdt) { // do we have a whole frame of raw data?
> >> +        int remaining = max_pkt_size - ((int)(s->buf_ptr - s->buf) + size);
> >
> > This calculation is slightly off - max_pkt_size already has the 6 bytes
> > header subtracted, but those 6 bytes still are included in s->buf_ptr - s->buf.
> > Also, it feels a bit convoluted.
> >
> > If you happen to have a packet of e.g. 1453, this forces the lines below
> > to send the currently buffered data, even if there isn't any frame buffered
> > (s->buf_ptr - s->buf is 3 bytes, and only contains the ident header).
> >
> 
> Hmm, OK. I tightened it up. The total header size is actually 4 + 2n,
> where n is the number of frames in the packet -- we need to prefix the
> length before each frame.
> 
> In this case though, those additional headers are included in
> (s->buf_ptr - s->buf), but we do need to have room for an additional 2
> bytes if the current frame is not the first of the packet.
> 
> I am not 100% certain this fix is correct, so a second pair of eyes
> would be good.
> 
> +        int data_size = (s->buf_ptr - s->buf) + size;
> +        int header_size = s->num_frames ? 8 : 6; // 6 bytes standard,
> 2 more bytes for length of extra frame
> +        int remaining = max_pkt_size - data_size - header_size;

Actually, the problem is that it's too tight. The check above, frag = size 
<= max_pkt_size ? 0 : 1; indicated that it should fit without fragmenting 
it, but this check says that it doesn't fit and you should send whatever 
you have buffered from before - even if there's no packet buffered from 
before.

You _could_ add an "s->num_frames > 0 &&" part to the if clause, so you 
won't accidentally send empty packets. I think the calculation of whether 
it fits or not is clearer this way:

        // We're allowed to write 6 + max_pkt_size bytes from s->buf.
        // Calculate how much space is left after writing 2 length bytes
        // + size from buf_ptr.
        int remaining = s->buf + 6 + max_pkt_size - (s->buf_ptr + 2 + size);

So, the s->buf + 6 + max_pkt_size could be stored away as an end_ptr or 
something, if you like - that makes it easier to check with the current 
s->buf_ptr if the things we're going to write (2 + size) fits or not. 
Writing it all in one expression like this is ok for me, too.

Except for this, it looks quite good.

// Martin


More information about the FFmpeg-soc mailing list