Skip to content

EncoderDelay

uupaa edited this page Feb 22, 2017 · 22 revisions

このエントリでは、Encoder Delay について解説を試みます。

AAC の前後には、無音部分(Encoder Delay)が必ず含まれており、duration はその分だけ長くなります。

#Introduction

AAC requires additional data in order to correctly encode and decode audio samples. During the encoding process, an AAC encoder will require some number of audio samples at input before it can generate an AAC access unit (also referred to as an audio packet). During decoding, data dependencies existing between AAC access units require an AAC decoder to see the "prior" AAC access unit in order to correctly decode the current AAC access unit.

Encoder delay is the term used to describe the delay incurred at encode to produce properly encoded packets. This is the number of silent sample frames (also called priming frames) added to the front of an AAC encoded bitstream.

The term Remainder refers to the number of silent samples (padding) added to the end of an AAC bitstream to round up to the AAC access unit size.

Note: The encoding delay for an AAC encoder is implementation dependent. The decoding delay for an AAC decoder should be fixed and consistent across different implementations.

Encoder Delay

In the original AAC implementations, the common practice was to propagate the encoding delay in the provided AAC bitstream. With these original implementations, the most common delay used was 2112 audio samples. Therefore, an AAC bitstream would generally be 3 AAC access units larger than what was theoretically required by the original signal.

Note: AAC typically represents 1024 samples in one AAC access unit.

As this encoding delay is represented in the AAC bitstream, the first actual audio sample is 2112 samples (the length of the encoding delay) into the decoded output.

In other words, the first and second AAC access units decoded would each produce 1024 samples of silence and the third AAC access unit decoded would produce the first 960 samples of the original source data. 960 being 1024 samples minus the remaining 64 samples of the encoding delay.

Note: 1024 + 1024 + 64 = 2112 encoding delay samples.

A playback implementation would then need to discard these first 2112 silent samples from the decoded output since they contain none of the original source audio data; these samples are an artifact of the encoding/decoding process.

AAC Encoded Bit Stream

2112 samples was chosen because at that time this was the common encoding delay used by most of the shipping implementations of AAC encoders (commercial and otherwise).

In the above diagram, the source audio to be encoded shown as the blue waveform is 5,389 samples long.

This data will be represented in 8 AAC access units, where each access unit represents 1024 audio samples. The total duration represented by these 8 AAC access units is 8192 samples (note that this is longer than the duration of the source audio).

The result breaks down into the following values:

  • 2112 priming samples at the start - required to correctly encode the start of the audio.
  • 5389 samples of actual audio.
  • 691 remainder samples - required to round up the last samples to the packet size.

Therefore, to correctly extract the original 5389 samples of source audio, the first 2112 samples of priming and the last 691 samples of the remainder must be removed.

8192 - 2112 - 691 = 5389 original source samples.

Important: Regardless of the length of source audio, the priming value is currently fixed at 2112 samples and the remainder will always be less than 1024 samples or 1 encoded packet long.

via https://developer.apple.com/library/mac/technotes/tn2258/_index.html

  • Priming samples + samples of actual audio + Remainder samples

    • Priming = 2112 Samples
    • ActualAudio = variable
    • Remainder = Math.max(1024, 1024 - ((2112 + actual) % 1024))
  • Example: 2112(priming) + 5389(actual) + 691(remainder) = 8192 = 1024 Samples x 8

        +---+
        |   | = AAC Frame = AccssUnit = ADTSHeader + RawDataBlocks(1024 Samples)
        +---+

        ======== AAC Encoded Bit Stream ========
        +---++---++---++---++---++---++---++---+
        |   ||   ||   ||   ||   ||   ||   ||   | -> Access Unit (1024 Samples) x 8
        +---++---++---++---++---++---++---++---+

        |----------|------------------------|--|
          Priming    Source Audio(PCM Data)   Remainder

本来のオーディオの前に埋め込まれる無音部分が Priming Samples で、後ろに埋め込まれる無音部分を Remainder Samples と呼びます。

Encoder Delay と Duration

AAC BitStream の frame数(ADTS+RDBs)をカウントし、次の式を使うと AAC全体の長さ(duration)を求める事ができます。

式: (1 / SamplingRate) * 1024 * frames
例: (1 / 44100) * 1024 * 100 = 2.321995464704秒(100フレーム)

上の式から得られるのは 無音部分(Encoder Delay)が含まれた状態の値なのですが、肝心の Encoder Delay に関する情報は AAC BitStream から(基本的に)取得できません。例外として、一部の Encoder は AAC の先頭の Frame に meta 情報を埋め込んでいるようです。

Encoder Delay を処理しないとどうなるか

AAC Decoder は Encoder Delay を必ず取り除く必要があります。

