Android多媒体框架一


前言

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官网中展示的多媒体架构图
android多媒体架构

三、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芯片上的实现无需关心。

猜你喜欢

转载自blog.csdn.net/qq_35831940/article/details/118497946