Opened 4 years ago

Closed 4 years ago

Last modified 4 years ago

#5121 closed defect (fixed)

Opus initial padding incorrectly written to mkv for sample rates != 48kHz

Reported by: pszemus Owned by:
Priority: normal Component: avformat
Version: git-master Keywords: mkv opus
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description

Summary of the bug:
As reported in https://bugzilla.mozilla.org/show_bug.cgi?id=1227153 trying to create a 24kHz opus@webm file produces a file that has 48kHz written to an opus header (?). What's strange is that MediaInfo? shows this sample rate correctly.

How to reproduce:

$ ffmpeg -i http://www.soundsnap.com/audio/play/72210%3A1448291371%3Ab4326304c013a3a61b3b87d83158c91b -c:a libopus -b:a 64k -ar 24000 /tmp/tmp.webm
ffmpeg version N-77704-g68eb208 Copyright (c) 2000-2016 the FFmpeg developers
  built with gcc 4.8.5 (GCC) 20150623 (Red Hat 4.8.5-4)
  configuration: --prefix=/home/pszemus/ffmpeg/build --enable-pic --enable-pthreads --enable-libmp3lame --enable-version3 --enable-libfaac --enable-gpl --enable-nonfree --enable-libvpx --enable-libvorbis --enable-libopus --enable-libx264 --enable-libwebp --enable-protocol=https --enable-openssl --extra-cflags=-I/opt/WP/common.libs/include --extra-ldflags='-L/opt/WP/common.libs/lib -ldl'
  libavutil      55. 12.100 / 55. 12.100
  libavcodec     57. 21.100 / 57. 21.100
  libavformat    57. 21.100 / 57. 21.100
  libavdevice    57.  0.100 / 57.  0.100
  libavfilter     6. 23.100 /  6. 23.100
  libswscale      4.  0.100 /  4.  0.100
  libswresample   2.  0.101 /  2.  0.101
  libpostproc    54.  0.100 / 54.  0.100
[mp3 @ 0x2ae63a0] Skipping 0 bytes of junk at 0.
[mp3 @ 0x2ae63a0] Estimating duration from bitrate, this may be inaccurate
Input #0, mp3, from 'http://www.soundsnap.com/audio/play/72210%3A1448291371%3Ab4326304c013a3a61b3b87d83158c91b':
  Metadata:
    title           : PleaseRefesh2015_1
    date            : 2015
    track           : 1
  Duration: 00:00:04.13, start: 0.000000, bitrate: 192 kb/s
    Stream #0:0: Audio: mp3, 44100 Hz, stereo, s16p, 192 kb/s
Output #0, webm, to '/tmp/tmp.webm':
  Metadata:
    title           : PleaseRefesh2015_1
    date            : 2015
    track           : 1
    encoder         : Lavf57.21.100
    Stream #0:0: Audio: opus (libopus), 24000 Hz, stereo, s16, 64 kb/s
    Metadata:
      encoder         : Lavc57.21.100 libopus
Stream mapping:
  Stream #0:0 -> #0:0 (mp3 (native) -> opus (libopus))
Press [q] to stop, [?] for help
size=      37kB time=00:00:04.13 bitrate=  73.7kbits/s speed=15.4x    
video:0kB audio:35kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 5.376523%
$ ffmpeg -i /tmp/tmp.webm 
ffmpeg version N-77704-g68eb208 Copyright (c) 2000-2016 the FFmpeg developers
  built with gcc 4.8.5 (GCC) 20150623 (Red Hat 4.8.5-4)
  configuration: --prefix=/home/pszemus/ffmpeg/build --enable-pic --enable-pthreads --enable-libmp3lame --enable-version3 --enable-libfaac --enable-gpl --enable-nonfree --enable-libvpx --enable-libvorbis --enable-libopus --enable-libx264 --enable-libwebp --enable-protocol=https --enable-openssl --extra-cflags=-I/opt/WP/common.libs/include --extra-ldflags='-L/opt/WP/common.libs/lib -ldl'
  libavutil      55. 12.100 / 55. 12.100
  libavcodec     57. 21.100 / 57. 21.100
  libavformat    57. 21.100 / 57. 21.100
  libavdevice    57.  0.100 / 57.  0.100
  libavfilter     6. 23.100 /  6. 23.100
  libswscale      4.  0.100 /  4.  0.100
  libswresample   2.  0.101 /  2.  0.101
  libpostproc    54.  0.100 / 54.  0.100
