2006年01月23日

MEncoder のa-v desync

【概要】B-frame使用時におけるa-v desync対策が始まった模様。
【原文】[MPlayer-dev-eng] [PATCH] mencoder, B-frames, and video/audio delay
【タグ】[A/V Sync][音ズレ][Bフレーム]
MEncoder.264とffmpeg.aac.mp4をmp4box でmuxした.mp4は、delay frameをカットするだけじゃダメ。
MovieVideoChartで1stフレームのタイ ムスタンプを見て、ソレに合わせてaudio delayをかけてmuxしないと、映像1フレーム分のa-v desyncはそのまま残っている可能性がある。

〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜訳文開始

Corey Hickey:Fri, 20 Jan 2006

B-frameを使ったエンコードがa-v desyncを引き起こす問題は広く知られており、長く未解決のままだ。私はマジでマジでこの問題に深入りし、バグフィックス、または回避手段の発見と文 書化に全力を尽くしたいと思う。添付したパッチで解決できるかもしれない、、、。

最初のテスト素材はSerenityのトレイラだ。
このビデオには、いくつかの場面転換で特徴的なサウンドが使われており、a-v desyncが見つけ易い。この素材で正しいa-v syncのエンコード結果を得るには-mc 0 -noskip (詳細後述)。素材入手先は以下:
http://movies.apple.com/movies/universal/serenity/serenity_m480.mov

私の通常エンコードオプションは:
mencoder serenity_m420p.mov -oac pcm -vf scale=480:208 -ovc x264 \
-x264encopts bitrate=800:bframes=16 -frames 1000 -o wayoff.avi

*ミヒャエルの算定式[1]により、B-frameが引き起こすVideo Delayは(1+b_frames)/fps(*キターーーー!!*)。Bフレーム16枚は通常ならやり過ぎだ が、Video delayが17/24secになるので見つけ易くなる(素材は24fps。24000/1001ではない)。

[1]http://www1.mplayerhq.hu/pipermail/mplayer-dev-eng/2005-December/039425.html
*-oac pcmを使ったのはAAC音声で-oac copy が効かない為。
*スケーリングパラメータと-framesはエンコードの速度向上の為。

(*2番目の素材略*)

私の理解では、映像にDelayが出る理由は、エンコーダはがBフレームのエンコードを始める前に十分な数のフレームをバッファする必要があるから(当然 の事ながら)。そしてmuxerに最初のフレームを送るまでの間にオーディオエンコーダは既にエンコード済み音声をいくらか送ってしまっている。

 この事自体は別に問題ではない。しかしmencoderはこれをvideoストリームにdelayがかけられたと看做し、数枚のカラのビデオフレームを 符号化して(数個の"1 duplicate frame(s)!"メッセージ)これを補う。かくして、mencoderはこの状態でsyncが成立したと考え、エンコードの最後までその状態を守り、 映像と音声を同じduration(*各フレームの持続時間か全体の持続時間か 不明*)でmuxする。しかしながら、ビデオストリーム中のempty framesは実際のフレームの位置をズラし、後続フレームを全て、時間軸上で後方へシフトさせてしまう(*要するに表示すべきタイミングが後ろにズレる*)
 再生においてはこのシフトはvideo delayとなって現れる。エンコードが終了すると、エンコーダはバッファしたフレームを全て吐き出し、making the encoded video stream trail past the end of the audio stream.(*理解不能*)

 添付したパッチはmencoder.cの一部をdisableにして、muxer stream timerに基づいてA-V syncをを調節する。これが正しい方法かは解らない。もしmencoderがsyncのズレたinput streamに対してもフレームのskip/duplicateができるなら、これで良いと思うのだが。なにか間違っているかもしれないが、このパッチを 当てたmencoderはSerenityのトレイラ(a-v調整抜きで動く)も、DVD clip(素材がずれているのを調整したもの)もB16枚で完璧にsyncする。
 私より知識のある誰かがOKしてくれたら、このパッチをコミットする。

テストして下さい。(*パッチ省略*)

以降のレスからまめ知識抜粋

