AACエンコーダディレイとx264guiExでの対処方法について
音ズレについて再調査したので、いい機会なのでまとめてみた。
AACエンコーダは一般に2つのフレームで完全な音を出すデータを保持するため、最初の音声フレームからは完全な音を出すことができず、この問題を解消するため、最初に無音のフレームを挿入する。この無音区間で生じる遅延がencoder delayで、そのままでは映像との同期がずれる(音ずれ)原因となりうる。このAACのencoder delayについてはこちらが非常に詳しい。
x264guiExではL-SMASH muxerにお世話になり、その機能を活用するなどして、このディレイカットにx264guiEx 2.05から対応している。
結論から言うと、現在のx264guiExでデフォルトの「AAC (ffmpeg)」エンコーダを使用して出力した場合、edit listの情報によるディレイカットがなされるため、encoder delayは補正され、(encoder delayが原因で)音ずれすることはない。
多くの方はAACエンコーダのディレイについてはご存じと思うが、このあたりのx264guiExでの対応方法をまとめたものがなかったと思うので、今回まとめてみた。
AACエンコーダの遅延は、エンコーダごとに遅延量は決まっており、下記sample数となっている。(HE-AAC*は元の周波数での値)
例えば、ffmpeg AACの無音区間は1024sampleなので、音声のサンプリングレートは48kHzの場合21.3ms、44.1kHzの場合23.2msの遅延が生じる。
これに対して、x264guiExではx264guiEx 2.05以降、音ずれを打ち消す方法を2パターン用意している。
(1). edit listを用いる方法
mp4/m4aコンテナのedit list情報を使用して、encoder delayをdemuxer/デコーダに伝え、demux/デコード時に補正させる方法。
edit listが存在するかどうかはmp4box -info "mp4ファイル" で確認できる。例えば、ffmpeg AACの出力をみるとこんな感じ。
Track # 2 Info - TrackID 2 - TimeScale 44100
Media Duration 00:00:03.023 - Indicated Duration 00:00:03.023
Track has 1 edit lists: track duration is 00:00:03.000 <<<< これ
edit listの効果は、下記のように見ることができる。
一番上: オリジナル
真ん中: ffmpegのAACエンコーダでedit listの情報を持たせない場合
一番下: ffmpegのAACエンコーダでedit listの情報を持たせた場合

edit listの情報を持たせ、(demux/デコード時に)それを反映することで、ffmpegのAACエンコーダで発生する遅延(1024sample = 23.2ms@44.1kHz)を除去できていることがわかる。
ただし、この方法をうまく活用するには、再生時・デコード時にedit listの情報を反映してくれるdemuxer/デコーダが必要になる。ffmpegとそれを使用するソフトウェア(lwinput.aui)などは問題なくedit listの情報を反映してくれる。
一方、使っている人がいるかはわからないが"MP4 File Reader"などはedit listの情報を反映してくれないみたいなので、できればlwinput.auiを使用したほうがよいと思う。
(1)-1 x264guiExのディレイカット「補正なし」 (=デフォルト)
デフォルトの「補正なし」でも一部の音声エンコーダについては、remuxerでmuxすることで、各音声エンコーダが出力するm4aに含まれるedit listをそのまま活用することができるようにしている。
ディレイカット「補正なし」で音声エンコーダの出力するedit listの活用が可能なのは下記のエンコーダ。
これ以外のAACエンコーダ、例えばneroaacencについては、edit listの情報込みのm4aを出力できず「補正なし」では遅延が生じるため、encoder delay対策のためには次の「(1)-2 : edts」を使用する必要がある。
(1)-2 x264guiExのディレイカット「edts」
(1)-1の方法のとれないneroaacencなどの音声エンコーダを用いる場合の方法。L-SMASH muxerのencoder-delayオプションで指定したedit listにより対応する。
このときの音声エンコーダごとの無音区間のsample数は、x264guiEx.iniのmode_x_delayに記載されているものを使用している。
(2). 映像・音声の長さを調整して無理やり同期する方法
edit listを使わず、無理やり同期させる方法のため、特に問題なければ(1)の方法をとるべきと思う。
(2)-1 x264guiExのディレイカット「音声カット」 :
遅延するsample数分、音声の前方をカットして帳尻あわせをする方法。すぐに音声が始まっている動画には不向きだと思う。
(2)-2 x264guiExのディレイカット「映像追加」
遅延するsample数を見越して、先頭に映像・音声フレームを追加して帳尻あわせをする方法。映像・音声の動機は取れるが元動画より映像・音声ともに遅れが生じ、動画時間が延びる。
参考資料
EncoderDelay
Audio Priming - Handling Encoder Delay in AAC
終わりに
AACエンコーダの遅延と、x264guiExでの対処方法についてまとめた。
もし間違ってる点等あればご指摘ください。
AACエンコーダは一般に2つのフレームで完全な音を出すデータを保持するため、最初の音声フレームからは完全な音を出すことができず、この問題を解消するため、最初に無音のフレームを挿入する。この無音区間で生じる遅延がencoder delayで、そのままでは映像との同期がずれる(音ずれ)原因となりうる。このAACのencoder delayについてはこちらが非常に詳しい。
x264guiExではL-SMASH muxerにお世話になり、その機能を活用するなどして、このディレイカットにx264guiEx 2.05から対応している。
結論から言うと、現在のx264guiExでデフォルトの「AAC (ffmpeg)」エンコーダを使用して出力した場合、edit listの情報によるディレイカットがなされるため、encoder delayは補正され、(encoder delayが原因で)音ずれすることはない。
多くの方はAACエンコーダのディレイについてはご存じと思うが、このあたりのx264guiExでの対応方法をまとめたものがなかったと思うので、今回まとめてみた。
AACエンコーダの遅延は、エンコーダごとに遅延量は決まっており、下記sample数となっている。(HE-AAC*は元の周波数での値)
AAC-LC | HE-AAC | HE-AACv2 | |
ffmpeg | 1024 | ||
qaac | 2112 | 5184 | |
nero | 2624 | 4672 | 5616 |
fdkaac | 2048 | 5056 | 7104 |
例えば、ffmpeg AACの無音区間は1024sampleなので、音声のサンプリングレートは48kHzの場合21.3ms、44.1kHzの場合23.2msの遅延が生じる。
これに対して、x264guiExではx264guiEx 2.05以降、音ずれを打ち消す方法を2パターン用意している。
(1). edit listを用いる方法
mp4/m4aコンテナのedit list情報を使用して、encoder delayをdemuxer/デコーダに伝え、demux/デコード時に補正させる方法。
edit listが存在するかどうかはmp4box -info "mp4ファイル" で確認できる。例えば、ffmpeg AACの出力をみるとこんな感じ。
Track # 2 Info - TrackID 2 - TimeScale 44100
Media Duration 00:00:03.023 - Indicated Duration 00:00:03.023
Track has 1 edit lists: track duration is 00:00:03.000 <<<< これ
edit listの効果は、下記のように見ることができる。
一番上: オリジナル
真ん中: ffmpegのAACエンコーダでedit listの情報を持たせない場合
一番下: ffmpegのAACエンコーダでedit listの情報を持たせた場合

