2012年10月7日日曜日

まだ、データ変換まわりにバグがあるので、しばらくバグ処理したいと思います。

xuggleの変換。AVC nal sizeなんたらというバグがのこったままです。
いまのところh.264でしか出現しないバグっぽいですが、気持ちわるいのでずっとなんとかしたいと思っています。

というわけで対処を考えてみました。

まずログを大量にはさんでどこがわるいか調査してみました。
調べてみたところこけた場所が発覚しました。

・IContainer.readNextPacketを実行。
・FLVHandlerからデータを取り出す。
・Codec情報を確認
・IVideoPictureにデコードをする。←ここでこける。
その後はfreezeした風になりますが、実際はfreezeではなく、次のバッファ読み込みサイズが数MByteになり、読み込み待機中がながくなっているようです。
我慢してまっていると、次の処理が発生しますが、またこける・・・これを繰り返している模様。

ということで、flvデータの読み込みでこけているみたいです。
ここでよくよく考えたら、前のhttpLiveStreaming用の変換処理を実施しているときにも同じこけかたしてたのを思い出したので、前のxuggleのバージョンでも発生していたことになります。

エラーの場所が特定できたわけですが、自分のコードがわるいのか、xuggleがわるいのか、ffmpegがわるいのかさっぱりわかりません。

というわけでその辺り調査するために、いろいろがんばってみました。
目標の動作は
FlashMediaServer -> flazr -> xuggle -> いろんなメディアファイル

やったことその1
FlashMediaServer -> flazr -> ffmpeg -> 適当な出力
をやってみました。
flazrはデフォルトのclient.shを使うもの。ffmpegもコマンドラインで実行で標準出力をパイプでつなげます。
デフォルトのflazrには標準出力への出力はないのでtail等を組み合わせました。
$ ./client.sh -host localhost -app live test test.flv
$ tail -f test.flv | ffmpeg -f flv -i - -an -f flv output.flv
いったんファイルにして、それをtailで無理矢理つなぐ。
この処理では、問題がでませんでした。

やったことその2
FlashMediaServer -> rtmpdump -> ffmpeg -> 適当な出力
これを試しましたが、rtmpdumpがFlashMediaServerにアクセスしてくれません。
FlashMediaServer -> ffmpeg(librtmp経由) -> 適当な出力
こちらもアウトでした。
なんかストリームを認識してくれません。

この2つは別の方法で動作させてうまく動くか確認するというものです。
別の方法でffmpegにデータをながして動作するんだから、自分のコードがわるいというわけですね。
んで、まちがっていたらrtmpdumpのソースやflazrのソースとにらめっこすればよいという・・・

で、次
やったことその3
FlashMediaServer -> flazr [a]->[b] ffmpeg -> 適当な出力
aやbのところにファイル出力をいれてみて、あとからそのファイルを変換にかけてみたらどうなる?というやりかた。
具体的にはFlvQueueにいれる直前。FlvQueueから取り出した直後。ffmpegにFlvHandlerがデータを渡す直前の3箇所にプログラムの出力を出すようにしてどうなるか確認。その後、その生成ファイルをコマンドラインでffmpegにわたしたら同じエラーがでるか・・・という検証です。
実際やってみたところ、プログラム上でエラーがでたときのflv出力をあとで別途ffmpegにかけてみたところ、きちんと動作してしまいました。
うーん。なんで?と思いました。

仕方ないので、さらにやってみた。
やったことその4
その3で生成したファイルを改めてxuggleの変換プログラムにぶち込んでみようと思いました。
https://github.com/taktod/xuggle-test
で、書いてみたxuggleのプログラムがこれ。
冒頭で書きましたが、デコード処理でこけるので、プログラムにはデコードまでしか書いていません。
で、これで実行してみたところ・・・
FlvQueueにいれる直前とFlvQueueから取り出した直後のデータは問題なく変換できました。
ffmpegにデータを渡す直前のデータをながしてみたところ、AVC nal sizeのエラーが発生。
ffmpegにデータを渡す直前のデータでは、flvのデータタグがきちんと成立せずにおわりのところがぶつ切りになっていたので、それがまずかったみたいです。
バイナリエディタで、こわれているflvのデータタグを消してみて、再度変換をかけたところ、今回はエラーがでずに動作しました。

で、いまここです。
xuggleの変換では、FlvHandlerに適当なデータ量の要求がread関数にとんできます。
このときに応答せよと指定されるサイズってflvのデータタグの量関係なしに飛んできます。
かつ、このときに要求された量を返さないと、次の処理にすすんでくれません。
また、要求量以上応答するとメモリーオーバーフローするし・・・

なんかうまい解決策ないものですかね・・・

0 件のコメント:

コメントを投稿