ijkplayer编译脚本解析(二)

上一篇,我们查看ijkplayer编译脚本,仍然是使用ndk-build进行编译。

这部分是用c语言编写的部分,属于jni层,或者说是native层。

 

这样的方式带来很多的不便:

1.  java与native编译分离,我们需要手动编译native源码,完成后,在运行anroid studio编译

2. 阅读native源码非常不方便,不支持跳转

3. 不支持native源码debug

 

我们知道android studio其实是支持native编译,并且支持阅读源码时,支持从函数跳转到函数实现,也支持native debug。

不过需要使用cmake对native源码进行构建,这才是android studio支持的native的主流方式。

 

那么这里我们就要对native的编译进行改造,使其支持cmake。

在修改过程中,坚持以下几个原则:

1. 不修改源码,以及不改变源码目录结构,只进行添加。

2. 不修改native生成的so数量,名字,以及依赖关系。

3. 去掉静态库的编译,全部改为源码编译。

    比如在原来环境中,a.c 编译成 静态库a,b.c 与静态库a 编译生成 动态库b。 直接修改为 a.c 、b.c 编译生成动态库b.

4. 因为我这边使用的android studio 4.1 ,所以涉及到gradle等的升级,主要的变更如下

    gradle:2.13 -> 3.6.4

    compileSdkVersion: 25 -> 29

    buildToolVersion:25.0.3 -> 29.0.3

    

具体操作:

   ijkplayer-java是ijkMediaPlayer所在工程,对native层so有直接依赖。

    因此,我们主要改造这个工程就可以达到目的了。

1.  android/ijkplayer/ijkplayer-java/gradle.build 

进行一般的cmake的配置,指明CMakeLists.txt路径。

