読者です 読者をやめる 読者になる 読者になる

Tech と Culture

テクノロジーとカルチャー

IJGソフト内部でのJPEG処理の流れ 

IJGのソフトウェアのハフマンデコード以降の処理の流れが理解できました。
このソフトウェアでは、画像データの種類や、オプション指定によって、各処理関数が変更されるようになっています。以降の説明は、現在用いているmotion JPEGのデータをオプション無しで実行した場合の流れです。
mcu1.png
IJGのソフトウェアでは、structure.docにも記述してあるように、ある一つの処理を行う関数が二つの処理を行う関数を呼び出すという構造となっています。
djpeg.cは、jpeg_read_scanlineという関数で順次処理を行っていますが、その実体は、process_data_simple_mainというAPI関数です。この関数が、ハフマンデコードとDCTを実行する関数であるdecompress_onepass、アップサンプルとカラー変換を実行する関数post_process_dataをコールしています。
ハフマンデコードとDCTは、MCUという単位で処理を行っていきます。
mcu2.png
一番左の図のように画面全体を16x16画素単位に分割します。これがMCUです。
左上から右側に向かって処理が進みます。
DCT処理は8x8画素単位で行われます。
MCUの中で、Y,Cb,Crそれぞれに対してDCTが行われる訳ですが、ここでデータの間引きが行われています。人間の目はY成分に圧倒的に敏感であるため、Cb,Cr成分にはそれほど厳しい誤差要求がありません。そこで、Cb,Cr成分は左右となりあった画素で一つの同じ値を用います。
この方法をとることで、一つのMCU処理中にY成分4回、Cb成分2回、Cr成分2回の計8回のDCT処理が行われます。このような画像を4:2:2と呼ぶようです。ネットで検索しますと、「人間の目には4:1:1で充分綺麗に見える」という記述をたくさん見かけました。4:1:1の場合は、Cb,Cr成分が上下左右4画素で一つの値となっています。4:1:1にすると処理が格段に軽くなってfpsもあがると思われますが、現在用いている測定データを4:1:1に変更する方法が分かりませんので4:2:2前提で進めます。
4:1:1に対応することは、ハードウェア的には微小変更ですので、後ほど両方に対応するつもりです。

実際の処理の流れとしては、画面の左上のMCU分のハフマンデコードが行われ、それによって得られた係数から8回のDCTを行い一つのMCU分の画素データが得られます。
次に処理が一つ右のMCUに移り同じことを繰り返します。
右上のMCU処理が終わったところで、16行分の画素データが得られています。
ここで、処理がpost_process_dataの方に移ります。
それからは、行単位でh2v1_fancy_upsample,color_convertが呼ばれ、16行分の処理を行います。

以上の処理が終われば、上から2段目のMCUの処理が始まります。これを最終段まで繰り返して1画像データの処理が終了です。

なお、画像の縦横ビット数が16の倍数でない場合は、パッディングのデータが入っています(圧縮しやすいデータが入っている)。そして出力するときにそこの部分をオミットしています。
しかし、今回は16の倍数サイズの画面だけに対応することにします。

(ハードウェアが少し面倒になるので省略しました。早く動くところが見たいためです。)