IjkPlayer系列之JNI基础及源码目录介绍
PS:最近市场连续几天普跌,既是风险也是难得的机会。
IjkPlayer编译
IjkPlayer源码目录
NDK介绍
JNI基础知识
总结
IjkPlayer编译
IjkPlayer源码目录
1├── android // android相关目录
2│ ├── compile-ijk.sh
3│ ├── contrib // ffmpeg编译目录
4│ │ ├── compile-ffmpeg.sh // ffmpeg编译脚本
5│ │ ├── compile-libsoxr.sh // libsoxr编译脚本
6│ │ ├── compile-openssl.sh // openssl编译脚本
7│ │ ├── ffmpeg-arm64
8│ │ ├── ffmpeg-armv5
9│ │ ├── ffmpeg-armv7a
10│ │ ├── ffmpeg-x86
11│ │ ├── ffmpeg-x86_64
12│ ├── ijk-addr2line.sh
13│ ├── ijk-ndk-stack.sh
14│ ├── ijkplayer // android ijkPlayer源码目录
15│ │ ├── ijkplayer-arm64
16│ │ ├── ijkplayer-armv5
17│ │ ├── ijkplayer-armv7a
18│ │ ├── ijkplayer-example // ijkPlayer使用案例
19│ │ ├── ijkplayer-exo
20│ │ ├── ijkplayer-java
21│ │ ├── ijkplayer-x86
22│ │ ├── ijkplayer-x86_64
23├── compile-android-j4a.sh
24├── config // ffmpeg编译脚本配置目录
25│ ├── module-default.sh // ffmpeg默认配置脚本文件
26│ ├── module-lite-hevc.sh // ffmpeg最小化配置添加hevc功能脚本文件
27│ ├── module-lite.sh // ffmpeg最小化配置脚本文件
28│ └── module.sh // ffmpeg当前编译配置脚本文件
29├── doc
30│ └── preflight_checklist.md
31├── extra // ijkPlayer使用的开源库的下载目录
32│ ├── ffmpeg // ffmpeg
33│ ├── libyuv // yuv图像处理库
34│ └── soundtouch // 音频处理库,主要是变速、变调等
35├── ijkmedia // ijkPlayer native层的核心代码
36│ ├── ijkj4a // native层和 java层回调的接口层,开源项目jni4android生成
37│ ├── ijkplayer // ijkPlayer native层代码
38│ ├── ijksdl // ijkPlayer音视频渲染SDL库
39│ ├── ijksoundtouch // ijk封装后的soundtouch库
40│ └── ijkyuv // yuv图像处理库
41├── ijkprof // ijkplayer的性能调试库
42├── init-android-exo.sh // 初始化exoPlayer脚本
43├── init-android-j4a.sh // 初始化j4a脚本
44├── init-android-libsoxr.sh // 初始化soxr脚本
45├── init-android-libyuv.sh // 初始化yuv脚本
46├── init-android-openssl.sh // 初始化openssl脚本
47├── init-android-prof.sh // 初始化android-ndk-profile脚本
48├── init-android.sh // 初始化android平台脚本,主要拉取ffmpeg、第三方库等
49├── init-android-soundtouch.sh
50├── init-config.sh // ffmpeg脚本文件配置脚本
51├── init-ios-openssl.sh
52├── init-ios.sh
53├── ios // IOS相关目录
NDK介绍
JNI基础知识
JavaVM和JNIEnv
第一种:
1static JavaVM* g_jvm;
2// 第一种
3JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved)
4{
5 JNIEnv* env = NULL;
6 // 为JavaVM指针赋值
7 g_jvm = vm;
8 if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) {
9 return -1;
10 }
11 // ...
12 return JNI_VERSION_1_4;
13}
第二种:
1static JavaVM* g_jvm;
2JNIEXPORT jint JNICALL Java_manu_com_iptvsamples_ndk_NDKSampleActivity_sum
3 (JNIEnv * env, jobject obj, jint addend1, jint addend2){
4 // 为JavaVM指针赋值
5 env->GetJavaVM(&g_jvm);
6 return addend1 + addend2;
7}
JNI_CreateJavaVM
来创建 JavaVM。JNI注册方式
静态注册
1public native int sum(int addend1, int addend2);
1javah -jni com.manu.ndksamples.MainActivity
-classpath
参数生成对应头文件,上述本地方法生成的头文件代码如下:1/* DO NOT EDIT THIS FILE - it is machine generated */
2#include
3/* Header for class manu_com_iptvsamples_ndk_NDKSampleActivity */
4
5#ifndef _Included_com_manu_ndksamples_MainActivity
6#define _Included_com_manu_ndksamples_MainActivity
7#ifdef __cplusplus
8extern "C" {
9#endif
10/*
11 * Class: com_manu_ndksamples_MainActivity
12 * Method: sum
13 * Signature: (II)I
14 */
15JNIEXPORT jint JNICALL Java_com_manu_ndksamples_MainActivity_sum
16 (JNIEnv *, jobject, jint, jint);
17
18#ifdef __cplusplus
19}
20#endif
21#endif
com_manu_ndksamples_MainActivity.h
,导入头文件,使用 C/C++ 实现 Java 中定义的 native 方法,参考如下:1#include "com_manu_ndksamples_MainActivity.h"
2
3/*
4 * Class: com_manu_ndksamples_MainActivity
5 * Method: sum
6 * Signature: (II)I
7 */
8extern "C" JNIEXPORT jint JNICALL Java_com_manu_ndksamples_MainActivity_sum
9 (JNIEnv * env, jobject obj, jint addend1, jint addend2){
10 return addend1 + addend2;
11}
动态注册
JNINativeMethod
的结构体来保存 native 函数与 JNI 函数之间的一一对应关系,该结构体定义如下:1typedef struct {
2 const char* name;
3 const char* signature;
4 void* fnPtr;
5} JNINativeMethod;
sum
方法也可以用动态注册的方式,如下:1#include
2#include
3#include
4
5using namespace std;
6
7#define JNI_CLASS "com/manu/ndksamples/MainActivity"
8
9static JavaVM *g_jvm;
10
11static jint sample_sum(JNIEnv *env, jobject thiz, jint add1, jint add2) {
12 cout << "sample_sum" << endl;
13 return add1 + add2;
14}
15
16static JNINativeMethod g_methods[] = {
17 {"sum", "(II)I", (void *) sample_sum}
18};
19
20JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {
21 JNIEnv *env = nullptr;
22 g_jvm = vm;
23 if ((*vm).GetEnv((void **) &env, JNI_VERSION_1_4) != JNI_OK) {
24 return -1;
25 }
26 assert(env != nullptr);
27 jclass clazz = (*env).FindClass(JNI_CLASS);
28 // 注册函数对应关系
29 (*env).RegisterNatives(clazz, g_methods, sizeof(g_methods) / sizeof((g_methods)[0]));
30 return JNI_VERSION_1_4;
31}
32
33JNIEXPORT void JNI_OnUnload(JavaVM *jvm, void *reserved) {
34 // JNI_OnUnload
35}
sample_sum
与 Java 中的 native 方法 sum
相对应,这种对应关系是通过 RegisterNatives
函数来进行注册的,其基本流程是当调用 System.loadLibrary
加载库的时候会去查找 JNI_OnLoad
这个函数,然后再该函数回调中进行注册,同样的在JNI_OnUnload
中进行销毁操作。总结
评论