« VMR9とNV12で嵌る(その4) | トップページ | VMR9とNV12で嵌る(その6) »

2009年10月25日 (日)

VMR9とNV12で嵌る(その5)

最近、忙しくて、ここを放置していたのだが、さすがに間が空きすぎなので、更新。

以前、嵌っていると言っていた、NV12サーフェスをVMR9で表示すると色がおかしい件は、やっぱり、ブログ主の頭の悪さが問題だった。普段から、適当にコードを書いているから、ちゃんと理解していない事を、間違っていても、全然、気が付く事ができない。

原因は、すごく単純で、NV12サーフェスに書き込む際に、ダウンサンプリングを行っていないことだった。これは、かなり、恥ずかしいレベルのミスだ。該当箇所のコードを書いている時に、頭をよぎっていたにも関わらず、ちょっと動かしてみて、上手く動いたように見えたので、すっかり忘れてしまっていた。ストレートに言うと、酔っ払いすぎだった。その上、次の日からは、「ここは、動いたから、問題なし」と思い込んで、色々な設定の組み合わせを、調べ始めてしまい、自ら、穴に嵌っていただけだった。うーん、典型的な駄目パターンだ。

という訳で、このブログに書いてある事は、あまり信用しないほうが良い。真剣にそう思う。

これで、更新が終わってしまうと、かなり悲しいので、ダウンサンプリングについて、書いておこう。

ダウンサンプリング

ここで書く「ダウンサンプリング」は、画像データに関する話だ。一般的な意味での「標本化」に関する話ではないので、注意して欲しい。

ダウンサンプリングとは、簡単に言うと、「ある画像データから、その画像よりも、小さいサイズの画像データを作り出すこと」だ。逆に、「大きいサイズの画像データを作り出すこと」が、アップサンプリングだ。両方とも、リサンプリングの一種だ。

このダウンサンプリング、アップサンプリングは、画像を扱うプログラムの場合、必ずと言っていいほど必要になるものだ。勿論、Windowsでも、ディスプレイ上に、個々のウィンドウを表示させる際に、ダウンサンプリング、又はアップサンプリングが行われている。(画像の拡大、縮小の際に行われている。)

ダウンサンプリングを行う際には、「基になる画像のピクセルデータから、どのように、ピクセルデータを作り出すか」ということが問題になる。この方法(以下、アルゴリズム)ならば、必ずうまくいくというものは無い。例を、図で添付。

down_sampling1

幅8ピクセル、高さ8ピクセルの画像から、幅4ピクセル、高さ4ピクセルの画像を、ダウンサンプリングしている例だ。この例は、一番単純なケースで、ダウンサンプリングを行う際に、単純にピクセルを、2分の一に、間引いている。(アルゴリズムはDecimate)

では、幅2ピクセル、高さ2ピクセルの画像に、ダウンサンプリングする場合は、どうだろうか?

down_sampling2

対象となるサイズが小さすぎるため、どのような方法でダウンサンプリングを行ったとしても、元の画像の情報は、ほとんど失われてしまう。つまり、ある程度の小さい画像サイズに、ダウンサンプリングする場合は、アルゴリズムは、重要ではなくなる。

ここで、幅7ピクセル、高さ7ピクセルの画像に、ダウンサンプリングする場合を考えて欲しい。(図を描こうとしたが、上手く描けなかったので、勘弁して欲しい。)

元の画像データの情報を、なるべく失わないようなアルゴリズムで、ダウンサンプリングすれば良いのだが、色々考えてみると、結局、アルゴリズムは、元になる画像データに依存する事に、気が付くと思う。

このように、ダウンサンプリングを行う場合、元の画像データと、生成される画像データのサイズによって、アルゴリズムを、動的に変更する事ができれば良さそうなのだが、有名な方法を、ブログ主は、見つける事はできなかった。

以上が、ダウンサンプリングの話なのだが、ここまでの話は、暗黙的にRGB32のピクセルデータを前提にしている。そのため、画像の拡大、縮小を行う時に、ダウンサンプリング、アップサンプリングを考慮することになる。(同じサイズならば、単純にコピーすればよい。)

しかし、以前の更新で書いたように、NV12はYUV4:2:0のピクセルフォーマットなので、RGB32の画像データを、NV12サーフェスに書き込む場合は、同じサイズの画像であっても、UV成分のダウンサンプリングは避けられない。

ここで、最初の目的を思い出してみると、ブログ主がやりたい事は、DXVA1のデインタレースのベンチマークプログラムの作成だ。このプログラム上で、画像データが、どのように変換されていくのか考えてみると、

RGB32のアニメーションデータ
↓ (ピクセルフォーマット変換、UV成分ダウンサンプリング)
NV12ピクセルデータ
↓ (インタレース化)
NV12サーフェス

ここまでを、プログラム上で行い、用意したNV12サーフェスを、VMR9(GPU)上で、

NV12サーフェス
↓ (DXVA1デインタレース)
NV12ピクセルデータ
↓ (ピクセルフォーマット変換、UV成分アップサンプリング)
RGB32の画像データ

このような変換を行い、RGB32画像データを、ディスプレイ上で表示する事になる。

ここで、デインタレースのベンチマークが目的ならば、UV成分のダウンサンプリング、アップサンプリングで生じる画像の劣化を、最小限にしなければいけない。

そのためには、ダウンサンプリングのアルゴリズムを、アップサンプリングのアルゴリズムの逆関数にすれば良い。しかし、GPUで行われるアップサンプリングのアルゴリズムが不明だ。

というわけで、ダウンサンプリングを、どんなアルゴリズムで行うか考えているのだが、良いアイディアが浮かばない。

以上、現状報告終わり。次回更新の時期は不明。

« VMR9とNV12で嵌る(その4) | トップページ | VMR9とNV12で嵌る(その6) »

パソコン・インターネット」カテゴリの記事

コメント

コメントを書く

(ウェブ上には掲載しません)

« VMR9とNV12で嵌る(その4) | トップページ | VMR9とNV12で嵌る(その6) »