何と言うか……。MPEG-2 VIDEO について最近調べているのだけれども、本当にランダムアクセスには向いていないフォーマットのように思えてきた。
プログラムストリームは別として、ビデオストリームのみのビットストリームの場合、基本的にランダムアクセスの際に参考になるのは GOP ヘッダの TIME CODE のみで、 GOP スタートコードを探し、TIME CODE を読んで、そこからフレーム数を計算し、目的のフレームがその GOP に含まれているかを判断しなければならない。
まあ、この場合は良いのだけど、問題は 12cm 円盤由来の MPEG-2 Video だと、この GOP ヘッダ内の TIME CODE がファイル内で一貫していないみたいなのだ。
この場合、ランダムアクセスを実現しようと考えたら、1G 弱にもなるファイルを延々読んで GOP のリストを作成し、何処に何があるか調べておかなきゃいけない。
予想どうり……すっごく遅い。(試しに作ってみたのだけど)
1G のファイル読むのに 4 分 も 5 分も待てないよな〜普通の人は。
もう少しなんとかならないかと思って、fread/fgetc の使用を諦め _read() を使って、自前でバッファリングしてスタートコードを BM 法で検索するようにしたら、何とか 1 分程度で済むようになってくれたけど、それでもやっぱり遅いよな〜。こればっかりは N オーダでファイルを読まなければいけない限りどうしようも無いから。う〜ん。
MPEG-2 VIDEO をデコードする際は、大体次の図のような経路で処理が進む。
まず初めはシーケンスヘッダを読んで、GOP ヘッダを読んで、ピクチャヘッダを読んで、スライスヘッダを読んで……、と進んで行って、肝心のデコード作業と言うか、逆 DCT と 動き補償 はブロック層とマクロブロック層でそれぞれ実行されるわけだ。(動き補償はマクロブロック層で、逆 DCT はブロック層で)
このブロック単位での逆 DCT や、マクロブロック単位での動き補償を積み重ねて、一枚のピクチャが完成する。
で、今書いてるデコーダはどこまで作業が進んでいるかと言うと……。
上の図で○を置いた所までしか進んでいない。(書き初めてからそろそろ3週間近くにもなろうというのに……)
先は長いな〜。(できればあと1週間ぐらいで終らせたいのだけど)
MSSG の mpeg2dec をそのまま使えれば楽だったのだろうけれども、あれはグローバル変数を大量に使ってる為に下手にコードに手を加えられないから。特にビットストリームの読み出し部分に手を加えてランダムアクセスを受付けるようにして、さらに任意のフレームをデコードできるように変更するなんて……悪夢だ。
まあ、マクロブロックのパラメータを入手する関数はほぼ書き終えたから、後はブロック層で DCT 係数を入手して、逆 DCT 処理をして、マクロブロック層に戻って、動き補償処理して、この繰り返しで、ピクチャが完成して、IBP の並べ替えをやって……。
やっぱり1週間程度じゃ無理かも。(涙)