Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
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".

      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