2000-11-6 作成
2001-8-3 更新

フィールドオーダーのナゾ


注意事項:ここの解説は私独自に調査した結果です。誤りも含まれている可能性がある点はご容赦ください。

 ここではフィールドオーダーについて、Bt8x8ドライバのバグの話を中心に、稚拙ながら解説したいと思います。


NTSCの基本
 まず、フィールドを議論するには日本や北米のTV放送規格である、NTSCを理解しなければなりません。これについて簡単に説明します。

フィールドの概念
Fig1 フィールドの概念
Fig1.フィールドの概念

 上記はFig1はTVの一画面を模式的に示したものです。厳密に言えば、NTSC規格の有効垂直解像度(縦の解像度)は、486本なのですが、動画キャプチャを前提に説明しますので、ここでは便宜的に縦480本として説明します。

 TVは1秒間に何枚もの画像を紙芝居のように書き換えて、動画のようにみせていることはご存知のことと思います。NTSCでは1秒間に29.97枚の画像を書き換えている、と言われていますが、厳密には異なります。1秒間に半分ずつの画像を59.94枚書き換えている、が正確な表現になります。

 半分ずつの画像、というのがFig1に示したとおりで、1ラインおきに交互にスキャンした画像で1枚を構成しています。これを「フィールド」と呼び、一番上のラインを含むフィールドを「トップフィールド」、一番下のラインを含むフィールドを「ボトムフィールド」と呼びます。

Fig2 フィールドの表示
Fig2.フィールドの表示

 これがどのように表示されるか示したのが上記Fig2です。トップフィールドとボトムフィールドを交互に表示させ、1秒間に59.94画面を書き換えています。また、トップ/ボトムをひとまとめとすると、1秒間に29.97画面となり、これを「フレーム」と呼びます。一般にフレームレートを数えるとき、この「フレーム」を指す事が多いため30fpsとか、29.97fpsとか言われるわけです。ちなみに、どちらのフィールドから始まる、という規定は無いそうです(^^;;; DVDは決まっているんですがねえ。。。

 動画キャプチャを行うときは、縦480ラインの場合、フレーム単位でキャプチャを行います。ということは、1画面にトップ/ボトムフィールドが混じっている状態になっていることが分かります。よく動画掲示板で「動きの激しいところで2重に見える」との質問がありますが、それで正常なんですね。これを分離する作業が24fps化であり、インターレース解除なのです。これはBt8x8に限らず、DVでも、ハードウェアMPEG1、2エンコードボードでも同じです。

 なお、縦240ラインでキャプチャした場合は、フレーム単位で取りこむ関係上、片フィールドしか取りこまれません。したがって、インターレースずれは起こりませんが、取りこめていないフィールドが存在するので、解像度はもとより、時間軸にも欠落が発生している事になります。良く「縦480ラインでキャプチャを」と言われますが、これが根拠になっています。

偶数、奇数フィールド?
Fig3 偶数・奇数フィールドの定義
Fig3.偶数/奇数フィールドの定義

 「偶数フィールド」「奇数フィールド」という言葉を聞いた事のある方もいらっしゃると思います。あえてこの表現を使わなかったのには理由があります。上のFig3に示したとおり、ラインの数え方によって指すフィールドが逆になってしまうからです。もちろん、定義がしっかりしていれば問題無いのですが、一般的には1〜480で数えているのに対し、TMPGEncでは0〜479で数えているため混乱しがちです。よって、ここでは「トップ」「ボトム」という表現で統一することにします。


Bt8x8におけるキャプチャ
 では、本題に入りまして、Bt8x8におけるキャプチャはどうなるかみてみましょう。まず、NTSCのフィールドを、以下のように示すことにします。

フレーム  ・・・
トップ 1  3  5  7  9 
ボトム  2  4  6  8  10   ・・・ (A)

 半角の数字は1フィールドを示し、横方向は時間軸、縦方向は画像の描画される位置を示しています。トップフィールドは1ライン目から始まるので、ボトムフィールドに比べて1ライン分上に表示されている画像を構成しています。そういう意味で上の表はトップを上側に書いています。

 それと、NTSCの解説で書いたとおり、トップ/ボトムのどちらが先か、というのは規定されていないようなので、便宜的にここでは「トップフィールドが先に表示される」、すなわち上記表のとおりのデータ並びのソースを基準として解説します。

フィールドオーダーの設定
 解説の前に、フィールドオーダーの設定について言及します。フィールドオーダーの設定は、Codecとアプリケーション側と2種類あります。Codecは、PIC MJPEGで言うと、「Swap Decompress Fields」のチェックボックスがそれにあたります。チェックをONにすると有効になります。無効の場合は何もしないので、無圧縮と同じフィールドオーダーになります。

(注)PICを使うときは、「2 Fields If More Than xxx Lines」にチェックを入れ、xxx=240としてキャプチャを行ってください。そうしないと「Swap Decomp〜」が機能しないことが確認されました。

 一方のアプリケーション側は、TMPGEncでは言うまでも無く、フィールドオーダーの設定です。トップが先か、ボトムが先か、が設定できます。AviUtlですと、「奇数ラインを1フレーム遅らせる」のチェック有り無しです。これらの対応関係は後ほどまとめますので、ここでは設定できるということだけ覚えておいてください。

 Codecとアプリケーション側とで機能が重複していて、片方は要らないだろう、と思う方がいらっしゃると思いますが、実はCodecとアプリケーション側で働きが異なり、設定の組み合わせとしては2x2=4通り存在します。そして困った事に、そのうち動画として正常になるのはだたの一つしかありません。これが混乱のもとになっていたりします。

RGB、BtYUV、YVU9のときのデータ
 やっと本題に入りまして、Bt8x8においてRGB、BtYUV、YVU9で取りこみ、それをアプリケーションで読みこんだフィールドの並びは、(A)にしたがって表現すると以下のようになります。なお、例としてTMPGEncの各々の設定でファイルを開いたケースを説明します。

上のほうの図(A)のような画像をキャプチャしたとき。

1)Codec反転OFF、あるいは無圧縮の場合
a)「トップフィールドを先に表示する」
フレーム  ・・・
トップ 1  3  5  7  9 
ボトム  2  4  6  8  10   問題無し ・・・(1,a)

