Opened 9 years ago

Closed 9 years ago

Last modified 9 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 by Carl Eugen Hoyos, 9 years ago

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 by pszemus, 9 years ago

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 by Carl Eugen Hoyos, 9 years ago

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 by pszemus, 9 years ago

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 by Carl Eugen Hoyos, 9 years ago

Component: undeterminedavformat
Keywords: mkv opus added
Resolution: fixed
Status: newclosed
Summary: Wrong sample rate read from / written to opus webm fileOpus initial padding incorrectly written to mkv for sample rates != 48kHz
Version: unspecifiedgit-master

comment:6 by Carl Eugen Hoyos, 9 years ago

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

comment:7 by Jérôme Martinez, 9 years ago

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 by Carl Eugen Hoyos, 9 years ago

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.