[FFmpeg-devel] [PATCH] avformat/matroskadec: force 48kHz sample rate when rescaling Opus inital padding

James Almer jamrial at gmail.com
Mon Jun 6 21:13:51 CEST 2016


Mkvtoolnix stores the sample rate of the original stream as reported by the
"OpusHead" stream header instead of 48kHz, the actual sample rate of the Opus
stream.
Ignoring the stored sample rate and forcing 48kHz preserves the correct initial
padding when remuxing.

Signed-off-by: James Almer <jamrial at gmail.com>
---
OggOpus files created by opus-tools then remuxed into Matroska with mkvtoolnix
results in files like the one mentioned above. See https://0x0.st/caG.mka or just
use mkvtoolnix to remux fate-samples/ogg/intro-partial.opus

Before this patch:

$ mkvinfo caG.mka | grep delay
|  + Codec delay: 7.417ms (7416667ns)

$ mkvinfo caG.mka | grep Sampling
|   + Sampling frequency: 44100

$ ffmpeg -v 0 -i caG.mka -c:a copy before.webm

$ mkvinfo before.webm | grep delay
|  + Codec delay: 6.812ms (6812500ns)

$ mkvinfo before.webm | grep Sampling
|   + Sampling frequency: 48000

Firefox can't play before.webm, but Opera (Chromium based) can.

After this patch:

$ ffmpeg -v 0 -i caG.mka -c:a copy after.webm

$ mkvinfo after.webm | grep delay
|  + Codec delay: 7.417ms (7416667ns)

$ mkvinfo after.webm | grep Sampling
|   + Sampling frequency: 48000

Both Firefox and Opera play after.webm


I'm adding a check for Opus since I don't know when or if some other codec will
use the codec_delay element in the future. At least for now it seems to be Opus
exclusive.

 libavformat/matroskadec.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index 3270009..7880a10 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -2353,7 +2353,8 @@ static int matroska_parse_tracks(AVFormatContext *s)
             if (track->codec_delay > 0) {
                 st->codecpar->initial_padding = av_rescale_q(track->codec_delay,
                                                              (AVRational){1, 1000000000},
-                                                             (AVRational){1, st->codecpar->sample_rate});
+                                                             (AVRational){1, st->codecpar->codec_id == AV_CODEC_ID_OPUS ?
+                                                                             48000 : st->codecpar->sample_rate});
             }
             if (track->seek_preroll > 0) {
                 st->codecpar->seek_preroll = av_rescale_q(track->seek_preroll,
-- 
2.8.2



More information about the ffmpeg-devel mailing list