簡単にいうと YCrCb のようなフォーマットのイメージデータを 拡大縮小し RGB に変換して転送する装置。これがあると高速化されるのは、mplayer のような動画ソフトと jpeg のデコード。
この処理は 3 つのデータに係数をかけて加算する処理を RGB の 3つに対して行うわけでかなり重い。さらに画面サイズに合わせて拡大縮小するとなれば 相当な処理量だ。これをハードウェアで行わせることが出来るわけでかなり嬉しい機能。
ちょっと見積もってみよう。仮に 400x226@30fps の動画があったとすると、4MB/sec で YCrCb のデータができる。これを 16bpp の フレームバッファに書くとすれば 5.3MB/sec で書き出すことになる。Jz4725B では、16 バイトの READ/WRITE には 17 メモリクロックかかる(CPUクロックなら さらにx3)。単純計算で 7.6 % のメモリ 負荷。CPU でやるとすれば .. これの数割増しぐらいのメモリ負荷になるはず。仮に 10 % だとしよう。
あと演算がある。演算量は、multi-add が 1画素あたり 9 だとして、24M 演算 /sec 。CPU が 400MHz だとして、CPU 負荷を 10% 使えるとすると 1 演算あたり 1.6 クロック使える。... これはかなり厳しい数字。仮に 10 % でできたとしても、上記の メモリアクセスと並列にはならない。(メモリ待ちの間 CPU は止まっている) 。結局 合計 20 % ぐらい使う計算になる。
これがバックグラウンドになればかなり嬉しいわけだ。
ところが DINUX では disable カーネルがあって わざわざ使わないようにしていたりする。
どうもメモリーの使用量が増えるというデメリットがあって 32MB しかない A320 では無視できないらしい。
mplayer や jpeg を扱うソフトだけ enable すれば良いと思うのだが そういうわけには行かないようだ。IPU は 装置なので 物理メモリを扱う。入力・出力用のイメージは物理メモリで連続した領域でないといけない。一方アプリケーションは仮想メモリで 4KB 単位の page でメモリを割り付ける。使っているうちにフラグメント化されて、物理メモリで連続した領域がなくなってしまう恐れがあるので、リザーブしているらしい。
仮想メモリを移動して 物理メモリで連続した領域を確保する機能があれば問題ないのだが、linux にあったようななかったような... あったとしても使い方が難しいなら対応が後回しにされている可能性もある。
さて、もう少し詳しく機能を調べてみよう。
まず入力フォーマット。これは Y,U,V と名前がついた 3つのプレーン。それぞれ 8bpp でパラメータには、width,height 以外に stride があり、大きなイメージの一部を入力にできる。
入力は、YUV/YCrCb フォーマットの 4:4:4, 4:2:2, 4:2:0 , 4:1:1 をサポートしている。
出力は、R8G8B8 (32bpp) か R5G6B5,R5G5B5(16bpp) こちらも width,height 以外に stride がある。
変換終了は レジスタの値で分かるが割り込みも使える。
だいたいこんなところ。画像viewer などで オリジナルを 1回展開しておけば スクロールやズーム処理を コスト 0 で出来るから、積極的に使うと良いと思うのだが ... やはりメモリが問題か。
ちなみに この機能と MXU命令 を使えばかなり動画の性能が上がる。Neo Slim 3000 では H.264(400x226,30fps) を 遅いながらも再生できた。ただし、起動の時間が異常に長く 音ずれも尋常ではなく現状では実用的ではない。
このあたりが限界なのか?というとよくわからない。根拠はないが、ソフトのチューニングとオーバクロックで この程度ならなんとかなりそうな感じはする。
ちなみに、Xburst が 2つ載っていて さらに H.264 用のアクセラレータの video Engine を載せた jz4755 は別格かも。400MHz とクロックも上がっているし、 H.264 対応とか 1080p 対応とかを謳っているが本当にまともに再生できるのかも知れない。
データシートによると jz4755 は single core に比べて 2 倍の動画再生性能だそうだ。そしてその性能は XGA (1024x768) の H.264 の 30fps 再生。ならば jz4725や jz4740 で 720x480 の H.264 の 30 fps が出来ても不思議ではない。
ただし 期待は 700Mhz とか噂されている jz4760 。u-boot などにはコードがマージされているのでいずれは出て来るはず。
jz4760 は、600MHz かも知れない。プロセスが 130nm だそうだ。ある記事によると jz4750 の機能に加えて DDR2(DDR) をサポートし、USB は OTG 対応。性能は ARM11 800MHz 相当だそうだ。
まぁ ARM勢 と比べると明らかに差を付けられている感のある jz47xx だが、いじり甲斐はある。特に MXU 命令。難解だが使いこなせると bit 操作とかいろいろ高速化できるような気がする。気が済むまで遊んでみたい。
追記:IPU の使い方
IPU が使える状態では、IPU のために 4MB の連続領域がある。
まずこの 4MB を 4 つまでのエリアに分割する。
リクエストは、/proc/imem に対して書き込む。
結果を知るには、/proc/imem を読み込む。
書き込み / 読み込み フォーマットは省略。
次に バッファーを IPU に設定する。
- emc
EMC -- External Memory Controller の情報が読める。 - pmc
PMC -- Power Manager Module の情報が読める。 - cgm
write することで、CGM -- Clock Generation Module の CPCCR -- Clock Control Register に書き込みができる。
read すると CGM の様々な設定情報が読める。 - udc (JZ4750L, JZ4750D のみ)
udc hotplug と書いてある。udc は デバイス側の USB 。read することで、USB の抜き差しのメッセージが見える。機能はそれだけ。 - tlb (JZ4750 のみ)
read しかできない。ipu の設定と TLB が見える。 - imem1 (JZ4750D のみ)
jz4750d は、最大 16MB の imem に加えて 最大 8MB の imem1 を確保しようとする。
jz4750 は、最大 16MB の imem を確保しようとする。
この 2 つは普通に 128MB ぐらいのメモリがあることが前提なのか?
同じように /proc/ipu に書き込むことで設定ができる。
ちなみに、/proc にはimem,ipu 以外に 次のようなエントリーがある。imem1 以外はデバッグ用。
ところで.. imem1 がありダブルバッファにしているのは JZ4750D のみ。これって必要なのだろうか?
普通に考えると、IPU の転送が終わるまでは、YCrCb のメモリにアクセスできない。上記で一例として 7.5 % という数字を出したが、これはメモリを占有できたときの値。CPU や フレームバッファやその他でメモリアクセスが起きれば それだけ遅れる。30% しか利用できないとすると 25% の時間がかかる。この間、データを展開できないのは厳しいかも知れない。
例えば、上下の 2 つに分けて 上部が終わったら 上部が使えるようになる .. みたいなことをすれば 問題ないのだが、拡大縮小をしていた場合 合わせ目が綺麗になるのかどうか?
やはりダブルバッファに対応できたほうが良いのではないだろうか? 上記の 400x226 のデータを例にすると 必要なのは、135KB ほどだ。4MB も取るなら 割り当てられる。
実装方法としては、imem1 を作るよりは imem の分割数を増やしたほうが良いように思う。
あと、動画しか対象として見てこなかったが、画像にも使えるのだろうか?
JPEG の出力は、YCrCb だから やはり同じように使える。4MB をフルに使って YCrCb のデータを置いておけば 拡大縮小 や View の移動は 簡単かつ高速にできる。
これは他の Viewer についても 同じ。
ページという概念があって、1 ページのサイズが 1200x1600 ぐらいまでなら 4MB に収まるから、同じようなことができるはず。
2 ページ確保してのダブルバッファというのも良いかも知れない。-- この場合 1280x1024 x 2 ぐらいまで。