2012年10月21日日曜日

デコードに失敗するので、パケットの生成を自力にしてみた。

xuggleによる、flvデータのリアルタイム変換の件なんですが

どうしてもうまくいかないので、自力でがんばってみました。
これで正解なのかは、わかりません。

で、やったこと。
https://github.com/taktod/xuggle-test/
こちらのリポジトリにxuggleで変換を動作させるためのさわりを書いてありますが、

■通常の動作は次のような感じになります。
Transcoder1のrunあたりを参照
1:コンテナを開く(独自URLをひもづけることで入力をFlvHandlerにデータの読み込みを依頼)
2:コンテナから、パケットを読み込む
3:始めの場合はcoderが開いていないので、映像コーダーと音声コーダーを開く
4:コーダーにデコード処理をさせる。

2のあとに取得できるパケットの中身を確認したところ、動作が壊れるときには、内部のデータがおかしくなっているみたいでした
通常なら、IPacket.getDataで取り出したbyteArrayのデータの中身の先頭は00 00で始まるのですが、そうではないデータがきた後に・・
16:13:59,956 [Thread-0] ERROR [ffmpeg] - [h264 @ 0x7f307c0561e0] AVC: nal size 66051
といったエラーがでて止まってしまいます。
同じデータをflvに出力してみて、各flvの構成要素のどの部分が出力されているのか確認したところ、たしかに、問題になる部分にさしかかると、開始位置がおかしくなっていました。

■では、壊れているなら、正しいデータに直しておくってやればいいじゃないか
ということでつくってみたのがTranscoder2です。
こちらのプログラムでは、コンテナをそもそも開かず。Coderも自力で開いて動作させています。

1:コンテナを開くところで、flvファイルを普通にオープン
2:ファイルデータから、パケットを作成。
3:ファイルデータから必要ならデコード用のコーダーも開く。
4:コーダーにデコード処理をさせる。

この動作の場合、mp3はうまく動作しましたが、h.264のデータがうまくデコードできませんでした。frameがなんたらというエラーがでます。
どうやら、1フレーム目を送る前に特別な処理をしなければいけないみたいです。
ffmpegのlibavformatのflvdec.c等も読んでみましたが、この特別な処理の仕方がいまいちわかりませんでした。

■仕方ないので、コーダーを開くところまでは、native動作にまかせておいて、
データの生成部分だけ、自力でやろうか・・・ということになりました。
それが、Transcoder3になります。

1:コンテナを開くところで、flvファイルも開くしFlvHanlerのひも付けもしとく。
2:coderが準備されていない場合はコンテナからreadNextPacketでパケットデータを取得する。
3:その直後ファイルデータから、packetを自力作成
4:始めは処理coderが開いていないので、音声コーダーと映像コーダーを開く。
5:コーダーにデコード処理をさせる。
これで、mp3もaacもh.264もとりいそぎ処理できました。

あとは、ストリーミング変換にいれてみて動作がどうなるか・・・ですね。

0 件のコメント:

コメントを投稿