[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