• MediaPlayer_Analyze-2-JNI


    MediaPlayer Analyze - Framework JNI

    frameworks\base\media\jni\android_media_MediaPlayer.cpp

    static const JNINativeMethod gMethods[] = {
        {"_setDataSource",      "(Ljava/io/FileDescriptor;JJ)V",    (void *)android_media_MediaPlayer_setDataSourceFD},
        {"_setDataSource",      "(Landroid/media/MediaDataSource;)V",(void *)android_media_MediaPlayer_setDataSourceCallback },
        {"_setVideoSurface",    "(Landroid/view/Surface;)V",        (void *)android_media_MediaPlayer_setVideoSurface},
        {"_prepare",            "()V",                              (void *)android_media_MediaPlayer_prepare},
        {"prepareAsync",        "()V",                              (void *)android_media_MediaPlayer_prepareAsync},
        {"_start",              "()V",                              (void *)android_media_MediaPlayer_start},
        {"_stop",               "()V",                              (void *)android_media_MediaPlayer_stop},
        ......
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    一 初始化

    1.1 java层接口

    native_setup(new WeakReference<MediaPlayer>(this));
    
    • 1

    1.2 jni层接口

    frameworks\base\media\jni\android_media_MediaPlayer.cpp

    static void
    android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this)
    {
        ALOGV("native_setup");
        sp<MediaPlayer> mp = new MediaPlayer(); // new C++ MediaPlayer()
        if (mp == NULL) {
            jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
            return;
        }
    
        // create new listener and give it to MediaPlayer
        sp<JNIMediaPlayerListener> listener = new JNIMediaPlayerListener(env, thiz, weak_this);
        mp->setListener(listener);
    
        // Stow our new C++ MediaPlayer in an opaque field in the Java object.
        // 保存C++对象到Java对象中
        setMediaPlayer(env, thiz, mp);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    二 设置source

    2.1 java层接口

        // 网络流调用
                nativeSetDataSource( // 非本地流调用
                    MediaHTTPService.createHttpServiceBinderIfNecessary(path, cookies),
                    path,
                    keys,
                    values);
        // 本地流调用
            _setDataSource(fd, offset, length);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2.2 jni层接口

    frameworks\base\media\jni\android_media_MediaPlayer.cpp

    static void
    android_media_MediaPlayer_setDataSourceAndHeaders(
            JNIEnv *env, jobject thiz, jobject httpServiceBinderObj, jstring path, jobjectArray keys, jobjectArray values) {
    
        sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
    
        sp<IMediaHTTPService> httpService;
        if (httpServiceBinderObj != NULL) {
            sp<IBinder> binder = ibinderForJavaObject(env, httpServiceBinderObj);
            httpService = interface_cast<IMediaHTTPService>(binder);
        }
    
        // 调用native层接口
        status_t opStatus =
            mp->setDataSource(
                    httpService,
                    pathStr,
                    headersVector.size() > 0? &headersVector : NULL);
    
        // 回调
        process_media_player_call(
                env, thiz, opStatus, "java/io/IOException",
                "setDataSource failed." );
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    三 准备

    3.1 java层接口

            _prepare();
    
    • 1

    3.2 jni层接口

    frameworks\base\media\jni\android_media_MediaPlayer.cpp

    static void
    android_media_MediaPlayer_prepare(JNIEnv *env, jobject thiz)
    {
        sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
        
        sp<IGraphicBufferProducer> st = getVideoSurfaceTexture(env, thiz);
        mp->setVideoSurfaceTexture(st);
    
        process_media_player_call( env, thiz, mp->prepare(), "java/io/IOException", "Prepare failed." );
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    四 开始/恢复播放

    4.1 java层接口

            _start();
    
    • 1

    4.2 jni层接口

    frameworks\base\media\jni\android_media_MediaPlayer.cpp

    static void
    android_media_MediaPlayer_start(JNIEnv *env, jobject thiz)
    {
        ALOGV("start");
        sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
        
        process_media_player_call( env, thiz, mp->start(), NULL, NULL );
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    五 暂停播放

    5.1 java层接口

            _pause();
    
    • 1

    5.2 jni层接口

    frameworks\base\media\jni\android_media_MediaPlayer.cpp

    static void
    android_media_MediaPlayer_pause(JNIEnv *env, jobject thiz)
    {
        ALOGV("pause");
        sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
        
        process_media_player_call( env, thiz, mp->pause(), NULL, NULL );
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    六 停止播放

    6.1 java层接口

            _stop();
    
    • 1

    6.2 jni层接口

    frameworks\base\media\jni\android_media_MediaPlayer.cpp

    static void
    android_media_MediaPlayer_stop(JNIEnv *env, jobject thiz)
    {
        ALOGV("stop");
        sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
        
        process_media_player_call( env, thiz, mp->stop(), NULL, NULL );
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    七 重置

    7.1 java层接口

            _reset();
    
    • 1

    7.2 jni层接口

    frameworks\base\media\jni\android_media_MediaPlayer.cpp

    static void
    android_media_MediaPlayer_reset(JNIEnv *env, jobject thiz)
    {
        ALOGV("reset");
        sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
        
        process_media_player_call( env, thiz, mp->reset(), NULL, NULL );
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    八 释放

    8.1 java层接口

            _release();
    
    • 1

    8.2 jni层接口

    frameworks\base\media\jni\android_media_MediaPlayer.cpp

    static void
    android_media_MediaPlayer_release(JNIEnv *env, jobject thiz)
    {
        ALOGV("release");
        decVideoSurfaceRef(env, thiz);
        sp<MediaPlayer> mp = setMediaPlayer(env, thiz, 0);
        if (mp != NULL) {
            // this prevents native callbacks after the object is released
            mp->setListener(0);
            mp->disconnect();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
  • 相关阅读:
    马斯克 VS 乔布斯,谁是21世纪最伟大的创业家
    【知识点随笔分析 | 第六篇】HTTP/1.1,HTTP/2和HTTP/3的区别
    使用gpio_direction_output()无法设置GPIO原因分析
    大模型从入门到应用——LangChain:回调函数(Callbacks)]
    c++ 对象模型
    数据挖掘期末复习
    sde Geodatabase tool to upgrade system tables
    渗透测试-目录遍历漏洞
    JPA在不写sql的情况下实现模糊查询
    罗尔中值定理习题
  • 原文地址:https://blog.csdn.net/tujidi1csd/article/details/126867739