Input #0, matroska,webm, from '/tmp/tmp.webm':
  Metadata:
    title           : PleaseRefesh2015_1
    encoder         : Lavf57.21.100
  Duration: 00:00:04.14, start: 0.007000, bitrate: 73 kb/s
    Stream #0:0: Audio: opus, 48000 Hz, stereo, fltp (default)
At least one output file must be specified
$ mediainfo /tmp/tmp.webm 
General
Unique ID                                : 23699742163318188445154506414781705045 (0x11D46780E7425B3B392AC806ACE92B55)
Complete name                            : /tmp/tmp.webm
Format                                   : WebM
Format version                           : Version 4 / Version 2
File size                                : 37.2 KiB
Duration                                 : 4s 135ms
Overall bit rate                         : 73.6 Kbps
Track name                               : PleaseRefesh2015_1
Writing application                      : Lavf57.21.100
Writing library                          : Lavf57.21.100

Audio
ID                                       : 1
Format                                   : Opus
Codec ID                                 : A_OPUS
Duration                                 : 4s 135ms
Channel(s)                               : 2 channels
Channel positions                        : Front: L R
Sampling rate                            : 24.0 KHz
Bit depth                                : 16 bits
Compression mode                         : Lossy
Default                                  : Yes
Forced                                   : No

Change History (8)

comment:1 Changed 4 years ago by cehoyos

I thought this is just how the opus codec works, but reading the Mozilla bug report maybe you just want MediaCodec? not to show the original sample rate?

comment:2 Changed 4 years ago by pszemus

No, I want the ffmpeg to create with and report the correct sample rate value.
Let's create an opus file like this:

$ ffmpeg -i http://www.soundsnap.com/audio/play/72210%3A1448291371%3Ab4326304c013a3a61b3b87d83158c91b -c:a libopus -b:a 64k -ar 24000 /tmp/tmp.opus
ffmpeg version N-77704-g68eb208 Copyright (c) 2000-2016 the FFmpeg developers
  built with gcc 4.8.5 (GCC) 20150623 (Red Hat 4.8.5-4)
  configuration: --prefix=/home/pszemus/ffmpeg/build --enable-pic --enable-pthreads --enable-libmp3lame --enable-version3 --enable-libfaac --enable-gpl --enable-nonfree --enable-libvpx --enable-libvorbis --enable-libopus --enable-libx264 --enable-libwebp --enable-protocol=https --enable-openssl --extra-cflags=-I/opt/WP/common.libs/include --extra-ldflags='-L/opt/WP/common.libs/lib -ldl'
  libavutil      55. 12.100 / 55. 12.100
  libavcodec     57. 21.100 / 57. 21.100
  libavformat    57. 21.100 / 57. 21.100
  libavdevice    57.  0.100 / 57.  0.100
  libavfilter     6. 23.100 /  6. 23.100
  libswscale      4.  0.100 /  4.  0.100
  libswresample   2.  0.101 /  2.  0.101
  libpostproc    54.  0.100 / 54.  0.100
[mp3 @ 0x3c683a0] Skipping 0 bytes of junk at 0.
[mp3 @ 0x3c683a0] Estimating duration from bitrate, this may be inaccurate
Input #0, mp3, from 'http://www.soundsnap.com/audio/play/72210%3A1448291371%3Ab4326304c013a3a61b3b87d83158c91b':
  Metadata:
    title           : PleaseRefesh2015_1
    date            : 2015
    track           : 1
  Duration: 00:00:04.13, start: 0.000000, bitrate: 192 kb/s
    Stream #0:0: Audio: mp3, 44100 Hz, stereo, s16p, 192 kb/s
Output #0, opus, to '/tmp/tmp.opus':
  Metadata:
    title           : PleaseRefesh2015_1
    date            : 2015
    track           : 1
    encoder         : Lavf57.21.100
    Stream #0:0: Audio: opus (libopus), 24000 Hz, stereo, s16, 64 kb/s
    Metadata:
      encoder         : Lavc57.21.100 libopus
      title           : PleaseRefesh2015_1
      date            : 2015
      TRACKNUMBER     : 1
Stream mapping:
  Stream #0:0 -> #0:0 (mp3 (native) -> opus (libopus))
Press [q] to stop, [?] for help
size=      36kB time=00:00:04.13 bitrate=  71.0kbits/s speed=15.3x    
video:0kB audio:35kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 1.533776%

Now compare the output form FFmpeg and opusinfo (from opus-tools) analysis:

