ijkplayer阅读学习笔记之从代码上看播放流程

看了很久的ijkplayer的视频播放,其实还是没有怎么看懂,只是个人浅浅的笔记
摘要由CSDN通过智能技术生成

看了很久的ijkplayer的视频播放,其实还是没有怎么看懂,只是个人浅浅的笔记

关键部分就是联网获取数据那部分,还没有搞定其实

从用户点击一个已有地址的网络视频开始,从源码分析播放流程。

1.        // init player  加载native底层库

        IjkMediaPlayer.loadLibrariesOnce(null);

        IjkMediaPlayer.native_profileBegin("libijkplayer.so");

第一句话是加载三个重要的so文件

libLoader.loadLibrary("ijkffmpeg");

                libLoader.loadLibrary("ijksdl");

                libLoader.loadLibrary("ijkplayer");

第二句话调用了一个native方法public static native void native_profileBegin(String libName);

2.  设置uri,可以是rtmprtsphttp等,native ffplay代码中会根据该uri匹配不同的流媒体协议,具体参考ffplay 支持本地和网络视频。

if (mVideoPath != null)

            mVideoView.setVideoPath(mVideoPath);

        else if (mVideoUri != null)

            mVideoView.setVideoURI(mVideoUri);

3. 分析网络视频源:接着openVideo()

先创建播放器 mMediaPlayer = createPlayer(mSettings.getPlayer());接着是播放器的相关设置

诸如:       mMediaPlayer.setOnPreparedListener(mPreparedListener);

            mMediaPlayer.setOnVideoSizeChangedListener(mSizeChangedListener);

            mMediaPlayer.setOnCompletionListener(mCompletionListener);

            mMediaPlayer.setOnErrorListener(mErrorListener);

            mMediaPlayer.setOnInfoListener(mInfoListener);

            mMediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener);

当然,还需要设置播放源,会调用

tv.danmaku.ijk.media.player.IMediaPlayer#setDataSource(android.content.Context, android.net.Uri, java.util.Map<java.lang.String,java.lang.String>)

开始播放mVideoView.start();调用tv.danmaku.ijk.media.player.IMediaPlayer#start,这里java层就结束了,进入c底层,其实从加载native底层库开始就进入c底层了

4. 分析c底层:/ijkmedia/ijkplayer/android/ijkplayer_jni.c这个文件里 static JNINativeMethod g_methods[] 一个数组,声明了全部的java层的native方法 ,而调用native的方法集中在类 tv.danmaku.ijk.media.player.IjkMediaPlayer

 

5. 没想到居然是c主动调用java,通过反射生成java端所需要的函数,这个地方不是我们正常JNI的调用思路

正常调用JNI的思路:是通过javah,获取一组带签名函数,然后实现这些函数。这种方法很常用,也是官方推荐的方法。

分析一下JNI运行时机制:

当在系统中调用System.loadLibrary函数时,该函数会找到对应的动态库,然后首先试图找到"JNI_OnLoad"函数,如果该函数存在,则调用它。
JNI_OnLoad可以和JNIEnvregisterNatives函数结合起来,实现动态的函数替换。很显然ijk的作者是使用的这种调用方式

在 ijkplayer-sample/src/main/jni/ijkmedia/ijkplayer/android/ijkplayer_jni.c

 


 

然后在JNI_OnLoad 初始化好多内容,比如上图三个 global 型的函数

这样就可以理解作者为什么一开始就先调用三个 so 文件了

ijkplayer-sample/src/main/jni/ijkmedia/ijksdl/android/ijksdl_android_jni.c里也有JNI_OnLoad

Ffmpeg的个人感觉是不需要,因为作者直接使用的ffmpeg的代码,只需要正常引入就好。

 

6. J4a里生成的两个java文件也是很重要的类

 

目前还不清楚作用

7. ijkplayer-sample/src/main/jni/ijkmedia/ijkplayer/ff_ffplay_def.h  这个定义了ijk播放器核心数据结构体的类,作者是直接使用的ffmpegijkplayer-sample/src/main/jni/ffmpeg/ffplay.cffmpeg的文件的基础上的扩展,里面引用了很多ffmpeg的源文件。基本上就不需要关心ffmpeg的源代码了。

8. 这里只分析libijkplayer.so

8.1  ijkmp_global_init 在 ijkplayer-sample/src/main/jni/ijkmedia/ijkplayer/ijkplayer.c

void ijkmp_global_init()

{

     ffp_global_init();

}

ffp_global_init() 

ijkplayer-sample/src/main/jni/ijkmedia/ijkplayer/ijkplayer_internal.hinclude

ijkplayer-sample/src/main/jni/ijkmedia/ijkplayer/ff_ffplay.h里,具体定义代码在

ijkplayer-sample/src/main/jni/ijkmedia/ijkplayer/ff_ffplay.c中,主要是ffmpeg的初始化工作。

8.2 ijkmp_global_set_inject_callback(inject_callback)是在

ijkplayer-sample/src/main/jni/ijkmedia/ijkplayer/ijkplayer.cinclude

ijkplayer-sample/src/main/jni/ijkmedia/ijkplayer/ijkavformat/ijkavformat.h里声明,

ijkplayer-sample/src/main/jni/ijkmedia/ijkplayer/ijkavformat/utils.c里定义

这里使用最多的是ijkavformat.h里的

typedef int (*IjkAVInjectCallback)(void *opaque, int message, void *data, size_t data_size);

这个声明引入了 IjkAVInjectCallback 类型作为函数指针的同义字,该函数有四个不同 类型的参数以及一个 int 类型的返回值

IjkAVInjectCallback ijkav_register_inject_callback(IjkAVInjectCallback callback);定义一个函数ijkav_register_inject_callback,这个函数的参数是一个函数指针,返回值也是个函数指针,相当于int ( *ijkav_register_inject_callback( int (*callback)(void *opaque, int message, void *data, size_t data_size) ) )(void *opaque, int message, void *data, size_t data_size);

由于int (*callback)(void *opaque, int message, void *data, size_t data_size) 

IjkAVInjectCallback ,上面的简化一下就是

int ( *ijkav_register_inject_callback( IjkAVInjectCallback ) )(void *opaque, int message, void *data, size_t data_size);这里的

*ijkav_register_inject_callback( IjkAVInjectCallback ) 又是一个返回IjkAVInjectCallback的函数 ,再简化一下,即

  • 17
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值