Fixed bug in ffmpeg shows HE-AAC not gapless (should be 5186)
See https://github.com/FFmpeg/FFmpeg/commit/5114ce1e2a4c71ddf4971ad3cf9bd43ae16571c3
You wrote 2112 in media time (so using --gapless-mode 1) instead for --he, but 2112 is only correct for AAC LC.
5186 is sample accurate, I checked.
You can use ignore_editlist 1 in ffmpeg to verify.
- qaac (and fdkaac) uses down-sampled timescale for HE-AAC. So media_time in edits gets halved.
- qaac (and fdkaac) omit implicit 481 samples SBR decoder delay for iTunSMPB and edits.
Basically I just follow what iTunes does for HE-AAC. HE-AAC is a layered format over LC, and I believe these are all for the sake of compatibility with LC-AAC. they should be correct even when decoded as LC-AAC, but HE-AAC decoder has to take into account added decoder delay by themself.
In short, (2112+481) * 2 will exactly give you 5186.
- uses down-sampled timescale for HE-AAC. So media_time in edits gets halved
No, fdkaac is truely gapless in v2 of HE-AAC and v1 after fix in ffmpeg (it writes 5058 for HE-AACv1 and 7106 for HE-AACv2, each sample is one sample). So you mean there is another bug in ffmpeg? I heard about it. Even mediainfo does not check timescale, see https://github.com/MediaArea/MediaInfoLib/issues/1441
media_time is an integer containing the starting time within the media of this edit segment (in media time scale units, in composition time).
Also see our bug in chrome/chromium fixed by that commit in FFmpeg: https://bugs.chromium.org/p/chromium/issues/detail?id=1234227#c_ts1659959705
It is now truly gapless in Chrome (because chrome also removes remainder per media duration in editlist, ffmpeg does not yet).
Historically, Nero and Winamp's FhG AAC encoder include SBR delay in encoder delay. Apple does not. As for FDK-AAC, they have changed their API. On their V1 API AACInfo.encoderDelay included SBR delay. On V2 API, they have AACInfo.nDelay(which include SBR delay) and AACInfo.nDelayCore(which does not include SBR delay).
fdkaac uses the latter on V2 API. On V1, fdkaac just manually subtracts 481*2 from AACInfo.encoderDelay to get core(LC) delay.
So, decoder has to deal with two possibilities to achieve true gapless playback of HE-AAC. As for qaac, when HE-AAC M4A is in up-sampled time scale, then it assumes SBR delay is included (Nero/FhG-AAC style). Otherwise, it assumes SBR delay is not included (Apple style).
How hard would it be to fix this value (and timescale) to 5186? It is just an if condition on he option...
So, decoder has to deal with two possibilities to achieve true gapless playback of HE-AAC.
It does not look like ffmpeg does it... It does not even support ITunSMPB (seamless playback), even for mp3! BTW, this is the first time I hear about SBR delay, I will admit so. I do not get how you would "see" it is there.
You know I see qaac64.exe xxx.m4a --decode is indeed truely gapless. Sample accurate, both wavs have 11462400 samples.
Still it is not cool ffmpeg cannot do it.
So Time scale: 24000 (0x00005DC0) - 24000 Hz should be changed to Time scale: 1000 (0x000003E8) - 1000 Hz...
Actually I just found out that ffmpeg does remove SBR delay, wow. But after the fix it now removes 6144, while before the fix 6272. The difference is 128 only in the start, not in the end.
The point is 6144 is closer to our 5186, which is good. But, it looks like it does 6144/2 = 3072. Now, 3072- 2112 is 960. 960 is SBR delay in libfdk-aac. Here we go! You can change 2112 to 1633 to get gapless playback!