前言
Android多媒体框架学习
一、Android多媒体框架历史回顾
- Android 1.0 ->Packet video - Open core
- Android 1.6 ->Open core 2.0
- Android 2.0 ->StageFright
- Android 2.1 ->StageFright
- Android 3.0 ->增强版StageFright
- Android 4.1 ->支持编解码功能
- Android 5.0->增加MediaSession 和MediaController功能
二、多媒体架构图
在AOSP中,多媒体相关代码主要在av/media和base/media两个目录。其中base/media中重点在其jni目录,这里面就是libmedia_jni.so的代码,也就是Java层多媒体API对应的JNI模块。av/media中包含了Android多媒体服务的具体实现,包含了MediaPlayerService、Stagefright引擎等。
Java层API通过JNI调用Native层(libmedia_jni.so),Native层通过Binder IPC调用到相关Service进程,获取相关服务,而Service进程通过Open MAX调用硬件层实现
下面这张图是AOSP官网中展示的多媒体架构图
三、java 和jni
1、java层API
base/media/java目录中包含了全部的多媒体模块API,包含了我们熟悉的MediaPlayer、MediaRecorder、MediaCodec等。这些API在import的时候,都会开始加载libmedia_jni.so,并注册native方法映射。
static {
System.loadLibrary("media_jni");
native_init();
}
2、Native层 jni
在base/media/jni/android_media_MediaPlayer.cpp中定义了libmedia_jni.so的JNI_OnLoad方法,在方法中注册了整个多媒体API需要的native方法映射。
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层同名的对象来一一对应,两个对象互相持有引用,借助JNI来交互。在Native的实现中,会通过Binder IPC向指定的Service进程获取到一个Client,通过Client向服务进程请求分配一个实现的实例,然后应用进程使用该实例完成对应的功能。
四、服务层进程
上面提到的MediaPlayerService、Stagefright引擎等都是运行在独立的进程上,应用进程通过Binder IPC来与服务进程进行交互,Bilder IPC代码位于av/media/libmedia目录中。
在7.0时,为了安全考虑,将整个多媒体服务进程拆分成多个进程,每个功能都拥有独立的进程。
五、硬件集成层OpenMax
OpenMax全称是Open Media Acceleration,是一个免费的多媒体API标准,提供了音频视频等常用处理操作的接口,是对硬件功能的抽象,减少了应用层适配硬件的复杂度。
对于应用层来说,只需要调用OpenMAX对应功能的API即可,具体SOC芯片上的实现无需关心。