STM32F2でMotion JPEGの再生に挑戦してます。
動画ファイルのコンテナにはAVIやQuickTimeなどいろいろがありますが、音楽プレーヤを作ったときにMP4のIDタグを取り出した経験があったので馴染みのあるQuickTimeでデコードして構造を勉強してます。
QuickTime File Format Specification
http://developer.apple.com/library/mac/documentation/QuickTime/QTFF/qtff.pdf
↑QuickTimeフォーマットの仕様書
QuickTimeはAtomという階層型の入れ子で構成されていて、再生情報やデータ(ビデオやサウンドやテキスト等)は全てAtomに入れられ管理されています。
各Atomは自身の大きさとタイプ(ASCII文字列)が先頭に記述されていて、子を持つか、どういった情報を持つかなど予め仕様書で定義されています。
動画ファイルの全Atomを取り出してみました。画像の左文字列がAtomの種類で右がその大きさです。
親子の関係を表記しておらずただ単に列挙しただけのものです。
選択表示しているtrakがそれぞれサウンドトラックとビデオトラックです。
stxxというAtomがサンプルテーブルになっており、各サンプルの表示デュレーションやチャンクのまとめ方、各サンプルのファイルオフセットの位置等が記述されています。
ビデオトラックのstcoから1枚目のJPEG画像が格納されてあるファイルオフセットの位置を探ってみました。
選択部分の後ろ4バイトの0x000158B8が該当するのでそこに飛んでみます。
するとJPEGのStart of Imageマーカー(FFD8)がちゃんと現れました。
JPEG画像の終端が分からないといけないので調べてみるとサイズはstszに記述されていました。
1枚目の画像は選択範囲の後ろ4バイトの0x00000A45です。
さっきの先頭オフセットから0xA45分だけ選択してみると終端にJPEGのEnd of Imageマーカー(FFD9)が現れました。その直後にまたSOIマーカーがきてます。
これでQuickTimeのMOVファイルからMotion JPEGの1フレーム画像の位置と大きさを求めることができました。
これを取り込んでlibjpegでデコードして描画を繰り返せばとりあえず動画再生できるかも。
表示デュレーションや音楽との再生をとりあえず後回し^^
しかしここでちょっとした問題が><;
上の検証に使った動画はQVGAサイズ24分程度のもので約700MBの容量があります。
ビデオトラック情報が書かれてあるtrakのAtomはファイル先頭より692,413,886バイト後方に位置しています。
そこへ飛ぶために自作のfseek関数でシークすると9秒もかかってしまいました><;
クラスタサイズは32KBなので約2万個以上ものアロケーションテーブルを辿ったことになります。
改良次第でもうちょっと高速化することができるかなぁ。
動画ファイルのコンテナにはAVIやQuickTimeなどいろいろがありますが、音楽プレーヤを作ったときにMP4のIDタグを取り出した経験があったので馴染みのあるQuickTimeでデコードして構造を勉強してます。
QuickTime File Format Specification
http://developer.apple.com/library/mac/documentation/QuickTime/QTFF/qtff.pdf
↑QuickTimeフォーマットの仕様書
QuickTimeはAtomという階層型の入れ子で構成されていて、再生情報やデータ(ビデオやサウンドやテキスト等)は全てAtomに入れられ管理されています。
各Atomは自身の大きさとタイプ(ASCII文字列)が先頭に記述されていて、子を持つか、どういった情報を持つかなど予め仕様書で定義されています。
動画ファイルの全Atomを取り出してみました。画像の左文字列がAtomの種類で右がその大きさです。
選択表示しているtrakがそれぞれサウンドトラックとビデオトラックです。
stxxというAtomがサンプルテーブルになっており、各サンプルの表示デュレーションやチャンクのまとめ方、各サンプルのファイルオフセットの位置等が記述されています。
ビデオトラックのstcoから1枚目のJPEG画像が格納されてあるファイルオフセットの位置を探ってみました。
選択部分の後ろ4バイトの0x000158B8が該当するのでそこに飛んでみます。
するとJPEGのStart of Imageマーカー(FFD8)がちゃんと現れました。
JPEG画像の終端が分からないといけないので調べてみるとサイズはstszに記述されていました。
1枚目の画像は選択範囲の後ろ4バイトの0x00000A45です。
さっきの先頭オフセットから0xA45分だけ選択してみると終端にJPEGのEnd of Imageマーカー(FFD9)が現れました。その直後にまたSOIマーカーがきてます。
これでQuickTimeのMOVファイルからMotion JPEGの1フレーム画像の位置と大きさを求めることができました。
これを取り込んでlibjpegでデコードして描画を繰り返せばとりあえず動画再生できるかも。
表示デュレーションや音楽との再生をとりあえず後回し^^
しかしここでちょっとした問題が><;
上の検証に使った動画はQVGAサイズ24分程度のもので約700MBの容量があります。
ビデオトラック情報が書かれてあるtrakのAtomはファイル先頭より692,413,886バイト後方に位置しています。
そこへ飛ぶために自作のfseek関数でシークすると9秒もかかってしまいました><;
クラスタサイズは32KBなので約2万個以上ものアロケーションテーブルを辿ったことになります。
改良次第でもうちょっと高速化することができるかなぁ。