@@ -13,6 +13,14 @@ android {
     defaultConfig {
         minSdkVersion 9
         targetSdkVersion rootProject.ext.targetSdkVersion
+        flavorDimensions "default"
+
+        externalNativeBuild {
+            cmake {
+                cppFlags ""
+                abiFilters 'armeabi-v7a', 'arm64-v8a'
+            }
+        }
     }
     buildTypes {
         release {
@@ -20,6 +28,17 @@ android {
             proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
         }
     }
+    externalNativeBuild {
+        cmake {
+            path "CMakeLists.txt"
+        }
+    }
+    sourceSets {
+        main {
+            jniLibs.srcDirs 'main/jniLibs'
+        }
+
+    }
 }
 
 dependencies {

2.  添加CMakeLists.txt

# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html

# Sets the minimum version of CMake required to build the native library.

cmake_minimum_required(VERSION 3.4.1)

add_definitions(-DANDROID -DNDEBUG)

set(IJK_PROF_PATH ${CMAKE_SOURCE_DIR}/../../../ijkprof/android-ndk-profiler-dummy/jni/)
set(IJK_MEDIA_PATH ${CMAKE_SOURCE_DIR}/../../../ijkmedia)
set(IJK_MEDIA_J4A_PATH ${IJK_MEDIA_PATH}/ijkj4a)
set(IJK_MEDIA_PLAYER_PATH ${IJK_MEDIA_PATH}/ijkplayer)
set(IJK_MEDIA_SDL_PATH ${IJK_MEDIA_PATH}/ijksdl)
set(IJK_MEDIA_SOUNDTOUCH_PATH ${IJK_MEDIA_PATH}/ijksoundtouch)
set(IJK_MEDIA_YUV_PATH ${IJK_MEDIA_PATH}/ijkyuv)

if (${ANDROID_ABI} STREQUAL armeabi-v7a)
    set(MY_APP_FFMPEG_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/../../../android/contrib/build/ffmpeg-armv7a/output)
elseif (${ANDROID_ABI} STREQUAL armeabi)
    set(MY_APP_FFMPEG_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/../../../android/contrib/build/ffmpeg-armv5/output)
elseif (${ANDROID_ABI} STREQUAL arm64-v8a)
    set(MY_APP_FFMPEG_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/../../../android/contrib/build/ffmpeg-arm64/output)
elseif (${ANDROID_ABI} STREQUAL x86)
    set(MY_APP_FFMPEG_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/../../../android/contrib/build/ffmpeg-x86/output)
elseif (${ANDROID_ABI} STREQUAL x86_64)
    set(MY_APP_FFMPEG_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/../../../android/contrib/build/ffmpeg-x86_64/output)
endif ()


set(PROF_SRC 
        ${IJK_PROF_PATH}/prof.c)
        
set(IJK_J4A_SRC 
        ${IJK_MEDIA_J4A_PATH}/j4a/j4a_allclasses.c
        ${IJK_MEDIA_J4A_PATH}/j4a/j4a_base.c
        ${IJK_MEDIA_J4A_PATH}/j4a/class/android/media/AudioTrack.c
        ${IJK_MEDIA_J4A_PATH}/j4a/class/android/media/MediaCodec.c
        ${IJK_MEDIA_J4A_PATH}/j4a/class/android/media/MediaFormat.c
        ${IJK_MEDIA_J4A_PATH}/j4a/class/android/media/PlaybackParams.c
        ${IJK_MEDIA_J4A_PATH}/j4a/class/android/os/Build.c
        ${IJK_MEDIA_J4A_PATH}/j4a/class/android/os/Bundle.c
        ${IJK_MEDIA_J4A_PATH}/j4a/class/java/nio/Buffer.c
        ${IJK_MEDIA_J4A_PATH}/j4a/class/java/nio/ByteBuffer.c
        ${IJK_MEDIA_J4A_PATH}/j4a/class/java/util/ArrayList.c
        ${IJK_MEDIA_J4A_PATH}/j4a/class/tv/danmaku/ijk/media/player/misc/IMediaDataSource.c
        ${IJK_MEDIA_J4A_PATH}/j4a/class/tv/danmaku/ijk/media/player/misc/IAndroidIO.c
        ${IJK_MEDIA_J4A_PATH}/j4a/class/tv/danmaku/ijk/media/player/IjkMediaPlayer.c
    
        ${IJK_MEDIA_J4A_PATH}/j4au/class/android/media/AudioTrack.util.c
        ${IJK_MEDIA_J4A_PATH}/j4au/class/java/nio/ByteBuffer.util.c)

set(IJK_PLAYER_SRC 
        #ijkplayer
        ${IJK_MEDIA_PLAYER_PATH}/ff_cmdutils.c
        ${IJK_MEDIA_PLAYER_PATH}/ff_ffplay.c
        ${IJK_MEDIA_PLAYER_PATH}/ff_ffpipeline.c
        ${IJK_MEDIA_PLAYER_PATH}/ff_ffpipenode.c
        ${IJK_MEDIA_PLAYER_PATH}/ijkmeta.c
        ${IJK_MEDIA_PLAYER_PATH}/ijkplayer.c
        
        ${IJK_MEDIA_PLAYER_PATH}/pipeline/ffpipeline_ffplay.c
        ${IJK_MEDIA_PLAYER_PATH}/pipeline/ffpipenode_ffplay_vdec.c
        
        ${IJK_MEDIA_PLAYER_PATH}/android/ffmpeg_api_jni.c
        ${IJK_MEDIA_PLAYER_PATH}/android/ijkplayer_android.c
        ${IJK_MEDIA_PLAYER_PATH}/android/ijkplayer_jni.c
        
        ${IJK_MEDIA_PLAYER_PATH}/android/pipeline/ffpipeline_android.c
        ${IJK_MEDIA_PLAYER_PATH}/android/pipeline/ffpipenode_android_mediacodec_vdec.c
        
        ${IJK_MEDIA_PLAYER_PATH}/ijkavformat/allformats.c
        ${IJK_MEDIA_PLAYER_PATH}/ijkavformat/cJSON.c
        ${IJK_MEDIA_PLAYER_PATH}/ijkavformat/ijklas.c
        ${IJK_MEDIA_PLAYER_PATH}/ijkavformat/ijklivehook.c
        ${IJK_MEDIA_PLAYER_PATH}/ijkavformat/ijkmediadatasource.c
        ${IJK_MEDIA_PLAYER_PATH}/ijkavformat/ijkio.c
        ${IJK_MEDIA_PLAYER_PATH}/ijkavformat/ijkiomanager.c
        ${IJK_MEDIA_PLAYER_PATH}/ijkavformat/ijkiocache.c
        ${IJK_MEDIA_PLAYER_PATH}/ijkavformat/ijkioffio.c
        ${IJK_MEDIA_PLAYER_PATH}/ijkavformat/ijkioandroidio.c
        ${IJK_MEDIA_PLAYER_PATH}/ijkavformat/ijkioprotocol.c
        ${IJK_MEDIA_PLAYER_PATH}/ijkavformat/ijkioapplication.c
        ${IJK_MEDIA_PLAYER_PATH}/ijkavformat/ijkiourlhook.c
        
        ${IJK_MEDIA_PLAYER_PATH}/ijkavformat/ijkasync.c
        ${IJK_MEDIA_PLAYER_PATH}/ijkavformat/ijkurlhook.c
        ${IJK_MEDIA_PLAYER_PATH}/ijkavformat/ijklongurl.c
        ${IJK_MEDIA_PLAYER_PATH}/ijkavformat/ijksegment.c
        
        ${IJK_MEDIA_PLAYER_PATH}/ijkavutil/ijkdict.c
        ${IJK_MEDIA_PLAYER_PATH}/ijkavutil/ijkutils.c
        ${IJK_MEDIA_PLAYER_PATH}/ijkavutil/ijkthreadpool.c
        ${IJK_MEDIA_PLAYER_PATH}/ijkavutil/ijktree.c
        ${IJK_MEDIA_PLAYER_PATH}/ijkavutil/ijkfifo.c
        ${IJK_MEDIA_PLAYER_PATH}/ijkavutil/ijkstl.cpp
        )

set(IJK_SDL_SRC 
        ${IJK_MEDIA_SDL_PATH}/ijksdl_aout.c
        ${IJK_MEDIA_SDL_PATH}/ijksdl_audio.c
        ${IJK_MEDIA_SDL_PATH}/ijksdl_egl.c
        ${IJK_MEDIA_SDL_PATH}/ijksdl_error.c
        ${IJK_MEDIA_SDL_PATH}/ijksdl_mutex.c
        ${IJK_MEDIA_SDL_PATH}/ijksdl_stdinc.c
        ${IJK_MEDIA_SDL_PATH}/ijksdl_thread.c
        ${IJK_MEDIA_SDL_PATH}/ijksdl_timer.c
        ${IJK_MEDIA_SDL_PATH}/ijksdl_vout.c
        ${IJK_MEDIA_SDL_PATH}/ijksdl_extra_log.c
        ${IJK_MEDIA_SDL_PATH}/gles2/color.c
        ${IJK_MEDIA_SDL_PATH}/gles2/common.c
        ${IJK_MEDIA_SDL_PATH}/gles2/renderer.c
        ${IJK_MEDIA_SDL_PATH}/gles2/renderer_rgb.c
        ${IJK_MEDIA_SDL_PATH}/gles2/renderer_yuv420p.c
        ${IJK_MEDIA_SDL_PATH}/gles2/renderer_yuv444p10le.c
        ${IJK_MEDIA_SDL_PATH}/gles2/shader.c
        ${IJK_MEDIA_SDL_PATH}/gles2/fsh/rgb.fsh.c
        ${IJK_MEDIA_SDL_PATH}/gles2/fsh/yuv420p.fsh.c
        ${IJK_MEDIA_SDL_PATH}/gles2/fsh/yuv444p10le.fsh.c
        ${IJK_MEDIA_SDL_PATH}/gles2/vsh/mvp.vsh.c
        
        ${IJK_MEDIA_SDL_PATH}/dummy/ijksdl_vout_dummy.c
        
        ${IJK_MEDIA_SDL_PATH}/ffmpeg/ijksdl_vout_overlay_ffmpeg.c
        ${IJK_MEDIA_SDL_PATH}/ffmpeg/abi_all/image_convert.c
        
        ${IJK_MEDIA_SDL_PATH}/android/android_audiotrack.c
        ${IJK_MEDIA_SDL_PATH}/android/android_nativewindow.c
        ${IJK_MEDIA_SDL_PATH}/android/ijksdl_android_jni.c
        ${IJK_MEDIA_SDL_PATH}/android/ijksdl_aout_android_audiotrack.c
        ${IJK_MEDIA_SDL_PATH}/android/ijksdl_aout_android_opensles.c
        ${IJK_MEDIA_SDL_PATH}/android/ijksdl_codec_android_mediacodec_dummy.c
        ${IJK_MEDIA_SDL_PATH}/android/ijksdl_codec_android_mediacodec_internal.c
        ${IJK_MEDIA_SDL_PATH}/android/ijksdl_codec_android_mediacodec_java.c
        ${IJK_MEDIA_SDL_PATH}/android/ijksdl_codec_android_mediacodec.c
        ${IJK_MEDIA_SDL_PATH}/android/ijksdl_codec_android_mediadef.c
        ${IJK_MEDIA_SDL_PATH}/android/ijksdl_codec_android_mediaformat_java.c
        ${IJK_MEDIA_SDL_PATH}/android/ijksdl_codec_android_mediaformat.c
        ${IJK_MEDIA_SDL_PATH}/android/ijksdl_vout_android_nativewindow.c
        ${IJK_MEDIA_SDL_PATH}/android/ijksdl_vout_android_surface.c
        ${IJK_MEDIA_SDL_PATH}/android/ijksdl_vout_overlay_android_mediacodec.c
        )

set(IJK_SOUNDTOUCH_SRC 
        ${IJK_MEDIA_SOUNDTOUCH_PATH}/source/SoundTouch/AAFilter.cpp
        ${IJK_MEDIA_SOUNDTOUCH_PATH}/source/SoundTouch/FIFOSampleBuffer.cpp
        ${IJK_MEDIA_SOUNDTOUCH_PATH}/source/SoundTouch/FIRFilter.cpp
        ${IJK_MEDIA_SOUNDTOUCH_PATH}/source/SoundTouch/cpu_detect_x86.cpp
        ${IJK_MEDIA_SOUNDTOUCH_PATH}/source/SoundTouch/sse_optimized.cpp
        ${IJK_MEDIA_SOUNDTOUCH_PATH}/source/SoundTouch/RateTransposer.cpp
        ${IJK_MEDIA_SOUNDTOUCH_PATH}/source/SoundTouch/InterpolateCubic.cpp
        ${IJK_MEDIA_SOUNDTOUCH_PATH}/source/SoundTouch/InterpolateLinear.cpp
        ${IJK_MEDIA_SOUNDTOUCH_PATH}/source/SoundTouch/InterpolateShannon.cpp
        ${IJK_MEDIA_SOUNDTOUCH_PATH}/source/SoundTouch/TDStretch.cpp
        ${IJK_MEDIA_SOUNDTOUCH_PATH}/source/SoundTouch/BPMDetect.cpp
        ${IJK_MEDIA_SOUNDTOUCH_PATH}/source/SoundTouch/PeakFinder.cpp
        ${IJK_MEDIA_SOUNDTOUCH_PATH}/source/SoundTouch/SoundTouch.cpp
        ${IJK_MEDIA_SOUNDTOUCH_PATH}/source/SoundTouch/mmx_optimized.cpp
        ${IJK_MEDIA_SOUNDTOUCH_PATH}/ijksoundtouch_wrap.cpp
        )

if (${ANDROID_ABI} STREQUAL armeabi-v7a)
    set(IJK_YUV_NEON_SRC
        ${IJK_MEDIA_YUV_PATH}/source/compare_neon.cc
        ${IJK_MEDIA_YUV_PATH}/source/rotate_neon.cc
        ${IJK_MEDIA_YUV_PATH}/source/row_neon.cc
        ${IJK_MEDIA_YUV_PATH}/source/scale_neon.cc
        )
elseif (${ANDROID_ABI} STREQUAL arm64-v8a)
    set(IJK_YUV_NEON_SRC
        ${IJK_MEDIA_YUV_PATH}/source/compare_neon64.cc
        ${IJK_MEDIA_YUV_PATH}/source/rotate_neon64.cc
        ${IJK_MEDIA_YUV_PATH}/source/row_neon64.cc
        ${IJK_MEDIA_YUV_PATH}/source/scale_neon64.cc
        )
else ()

endif ()


set(IJK_YUV_SRC
        ${IJK_MEDIA_YUV_PATH}/source/compare.cc
        ${IJK_MEDIA_YUV_PATH}/source/compare_common.cc
        ${IJK_MEDIA_YUV_PATH}/source/compare_posix.cc
        ${IJK_MEDIA_YUV_PATH}/source/convert.cc
        ${IJK_MEDIA_YUV_PATH}/source/convert_argb.cc
        ${IJK_MEDIA_YUV_PATH}/source/convert_from.cc
        ${IJK_MEDIA_YUV_PATH}/source/convert_from_argb.cc
        ${IJK_MEDIA_YUV_PATH}/source/convert_to_argb.cc
        ${IJK_MEDIA_YUV_PATH}/source/convert_to_i420.cc
        ${IJK_MEDIA_YUV_PATH}/source/cpu_id.cc
        ${IJK_MEDIA_YUV_PATH}/source/format_conversion.cc
        ${IJK_MEDIA_YUV_PATH}/source/planar_functions.cc
        ${IJK_MEDIA_YUV_PATH}/source/rotate.cc
        ${IJK_MEDIA_YUV_PATH}/source/rotate_argb.cc
        ${IJK_MEDIA_YUV_PATH}/source/rotate_mips.cc
        ${IJK_MEDIA_YUV_PATH}/source/row_any.cc
        ${IJK_MEDIA_YUV_PATH}/source/row_common.cc
        ${IJK_MEDIA_YUV_PATH}/source/row_mips.cc
        ${IJK_MEDIA_YUV_PATH}/source/row_posix.cc
        ${IJK_MEDIA_YUV_PATH}/source/scale.cc
        ${IJK_MEDIA_YUV_PATH}/source/scale_argb.cc
        ${IJK_MEDIA_YUV_PATH}/source/scale_common.cc
        ${IJK_MEDIA_YUV_PATH}/source/scale_mips.cc
        ${IJK_MEDIA_YUV_PATH}/source/scale_posix.cc
        ${IJK_MEDIA_YUV_PATH}/source/video_common.cc
        ${IJK_YUV_NEON_SRC}
        )
#copy ffmpeg
configure_file(${MY_APP_FFMPEG_OUTPUT_PATH}/libijkffmpeg.so ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libijkffmpeg.so COPYONLY)

add_library(ijkffmpeg SHARED IMPORTED)
set_target_properties(ijkffmpeg PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libijkffmpeg.so)

find_library(log-lib log)
find_library(m-lib m)
find_library(z-lib z)
find_library(android-lib android)
find_library(EGL-lib EGL)
find_library(jnigraphics-lib jnigraphics)
find_library(GLES-lib GLESv2)
find_library(OpenSLES-lib OpenSLES)


include_directories(
        ${MY_APP_FFMPEG_OUTPUT_PATH}/include
        ${IJK_MEDIA_PATH}
        ${IJK_MEDIA_PATH}/ijkplayer
        ${IJK_MEDIA_PATH}/ijkj4a
        ${IJK_MEDIA_PATH}/ijksdl
        ${IJK_MEDIA_PATH}/ijksoundtouch
        ${IJK_MEDIA_PATH}/ijksoundtouch/include
        ${IJK_MEDIA_PATH}/ijkyuv
        ${IJK_MEDIA_PATH}/ijkyuv/include
)

add_library(ijksdl
        SHARED
        ${IJK_J4A_SRC}
        ${IJK_SDL_SRC}
        ${IJK_YUV_SRC}
        )


target_link_libraries( # Specifies the target library.
        ijksdl
        ijkffmpeg ${log-lib} ${android-lib} ${EGL-lib} ${GLES-lib} ${OpenSLES-lib})

add_library(ijkplayer
        SHARED
        ${PROF_SRC}
        ${IJK_PLAYER_SRC}
        ${IJK_SOUNDTOUCH_SRC}
        )

target_link_libraries( # Specifies the target library.
        ijkplayer
        ijksdl
        ijkffmpeg )

3. android/ijkplayer/build.gradle

版本升级以及加入google()\jcenter()阿里云镜像服务器。

@@ -2,13 +2,14 @@
 
 buildscript {
     repositories {
-        jcenter()
+        maven { url 'http://maven.aliyun.com/repository/google' }
+        maven { url 'http://maven.aliyun.com/repository/jcenter' }
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:2.1.3'
+        classpath 'com.android.tools.build:gradle:3.6.4'
 
-        classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'
-        classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7'
+        classpath 'com.github.dcendents:android-maven-gradle-plugin:2.0'
+        classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.1'
         // NOTE: Do not place your application dependencies here; they belong
         // in the individual module build.gradle files
     }
@@ -16,13 +17,14 @@ buildscript {
 
 allprojects {
     repositories {
-        jcenter()
+        maven { url 'http://maven.aliyun.com/repository/google' }
+        maven { url 'http://maven.aliyun.com/repository/jcenter' }
     }
 }
 
 ext {
-    compileSdkVersion = 25
-    buildToolsVersion = "25.0.3"
+    compileSdkVersion = 29
+    buildToolsVersion = "29.0.3"
 
     targetSdkVersion = 25
 

至此,就修改完啦,运行也没有问题。

有些遗憾呢,是native使用的动态注册,比如

IjkMediaPlayer.java:

public native void setVolume(float leftVolume, float rightVolume);

这个函数实现是在native层,因此只是一个声明,想通过setVolume声明快速跳转到native方法还是不行。

实际上这个方法是在native层ijkplayer_jni.c中注册的

static JNINativeMethod g_methods[] = {
...
    { "setVolume",              "(FF)V",    (void *) IjkMediaPlayer_setVolume },
...   
}

庆幸的是,IjkMediaPlayer.java所有native接口注册全部都在ijkplayer_jni.c这个文件中完成的。因此,有native方法,直接就来这个文件找就好了。

想从java源码跳到相应的native源码,只能通过这种方式来衔接了。

终于,可以打断点,可以快速阅读native源码啦。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值