实现基于 CMake 编译调试 ijkplayer (ijk0.8.8--ffmpeg4.0)

最近在学习和研究 ijkplayer,其源码是用 Android.mk 方式编译的,为了方便开发、调试,现将其编译方式替换成 CMake,可以直接在 Android Studio 中查看、跳转、调试 ijkplayer 源码。具体见我 github: A4ijkplayer

只要不是修改 ffmpeg 的源代码,修改其他其它代码包括 ijkplayer 的 C 代码、Java 代码,都可以在 Android Studio 中修改、运行、调试。

本文是基于 ijkplayer 最新的 k0.8.8 版本,ffmpeg 4.0 编译(基于 ff4.0–ijk0.8.8–20210426–001 版本),并包含了 openssl(即支持 https 网络视频)、yuv、sdl、soundtouch 等模块,整个项目已上传至我的 github 仓库 A4ijkplayer

其中 ffmpeg (libijkffmpeg.so) 需要先编译好,可以参考我上一篇文章编译(Android ijkplayer 编译踩坑与记录),或直接使用我编译好的。

编译 ijkplayer 的 CMakeList.txt 如下:

cmake_minimum_required(VERSION 3.4.1)

set(PATH_TO_A4_PRJ_CPP ${CMAKE_CURRENT_SOURCE_DIR})
set(PATH_TO_A4_IJK_MEDIA ${PATH_TO_A4_PRJ_CPP}/ijkmedia)
set(PATH_TO_A4_IJK_PROF ${PATH_TO_A4_PRJ_CPP}/ijkprof)
set(PATH_TO_OTHER_LIBS ${PATH_TO_A4_PRJ_CPP}/otherlibs)

message(${ANDROID_ABI})
message(${PATH_TO_A4_PRJ_CPP})
message(${PATH_TO_A4_IJK_MEDIA})

# 需要加 NDEBUG 宏定义,否则运行时内部的 assert 会出错
add_definitions(-DNDEBUG)

# <------- ijkmedia/ijkj4a 目录下的文件
file(GLOB_RECURSE SOURCE_C_FILES_OF_IJKJ4A "${PATH_TO_A4_IJK_MEDIA}/ijkj4a/*.c")

# <------- ijkmedia/ijksdl 目录下的文件
file(GLOB_RECURSE SOURCE_C_FILES_OF_IJKSDL "${PATH_TO_A4_IJK_MEDIA}/ijksdl/*.c")

# <------- ijkmedia/ijksoundtouch 目录下的文件
file(GLOB_RECURSE SOURCE_CPP_FILES_OF_IJKSOUNDTOUCH "${PATH_TO_A4_IJK_MEDIA}/ijksoundtouch/*.cpp")

# <------- ijkmedia/ijkplayer 目录下的文件
file(GLOB_RECURSE SOURCE_C_FILES_OF_IJKPLAYER "${PATH_TO_A4_IJK_MEDIA}/ijkplayer/*.c")
file(GLOB_RECURSE SOURCE_CPP_FILES_OF_IJKPLAYER "${PATH_TO_A4_IJK_MEDIA}/ijkplayer/*.cpp")

# <------- ijkmedia/ijkyuv 目录下的文件
#file(GLOB_RECURSE SOURCE_CC_FILES_OF_IJKYUV "${PATH_TO_A4_IJK_MEDIA}/ijkyuv/*.cc")

set(SOURCE_COMMON_CC_FILES_OF_IJKYUV
        # ijkmedia/ijkyuv
        ${PATH_TO_A4_IJK_MEDIA}/ijkyuv/source/compare.cc
        ${PATH_TO_A4_IJK_MEDIA}/ijkyuv/source/compare_common.cc
        ${PATH_TO_A4_IJK_MEDIA}/ijkyuv/source/compare_posix.cc
        ${PATH_TO_A4_IJK_MEDIA}/ijkyuv/source/convert.cc
        ${PATH_TO_A4_IJK_MEDIA}/ijkyuv/source/convert_argb.cc
        ${PATH_TO_A4_IJK_MEDIA}/ijkyuv/source/convert_from.cc
        ${PATH_TO_A4_IJK_MEDIA}/ijkyuv/source/convert_from_argb.cc
        ${PATH_TO_A4_IJK_MEDIA}/ijkyuv/source/convert_to_argb.cc
        ${PATH_TO_A4_IJK_MEDIA}/ijkyuv/source/convert_to_i420.cc
        ${PATH_TO_A4_IJK_MEDIA}/ijkyuv/source/cpu_id.cc
        ${PATH_TO_A4_IJK_MEDIA}/ijkyuv/source/format_conversion.cc
        ${PATH_TO_A4_IJK_MEDIA}/ijkyuv/source/planar_functions.cc
        ${PATH_TO_A4_IJK_MEDIA}/ijkyuv/source/rotate.cc
        ${PATH_TO_A4_IJK_MEDIA}/ijkyuv/source/rotate_argb.cc
        ${PATH_TO_A4_IJK_MEDIA}/ijkyuv/source/rotate_mips.cc
        ${PATH_TO_A4_IJK_MEDIA}/ijkyuv/source/row_any.cc
        ${PATH_TO_A4_IJK_MEDIA}/ijkyuv/source/row_common.cc
        ${PATH_TO_A4_IJK_MEDIA}/ijkyuv/source/row_mips.cc
        ${PATH_TO_A4_IJK_MEDIA}/ijkyuv/source/row_posix.cc
        ${PATH_TO_A4_IJK_MEDIA}/ijkyuv/source/scale.cc
        ${PATH_TO_A4_IJK_MEDIA}/ijkyuv/source/scale_argb.cc
        ${PATH_TO_A4_IJK_MEDIA}/ijkyuv/source/scale_common.cc
        ${PATH_TO_A4_IJK_MEDIA}/ijkyuv/source/scale_mips.cc
        ${PATH_TO_A4_IJK_MEDIA}/ijkyuv/source/scale_posix.cc
        ${PATH_TO_A4_IJK_MEDIA}/ijkyuv/source/video_common.cc
)
# ijkyuv 目录下与 abi 架构相关的代码
if(${ANDROID_ABI} STREQUAL "armeabi-v7a")
    set(SOURCE_ABI_CC_FILES_OF_IJKYUV
            ${PATH_TO_A4_IJK_MEDIA}/ijkyuv/source/compare_neon.cc
            ${PATH_TO_A4_IJK_MEDIA}/ijkyuv/source/rotate_neon.cc
            ${PATH_TO_A4_IJK_MEDIA}/ijkyuv/source/row_neon.cc
            ${PATH_TO_A4_IJK_MEDIA}/ijkyuv/source/scale_neon.cc
            )
