Android ----Ijkplayer源码阅读native层之动态库的加载和初始化(三)

整章目录:Android------- IjkPlayer 源码学习目录

 

Android ----- ijkplayer源码阅读Java层(二)中欠了一篇细说加载Ijkplayer动态库时到底干了写啥???那我们就来聊聊上图红色圈起来部分。 

VideoActivity.onCreate中调用

native_profileBegin这个是加载----性能分析工具android-ndk-profiler的动态库。这方面没用过,不说。

loadLibrariesOnce:

加载三个动态库

ffmpeg:音视频编解码的核心库

ijksdl:在native层创建一些java类对象,并存放在native层全局引用

ijkplayer : 播放器的核心库,Java层所有native方法的实现库。

由于介绍的是Ijkplayer框架所以ffmpeg不是我们的重点,后面只提ffmpeg基本的执行流程。

所以只聊加载ijksdl和ijkplayer动态库的那些事


加载ijksdl:

由于本人在模拟器运行,所以找ijkplayer-x86/src/main/jni/ijkmedia/ijksdl/android/ijksdl_android_jni.h

入口:

ijksdl_android_jni.JNI_OnLoad

j4a_allclasses.J4A_LoadAll__catchAll:

上图:加载用到的大部分Java类

下面已加载Android_os_Build举例

j4a_base.J4A_LOAD_CLASS:宏定义

其中 \ 的作用----连接多行。即在头文件中换行前,还需要连接后面的代码时,使用该符合。例如:

#define HELLO "hello \
the world"

printf("HELLO is %s\n", HELLO);

输出结果:hello the world

 和 # 运算符一样,## 运算符用在替换文本。所以上面的例子我们就可以看成如下:

class__=android_os_Build;

J4A_loadClass__J4AC_##class__(env);

===》J4A_loadClass__J4AC_android_os_Build(env);

于是全局搜索下J4A_loadClass__J4AC_android_os_Build这个函数的实现,在ijkplayer-x86/src/main/jni/ijkmedia/ijkj4a/j4a/class/android/os/Build.c中找到我们的函数。

上图添加了相应的备注,两个箭头都是去创建相应的Java类,所以介绍第一个红箭头

Build.J4A_FindClass__asGlobalRef__catchAll:

J4A_FindClass__catchAll:

J4A_NewGlobalRef__catchAll:

这些都是jni开发的基础知识,不多细讲,其目的就是创建系统中的android/os/Build.java类。

OK,第一个动态库就这么加载完成了。


加载ijkplayer:

找到其入口:ijkplayer-x86/src/main/jni/ijkmedia/ijkplayer/android/ijkplayer_jni.c

ijkplayer_jni.JNI_OnLoad

红一:创建IjkMediaPlayer.java,前面讲过,不多说

红二:动态注册了IjkMediaPlayer.java的native方法(红五也是一样的)

接下来就是播放器正式的初始化了

红三:ijkmp_global_init最终回去调用ff_ffplay.ffp_global_init

红框圈着的为ffmpeg基本操作

FFMPeg一般流程:

1、av_register_all();//注册所有文件格式和编解码库

2、avformat_network_init();//打开网络视频流

3、av_open_input_file();//读取文件头部把信息保存到AVFormatContext结构体

4、av_find_stream_info();//为pFormatCtx->streams填充上正确的信息

5、CODEC_TYPE_VIDEO;//通过判断得到视频流类型

6、avcodec_find_decoder();//查找解码器

7、avcodec_open();//打开编解码器

8、avcodec_alloc_frame();//分配空间保存帧数据

9、av_read_frame();//不断从流中提取帧数据

10、avcodec_decode_video();//解码视频流

11、avcodec_close();//关闭解码器

12、avformat_close_input_file();//关闭输入文件

红四:ijkmp_global_set_inject_callback(inject_callback)

设置一个回调函数,作用将jni数据通过Java的bundle类封装后,传到Java层使用

inject_callback:

上面做了什么事???我们先看一段Java代码:

        Bundle jbundle=new Bundle();
        jbundle.putString("url",real_data->url);
        jbundle.putString("segment_index",real_data->segment_index);
        jbundle.putString("retry_counter",real_data->retry_counter);
        weak_thiz.onNativeInvoke(jbundle);

是不是很熟悉,而inject_callback也是做的同样的事情,只是它是用c语言实现的。

重要步骤:

1. jobject weak_thiz = (jobject) opaque;

2. jbundle = J4AC_Bundle__Bundle__catchAll(env);

3. J4AC_Bundle__putString__withCString__catchAll(env, jbundle, "url", real_data->url);

4. real_data->is_handled = J4AC_IjkMediaPlayer__onNativeInvoke(env, weak_thiz, what, jbundle);

1. 在Java层创建IjkMediaPlayer时,将自己闯入native层,最后存放在native层的IjkMediaPlayer结构体的weak_thiz中。

2、3、4 都一样,以4为例说明:

J4AC_IjkMediaPlayer__onNativeInvoke:

在IjkMediaPlayer.h头文件中定义的别名

然后在IjkMediaPlayer.c中去找其实现方法:

只调用了一个方法:

jboolean J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer__onNativeInvoke(JNIEnv *env, jobject weakThiz, jint what, jobject args)
{
    return (*env)->CallStaticBooleanMethod(env, class_J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer.id, class_J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer.method_onNativeInvoke, weakThiz, what, args);
}

其中

class_J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer.id参数:需要用的Java类

class_J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer.method_onNativeInvoke参数:需要调用的函数名称

在IjkMediaPlayer.c中的J4A_loadClass__J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer方法,明确注册了这两个参数。

OK,Ijkplayer 加载动态库的故事讲完了。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android Framework 层是 Android 系统中非常重要的一层,它提供了丰富的 API 和服务,包括 Activity、Service、Content Provider、Broadcast Receiver、PackageManager、Window Manager 等等,它们为应用程序提供了一个丰富的运行环境和开发框架。 Android Framework 层的码主要包括以下几个部分: 1. Activity Manager:负责管理 Android 应用程序的生命周期、进程和任务栈等。 2. Package Manager:负责管理应用程序的安装、卸和更新等操作。 3. Content Provider:提供了一种标准的接口,让应用程序之间可以共享数据。 4. Telephony Manager:提供了访问手机通讯功能的接口和服务。 5. Location Manager:提供了访问 GPS 和其他位置服务的接口和服务。 6. Notification Manager:提供了管理通知的接口和服务。 7. View System:提供了 Android 应用程序的 UI 界面的渲染和事件处理等功能。 8. Resource Manager:提供了访问 Android 应用程序的资文件的接口和服务。 9. Window Manager:提供了窗口管理和界面绘制等功能。 10. Activity Manager Service:提供了 Activity Manager 的服务接口。 11. System Server:提供了 Android 系统的核心服务,包括 PackageManager、ActivityManager、WindowManager 等。 以上是 Android Framework 层码的主要部分,通过阅读 Android Framework 层码可以深入了解 Android 系统的实现原理和应用程序的开发框架。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值