※妖精現実さんからの記事コピペについては妖精のライセンス(「無断コピー以外」を禁止するライセンス)を選択しています。
リンクも貼りません。
速報: mencoder(またはdwStart)を使うとAVIで同期が保証されない
2006年11月17日
要約: mencoder で作成したAVIファイルは、WMP で再生したときだけ映像1フレーム分、音が遅れるこ
とがある。Windows/Linux上の他のプレーヤーではこの問題は生じないが、技術的にはWMPの挙動の方が正しい。
mencoder
はユーザーが指示していないのに勝手に dwStart を設定してしまうことがある。
この報告の信頼度: 75%
問題の深刻度: 高い。どのプレーヤーで再生するかによってAV同期がビデオ1フレーム(42 ms)程度、違ってしまうことがある。
現象
mencoderで-audio-delayスイッチを使ってAVIを作成すると、AVIヘッダのdwStartで同期調整される。-audio-
delayスイッチを
使わなくても、勝手に非ゼロのdwStartが書き込まれることがある
(Bフレームのデコーダーディレイを補正しているつもりらしい)。
ところが、 MPC 等の DirectShowプレーヤー(GraphEdit を含む)、VDMやVD などの
VfWインターフェイス、さらにクロスプラットフォームの ffplay や VLC は現在、一般に、dwStart を無視する(VD 1.7.0
ではその件の警告が出る)。一方、マイクロソフト純正のWMPは dwStart を解釈する。したがって、dwStart
がゼロでないAVIファイルは、環境によってAV同期が保証されない。
この問題は、mplayer が独自のロジックにより
audio_delay_fixを自動補正しようとすることから発生する。生成されるAVIファイルは規格に合致しており、mplayer
はわざとやっているので、バグではなく仕様と主張するであろう。しかしこのAVIファイルは現実的に正しい再生が保証されない。
// 自分で dwStart をセットするが…
//muxer_avi.c, Line 290 @ 1.0rc1
if (s->type == MUXER_TYPE_AUDIO && muxer->audio_delay_fix > 0.0) {
s->h.dwStart = muxer->audio_delay_fix * s->h.dwRate/s->h.dwScale + 0.5;
...
}
// 再生するときは自分自身、厳守しない...
// cfg-common.h
// ignore header-specified delay (dwStart)
{"ignore-start", &ignore_start, CONF_TYPE_FLAG, 0, 0, 1, NULL},
{"noignore-start", &ignore_start, CONF_TYPE_FLAG, 0, 1, 0, NULL},
// audio_delay_fix は encoder_delay に対応するのだが、
// bフレームを使うと1にセットされる(x264でピラミッドだと2)
// ve_xvid.c
#ifdef XVID_API_UNSTABLE
fp->mux->decoder_delay = enc_param.max_bframes ? 1 : 0;
#endif
/*
つまり…xvidでは映像1フレーム、x264では2フレームに対応するdwStart(音声の遅れ)
がセットされるが、ほとんどの再生側ではdwStartは尊重されず、混乱の原因になる。
そもそも「bフレームを使うから音声を遅らせなければいけない」という考えが、
一般に正しくない。デコーダーがbフレームをどう処理するかの問題であり、
dwStartでハードコーディングするべきでない。さいわい、たまたまdwStartを皆が無視するので、
表面化していない。
XviDの場合は XVID_API_UNSTABLE がセットされていると、
1フレーム遅れる。
*/
問題点
- AVIの仕様に反してほとんどのデコーダーが dwStart を解釈しない。
- mencoder は、音ズレ補正を要求していなくても、自分勝手に非ゼロの
dwStart を設定してしまう。
第一の問題は既知(2006年1月に報告あり→参考文献)。第二の問題は今日、気が付いた。
解決法
dwStart に関する混乱を回避するには、現実問題として dwStart
という仕様を使わず、この値をゼロに設定するしかない。すなわち、AVIにおいては、音声トラックを遅らせるにはオーディオエディタで冒頭に無音挿入をす
るべきであり、AVI Muxer で補正するべきでない。Windows 上で広く行われている方法(VDなど)で AVI
を作成した場合、dwStart はゼロになる。
mencoder で強制的に dwStart をゼロにする方法は研究中。Windows 上でも作業できるなら、一回 VD で開いて
DirectStream Copy で再保存すると、dwStart が(もともとゼロでなくても)ゼロになる。
既存のファイルに関して
AVI に対してタイミングするとき、dwStart
がゼロでないファイルの場合は、特に注意を要する。VD等で音声トラックをdemuxすると、dwStart が設定されていてもdwStart
ゼロにずれて音が出てくる。「動画作成者が知らずに mencoder を使い意図せず dwStart
をセットした場合」はそれで良いが、「動画作成者が同期を補正するため意図的に dwStart をセットした場合」に dwStart
を無視すると、同期の混乱が生じうる。
dwStartの確認法
dwStart を確認するには、abcAVI Tag Editor などのツールを使うか、または mplayer -v file.avi
とする。最も簡単には VirtualDub 1.7.0 でファイルを開くと、dwStart
がゼロでない場合、警告が出る。(警告が出なければ、dwStart=0)。ただし VD 1.6.x系は警告なしで dwStart
を無視するのでバージョンに注意。
mplayer -v で見たときのdwStart
この例では Start: 0 つまりゼロ
====== STREAM Header =====
Type: auds FCC: (0)
Flags: 0
Priority: 0 Language: 17
InitialFrames: 1
Start: 0 ...
参考文献
スポンサーサイト