Android で ffmpeg 等を使わずに端末標準のデコーダでflvを再生してみました.
flvのフォーマットや MediaCodec API の基本的な使い方は下記のURLを参照してください.
- http://developer.android.com/reference/android/media/MediaCodec.html
- http://www.adobe.com/jp/devnet/f4v.html
flvの仕様のPDFファイルは,いまadobeからダウンロードできる10.1より,10のもののほうが目次がちゃんとしてたりして読みやすい(?).
コーデック
flv のコーデックのうち,AAC, mp3と H.264, H.263 あたりは,Androidがコーデック持ってるので再生できそうです.
VP6とかもよく見かけるけど, Stagefright に入ってないようなので難しそうです.
音声コーデック(AAC,mp3)
音声データは特に難しいところはありませんが,Audio tagの最初のバイトに SoundRate, SoundSize 等が入っているので,最初のAudio tagを見つけた時点で,AudioTrackやDecoderを初期化します.
また,AACのみパケットのタイプがデータの先頭に1バイト付いてるので処理する必要があります(無視してもデコード出来ると思いますが).
H.264
デコーダに渡すNAL unitのスタートコードはAnnex-B形式の [0x00,0x00,0x00,0x01] でなければいけないようです.
flvは4バイトのサイズが付いているので,そこをすべて[0,0,0,1]に書き換えるだけです.
わかりにくい箇所は,コンフィグレーションレコードの扱いで,flvにはmp4のavcCと同じ形式でH.264のコンフィグレーションが入っていますが,そのままMediaDecoderに渡してもデコード出来ません.
mp4をMediaExtractorでパースした場合にどうなっているのかも疑問だったのですが,MediaFormatに"csd-0","csd-1"という名前のキーで書き込まれているようです.
同様に,MediaFormatに入れても良いし,または,NAL形式に変換してBUFFER_FLAG_CODEC_CONFIG フラグを付けて
デコーダに渡せばデコードできます.
H.263
FLVはH.263を格納出来ますが,通常のH.263ではなく,Sorenson Sparkです.よく似たフォーマットですが,互換性は無いのでビットストリームをパースして組み立て直す必要があります.
(目処はついてますが,まだ上手くデコードできてません)
Sorenson Spark は H.263 のサブセットなので,再エンコードせずに変換可能なはずです.Group of Block(GOB) Layerが存在しませんが,Macro Block(MB)は1つしかMBがないGOBと等しいので,Picture Layerだけ上手く作ればデコードできます.
ffmpegを読めば,どうにか出来そうです.
CEREVOの稲垣さんが,今回とは逆の,H.263からSparkへの変換をやっている記事.H.263からSparkへは一般的には変換出来ないのですが,エンコード時のパラメータさえ気をつければ可能なようです.
- http://www.itu.int/rec/T-REC-H.263-200501-I
- http://hkpr.info/flash/swf/index.php?%E3%83%93%E3%83%87%E3%82%AA%2FSorenson%20H.263%20%E3%83%93%E3%83%83%E3%83%88%E3%82%B9%E3%83%88%E3%83%AA%E3%83%BC%E3%83%A0%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%83%E3%83%88
いろいろメモ
最初,ffmpegのコードを読もうとしていたけど,つらくなって諦めました.
ビデオのデコード時にMediaFormatにColorFormatは指定できません.リファレンスにも指定できるとは書かれてないし,指定しても無視されます.デバッグ時に,RGBで出力して欲しくて試行錯誤して少し嵌りました.H.264の場合はFormatYUV420PackedSemiPlanar等で出てきます.
コーデックに変なデータ渡したりして,久しぶりにOSごと固まったりするのを見ました.
H.264は端末によってサポートしてるプロファイルが違うので,再生できなくて間違ってるのかなーと思ったら別の端末では再生できたりも.
まとめとか
Androidで AAC, mp3と H.264 はデコードできるのを確認しました(当たり前ですが...).
標準のデコーダを使うのでハードウェアデコーダが有効になるのが良いです.
書いた実験用アプリ
この記事も含めて,MIT Licenseです.