Android MediaPlayer に関するメモ
Android で音楽や動画を再生するときに必要な MediaPlayer だけど、直に JNI に処理を吸い込まれていってデバッグしづらいので、 AOSP ネイティブ実装を追い掛けてみた。
TP Vision の資料 (以下の図) がわかりやすすぎて、あんま調べる意味がなかった感じもする。
Android builders summit - The Android media framework (PDF)
Application
- MediaPlayer (Java)
- media/java/android/media/MediaPlayer.java - platform/frameworks/base.git - Git at Google
- MediaPlayer (Java) は大したことはしてなくて、大部分を MediaPlayer (JNI) に投げている
JNI
- MediaPlayer (JNI)
- media/jni/android_media_MediaPlayer.cpp - platform/frameworks/base.git - Git at Google
- JNI で MediaPlayer (libmedia) のインスタンスを作ってやりとりをしている
libmedia
media/libmedia - platform/frameworks/av - Git at Google
- MediaPlayer (libmedia)
- media/libmedia/mediaplayer.cpp - platform/frameworks/av - Git at Google
- include/media/mediaplayer.h - platform/frameworks/av - Git at Google
- IMediaPlayer や IMediaPlayerService を通じて Binder (IPC) でやりとりしている
getMediaPlayerService()
の実装は IMediaDeathNotifier にある
- IMediaPlayer / IMediaPlayerService
- IMediaPlayer
- IMediaPlayerService
- IMediaDeathNotifier
- media/libmedia/IMediaDeathNotifier.cpp - platform/frameworks/av - Git at Google
- ServiceManager から "media.player" サービスを取得している
MediaPlayerService
libmedia で ServiceManager 経由で呼び出された "media.player" サービスは libmediaplayerservice に実体がある。
libmediaservice (MediaPlayerService)
media/libmediaplayerservice - platform/frameworks/av - Git at Google
- MediaPlayerService
- media/libmediaplayerservice/MediaPlayerService.cpp - platform/frameworks/av - Git at Google
MediaPlayerFactory#createPlayer
を通じてタイプに応じたプレイヤー (MediaPlayerBase) を生成している
- MediaPlayerFactory
- media/libmediaplayerservice/MediaPlayerFactory.cpp - platform/frameworks/av - Git at Google
- registerFactory で実装を追加している
- AOSP 版では StagefrightPlayer 、 NuPlayer 、 SonivoxPlayerFactory 、 TestPlayer の 4 種類を追加している
- MediaPlayerService を変更できる環境 (端末メーカなど) なら、ここに Player を追加することで独自のプレイヤー実装することが出来そう
- Widevine なら StagefrightPlayer 、 RTSP or HLS っぽかったら NuPlayer 、 MIDIは SonivoxPlayer 、それ以外はデフォルトプレイヤー
- Lollipop の場合は、開発者設定からデフォルトプレイヤーを AwesomePlayer (StagefrightPlayer) にするか NuPlayer にするか選べる
- StagefrightPlayer
- media/libmediaplayerservice/StagefrightPlayer.cpp - platform/frameworks/av - Git at Google
- AwesomePlayer (stagefright のプレイヤーの名前) のインスタンスを作って、そことやりとりしている
- Awesome って…
libstagefright (Stagefrihgt)
Stagefright の役割はだいたい以下のような感じ、パースとレンダリングをやって、デコード処理とかは OMX (OpenMAX) を通じてハードウェアにやらせている。
Integrating a Hardware Video Codec into Android Stagefright using OpenMAX IL (PDF)
- AwesomePlayer
- media/libstagefright/AwesomePlayer.cpp - platform/frameworks/av - Git at Google
- やっとメディアプレイヤーっぽい実装がされている
- 各種操作は AwesomeEvent というイベントのインスタンスを作って Queue に入れていく
AwesomePlayer#prepareAsync
prepareAsync_l
onPrepareAsyncEvent
beginPrepareAsync_l
- http や https ならば MediaHTTP を使ってコンテンツを取得してくる
- dataSource を元に MediaExtractor::Create を呼び出す
- MediaExtractor
setDataSource_l
- extractor 内の Track に "video/" があれば、それをフィールド変数で保持する
NuPlayer
media/libmediaplayerservice/nuplayer - platform/frameworks/av - Git at Google
- NuPlayer は libmediaplayerservice 内にあるけど、 httplive 周りのソースは libstagefright に依存している
用語集
- Stagefright
- 脆弱性で話題の Stagefright
- AwesomePlayer
- Stagefright のプレイヤーの名前
- NuPlayer
- ストリーミング用のプレイヤーの名前
- Lollipop から、ストリーミング以外の部分もやろうとしている (Stagefright 置き換え?)
- OMX / Open MAX
- Khronos Group が策定しているメディア API
- Bellagio
- Bellagio OpenMAX Integration Layer
- OpenMAX IL 実装の一つ
- Widevine
- Google の DRM
- HLS / Http Live Streaming
- HTTP 越しにメディアを再生するやつ
- Apple が m3u というプレイリストフォーマットを魔改造して作ったもの
参考リンク
- Stagefright入門
- Android builders summit - The Android media framework (PDF)
- Integrating a Hardware Video Codec into Android Stagefright using OpenMAX IL (PDF)
所感
- メディア再生の仕組みを調べたいのに脆弱性ばかりでてくる
- まだまだ調べ切れてないので、もっとソース読んでいきたい
追記 (2015/9/15)
Git の参照しているブランチが master だったので MediaPlayer まわりにコミットがあるとだんだんこの解説と乖離してしまいそう。ということで、 2015/9/15 現在で最新の android-5.1.1_r18 というタグに変更した。