[FFmpeg-soc] [PATCH] xiph packetizer
Josh Allmann
joshua.allmann at gmail.com
Thu Jul 29 13:32:43 CEST 2010
Hi,
Thanks for the thorough review!
On 28 July 2010 02:56, Martin Storsjö <martin at martin.st> wrote:
> On Tue, 27 Jul 2010, Josh Allmann wrote:
>
>> @@ -135,6 +137,12 @@ 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
>> + break;
>
> You do want the default case handling (setting the audio sample rate as
> stream time base) for vorbis. One way of doing that is adding a defaultcase:
> directly after the default: line, and replacing the break; with a
> goto defaultcase; here.
>
Fixed.
>> + /* set ident
>> + * Probably need a non-fixed way of generating
>> + * this, but it has to be done in SDP and passed in from there. */
>> + q = s->buf;
>> + *q++ = 0xfe;
>> + *q++ = 0xcd;
>> + *q++ = 0xba;
>
> Please add a note here saying that this must match what's in sdp.c.
>
Done.
>> + s->buf_ptr = q;
>> +
>> + /* set fragment
>> + * 0 - whole frame (possibly multiple frames)
>> + * 1 - first fragment
>> + * 2 - fragment continuation
>> + * 3 - last fragmement */
>> + frag = size <= max_pkt_size ? 0 : 1;
>
> You must readd the s->timestamp = s->cur_timestamp line that you removed.
> s->cur_timestamp gets set to the timestamp of the current AVPacket in
> rtp_write_packet, while ff_rtp_send_data only uses s->timestamp. If you
> don't set s->timestamp at all, all packets will be sent with the same
> timestamp.
>
> This value isn't copied directly, since if you bundle many AVPackets into
> the same RTP packet, you most often want the timestamp of the first
> packet, not the last.
>
Done.
>> @@ -872,7 +872,7 @@ int ff_rtsp_send_cmd_with_content_async(AVFormatContext *s,
>> int send_content_length)
>> {
>> RTSPState *rt = s->priv_data;
>> - char buf[4096], *out_buf;
>> + char buf[16384], *out_buf; // large buffer to accommodate xiph sdp
>> char base64buf[AV_BASE64_SIZE(sizeof(buf))];
>
> You don't need to enlarge this buffer - the body data of the request never
> gets stuffed into this buffer. (If we'd want to support HTTP tunneling in
> the muxer, too, we'd might want to stuff it in here, though, or allocate
> this buffer dynamically.)
>
Removed.
>> @@ -1295,7 +1295,7 @@ static int rtsp_setup_output_streams(AVFormatContext *s, const char *addr)
>> rt->start_time = av_gettime();
>>
>> /* Announce the stream */
>> - sdp = av_mallocz(8192);
>> + sdp = av_mallocz(16384); // massive SDP buffer due to Xiph extradata
>> if (sdp == NULL)
>> return AVERROR(ENOMEM);
>> /* We create the SDP based on the RTSP AVFormatContext where we
>> @@ -1314,7 +1314,7 @@ static int rtsp_setup_output_streams(AVFormatContext *s, const char *addr)
>> ff_url_join(sdp_ctx.filename, sizeof(sdp_ctx.filename),
>> "rtsp", NULL, addr, -1, NULL);
>> ctx_array[0] = &sdp_ctx;
>> - if (avf_sdp_create(ctx_array, 1, sdp, 8192)) {
>> + if (avf_sdp_create(ctx_array, 1, sdp, 16384)) {
>> av_free(sdp);
>> return AVERROR_INVALIDDATA;
>> }
>
> I fixed this to use a define now, you want to rebase this on top of that
> and adjust that define instead.
>
Done.
>> + config[0] = config[1] = config[2] = 0;
>> + config[3] = 1;
>> + config[4] = 0xfe;
>> + config[5] = 0xcd;
>> + config[6] = 0xba;
>
> Same here, add a note here saying that this must match what's in
> rtpenc_xiph.c.
>
Done.
>> + av_strlcatf(buff, size, "a=rtpmap:%d theora/9000\r\n"
>
> This should be 90000, not 9000.
>
Done.
> Once in the test stream I used, I got this message from the depacketizer,
> though:
>
> [rtsp @ 0x102049000] Unimplemented RTP Xiph packet settings (1,2,0)
> [rtsp @ 0x102049000] Unimplemented RTP Xiph packet settings (2,2,0)
> [rtsp @ 0x102049000] Unimplemented RTP Xiph packet settings (3,2,0)
>
Interesting, that indicates your sample has a comment embedded in it.
IIRC, the Theora decoder ignores comments anyway, but I'm not sure
about Vorbis.
> Also, there's an issue with vorbis timestamps if you stream copy from an
> ogg file - not all packets have pts/dts set when reading them, and for
> vorbis, you'd need to decode it to figure out the proper length of each
> frame. In ffmpeg.c, lines 1622-1623, the pts is updated using an estimate
> of the frame size, which doesn't turn out to be right (in my case at
> least).
>
> If playing only vorbis over RTSP/RTP, it still worked, but the timestamps
> advanced slowly from 0 to perhaps 1, then jumped to 5-6 seconds, advanced
> slowly there again, and jumped onwards when the ogg demuxer returned a
> packet that actually had a timestamp. Combined with a video stream, it
> doesn't work too well in that setup of course.
>
> If live transcoding into theora/vorbis, and sending it out over RTSP/RTP,
> it seemed to work really well, though!
>
That's pretty strange, I would like to see your sample. With Big Buck
Bunny, Vorbis standalone timestamps are fairly linear.
Using Theora and Vorbis together with RTSP/RTP, things work well.
Theora standalone is still full of artifacts around motion with TCP,
and UDP is a slideshow because of all the dropped packets. Tomorrow,
I'll copy over the packetization routine from Feng and see if the
results are more sane.
Josh
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Add-RTP-packetization-of-Theora-and-Vorbis.patch
Type: text/x-patch
Size: 12098 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-soc/attachments/20100729/ff057cbe/attachment.bin>
More information about the FFmpeg-soc
mailing list