b)「ボトムフィールドを先に表示する」
フレーム  ・・・
トップ  1  3  5  7  9
ボトム 2  4  6  8  10   時間軸が反転してしまう ・・・(1,b)

2)Codec反転ONの場合
a)「トップフィールドを先に表示する」
フレーム  ・・・
トップ 2  4  6  8  10 
ボトム  1  3  5  7  9  フィールド反転してしまう ・・・(1,c)

b)「ボトムフィールドを先に表示する」
フレーム  ・・・
トップ  2  4  6  8  10  
ボトム 1  3  5  7  9   表示位置が反転してしまう ・・・(1,d)

 こうなります。この4つを比べるとCodecとアプリ側で機能が異なる事が分かると思います。Codecの機能は、(1,a)と(1,c)、(1,b)と(1,d)を比べれば分かりますが、フィールドそのものを反転させる機能です。それに対しアプリ側は(1,a)と(1,b)、(1,c)と(1,d)のように、時間軸の反転のみにとどまります。従って、正しいのは(1,a)ひとつのみで、その他は異常になります。自動24fps化がうまく行かない方は、たいていここが狂っていますのでチェックしてみて下さい。

YUY2、UYVYのときのデータ
 一方、YUY2などのときのデータは、RGBなどの時と異なる並びをしています。これがBt8x8ドライバのバグとの事らしいです。RGBのときと同様に示しますと、

上のほうの図(A)のような画像をキャプチャしたとき。

1)Codec反転OFF、あるいは無圧縮の場合
a)「トップフィールドを先に表示する」
フレーム  ・・・
トップ 2  4  6  8  10 
ボトム  1  3  5  7  9  フィールド反転してしまう ・・・(2,a)

b)「ボトムフィールドを先に表示する」
フレーム  ・・・
トップ  2  4  6  8  10  
ボトム 1  3  5  7  9   表示位置が反転してしまう ・・・(2,b)

2)Codec反転ONの場合
a)「トップフィールドを先に表示する」
フレーム  ・・・
トップ 1  3  5  7  9 
ボトム  2  4  6  8  10   問題無し ・・・(2,c)

