Opened 11 years ago

Last modified 4 years ago

#2786 reopened defect

last packet of TTA stream in Matroska isn't decoded correctly

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

Description

Using inside.tta from the FATE test suit as an example:

Testing MD5 of the decoded stream:

$ ./ffmpeg -i ../samples/lossless-audio/inside.tta -f md5 -
ffmpeg version N-54738-g04b9836 Copyright (c) 2000-2013 the FFmpeg developers
  built on Jul 14 2013 17:57:33 with gcc 4.7.3 (GCC)
  configuration: --enable-nonfree --enable-gpl --enable-libfdk-aac --enable-libm
p3lame --enable-libvorbis --cross-prefix=x86_64-w64-mingw32- --target-os=mingw32
 --arch=x86_64 --cpu=amdfam10 --prefix=/mingw64
  libavutil      52. 39.100 / 52. 39.100
  libavcodec     55. 18.102 / 55. 18.102
  libavformat    55. 12.102 / 55. 12.102
  libavdevice    55.  3.100 / 55.  3.100
  libavfilter     3. 81.101 /  3. 81.101
  libswscale      2.  3.100 /  2.  3.100
  libswresample   0. 17.102 /  0. 17.102
  libpostproc    52.  3.100 / 52.  3.100
Input #0, tta, from '../samples/lossless-audio/inside.tta':
  Duration: 00:00:11.89, start: 0.000000, bitrate: 814 kb/s
    Stream #0:0: Audio: tta, 44100 Hz, stereo, s16
Output #0, md5, to 'pipe:':
  Metadata:
    encoder         : Lavf55.12.102
    Stream #0:0: Audio: pcm_s16le, 44100 Hz, stereo, s16, 1411 kb/s
Stream mapping:
  Stream #0:0 -> #0:0 (tta -> pcm_s16le)
Press [q] to stop, [?] for help
MD5=d0beb768d860b4776358077dd9fcb1e9
size=       0kB time=00:00:11.88 bitrate=   0.0kbits/s
video:0kB audio:2048kB subtitle:0 global headers:0kB muxing overhead -99.998236%

Remuxing into Matroska:

$ ./ffmpeg -i ../samples/lossless-audio/inside.tta -c:a copy inside.mka
ffmpeg version N-54738-g04b9836 Copyright (c) 2000-2013 the FFmpeg developers
  built on Jul 14 2013 17:57:33 with gcc 4.7.3 (GCC)
  configuration: --enable-nonfree --enable-gpl --enable-libfdk-aac --enable-libm
p3lame --enable-libvorbis --cross-prefix=x86_64-w64-mingw32- --target-os=mingw32
 --arch=x86_64 --cpu=amdfam10 --prefix=/mingw64

[...]

Input #0, tta, from '../samples/lossless-audio/inside.tta':
  Duration: 00:00:11.89, start: 0.000000, bitrate: 814 kb/s
    Stream #0:0: Audio: tta, 44100 Hz, stereo, s16
Output #0, matroska, to 'inside.mka':
  Metadata:
    encoder         : Lavf55.12.102
    Stream #0:0: Audio: tta, 44100 Hz, stereo
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
Press [q] to stop, [?] for help
size=    1182kB time=00:00:12.53 bitrate= 772.4kbits/s
video:0kB audio:1182kB subtitle:0 global headers:0kB muxing overhead 0.053638%

Testing MD5 of the decoded stream, this time from the Matroska file:

$ ./ffmpeg -i inside.mka -f md5 -
ffmpeg version N-54738-g04b9836 Copyright (c) 2000-2013 the FFmpeg developers
  built on Jul 14 2013 17:57:33 with gcc 4.7.3 (GCC)
  configuration: --enable-nonfree --enable-gpl --enable-libfdk-aac --enable-libm
p3lame --enable-libvorbis --cross-prefix=x86_64-w64-mingw32- --target-os=mingw32
 --arch=x86_64 --cpu=amdfam10 --prefix=/mingw64

[...]

Input #0, matroska,webm, from 'inside.mka':
  Metadata:
    ENCODER         : Lavf55.12.102
  Duration: 00:00:11.89, start: 0.000000, bitrate: 814 kb/s
    Stream #0:0: Audio: tta, 44100 Hz, stereo, s16 (default)
Output #0, md5, to 'pipe:':
  Metadata:
    encoder         : Lavf55.12.102
    Stream #0:0: Audio: pcm_s16le, 44100 Hz, stereo, s16, 1411 kb/s (default)
Stream mapping:
  Stream #0:0 -> #0:0 (tta -> pcm_s16le)
Press [q] to stop, [?] for help
MD5=eb96f9b80e0ce6bc5ddd841a8843620a
size=       0kB time=00:00:11.49 bitrate=   0.0kbits/s
video:0kB audio:1980kB subtitle:0 global headers:0kB muxing overhead -99.998175%

Remuxing inside.tta using mkvtoolnix, then testing MD5 of the decoded stream:

