横浜 Android プラットフォーム部
                  第13回勉強会

   Stagefright 入門
~ Android Multimedia~


                  2011/9/19
                     @l_b__
Stagefright とは?
➲   Gingerbread から採用された動画・音声再生を行う
    ためのメディアプレーヤーフレームワーク
➲   ソース自体は Eclair から入っていたが、正式採用は
    Gingerbread
➲   意味は「舞台負け」「気後れ」「舞台あがり」(研究
    社新英和中辞典より)
MediaPlayer のおさらい
➲   基本的な MediaPlayer の使い方(音楽再生)
    Uri myUri = ....; // initialize Uri here

    MediaPlayer mediaPlayer = new MediaPlayer();

    mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC)
    ;

    mediaPlayer.setDataSource(getApplicationContext(), myUri);

    mediaPlayer.prepare();

    mediaPlayer.start();
MediaPlayer のソースを見る
➲ frameworks/base/me

 dia 以下がマルチメディ
 ア関連のソース。
➲ コアである

 MediaPlayer.java の実
 行ステップ数450行!
MediaPlayer のソース
➲ イベント処理を行っているだけでほ

 とんどの機能で Native を呼んでい
 る。
➲ で、 JNI を通した呼び先が
 Stagefright。
Android のマルチメディア史
➲ 元々はメディアエンジンとして

 ffmpeg (http://ffmpeg.org/) を採
 用する予定だったらしい。
➲ しかし
    ffmpeg はライセンスに GPL
 を採用。
➲ しかも...
Hall of Shame
Android のマルチメディア史
➲   ライセンス違反ソフトの晒し上げページを作るほど
    強硬派。
➲   で、 ffmpeg はあきらめ、他のエンジンを探したら
    しい。
➲   そして採用されたのが PacketVideo 社の CORE を
    オープンソース化した OpenCore。
➲   以後、 Froyo まで/ external/opencore の下に存
    在。
OpenCore
➲   OpenCore はプレーヤー部分である pvPlayer
    と各 Codec から構成。
➲   開発向けガイドなどのドキュメント類
    が/ external/opencore/doc 配下にある。
➲   OpenCore には一つ面白い特徴が。
OpenMAX
➲   OpenCore は OpenMAX をサポート。
➲   OpenMAX(http://www.khronos.org/open
    max/) とは
     ●   Khronos グループが策定しているポータビリ
          ティを重視したクロスプラットフォーム向け
         のメディア API
余談: Khronos って?
➲   様々なオープンスタンダード API を策定して
    いるコンソーシアム。
➲   OpenGL,OpenCL,OpenVG,OpenSL,OpenK
    ODE,WebGL,EGL,WebCL,OpenWF etc etc.
➲   OpenAL が Khronos 策定で無いのをさっき知ったのはここだけの話で
    す。
OpenCore と OpenMAX
➲   OpenCore がサポートしているのは
    OpenMAX IL(Integration Layer)
➲   OpenMAX には DL(Development
    Layer)、IL、AL(Application Layer) があ
    り、 IL はコーデックを叩きやすくする API
    が定義されている。
OpenMAX IL




http://pc.watch.impress.co.jp/docs/2004/0729/kaigai104.htm  から
ここは想像
➲   OpenCore にスタンダードなエンコード/デ
    コードの API が用意されていたので、 Java
    側の AndroidMediaFramework に合わせて
    作り直したのが Stagefright じゃないかな
    と。
➲   Stagefright が公開されたのは Eclair から。
動画再生の基礎
➲   動画はおおざっぱに言うと、パラパラ漫画の
    絵(フレーム)を1枚ずつどう圧縮し(符号化)、
    どういう形でファイル/ストリームに格納する
    か(コンテナ)。
➲   動画再生はファイル/ストリームからコンテナ
    形式に従ってフレームを取り出し、デコード
    して取り出した画像を画面表示すること。
動画再生の図




➲   取り出したフレームには
     ●   それだけで復号できる I フレーム
     ●   前の I フレーム/ P フレームを参照して復号する P フレーム
     ●   前後のフレームを参照して復号する B フレーム
➲   デコーダには I フレームを含む形でフレームを渡す必要がある
音声再生の基礎
➲   基本は PCM(Pulse Code Modulation) フォー
    マット。
➲   サンプリング周波数単位で、音圧を変換した
    量子化ビットを記録したもの。
➲   サンプリング周波数は音声をどの頻度でデー
    タ化するかを Hz で表したもの。
➲   量子化ビット(ビット深度)はどの程度の精度
    で音圧を記録するか。
音声再生の基礎
➲   CD の場合、サンプリング周波数は
    44.1 KHz、 量子化ビット数は16 bit、 ステ
    レオで2 ch。
➲   データサイズは1秒辺り
    44100 x2byte(=16bit)x2(ch)=176400byt
    e
➲   このデータをコーデックでエンコード・デ
    コードする。
で、 Stagefright の話
➲   Stagefright の機能を簡単に
     ●   アプリから渡された uri を元にファイル/スト
          リームを取得
     ●   ファイル/ストリームがどのコンテナ形式かを
          チェックし、対応する
          DataSource/MediaSource に格納
Stagefright の処理(承前)
●   コンテナからフレームを取り出し
     ( Parser)、OpenMAX IL でデコード
●   デコードしたフレームを Surface/AudioTrack
     に設定して SurfaceFlinger/AudioFlinger に
     渡して再生する( Rendrer)
StageFright を簡単な図で




http://events.linuxfoundation.org/events/embedded-
linux-conference/garcia の資料
http://elinux.org/images/5/52/Elc2011_garcia.pdf から
Parser 処理
➲   ファイル/ストリームデータを格納する
    MediaSource クラス及びコンテナタイプ毎の
    サブクラスから MediaExtractor のコンテナ
    タイプ毎のサブクラスを呼び出して処理。
     ●   MPEG4 の場合、 MPEG4Source と
          MPEG4Extractor
➲
Parse 処理
➲   内部では泥臭くバイナリデータをパース。
➲   フレームのデータを取得しておく。
     ●   画面サイズ、フレームレート、 RGB フォー
          マット、サンプリングレート、ビット深度等
          デコード、レンダリングに必要な情報
デコード処理
➲   OpenMAX IL の API を使ってデコードする。
➲   OpenMAX IL の使い方は Bellagio(
    http://omxil.sourceforge.net/)が詳しく、サンプ
    ルソースがある。
➲   /external/opencore/doc にある開発ガイドにも説
    明あり。
➲   以下 openmax_call_sequences.pdf から抜粋
OMX Core 初期化
      ➲   OMX_Init で初期化
          し、使用可能な
          Codec をコンポーネ
          ント名として取得す
          る。
      ➲   コンポーネント名か
          ら機能(何の Codec
          か)を取得。
OMX コンポーネント設定
       ➲   OMXGetHandle で
           コンポーネントハン
           ドルを取得する。
       ➲   コンポーネントのパ
           ラメータ取得
OMX 入出力バッファ設定
       ➲   フレームを入力し、
           デコードされたデー
           タを出力するバッ
           ファを設定する。
       ➲   この後、コンポーネ
           ントの状態を
           Loaded→Idle→Exe
           cuting にする。
OMX のポート




➲   コンポーネントの入出力ポートを介してデ
    コード前/後のデータをやり取りする。
OMX デコード処理




➲   バッファにデータを設定した後、 EmptyThisBuffer でデ
    コード開始、 FillThisBuffer でデコードされたデータを取り
    出し。
Renderer 処理
➲   OMX コンポーネントから取得したデータを出
    力する。
➲   画像データは必要ならスケーリング、画像
    フォーマット( YUV→RGB) 変換を行
    い、 Surface を使って SurfaceFlinger で描
    画。
➲   音声データは AudioTrack を使って
    AudioFlinger で再生。
Stagefright の構成図




http://freepine.blogspot.com/2010/01/overview-of-
stagefrighter-player.html
Stagefright の構成
➲   緑が DataSource、MediaSource と
    MediaExtractor。 ファイル/ストリームから
    フレーム(やメタデータ)をパースする処理部
    分。
➲   オレンジが OpenMAX IL の実装部分。
➲   水色がレンダリング処理部分。
➲   赤が全体を制御する機能部分。
まとめ
➲   Android のマルチメディア処理はほとんど
    Native の Stagefright で行われます。
➲   Stagefright には OpenMAX DL というオー
    プンスタンダードが使われています。
最後に
➲   OpenMAX Dl の API は共有ライブラリとし
    て公開されているので、実は普通に JNI を
    使った Android アプリから叩けます。
➲   なので、 Android 標準で対応していない
    フォーマットの動画・音声も頑張れば HW デ
    コードをサポートした形で自作アプリから再
    生できます。
                        以上です。

Stagefright入門

  • 1.
    横浜 Android プラットフォーム部 第13回勉強会 Stagefright 入門 ~ Android Multimedia~ 2011/9/19 @l_b__
  • 2.
    Stagefright とは? ➲ Gingerbread から採用された動画・音声再生を行う ためのメディアプレーヤーフレームワーク ➲ ソース自体は Eclair から入っていたが、正式採用は Gingerbread ➲ 意味は「舞台負け」「気後れ」「舞台あがり」(研究 社新英和中辞典より)
  • 3.
    MediaPlayer のおさらい ➲ 基本的な MediaPlayer の使い方(音楽再生) Uri myUri = ....; // initialize Uri here MediaPlayer mediaPlayer = new MediaPlayer(); mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC) ; mediaPlayer.setDataSource(getApplicationContext(), myUri); mediaPlayer.prepare(); mediaPlayer.start();
  • 4.
    MediaPlayer のソースを見る ➲ frameworks/base/me dia 以下がマルチメディ ア関連のソース。 ➲ コアである MediaPlayer.java の実 行ステップ数450行!
  • 5.
    MediaPlayer のソース ➲ イベント処理を行っているだけでほ とんどの機能で Native を呼んでい る。 ➲ で、 JNI を通した呼び先が Stagefright。
  • 6.
    Android のマルチメディア史 ➲ 元々はメディアエンジンとして ffmpeg (http://ffmpeg.org/) を採 用する予定だったらしい。 ➲ しかし ffmpeg はライセンスに GPL を採用。 ➲ しかも...
  • 7.
  • 8.
    Android のマルチメディア史 ➲ ライセンス違反ソフトの晒し上げページを作るほど 強硬派。 ➲ で、 ffmpeg はあきらめ、他のエンジンを探したら しい。 ➲ そして採用されたのが PacketVideo 社の CORE を オープンソース化した OpenCore。 ➲ 以後、 Froyo まで/ external/opencore の下に存 在。
  • 9.
    OpenCore ➲ OpenCore はプレーヤー部分である pvPlayer と各 Codec から構成。 ➲ 開発向けガイドなどのドキュメント類 が/ external/opencore/doc 配下にある。 ➲ OpenCore には一つ面白い特徴が。
  • 10.
    OpenMAX ➲ OpenCore は OpenMAX をサポート。 ➲ OpenMAX(http://www.khronos.org/open max/) とは ● Khronos グループが策定しているポータビリ ティを重視したクロスプラットフォーム向け のメディア API
  • 11.
    余談: Khronos って? ➲ 様々なオープンスタンダード API を策定して いるコンソーシアム。 ➲ OpenGL,OpenCL,OpenVG,OpenSL,OpenK ODE,WebGL,EGL,WebCL,OpenWF etc etc. ➲ OpenAL が Khronos 策定で無いのをさっき知ったのはここだけの話で す。
  • 12.
    OpenCore と OpenMAX ➲ OpenCore がサポートしているのは OpenMAX IL(Integration Layer) ➲ OpenMAX には DL(Development Layer)、IL、AL(Application Layer) があ り、 IL はコーデックを叩きやすくする API が定義されている。
  • 13.
  • 14.
    ここは想像 ➲ OpenCore にスタンダードなエンコード/デ コードの API が用意されていたので、 Java 側の AndroidMediaFramework に合わせて 作り直したのが Stagefright じゃないかな と。 ➲ Stagefright が公開されたのは Eclair から。
  • 15.
    動画再生の基礎 ➲ 動画はおおざっぱに言うと、パラパラ漫画の 絵(フレーム)を1枚ずつどう圧縮し(符号化)、 どういう形でファイル/ストリームに格納する か(コンテナ)。 ➲ 動画再生はファイル/ストリームからコンテナ 形式に従ってフレームを取り出し、デコード して取り出した画像を画面表示すること。
  • 16.
    動画再生の図 ➲ 取り出したフレームには ● それだけで復号できる I フレーム ● 前の I フレーム/ P フレームを参照して復号する P フレーム ● 前後のフレームを参照して復号する B フレーム ➲ デコーダには I フレームを含む形でフレームを渡す必要がある
  • 17.
    音声再生の基礎 ➲ 基本は PCM(Pulse Code Modulation) フォー マット。 ➲ サンプリング周波数単位で、音圧を変換した 量子化ビットを記録したもの。 ➲ サンプリング周波数は音声をどの頻度でデー タ化するかを Hz で表したもの。 ➲ 量子化ビット(ビット深度)はどの程度の精度 で音圧を記録するか。
  • 18.
    音声再生の基礎 ➲ CD の場合、サンプリング周波数は 44.1 KHz、 量子化ビット数は16 bit、 ステ レオで2 ch。 ➲ データサイズは1秒辺り 44100 x2byte(=16bit)x2(ch)=176400byt e ➲ このデータをコーデックでエンコード・デ コードする。
  • 19.
    で、 Stagefright の話 ➲ Stagefright の機能を簡単に ● アプリから渡された uri を元にファイル/スト リームを取得 ● ファイル/ストリームがどのコンテナ形式かを チェックし、対応する DataSource/MediaSource に格納
  • 20.
    Stagefright の処理(承前) ● コンテナからフレームを取り出し ( Parser)、OpenMAX IL でデコード ● デコードしたフレームを Surface/AudioTrack に設定して SurfaceFlinger/AudioFlinger に 渡して再生する( Rendrer)
  • 21.
  • 22.
    Parser 処理 ➲ ファイル/ストリームデータを格納する MediaSource クラス及びコンテナタイプ毎の サブクラスから MediaExtractor のコンテナ タイプ毎のサブクラスを呼び出して処理。 ● MPEG4 の場合、 MPEG4Source と MPEG4Extractor ➲
  • 23.
    Parse 処理 ➲ 内部では泥臭くバイナリデータをパース。 ➲ フレームのデータを取得しておく。 ● 画面サイズ、フレームレート、 RGB フォー マット、サンプリングレート、ビット深度等 デコード、レンダリングに必要な情報
  • 24.
    デコード処理 ➲ OpenMAX IL の API を使ってデコードする。 ➲ OpenMAX IL の使い方は Bellagio( http://omxil.sourceforge.net/)が詳しく、サンプ ルソースがある。 ➲ /external/opencore/doc にある開発ガイドにも説 明あり。 ➲ 以下 openmax_call_sequences.pdf から抜粋
  • 25.
    OMX Core 初期化 ➲ OMX_Init で初期化 し、使用可能な Codec をコンポーネ ント名として取得す る。 ➲ コンポーネント名か ら機能(何の Codec か)を取得。
  • 26.
    OMX コンポーネント設定 ➲ OMXGetHandle で コンポーネントハン ドルを取得する。 ➲ コンポーネントのパ ラメータ取得
  • 27.
    OMX 入出力バッファ設定 ➲ フレームを入力し、 デコードされたデー タを出力するバッ ファを設定する。 ➲ この後、コンポーネ ントの状態を Loaded→Idle→Exe cuting にする。
  • 28.
    OMX のポート ➲ コンポーネントの入出力ポートを介してデ コード前/後のデータをやり取りする。
  • 29.
    OMX デコード処理 ➲ バッファにデータを設定した後、 EmptyThisBuffer でデ コード開始、 FillThisBuffer でデコードされたデータを取り 出し。
  • 30.
    Renderer 処理 ➲ OMX コンポーネントから取得したデータを出 力する。 ➲ 画像データは必要ならスケーリング、画像 フォーマット( YUV→RGB) 変換を行 い、 Surface を使って SurfaceFlinger で描 画。 ➲ 音声データは AudioTrack を使って AudioFlinger で再生。
  • 31.
  • 32.
    Stagefright の構成 ➲ 緑が DataSource、MediaSource と MediaExtractor。 ファイル/ストリームから フレーム(やメタデータ)をパースする処理部 分。 ➲ オレンジが OpenMAX IL の実装部分。 ➲ 水色がレンダリング処理部分。 ➲ 赤が全体を制御する機能部分。
  • 33.
    まとめ ➲ Android のマルチメディア処理はほとんど Native の Stagefright で行われます。 ➲ Stagefright には OpenMAX DL というオー プンスタンダードが使われています。
  • 34.
    最後に ➲ OpenMAX Dl の API は共有ライブラリとし て公開されているので、実は普通に JNI を 使った Android アプリから叩けます。 ➲ なので、 Android 標準で対応していない フォーマットの動画・音声も頑張れば HW デ コードをサポートした形で自作アプリから再 生できます。 以上です。