elseif(${ANDROID_ABI} STREQUAL "arm64-v8a")
    set(SOURCE_ABI_CC_FILES_OF_IJKYUV
            ${PATH_TO_A4_IJK_MEDIA}/ijkyuv/source/compare_neon64.cc
            ${PATH_TO_A4_IJK_MEDIA}/ijkyuv/source/rotate_neon64.cc
            ${PATH_TO_A4_IJK_MEDIA}/ijkyuv/source/row_neon64.cc
            ${PATH_TO_A4_IJK_MEDIA}/ijkyuv/source/scale_neon64.cc
            )
endif()

# <------- cpp/ijkprof 目录下的文件
file(GLOB_RECURSE SOURCE_C_FILES_OF_IJKPROF "${PATH_TO_A4_IJK_PROF}/*.c")

include_directories(
        ${PATH_TO_OTHER_LIBS}/ffmpeg/include
        ${PATH_TO_OTHER_LIBS}/ffmpeg/include/${ANDROID_ABI}
        ${PATH_TO_A4_IJK_MEDIA}
        ${PATH_TO_A4_IJK_PROF}
        ${PATH_TO_A4_IJK_MEDIA}/ijkj4a
        ${PATH_TO_A4_IJK_MEDIA}/ijksdl
        ${PATH_TO_A4_IJK_MEDIA}/ijksoundtouch
        ${PATH_TO_A4_IJK_MEDIA}/ijksoundtouch/include
        ${PATH_TO_A4_IJK_MEDIA}/ijkyuv
        ${PATH_TO_A4_IJK_MEDIA}/ijkyuv/include
        ${PATH_TO_A4_IJK_MEDIA}/ijkplayer
)

add_library(
        a4ijkplayer
        SHARED

        ${SOURCE_C_FILES_OF_IJKJ4A}
        ${SOURCE_C_FILES_OF_IJKSDL}
        ${SOURCE_CPP_FILES_OF_IJKSOUNDTOUCH}
        ${SOURCE_COMMON_CC_FILES_OF_IJKYUV}
        ${SOURCE_ABI_CC_FILES_OF_IJKYUV}
        ${SOURCE_C_FILES_OF_IJKPLAYER}
        ${SOURCE_CPP_FILES_OF_IJKPLAYER}
        ${SOURCE_C_FILES_OF_IJKPROF}
)

target_link_libraries( # Specifies the target library.
        a4ijkplayer
        ${PATH_TO_OTHER_LIBS}/ffmpeg/libs/${ANDROID_ABI}/libijkffmpeg.so
        log
        android
        EGL
        GLESv2
        jnigraphics
        OpenSLES
        m z
        )

需要注意的点:
1、需要在 CMakeList 中增加加 NDEBUG 宏定义,否则运行时内部的 assert 会出错

add_definitions(-DNDEBUG)

2、接入 SDL,或者直接看我 github A4ijkplayer 项目的的这个相关提交
1) 修改 ijksdl/android/ijksdl_android_jni.h,增加如下 SDL_JNI_OnLoad 函数声明:

JNIEXPORT jint JNICALL SDL_JNI_OnLoad(JavaVM *vm, void *reserved);

2)修改 ijksdl/android/ijksdl_android_jni.c,删除 JNI_OnUnload 函数,并将 JNI_OnLoad 函数名改成 SDL_JNI_OnLoad

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
改成 ====>> 
JNIEXPORT jint JNICALL SDL_JNI_OnLoad(JavaVM *vm, void *reserved)

3)修改 ijkplayer/android/ijkplayer_jni.c,在其 JNI_OnLoad 函数中增加 SDL_JNI_OnLoad 的调用:

SDL_JNI_OnLoad(vm,reserved);

github 项目源码:A4ijkplayer

运行效果截图:

实现基于 CMake 编译调试 ijkplayer (ijk0.8.8--ffmpeg4.0)_第1张图片

ijkplayer native 代码调试截图:
实现基于 CMake 编译调试 ijkplayer (ijk0.8.8--ffmpeg4.0)_第2张图片

你可能感兴趣的:(音视频,Android,ijkplayer,android,ijkplayer,cmake,ijkplayer,编译,ijkplayer,调试,ffmpeg4.0)