$ ./ffmpeg -i inside_mkvtoolnix.mka -f md5 -
ffmpeg version N-54738-g04b9836 Copyright (c) 2000-2013 the FFmpeg developers
  built on Jul 14 2013 17:57:33 with gcc 4.7.3 (GCC)
  configuration: --enable-nonfree --enable-gpl --enable-libfdk-aac --enable-libm
p3lame --enable-libvorbis --cross-prefix=x86_64-w64-mingw32- --target-os=mingw32
 --arch=x86_64 --cpu=amdfam10 --prefix=/mingw64

[...]

Input #0, matroska,webm, from 'inside_mkvtoolnix.mka':
  Metadata:
    creation_time   : 2013-07-15 07:41:51
  Duration: 00:00:11.89, start: 0.000000, bitrate: 818 kb/s
    Stream #0:0: Audio: tta, 44100 Hz, stereo, s16 (default)
Output #0, md5, to 'pipe:':
  Metadata:
    encoder         : Lavf55.12.102
    Stream #0:0: Audio: pcm_s16le, 44100 Hz, stereo, s16, 1411 kb/s (default)
Stream mapping:
  Stream #0:0 -> #0:0 (tta -> pcm_s16le)
Press [q] to stop, [?] for help
MD5=eb96f9b80e0ce6bc5ddd841a8843620a
size=       0kB time=00:00:11.49 bitrate=   0.0kbits/s
video:0kB audio:1980kB subtitle:0 global headers:0kB muxing overhead -99.998175%

To make sure I tried the bit-compare plugin for foobar2000, and unlike with avformat, both inside.tta and any of the Matroska files are the same:

All tracks decoded fine, no differences found.

Comparing:
"D:\MinGW\msys\1.0\ffmpeg\samples\lossless-audio\inside.tta"
"D:\MinGW\msys\1.0\ffmpeg\build\inside.mka"
No differences in decoded data found.
All tracks decoded fine, no differences found.

Comparing:
"D:\MinGW\msys\1.0\ffmpeg\samples\lossless-audio\inside.tta"
"D:\MinGW\msys\1.0\ffmpeg\build\inside_mkvtoolnix.mka"
No differences in decoded data found.

After converting inside.tta into WAV pcm_s16le with "./ffmpeg -i ../samples/lossless-audio/inside.tta inside_tta.wav":

All tracks decoded fine, no differences found.

Comparing:
"D:\MinGW\msys\1.0\ffmpeg\samples\lossless-audio\inside.tta"
"D:\MinGW\msys\1.0\ffmpeg\build\inside_tta.wav"
No differences in decoded data found.

After converting inside.mka into WAV pcm_s16le with "./ffmpeg -i inside.mka inside_mka.wav":

Differences found in 1 out of 1 track pairs.

Comparing:
"D:\MinGW\msys\1.0\ffmpeg\samples\lossless-audio\inside.tta"
"D:\MinGW\msys\1.0\ffmpeg\build\inside_mka.wav"
Length mismatch : 0:11.888367 vs 0:11.493878, 524277 vs 506880 samples

Looks like the Matroska demuxer is discarding data at the end of the stream or something, without giving an error or warning.

Attachments (1)

linux_x86_ticket2786.txt (5.7 KB ) - added by jamal 11 years ago.
Same tests on Linux x86

Download all attachments as: .zip

Change History (15)

comment:1 by Carl Eugen Hoyos, 11 years ago

Keywords: mkv added; matroska removed

comment:2 by Elon Musk, 11 years ago

Resolution: invalid
Status: newclosed

This is not our bug. Demuxing/muxing works fine.
There is no reliable way to decode last frame of TTA in matroska. As real number of samples in file is nowhere stored.

comment:3 by Hendrik, 11 years ago

Then how does foobar manage to reproduce the original stream perfectly?

comment:4 by Elon Musk, 11 years ago

Easy, by uploading file produced with foobar.

comment:5 by Elon Musk, 11 years ago

Actually ignore that one, from report I see nowhere proof that foobar whatever thing actually decodes everything.

So to make things valid, one should decode mka and tta into wav with foobar and than compare.

I already know that tta muxed in mkv can not usually decode last audio frame using ffmpeg so nothing new to me.

comment:6 by jamal, 11 years ago

Both files converted into WAV using foobar2000:

$ ./ffmpeg -i inside_mka_fb2k.wav -f md5 -
ffmpeg version N-54738-g04b9836 Copyright (c) 2000-2013 the FFmpeg developers
  built on Jul 14 2013 17:57:33 with gcc 4.7.3 (GCC)
  configuration: --enable-nonfree --enable-gpl --enable-libfdk-aac --enable-libm
p3lame --enable-libvorbis --cross-prefix=x86_64-w64-mingw32- --target-os=mingw32
 --arch=x86_64 --cpu=amdfam10 --prefix=/mingw64

[...]

Guessed Channel Layout for  Input Stream #0.0 : stereo
Input #0, wav, from 'inside_mka_fb2k.wav':
  Duration: 00:00:11.89, bitrate: 1411 kb/s
    Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, stereo, s16
