[FFmpeg-soc] vp8 de/packetizers

Martin Storsjö martin at martin.st
Fri Jul 30 09:22:13 CEST 2010


On Thu, 29 Jul 2010, Josh Allmann wrote:

> Here is a packetizer and a depacketizer for VP8 RTP.
> 
> Playback is only semi-smooth; it drops way too many frames. The
> depacketizer likes to claim it gets an extra packet after the
> frame-end (which is typically one byte smaller than the actual
> frame-end packet). Still a work in progress.

Didn't feel any significant frame dropping here (btw, if playing with 
ffplay, make sure you use -noframedrop, sometimes ffplay constantly feels 
it's behind and needs to drop some frames to catch up, but since the 
source is realtime, it still has to block for more frames, so it 
constantly drops frames), but the playback console is spammed with 
messages like this:

[vp8 @ 0x10188fe00] Unknown profile 6
[vp8 @ 0x10188fe00] Header size larger than data provided
[rtsp @ 0x10202dc00] Received no start marker; dropping frame

In general, this looks quite ok (I haven't read the spec, but from the 
code it looks quite simple), here's a quick initial review:



> +static void rtp_send_vp8(AVFormatContext *s1, const uint8_t *buf, int size)
> +{
> +    RTPMuxContext *s = s1->priv_data;
> +    int len, max_packet_size, keyframe;
> +
> +    s->buf_ptr = s->buf;
> +    s->timestamp = s->cur_timestamp;
> +    max_packet_size = s->max_payload_size - 1; // minus one for header byte
> +    keyframe = ( !(*buf & 1) ) << 3;
> +

I guess this could be written a little less convoluted as

keyframe = *buf & 1 ? 0 : 8;

but that's mostly bikeshedding. :-)

> +    *s->buf_ptr++ = keyframe | 4; // 0b100 indicates start of frame
> +    while (size > 0) {
> +        len = size > max_packet_size ? max_packet_size : size;

len = FFMIN(size, max_packet_size);

> +
> +        memcpy(s->buf_ptr, buf, len);
> +        ff_rtp_send_data(s1, s->buf, len+1, size == len); // marker bit is last packet in frame
> +
> +        size -= len;
> +        buf += len;
> +        s->buf_ptr = s->buf;
> +        *s->buf_ptr++ = keyframe;
> +    }
> +}
> +


> +static int vp8_handle_packet(AVFormatContext *ctx,
> +                             PayloadContext *vp8,
> +                             AVStream *st,
> +                             AVPacket *pkt,
> +                             uint32_t *timestamp,
> +                             const uint8_t *buf,
> +                             int len, int flags)
> +{
> +    int start_packet    = *buf & 4;
> +    int end_packet      = flags & RTP_FLAG_MARKER;
> +    int is_keyframe     = *buf & 8;

Keep in mind that buf can be NULL


Except for that, it mostly looked quite good.

// Martin


More information about the FFmpeg-soc mailing list