b)「ボトムフィールドを先に表示する」
フレーム  ・・・
トップ  1  3  5  7  9
ボトム 2  4  6  8  10   時間軸が反転してしまう ・・・(2,d)

 こうなっちまいます(^^;;; YUY2などで取りこむと、取りこんだデータ自体がフィールド反転しています。RGBの時と同様、やはり正しいのはただの一つで、(2,c)以外は異常になります。また、無圧縮ではどうあがいても駄目なことから、YUY2などの取りこみで反転オプションつきのCodecを推奨したのです。

<2001-8-3追記>
 このバグは、Bt8x8のVxDドライバ限定の話です。WDMドライバでは、どのカラーフォーマットでもRGB系と同じ並びであることが確認されました。

まとめ
 以上を踏まえ、Bt8x8でのキャプチャ時に、正常になる設定をマトリクスにしてみました。

  TMPGEnc AviUtl
β12b以降 β12a以前
RGB、BtYUV
YVU9
無圧縮 「トップフィールドを
先に表示する」
「偶数→奇数」 「奇数ラインを
1フレーム遅らせる」ON
Codec反転OFF
Codec反転ON × × ×
YUY2、UYVY 無圧縮 × × ×
Codec反転OFF × × ×
Codec反転ON 「トップフィールドを
先に表示する」
「偶数→奇数」 「奇数ラインを
1フレーム遅らせる」ON
※「×」・・・どう設定しても正常にならない
※「Codec反転」
  PIC MJPEG :Advancedの「Swap Decompress Fields」のチェックON/OFF
  Huffyuv :「Swap fields on decompress」のチェックON/OFF
これらは再生時のオプションなので、キャプチャのやり直しは必要ありません。

マトリクスにするほど複雑でもありませんが(^^;;;
YUY2系の場合、Codecとの併用が必須になることに注意してください。

蛇足
 ひとつの疑問、「Codecで反転させて、アプリ読みこみで反対にすれば、逆の逆で元に戻るのでは?」 ええ、私も最初はそう思っていたし、当然の疑問だと思います。が、実際は前述の通りCodecとアプリ側で働きが異なるため、元に戻らないのです。

 ここで、時間軸と表示位置の概念をちょこっと。時間軸?表示位置?なんじゃそりゃっ?

 時間軸は簡単です。NTSCの解説で述べたとおり、TVはトップ/ボトムを交互に59.94fpsで表示していますが、これが逆だったら2歩進んで1歩戻る動画になってしまいます。しかし、キャプチャはフレーム単位で行われるため、両フィールドが1フレームの29.97fps動画の段階では見分けがつきません。そこで、AviUtlなら「60fps読みこみ」で、TMPGEncなら「インターレース解除」で「偶数・奇数フィールド(フィールド)」を選ぶと片フィールドを1フレームにした59.97fps動画に変換できます。こうすると一発でわかります。

 表示位置は直感でわかりにくいと思います。もう一度、NTSC解説の頁のFig1を見てください。トップフィールドとボトムフィールドは、互いに1ライン分シフトした画像で成っており、両フィールドで1フレームを形成しています。「互いに1ライン分シフト」がミソです。もし、トップフィールドの位置で、ボトムフィールド画像を表示したらどうなるでしょうか。本来ボトムフィールドの位置で表示すべき画像なので、表示位置が縦1ライン分ずれることになります。同様にボトムフィールドの位置でトップフィールド画像を表示するとやはり1ラインずれます。両フィールド間で1+1=2ライン分、表示がずれるわけです。結果、表示位置反転させると、「互いに1ライン分シフト」の関係が崩れ、表示が壊れることになります。具体的には、上記60fps化すると、動画が上下にかくかく動きます。各フィールドの表示位置が間違っているためです。

 Codecの設定はフィールド反転の有無なので、時間軸、表示位置同時に入れ替わります。しかし、アプリ側は時間軸反転しかできません。こういう理由で、Codec、アプリ側両方を逆にしても元に戻らなかったのです。

 時間軸、表示位置はCodec、アプリ側で働きが異なる事から、互いに独立事象となり、4通りの結果が生まれます。両方正常、時間軸のみ逆、表示位置のみ逆、両方逆、の4つです。4通りの設定から生まれる4通りの結果のうち、正しいのはただの一つ、ということはもうおわかりでしょう。

 戻る


 Copyright(C) もりのみやこ

hi6@nnet.ne.jp