由于业务需要做音视频功能,所以需要c++进行开发,在android studio里编码没有在Clion里爽,所以将FFmpeg的代码集成到Clion里开发,踩了一些坑,记录一下。
FFmpeg先编译用于c/c++环境的静态库,不能用android ndk编译的!
# $HOME/ffmpeg-build是库输出目录
./configure --prefix="$HOME/ffmpeg-build" --bindir="$HOME/bin"
make -j 8
make install
得到.a文件放入工程中
报错信息一:
Undefined symbols for architecture x86_64:
"_AudioConverterDispose", referenced from:....
ld: warning: could not create compact unwind for _ff_cfhd_init_vlcs: stack subq instruction is too different from dwarf stack size
Undefined symbols for architecture x86_64:
"_AudioConverterDispose", referenced from:
_ffat_close_decoder in libavcodec.a(audiotoolboxdec.o)
_ffat_close_encoder in libavcodec.a(audiotoolboxenc.o)
"_AudioConverterFillComplexBuffer", referenced from:
_ffat_decode in libavcodec.a(audiotoolboxdec.o)
_ffat_encode in libavcodec.a(audiotoolboxenc.o)
"_AudioConverterGetProperty", referenced from:
_ffat_create_decoder in libavcodec.a(audiotoolboxdec.o)
_ffat_init_encoder in libavcodec.a(audiotoolboxenc.o)
"_AudioConverterGetPropertyInfo", referenced from:
_ffat_create_decoder in libavcodec.a(audiotoolboxdec.o)
_ffat_init_encoder in libavcodec.a(audiotoolboxenc.o)
"_AudioConverterNew", referenced from:
_ffat_create_decoder in libavcodec.a(audiotoolboxdec.o)
_ffat_init_encoder in libavcodec.a(audiotoolboxenc.o)
"_AudioConverterReset", referenced from:
_ffat_decode_flush in libavcodec.a(audiotoolboxdec.o)
_ffat_encode_flush in libavcodec.a(audiotoolboxenc.o)
"_AudioConverterSetProperty", referenced from:
_ffat_create_decoder in libavcodec.a(audiotoolboxdec.o)
_ffat_init_encoder in libavcodec.a(audiotoolboxenc.o)
"_AudioFormatGetProperty", referenced from:
_ffat_create_decoder in libavcodec.a(audiotoolboxdec.o)
"_AudioFormatGetPropertyInfo", referenced from:
_ffat_create_decoder in libavcodec.a(audiotoolboxdec.o)
"_CFArrayCreate", referenced from:
_vtenc_create_encoder in libavcodec.a(videotoolboxenc.o)
"_CFArrayCreateMutableCopy", referenced from:
_tls_open in libavformat.a(tls_securetransport.o)
...
解决方法:
几个需要 库需要导入:AudioToolBox CoreGraphics CoreMedia OpenGLles QuartCore openal mediaToolbox VideoToolBox accelerate
CMakeLists.txt加上
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -v -stdlib=libc++ -framework OpenGL -framework AppKit -framework Security -framework CoreFoundation -framework CoreVideo -framework CoreMedia -framework QuartzCore -framework CoreFoundation -framework VideoDecodeAcceleration -framework Cocoa -framework AudioToolbox -framework VideoToolbox -framework OpenCL ")
报错信息二:
Undefined symbols for architecture x86_64:
"_BZ2_bzDecompress", referenced from:
_matroska_decode_buffer in libavformat.a(matroskadec.o)
"_BZ2_bzDecompressEnd", referenced from:
_matroska_decode_buffer in libavformat.a(matroskadec.o)
"_BZ2_bzDecompressInit", referenced from:
ld: warning: could not create compact unwind for _ff_cfhd_init_vlcs: stack subq instruction is too different from dwarf stack size
Undefined symbols for architecture x86_64:
"_BZ2_bzDecompress", referenced from:
_matroska_decode_buffer in libavformat.a(matroskadec.o)
"_BZ2_bzDecompressEnd", referenced from:
_matroska_decode_buffer in libavformat.a(matroskadec.o)
"_BZ2_bzDecompressInit", referenced from:
_matroska_decode_buffer in libavformat.a(matroskadec.o)
"_iconv", referenced from:
_avcodec_decode_subtitle2 in libavcodec.a(decode.o)
_getstr8 in libavformat.a(mpegts.o)
"_iconv_close", referenced from:
_avcodec_open2 in libavcodec.a(utils.o)
_avcodec_decode_subtitle2 in libavcodec.a(decode.o)
_getstr8 in libavformat.a(mpegts.o)
"_iconv_open", referenced from:
_avcodec_open2 in libavcodec.a(utils.o)
_avcodec_decode_subtitle2 in libavcodec.a(decode.o)
_getstr8 in libavformat.a(mpegts.o)
ld: symbol(s) not found for architecture x86_64
解决方法:CMakeLists.txt里 target_link_libraries加上
target_link_libraries(
libbz2.dylib
libiconv.dylib
)
附一份完整的CMakeLists.txt
cmake_minimum_required(VERSION 3.19)
project(c)
#指定c++库 版本
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -v -stdlib=libc++ -framework OpenGL -framework AppKit -framework Security -framework CoreFoundation -framework CoreVideo -framework CoreMedia -framework QuartzCore -framework CoreFoundation -framework VideoDecodeAcceleration -framework Cocoa -framework AudioToolbox -framework VideoToolbox -framework OpenCL ")
set(INC_DIR ./include)
set(LINK_DIR ./lib)
#file(GLOB native_srcs
# "*.cpp"
# "include/*.cpp"
# )
#add_library( # Sets the name of the library.
# code
# SHARED
# ${native_srcs}
# )
set(SOURCE_FILES
main.cpp
)
#引入头文件
include_directories(${INC_DIR})
#引入库文件
link_directories(${LINK_DIR})
add_executable(c ${SOURCE_FILES})
include_directories(src/main/cpp/include)
target_link_libraries(
c
# avcodec avformat avutil swresample swscale swscale avfilte
${CMAKE_CURRENT_SOURCE_DIR}/lib/libavfilter.a
${CMAKE_CURRENT_SOURCE_DIR}/lib/libavformat.a
${CMAKE_CURRENT_SOURCE_DIR}/lib/libavcodec.a
${CMAKE_CURRENT_SOURCE_DIR}/lib/libswscale.a
${CMAKE_CURRENT_SOURCE_DIR}/lib/libavutil.a
${CMAKE_CURRENT_SOURCE_DIR}/lib/libswresample.a
# ${CMAKE_CURRENT_SOURCE_DIR}/lib/libavfilter.so
# ${CMAKE_CURRENT_SOURCE_DIR}/lib/libavformat.so
# ${CMAKE_CURRENT_SOURCE_DIR}/lib/libavcodec.so
# ${CMAKE_CURRENT_SOURCE_DIR}/lib/libavutil.so
# ${CMAKE_CURRENT_SOURCE_DIR}/lib/libswresample.so
# ${CMAKE_CURRENT_SOURCE_DIR}/lib/libswscale.so
z #z库 ffmpeg用到
#bz2库
libbz2.dylib
libiconv.dylib
)
cpp引用.h时,需要用extern "C"包起来,不然编译不过
#include <iostream>
#include <string>
extern "C" {
#include "include/libavcodec/avcodec.h"
#include "include/libavformat/avformat.h"
#include "include/libavfilter/avfilter.h"
#include "include/libavutil/file.h"
#include "include/libavutil/mathematics.h"
#include "include/libavutil/time.h"
#include "include/libavutil/mem.h"
#include "include/libswresample/swresample.h"
}
AVFormatContext *inputContext = nullptr;
AVFormatContext *outputContext;
int64_t lastReadPacktTime;
void Init() {
//av_register_all();
//avfilter_register_all();
avformat_network_init();
av_log_set_level(AV_LOG_ERROR);
}
int main() {
std::cout << "Hello, World!" << std::endl;
Init();
return 0;
}