記事ディレクトリ
序文
Android マルチメディア フレームワークの学習
1. Android マルチメディア フレームワークの歴史的レビュー
- Android 1.0 ->パケット動画 - オープンコア
- Android 1.6 -> オープンコア 2.0
- Android 2.0 ->StageFright
- Android 2.1 ->StageFright
- Android 3.0 -> 強化された StageFright
- Android 4.1 -> コーデック機能をサポート
- Android 5.0 -> MediaSession および MediaController 関数を追加
2. マルチメディア アーキテクチャ図
AOSP では、マルチメディア関連のコードは主に av/media と base/media の 2 つのディレクトリにあります。その中で、base/media は、Java 層のマルチメディア API に対応する JNI モジュールである libmedia_jni.so のコードを含む jni ディレクトリに焦点を当てています。av/media には、MediaPlayerService、Stagefright エンジンなど、Android マルチメディア サービスの特定の実装が含まれています。
Java レイヤー API は JNI を介してネイティブ レイヤー (libmedia_jni.so) を呼び出し、ネイティブ レイヤーは Binder IPC を介して関連するサービス プロセスを呼び出して関連するサービスを取得し、サービス プロセスは Open MAX を介してハードウェア レイヤーを呼び出します。
下の図は、AOSP の公式 Web サイトに表示されているマルチメディア アーキテクチャです。
三、JavaとJNI
1. Java レイヤー API
base/media/java ディレクトリには、おなじみの MediaPlayer、MediaRecorder、MediaCodec などを含むすべてのマルチメディア モジュール API が含まれています。これらの API がインポートされると、libmedia_jni.so のロードが開始され、ネイティブ メソッド マッピングが登録されます。
static {
System.loadLibrary("media_jni");
native_init();
}
2、Native层 jni
libmedia_jni.so の JNI_OnLoad メソッドは base/media/jni/android_media_MediaPlayer.cpp で定義され、マルチメディア API 全体で必要なネイティブ メソッド マッピングがメソッドに登録されます。
jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
{
JNIEnv* env = NULL;
jint result = -1;
if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
ALOGE("ERROR: GetEnv failed\n");
goto bail;
}
assert(env != NULL);
if (register_android_media_ImageWriter(env) != JNI_OK) {
ALOGE("ERROR: ImageWriter native registration failed");
goto bail;
}
if (register_android_media_ImageReader(env) < 0) {
ALOGE("ERROR: ImageReader native registration failed");
goto bail;
}
if (register_android_media_JetPlayer(env) < 0) {
ALOGE("ERROR: JetPlayer native registration failed");
goto bail;
}
if (register_android_media_MediaPlayer(env) < 0) {
ALOGE("ERROR: MediaPlayer native registration failed\n");
goto bail;
}
if (register_android_media_MediaRecorder(env) < 0) {
ALOGE("ERROR: MediaRecorder native registration failed\n");
goto bail;
}
if (register_android_media_MediaScanner(env) < 0) {
ALOGE("ERROR: MediaScanner native registration failed\n");
goto bail;
}
if (register_android_media_MediaMetadataRetriever(env) < 0) {
ALOGE("ERROR: MediaMetadataRetriever native registration failed\n");
goto bail;
}
if (register_android_media_ResampleInputStream(env) < 0) {
ALOGE("ERROR: ResampleInputStream native registration failed\n");
goto bail;
}
if (register_android_media_MediaProfiles(env) < 0) {
ALOGE("ERROR: MediaProfiles native registration failed");
goto bail;
}
if (register_android_mtp_MtpDatabase(env) < 0) {
ALOGE("ERROR: MtpDatabase native registration failed");
goto bail;
}
if (register_android_mtp_MtpDevice(env) < 0) {
ALOGE("ERROR: MtpDevice native registration failed");
goto bail;
}
if (register_android_mtp_MtpServer(env) < 0) {
ALOGE("ERROR: MtpServer native registration failed");
goto bail;
}
if (register_android_media_MediaCodec(env) < 0) {
ALOGE("ERROR: MediaCodec native registration failed");
goto bail;
}
if (register_android_media_MediaSync(env) < 0) {
ALOGE("ERROR: MediaSync native registration failed");
goto bail;
}
if (register_android_media_MediaExtractor(env) < 0) {
ALOGE("ERROR: MediaCodec native registration failed");
goto bail;
}
if (register_android_media_MediaMuxer(env) < 0) {
ALOGE("ERROR: MediaMuxer native registration failed");
goto bail;
}
if (register_android_media_MediaCodecList(env) < 0) {
ALOGE("ERROR: MediaCodec native registration failed");
goto bail;
}
if (register_android_media_Crypto(env) < 0) {
ALOGE("ERROR: MediaCodec native registration failed");
goto bail;
}
if (register_android_media_Drm(env) < 0) {
ALOGE("ERROR: MediaDrm native registration failed");
goto bail;
}
if (register_android_media_Descrambler(env) < 0) {
ALOGE("ERROR: MediaDescrambler native registration failed");
goto bail;
}
if (register_android_media_MediaHTTPConnection(env) < 0) {
ALOGE("ERROR: MediaHTTPConnection native registration failed");
goto bail;
}
/* success -- return valid version number */
result = JNI_VERSION_1_4;
bail:
return result;
}
Native層では、通常Java層と同名のオブジェクトを1対1で作成し、2つのオブジェクトは相互参照を保持し、JNIを介して相互にやり取りします。ネイティブの実装では、指定された Service プロセスから Binder IPC を介して Client を取得し、Client 要求を介してサービス プロセスに実装インスタンスを割り当て、アプリケーション プロセスはそのインスタンスを使用して対応する機能を完了します。 .
第四に、サービス層のプロセス
上記の MediaPlayerService および Stagefright エンジンはすべて独立したプロセスで実行されます. アプリケーション プロセスは Binder IPC を介してサービス プロセスとやり取りします. Bilder IPC コードは av/media/libmedia ディレクトリにあります.
7.0 では、セキュリティ上の理由から、マルチメディア サービス プロセス全体が複数のプロセスに分割され、各機能には独立したプロセスがあります。
5. ハードウェア統合層 OpenMax
OpenMax の正式名称は Open Media Acceleration です. これは、オーディオやビデオなどの一般的な処理操作のインターフェイスを提供する無料のマルチメディア API 標準です. これは、ハードウェア機能の抽象化であり、アプリケーション層でのハードウェアの適応の複雑さを軽減します.
アプリケーション層については、OpenMAX の対応する関数の API を呼び出すだけでよく、特定の SOC チップでの実装を気にする必要はありません。