掲示板にあった「吉里吉里でkrmovie with DirectShow Extend Filter Libraryを使ったときにレイヤーモードで再生がうまくいかない」との投稿から始まった更新劇でした。
まあ、利用者的な視点とプログラマ的な視点からちょっとこれについて書いてみたいと思います。
最新版についてはこちらにて公開しています。
そもそもDirectShow Extend Filter Library(dsexfilter)はこれがなくても更新対象だった
なんです。しかもdsexfilterは今回のkrmovieの問題とはあまり関係がありません。まあ、機能的な問題をこの記事を書いた日の一昨日あたりに気になって
更新しようかな~と思っていたところに飛び込んできた、というわけです。
本来の更新対象は
- dsexfilterでWebMを再生させたときのオーディオライン出力が整数16bit固定だったので浮動小数形式のサンプル出力もできるようにする
- WebMの(自分のプログラムライブラリ内での)管理位置をいろいろといじっていたのでそれが問題ないかの確認
だったわけです。(これが0.09での更新内容)
krmovieに本当にちょっとした問題があったことを確認
普通にMPEGやWMVをレイヤー経由で再生している分には絶対に出ない問題です。そういう問題に引っかかりました。
元々krmovie内に配置したdsexfilterの読み込みはAVIファイルなどをDirectShow経由で読み込もうとするときに通過するルーチンと同じ動作をするようにしてあったのですが、
その部分で問題が起こったのかな~?と思い独立した処理に変更して問題解決・・・?と思ったらそうでもなく。
ちょっと違う方法でデバッグをしてみて発覚したのが、
レイヤー描画を受け取るときに映像ラインのデコードフィルタが「高さを負(ボトムアップではなくトップダウン)」で渡したときにkrmovieのレイヤー描画処理まで「高さが負(不正な高さ)」と処理された
ことにあります。
というわけで、#if 0によるコメントアウトの部分を復活させてトップダウン絵がきたときの処理を追加することでとりあえず一つは解決したわけです。
そもそもWebMの出力をレイヤー描画することがそのままだとできない
というのも、WebMの映像ラインの最終出力フォーマットはYV12になります。
これはそれぞれの成分が平面になっているフォーマットなのでレイヤー描画するためには中間変換フィルタが必要になるのですが、Windowsのデフォルトフィルタではこれを変換する処理がありません。
そのため、WebMをレイヤーモードで描画するには変換フィルタを実装する必要性に迫られたわけです。
というわけで、0.10の更新ではこの中間フィルタを呼び出せるようにする、という変更を行いました。
デバッグの時間が取られそうな実装内容のような気がするかもしれませんが、実はdsexfilterに実装してあるTheoraもlibtheoraを使ったときの出力はYV12なので、
これを内部デコーダ上でYV12=>RGB32としている処理があるのでこれをフィルタとして独立させるという方法で実装しました。なのでそれほど手間ではなかったりします。
これのフィルタを追加登録した場合のみWebMの出力はRGB32で扱えます。あとはレイヤー描画フィルタに接続して完了ですね。
もう一つのkrmovieのちょっとした問題
そしてもう一つ問題だったのは、
映像ラインでデコードフィルタがフレームレート(正しくは1フレームの時間)を返さないときにレイヤー描画処理でエラーを起こす
ことにあります。まあ、どちらの問題もMPEGとWMVの2つのフォーマットを限定して吉里吉里(+krmovie)で扱っている限りはエラーを起こさないですので安心してください。
この部分を修正してなんとかレイヤーモードでの描画処理が正しくできるようになったわけです。