edit listの情報を持たせ、(demux/デコード時に)それを反映することで、ffmpegのAACエンコーダで発生する遅延(1024sample = 23.2ms@44.1kHz)を除去できていることがわかる。
ただし、この方法をうまく活用するには、再生時・デコード時にedit listの情報を反映してくれるdemuxer/デコーダが必要になる。ffmpegとそれを使用するソフトウェア(lwinput.aui)などは問題なくedit listの情報を反映してくれる。
一方、使っている人がいるかはわからないが"MP4 File Reader"などはedit listの情報を反映してくれないみたいなので、できればlwinput.auiを使用したほうがよいと思う。
(1)-1 x264guiExのディレイカット「補正なし」 (=デフォルト)
デフォルトの「補正なし」でも一部の音声エンコーダについては、remuxerでmuxすることで、各音声エンコーダが出力するm4aに含まれるedit listをそのまま活用することができるようにしている。
ディレイカット「補正なし」で音声エンコーダの出力するedit listの活用が可能なのは下記のエンコーダ。
エンコーダ | |
x264guiEx 3.06以降 | AAC (ffmpeg) |
fdk-aac (ffmpeg) | |
x264guiEx 3.14以降 | qaac |
fdkaac |
これ以外のAACエンコーダ、例えばneroaacencについては、edit listの情報込みのm4aを出力できず「補正なし」では遅延が生じるため、encoder delay対策のためには次の「(1)-2 : edts」を使用する必要がある。
(1)-2 x264guiExのディレイカット「edts」
(1)-1の方法のとれないneroaacencなどの音声エンコーダを用いる場合の方法。L-SMASH muxerのencoder-delayオプションで指定したedit listにより対応する。
このときの音声エンコーダごとの無音区間のsample数は、x264guiEx.iniのmode_x_delayに記載されているものを使用している。
(2). 映像・音声の長さを調整して無理やり同期する方法
edit listを使わず、無理やり同期させる方法のため、特に問題なければ(1)の方法をとるべきと思う。
(2)-1 x264guiExのディレイカット「音声カット」 :
遅延するsample数分、音声の前方をカットして帳尻あわせをする方法。すぐに音声が始まっている動画には不向きだと思う。
(2)-2 x264guiExのディレイカット「映像追加」
遅延するsample数を見越して、先頭に映像・音声フレームを追加して帳尻あわせをする方法。映像・音声の動機は取れるが元動画より映像・音声ともに遅れが生じ、動画時間が延びる。
参考資料
EncoderDelay
Audio Priming - Handling Encoder Delay in AAC
終わりに
AACエンコーダの遅延と、x264guiExでの対処方法についてまとめた。
もし間違ってる点等あればご指摘ください。
スポンサーサイト