From: toots@rastageeks.org To: ffmpeg-devel@ffmpeg.org Cc: Romain Beauxis <toots@rastageeks.org> Subject: [FFmpeg-devel] [PATCH v2 3/3] libavformat/oggdec.c: keep reading on empty packets to accommodate for chained bitstreams. Date: Fri, 5 May 2023 08:28:51 -0500 Message-ID: <20230505132848.18011-3-toots@rastageeks.org> (raw) In-Reply-To: <20230505132848.18011-1-toots@rastageeks.org> From: Romain Beauxis <toots@rastageeks.org> This patch is the last of a series of patch to enhance FFmpeg's handling of chained ogg streams. Documentation for chained (and multiplexed) ogg bitstream can be found here: https://xiph.org/ogg/doc/oggstream.html My understanding of the current code is that the ogg demuxer will process all pages from the current ogg track and, after reaching the last page, if another page follows, will try to match the new stream with the previous one using its codec. (See ogg_replace_stream in libavformat/oggdec.c). Meanwhile, the underlying resources for the old stream are destroyed and new resources are created. There seems to be issues with flushing remaining data in such cases (see oggvorbis_decode_frame in libavcodec/libvorbisdec.c). However, on the ogg bitstream side, sending an empty packet as the last packet of the stream is common practice in ogg/opus streams. For this reason, the previous patch in this series allowed opus_packet in libavformat/oggparseopus.c to process empty EOS packets without failing the stream for having invalid data. However, if this packet is allowed to go through ogg_read_packet in libavformat/oggdec.c, then the returned size from the function is 0, which results in a EINVAL error while reading the stream. Thus, this patch makes it so that empty packets are ignored. The bitstream is read further and, if it ends, a proper EOF is returned. Otherwise, a new chained bitream can begin and the demuxer can try to match it. Without this patch, typically, decoding a chained ogg/opus stream with a final empty ogg packet (very common) raises an error on each end of track. To reproduce or test: - Try this command: ffmpeg -re -i http://content.radiosega.net:8006/rs-opus-low.ogg \ -loglevel verbose -f null - This a typical log on track change before this series of patch is applied: <---- LOG BEGIN HERE ----> [ogg @ 0x13b004080] Packet processing failed: Invalid data found when processing input Error demuxing input file 0: Invalid data found when processing input Terminating demuxer thread 0 http://content.radiosega.net:8006/rs-opus-low.ogg: Invalid data found when processing input No more output streams to write to, finishing. [out#0/null @ 0x600000b5c180] All streams finished [out#0/null @ 0x600000b5c180] Terminating muxer thread size=N/A time=00:00:43.12 bitrate=N/A speed= 1x video:0kB audio:8089kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown Input file #0 (http://content.radiosega.net:8006/rs-opus-low.ogg): Input stream #0:0 (audio): 2161 packets read (229129 bytes); 2157 frames decoded (2070720 samples); Total: 2161 packets (229129 bytes) demuxed Output file #0 (pipe:): Output stream #0:0 (audio): 2157 frames encoded (2070720 samples); 2157 packets muxed (8282880 bytes); Total: 2157 packets (8282880 bytes) muxed [AVIOContext @ 0x13b104080] Statistics: 273900 bytes read, 0 seeks <---- LOG END HERE ----> (stream processing stops afterward) This means that, currently, the ffmpeg command line is not able to process chained ogg/opus that typically end with an empty packet beyong its first track. After the patch series is applied: processing continues sucessfully. --- libavformat/oggdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/oggdec.c b/libavformat/oggdec.c index 3b19e0bd89..b0d850a406 100644 --- a/libavformat/oggdec.c +++ b/libavformat/oggdec.c @@ -835,7 +835,7 @@ retry: ret = ogg_packet(s, &idx, &pstart, &psize, &fpos); if (ret < 0) return ret; - } while (idx < 0 || !s->streams[idx]); + } while (idx < 0 || !s->streams[idx] || psize == 0); ogg = s->priv_data; os = ogg->streams + idx; -- 2.37.1 (Apple Git-137.1) _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
prev parent reply other threads:[~2023-05-05 13:35 UTC|newest] Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top 2023-05-05 13:28 [FFmpeg-devel] [PATCH v2 1/3] libavformat/oggparseflac.c: Decode metadata packets toots 2023-05-05 13:28 ` [FFmpeg-devel] [PATCH v2 2/3] libavformat/oggparseopus.c: Accept empty packets, decode " toots 2023-05-05 13:28 ` toots [this message]
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20230505132848.18011-3-toots@rastageeks.org \ --to=toots@rastageeks.org \ --cc=ffmpeg-devel@ffmpeg.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel This inbox may be cloned and mirrored by anyone: git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \ ffmpegdev@gitmailbox.com public-inbox-index ffmpegdev Example config snippet for mirrors. AGPL code for this site: git clone https://public-inbox.org/public-inbox.git