depth
  • decoding delayの事。
  • x264 doesn't support pyramid with depth > 2.
  • depth 0: no B-frames.
    • I->P->P->P
  • depth 1: B-frame 1 depends on P-frame 0. (no B-refs)
    • I---------->P
      I->B<-------P
      I---->B<----P
      I------->B<-P
  • depth 2: B-frame 1 depends on B-frame 2 depends on P-frame 0.
    • I---------->P
      I---->B<----P
      I->B<-B->B<-P
  • *x264でb_pyramidを使う場合、 bframe=<3までという事になる。図はMichael Niedermayer 氏の投稿。この名前はDoom9/bond両名がffmpeg/Snowのdevとして時々言及する人物と同じだ。とりあえずミヒャエル・ネーデルマイヤーか、マ イケル・ニーダーマイヤーか。どっちでもいいか。
SPS,PPS
SPS:「stream-global settings」を保存するヘッダ。PPSとは異なる。
PPS:「more stream-global settings」を保存するヘッダ。:)

SPSはデコード後のストリームに関する情報を扱う(resolution, colorspace, interlacing, delay, etc)。
PPSはコデックが知る必要のある情報だけ扱う(quant matrices, cabac, weighted prediction, etc)。

しかし分離は完璧ではない(*the segregation isn't perfect。実用上のきちんと分離されてない例が多いのか、規格上、明白でないのか不明*)

その他、スレにはPTS,DTSなどに関する図も入ってるので理解できる人には 役立つかも。
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜訳文終了。
 その先の議論は、、、よくわからん。パッチの中身は仕方ないとしても、話のスジくらいは、、、あとちょっとで見えそうな、、、。
 全体のディレイをbframes+1(音声含めて?)にするにはどうすんだとか、muxerでそれやらんほうが良いとか、libavcodecと x264とXviDで対処法が違うんじゃまいかとか、、、。漏れ的にはb_adaptとの関係も気になる。
 とりあえず、MichaelさんとLorenさんが、Coreyさんを手取り足取りな印象を受けた。
 MEncoder本体は複雑で、手を入れたがる人があまりいないと理解していたので、ビビった。
あとCoreyさんのコレ。
I've found that doing something wrong is a very good way to get someone to tell me how to do it right, where they might not otherwise have done so if I had just asked. :)
そーともさ!b(^ ^)

ま、それはともかく、なかなか盛り上がってるモヨリ。
x264.mp4に手ぇ出してからVfWベースのMEncoderでは対策は期待できないとか、linuxで wine/avisynth/virtualdub(mod)が動いたりとか、ちょいとヘコミ気味だったんだけど。うし、今日もビルドすっか!
#!/bin/bash
# MEncoder_builder
#charset="UTF-8",LF

LOG=~/Desktop/menc_builder.txt
CFGX264="./configure --enable-pthread"
CFGME="./configure"

echo `date` | tee ${LOG}
echo === | tee -a ${LOG}
echo x264=== | tee -a ${LOG}
cd ${HOME}
svn co svn://svn.videolan.org/x264/trunk x264
cd ~/x264
echo ${CFGX264} | tee -a ${LOG}
${CFGX264} | tee -a ${LOG}
make
sudo make install

echo mencoder=== | tee -a ${LOG}
cd ~/main
cvs -z3 update -dPA | tee -a ${LOG}
echo ${CFGME} | tee -a ${LOG}
${CFGME} | tee -a ${LOG}
make
sudo make install
↑手許では大体1ヶ月くらいこれで平気。

余談
 今更だけど、音声と映像を別々にエンコードして、audio delayかけてmuxすんのが普通だったwin/linuxは、"莫迦でも使える"QuickTimeとは土台が違うんだ。と思い当たった。
 と、なると、QTプログラミングに純血マカーが手を出すと、一気にこのへんのややこしさがダマになって襲いかかって来るわけだ。使ってる時には存在すら 意識した事もないような問題が。挫折率高そう。
 ややこしさが剥き出しなwin/linuxの方が、ユーザから有益な情報(と敬意)が得易いと見た。avisynthもAviUtilも MEncoderもそうやって今の位置にあるわけだしな。
 ふいになんかの作者さんがMacのプログラミングは報われる事が少ないと書いていたのを思い出した。アレだ。マカは地震がおきてもコンビニにいけばなん でも買えると思ってる子供みたく見えたのかもしれない。ユーザと(サンデー)プログラマの距離が大きい。ふむ。
posted by ばる at 18:58| Comment(0) | TrackBack(0) | mencoder | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前: [必須入力]

メールアドレス: [必須入力]

ホームページアドレス: [必須入力]

コメント: [必須入力]

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
この記事へのトラックバックURL
http://blog.seesaa.jp/tb/12129586
※言及リンクのないトラックバックは受信されません。

この記事へのトラックバック
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。