$ ffmpeg -i /tmp/tmp.opus 
ffmpeg version N-77704-g68eb208 Copyright (c) 2000-2016 the FFmpeg developers
  built with gcc 4.8.5 (GCC) 20150623 (Red Hat 4.8.5-4)
  configuration: --prefix=/home/pszemus/ffmpeg/build --enable-pic --enable-pthreads --enable-libmp3lame --enable-version3 --enable-libfaac --enable-gpl --enable-nonfree --enable-libvpx --enable-libvorbis --enable-libopus --enable-libx264 --enable-libwebp --enable-protocol=https --enable-openssl --extra-cflags=-I/opt/WP/common.libs/include --extra-ldflags='-L/opt/WP/common.libs/lib -ldl'
  libavutil      55. 12.100 / 55. 12.100
  libavcodec     57. 21.100 / 57. 21.100
  libavformat    57. 21.100 / 57. 21.100
  libavdevice    57.  0.100 / 57.  0.100
  libavfilter     6. 23.100 /  6. 23.100
  libswscale      4.  0.100 /  4.  0.100
  libswresample   2.  0.101 /  2.  0.101
  libpostproc    54.  0.100 / 54.  0.100
Input #0, ogg, from '/tmp/tmp.opus':
  Duration: 00:00:04.13, start: 0.000000, bitrate: 70 kb/s
    Stream #0:0: Audio: opus, 48000 Hz, stereo, fltp
    Metadata:
      ENCODER         : Lavc57.21.100 libopus
      TITLE           : PleaseRefesh2015_1
      DATE            : 2015
      track           : 1
At least one output file must be specified
$ opusinfo /tmp/tmp.opus 
Processing file "/tmp/tmp.opus"...

New logical stream (#1, serial: 281a7d51): type opus
Encoded with Lavf57.21.100
User comments section follows...
        encoder=Lavc57.21.100 libopus
        title=PleaseRefesh2015_1
        date=2015
        TRACKNUMBER=1
Opus stream 1:
        Pre-skip: 156
        Playback gain: 0 dB
        Channels: 2
        Original sample rate: 24000Hz
        Packet duration:   20.0ms (max),   20.0ms (avg),   20.0ms (min)
        Page duration:   1000.0ms (max),  828.0ms (avg),  140.0ms (min)
        Total data length: 36674 bytes (overhead: 1.51%)
        Playback length: 0m:04.130s
        Average bitrate: 71.03 kb/s, w/o overhead: 69.96 kb/s
Logical stream 1 ended

Where this inconsistency come from? Why does FFmpeg and Firefox report 48kHz sample rate when MediaInfo? and opusinfo show 24kHz?

comment:3 Changed 4 years ago by cehoyos

Because Opus files always have a sample rate of 48kHz but the original sample rate is also written to the bitstream (but not used for decoding) so opusinfo is able to show it for informational purpose.

I sent a patch that may fix the issue described by Timothy Terriberry, this is not related to the shown sample rate.

comment:4 Changed 4 years ago by pszemus

You seem to be right as I read more about opus.
Also, browsing through forums, I've found a term:

YAMRI: Yet Another Mediainfo Related Issue.

comment:5 Changed 4 years ago by cehoyos

  • Component changed from undetermined to avformat
  • Keywords mkv opus added
  • Resolution set to fixed
  • Status changed from new to closed
  • Summary changed from Wrong sample rate read from / written to opus webm file to Opus initial padding incorrectly written to mkv for sample rates != 48kHz
  • Version changed from unspecified to git-master

comment:6 Changed 4 years ago by cehoyos

Should be fixed in c3c22bee6362737cf290929b7f31df9fb88da983 - thank you for the report and the testing!

comment:7 Changed 4 years ago by Zenitram

YAMRI: Yet Another Mediainfo Related Issue.

By curiosity, why do you consider that it is a MediaInfo? related issue?
Looks like MediaInfo? does its job: it shows the sampling rate indicated in the Matroska header (FYI, MediaInfo? does not parse Opus so it relies on the Matroska header, and displays the exact content from the Matroska header, this is the expected result, even if Opus is parsed: when Opus is supported by MediaInfo?, MediaInfo? will report both sampling rates, the one from Matroska header and the one form Opus, and Opus is always 48 kHz if I understand well so MediaInfo? will display the discrepancy between Matroska header and Opus 48 kHz only by design).
YAFRI (Yet Another FFmpeg Related Issue) and fixed in FFmpeg instead?

comment:8 Changed 4 years ago by cehoyos

The issue that FFmpeg only displays the actual Opus sample rate but not the sample rate used for encoding is not fixed yet.
But his is completely unrelated to the muxing issue that was fixed.

Note: See TracTickets for help on using tickets.