, 1411 kb/s
Output #0, md5, to 'pipe:':
  Metadata:
    encoder         : Lavf55.12.102
    Stream #0:0: Audio: pcm_s16le, 44100 Hz, stereo, s16, 1411 kb/s
Stream mapping:
  Stream #0:0 -> #0:0 (pcm_s16le -> pcm_s16le)
Press [q] to stop, [?] for help
MD5=d0beb768d860b4776358077dd9fcb1e9
size=       0kB time=00:00:11.88 bitrate=   0.0kbits/s
video:0kB audio:2048kB subtitle:0 global headers:0kB muxing overhead -99.998236%
$ ./ffmpeg -i inside_tta_fb2k.wav -f md5 -
ffmpeg version N-54738-g04b9836 Copyright (c) 2000-2013 the FFmpeg developers
  built on Jul 14 2013 17:57:33 with gcc 4.7.3 (GCC)
  configuration: --enable-nonfree --enable-gpl --enable-libfdk-aac --enable-libm
p3lame --enable-libvorbis --cross-prefix=x86_64-w64-mingw32- --target-os=mingw32
 --arch=x86_64 --cpu=amdfam10 --prefix=/mingw64

[...]

  libpostproc    52.  3.100 / 52.  3.100
Guessed Channel Layout for  Input Stream #0.0 : stereo
Input #0, wav, from 'inside_tta_fb2k.wav':
  Duration: 00:00:11.89, bitrate: 1411 kb/s
    Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, stereo, s16
, 1411 kb/s
Output #0, md5, to 'pipe:':
  Metadata:
    encoder         : Lavf55.12.102
    Stream #0:0: Audio: pcm_s16le, 44100 Hz, stereo, s16, 1411 kb/s
Stream mapping:
  Stream #0:0 -> #0:0 (pcm_s16le -> pcm_s16le)
Press [q] to stop, [?] for help
MD5=d0beb768d860b4776358077dd9fcb1e9
size=       0kB time=00:00:11.88 bitrate=   0.0kbits/s
video:0kB audio:2048kB subtitle:0 global headers:0kB muxing overhead -99.998236%

Same MD5 as the correct TTA demuxing with ffmpeg.

comment:7 by Elon Musk, 11 years ago

You are not testing demuxing at all, you are testing decoding. As I already said demuxing is perfect, the only thing that is missing is number of samples in last packet - which is essential for correct decoding of last frame, but for some reason you cut out error reported in decoding.

How foobar manages to guess number of samples in last packet is essential to solving this bug.

AFAIK there is nowhere in matroska stored actual number of audio samples put into TTA stream.

comment:7 by Elon Musk, 11 years ago

You are not testing demuxing at all, you are testing decoding. As I already said demuxing is perfect, the only thing that is missing is number of samples in last packet - which is essential for correct decoding of last frame, but for some reason you cut out error reported in decoding.

How foobar manages to guess number of samples in last packet is essential to solving this bug.

AFAIK there is nowhere in matroska stored actual number of audio samples put into TTA stream.

comment:8 by Elon Musk, 11 years ago

Resolution: invalid
Status: closedreopened
Summary: TTA streams in Matroska aren't demuxed correctlylast packet of TTA stream in Matroska isn't decoded correctly

comment:9 by jamal, 11 years ago

I have not cut out any errors in any of the outputs.
They are intact, save for the section that reports libraries version which i replaced with a [...] placeholder in all except the first output i pasted here.

And I have no idea how foobar2000 guesses the size of last packet since unfortunately it's not an open source player (Beyond using libavcodec to decode mp3, aac and vorbis streams).

comment:10 by Elon Musk, 11 years ago

Then how i get error whan decoding mka created with ffmpeg?

comment:11 by jamal, 11 years ago

I have no idea.
I'm using inside.tta from the FATE suit, ffmpeg compiled from git-head using mingw-w64 and Linux x86, and running "./ffmpeg -i inside.tta -c:a copy inside.mka" then "./ffmpeg -i inside.mka -f md5 -" doesn't report any demuxing or decoding errors at all.

I have even tried remuxing the mka into another mka with "./ffmpeg -i inside.mka -c:a copy inside2.mka" and still no errors.

by jamal, 11 years ago

Attachment: linux_x86_ticket2786.txt added

Same tests on Linux x86

comment:12 by Elon Musk, 11 years ago

Ah, it must be because of rounding error when using doubles.

comment:13 by mkver, 4 years ago

When I remux inside.tta with MKVToolNix, the TimestampScale is by default choosen so small that one can represent the timestamps sample-accurately. In this case the md5 is correct and no decoding error exists.

mkvmerge stores the information about the length twice in the file: Once in Info and once in a BlockDuration element (the last frame is written as BlockGroup, not as SimpleBlock). It is the duration in the Info element (that gets included in the extradata) that matters. The BlockDuration element gets exported, but it seems to be ignored by the decoder. Which is a shame because the duration in Info is not per-track, so one automatically has a problem when the file contains more than one track.

Note: See TracTickets for help on using tickets.