[FFmpeg-devel] theora depayloader
Martin Storsjö
martin
Fri Mar 19 10:23:37 CET 2010
Hi Josh,
On Fri, 19 Mar 2010, Josh Allmann wrote:
> Index: libavformat/rtsp.c
> ===================================================================
> --- libavformat/rtsp.c (revision 22597)
> +++ libavformat/rtsp.c (working copy)
> @@ -211,6 +212,8 @@
> hex_to_data(codec->extradata, value);
> }
> break;
> + case CODEC_ID_THEORA:
> + ff_theora_parse_fmtp_config(codec, ctx, attr, value);
> case CODEC_ID_VORBIS:
> ff_vorbis_parse_fmtp_config(codec, ctx, attr, value);
> break;
Can this be done through parse_sdp_a_line as for e.g. AMR? Then we
wouldn't need to hardcode these format specific parsing routines here...
Yes, this is the way it's done for vorbis, but I think it would be better
to migrate new things to use RTPDynamicProtocolHandler properly instead of
hardcoding these. (A patch for fixing this for vorbis would be welcome,
too, unless Ronald or someone disagrees...)
> +static inline void check_size(PayloadContext * data,
> + int pkt_len)
> +{
> + // check for overflows, enlarge buffer if needed
> + if (data->allocated_size < data->fragment_length+pkt_len){
> + data->allocated_size *= 2;
> + data->theora_fragment = av_realloc(data->theora_fragment, data->allocated_size);
> + }
> +}
This doesn't guarantee that the realloced buffer is large enough.
> +//TODO: dropped packet handling, RTCP feedback for dropped packets.
RTCP feedback for dropped packets should perhaps be done generally in
rtpdec.c instead of doing it specifically for each payload format? But
that's a wholly different story...
> + buf += 6; // move past header bits
You may want to decrease len here, too, to keep track of how much's left.
> + for (i = 0, data->fragment_length = 0; i < num_pkts; i++) {
> + pkt_len = AV_RB16(buf);
> + buf += 2;
You never check that pkt_len <= the number of bytes left in the buffer,
you only check the outermost pkt_len value.
> + // concatenate packets
> + memcpy(data->theora_fragment+data->fragment_length, buf, pkt_len);
> + data->fragment_length += pkt_len;
> + buf += pkt_len;
In this non-fragmented case, couldn't you simply do av_new_packet first to
allocate the whole packet and then write the data there? That would avoid
unnecessary memcpying of the data to the temp buffer, but would require
you to first do a fast pass over the data to calculate the total length.
> + }else{
> + assert(fragmented < 4);
> + check_size(data, pkt_len);
> +
> + // copy data to fragment buffer
> + memcpy(data->theora_fragment+data->fragment_length, buf, pkt_len);
> + data->fragment_length += pkt_len;
> +
As you mentioned in your TODO earlier regarding dropped packets - you may
want to check that the timestamp for this packet is the same as for the
first fragment, and then clear the earlier buffered part if the follow-up
doesn't belong to the same frame as the currently buffered part.
> + ptr = codec->extradata = av_mallocz(length + length / 255 + 64);
Doesn't extradata need FF_INPUT_BUFFER_PADDING_SIZE at the end?
Also, for H.263 among other we simply return fragmented packets one piece
at a time and use a parser to merge them together - is that feasible for
Theora too? That would simplify the depacketizer a lot. If not, this
approach seems ok to me.
The rest seemed quite sane to me...
// Martin
More information about the ffmpeg-devel
mailing list