Encoder Delay を除去せず再生すると、様々な謎現象に遭遇してしまいます。

  • 音声が長くなる(60秒のはずが60.6秒になる)
  • 音声の出だしが切られる。最後まで再生されない(デコーダによって前後がカットされてしまう)
  • ts ファイルの継ぎ目部分で click/pop ノイズが発生する

Encoder Delay 情報はどこにあるのか

AAC Decoder は AAC Encoder(Muxer) が書き残した情報(恐らくはメタ情報)を探し出し、その情報を元に Encoder Delayをカットする工程が必要となります。

  • MP4/M4A

    • moov/udta/meta/ilst box の 'iTunSMPB' から得られるらしい
  • MPEG-2 TS

    • MPEG-2 TS の META DESCRIPTION には AUDIO と VIDEO のメタ情報を格納可能なため、META DESCRIPTION をデコードすれば Priming Samples を特定する情報を取得可能かもしれない → TODO: 未解決
  • AAC

    • ffmpeg -i sin.wav -acodec libfdk_aac libfdk.aac を実行すると、特にエンコーダ名は確認できない状態のAACファイルが生成されます(macOS 10.11.6, ffmpeg v3.0.1)
    • ffmpeg -i sin.wav default.aac を実行すると、エンコーダ名が埋め込まれたAACファイルが生成されます(macOS 10.11.6, ffmpeg v3.0.1)
      • 先頭のframe の ID_FIL(fill element) に 'Lavc57.24.102' が確認できます

Magic Number

Apple 製ツールの Priming Samples は 2112 ですが、 実は、このマジックナンバーは AAC Encoder 毎に異なります。

環境 Priming
Samples (sec in 44100Hz)
判別方法
iTunes/QuickTime 2112 (0.04789115645952) 存在する
Nero AAC-LC 2624 (0.05950113378304)
Nero HE-AAC 2336 (0.05297052153856)
Nero HE-AAC v2 2808 (0.06367346938368)
ffmpeg -acodec libfdk_aac 2112 (0.04789115645952)
ffmpeg -acodec aac (ネイティブEncoder) 1024 (0.02321995464704) 存在する
  • 判別方法
    • iTunes/QuickTime では、文字列 'iTunSMPB' が mp4 file の ilst box に存在するため判別が可能
    • ffmpeg -acodec aac では 文字列 'Lavc' が AAC first frame に存在するため判別が可能
  • 廃止されたEncoder
    • libvoaacenc は ffmpeg v3 でサポート打ち切り
    • libaacplus は ffmpeg v3 でサポート打ち切り
  • Sample Rate
    • 44100Hz: 1 / 44100 = 0.00002267573696
    • 48000Hz: 1 / 48000 = 0.00020833333333

AAC Decoder は 適切な情報が(もしあれば)それを元に priming framesを除去した状態でデコードします。

対応するAAC Decoderはそれぞれのpriming framesを仮定し、デコード時に除外するため、注意が必要です。 例えばfaacでエンコードされたAACをiTunesでデコードすると 1024 - 2112 = 1088samples分のエンコード前のデータ成分が先頭から欠落します。 priming framesはmp4のmeta領域にiTunSMPBが存在するならば、2番目の32bit fieldにその値が示されています。

via http://looooooooop.blog35.fc2.com/blog-entry-1106.html

また、以下の mediainfo のサイトには、より詳細な記述が存在します

The following M4A AAC file, iTunSMPB_Example.m4a, has a iTunSMPB tag which it would be nice to display the information from in MediaInfo so that MediaInfo can be a one-stop shop for people to get all their media information needs. The tag is:

iTunSMPB 00000000 00000840 000001CA 00000000003F31F6 00000000 (HEX)
iTunSMPB        0     2112      458          4141558        0 (DEC)

It would be nice for MediaInfo to report the following information:
iTunSMPB Encoder Delay (samples) = 2112
iTunSMPB End Padding (samples) = 458
iTunSMPB Original Sample Count = 4141558
Also, MediaInfo should be consistent in that "Samples Count" is supposed to equal the sum of these three numbers = 4141558 + 458 + 2112 = 4144128.

The format of the iTunSMPB is explained here. The reason why AAC files have encoder delay is explained here The reason for the AAC End Padding is because AAC frame size is 1024 samples, so all AAC encoders add padding to fill up the last AAC frame until the total sample count is divisable by 1024. That is why all AAC files are supposed to have sample count divisable by 1024.

via https://sourceforge.net/p/mediainfo/feature-requests/398/

Mac の finder 上で sin.wav から変換した sin.m4a の場合はこのような値になります。

iTunSMPB 00000000 00000840 00000278 000000000021A548 00000000 (HEX)
iTunSMPB        0     2112      632          2205000        0 (DEC)
samples
Priming 2112
ActualAudio 4141558
Remainder 458

total = 2112 + 4141558 + 458 samples = 4144128 / 1024 = 4047 frames

1 frame は 1024 sample なため、 Priming + ActualAudio + Remainder を 1024 で正確に割り切れる事ができます。(割り切れない場合はどこかがおかしいはずです)。

sin.m4a を Audacity に読み込ませると、Priming を除去した状態の波形を生成しますが、後ろに若干の Remainder が残ってしまうようです。

Encoder Delay の確認

以下の手順で Encoder Delay の存在を確認します。

準備

Audacity のジェネレータ(チャープ)を使い、50秒の徐々に周波数が高くなる波形を生成し、sin.wav として保存します。

$ afinfo -r sin.wav

> Data format:     2 ch,  44100 Hz, 'lpcm' (0x0000000C) 16-bit little-endian signed integer
>                 no channel layout.
> audio bytes: 8820000
> audio packets: 2205000
> estimated duration: 50.000 sec
> bit rate: 1411200 bits per second
> packet size upper bound: 4
> maximum packet size: 4
> audio data file offset: 44
> optimized
> source bit depth: I16

WAV → M4A に変換しても見かけ上は Encoder Delay が含まれていないように振る舞う

sin.wav を Mac の Finder 上で m4a に変換します。 コンテキストメニューから サービス - 選択したオーディオファイルをエンコード を選択し表示されるポップアップで 高品質(128 kbsp 44.1KHz AAC) を選択し 続ける をクリックすると sin.m4a が生成されます。

afinfo -r sin.m4a の情報を見ると duration は 50秒です。恐らくAACには無音部分(Encoder Delay)が含まれているはずですが、duration 情報からは意識的に除外されているようです。

$ afinfo -r sin.m4a

> Data format:     2 ch,  44100 Hz, 'aac ' (0x00000000) 0 bits/channel, 0 bytes/packet, 1024 frames/packet, 0 bytes/frame
> Channel layout: Stereo (L R)
> audio bytes: 666903
> audio packets: 2156
> estimated duration: 50.000 sec
> bit rate: 106571 bits per second
> packet size upper bound: 454
> maximum packet size: 454
> audio data file offset: 12288
> optimized
> audio 2205000 valid frames + 2112 priming + 632 remainder = 2207744
> source bit depth: I16
> format list:
> [ 0] format:	  2 ch,  44100 Hz, 'aac ' (0x00000000) 0 bits/channel, 0 bytes/packet, 1024 frames/packet, 0 bytes/frame
Channel layout: Stereo (L R)

sin.m4a の MP4 box 情報を見ると、 moov/udta/meta/ilst に iTunSMPB が存在します。

生AAC の Duration だけを見ると Encoder Delay が含まれた状態になってしまう

sin.m4a は、MP4コンテナに格納された aac です。 次のコマンドで 生の aac ファイル(ADTS + RawDataBlocks) を無変換で取り出す事ができます。

$ ffmpeg -i sin.m4a -vn -acodec copy sin.aac

取り出した sin.aac を見てみると、 無音部分(Encoder Delay)として 0.062 秒が存在しており、 duration が 50.062秒 になっています。

$ afinfo -r sin.aac

> Data format:     2 ch,  44100 Hz, 'aac ' (0x00000000) 0 bits/channel, 0 bytes/packet, 1024 frames/packet, 0 bytes/frame
> Channel layout: Stereo (L R)
> audio bytes: 681995
> audio packets: 2156
> estimated duration: 50.062 sec
> bit rate: 108983 bits per second
> packet size upper bound: 1536
> maximum packet size: 454
> audio data file offset: 0
> optimized
> format list:
> [ 0] format:	  2 ch,  44100 Hz, 'aac ' (0x00000000) 0 bits/channel, 0 bytes/packet, 1024 frames/packet, 0 bytes/frame
Channel layout: Stereo (L R)

先頭部分を拡大した波形を見てみると、上の波形(sin.wav)に対して、下の波形(sin.aac)の出だしが 約0.048秒ずれており、AAC化により Priming Samples が埋め込まれている事が確認できます。

末尾部分を拡大した波形でも、Remainder Samples が埋め込まれ、トータルで 50.062秒 になっている事を確認できます。

先頭の約0.48秒の無音部分は以下の式で検証できます。

const SamplingRate = 44100;
const SamplingFrames = 1024;
const ApplePrimingSamples = 2112;
const PrimingSamples = (1 / SamplingRate) * SamplingFrames * (ApplePrimingSamples / SamplingFrames);

console.log(PrimingSamples) // -> 0.04789115646258504

これらの事から、

  • WAV を AAC に変換すると Encoder Delay が入る
  • M4A の状態では Encoder Delay は存在しない物として扱われている(補正されている)

という事が分かります。

Link