用NDK 20编译Android平台Opus库:CMake配置及浮点版编译问题
你的Opus Android编译配置分析与浮点版修复方案
一、定点版配置检查
先拆解你当前的定点版配置,整体逻辑是通顺的,不过可以做几个细节确认和优化:
- 编译宏定义:
-DFIXED_POINT是定点版的核心开关,搭配-DUSE_ALLOCA(Android NDK原生支持alloca,无需兼容性顾虑)、-DOPUS_BUILD(Opus内部编译必需的标识宏)、-D__OPTIMIZE__(告知代码开启优化分支),这几个宏的设置完全符合定点版的编译要求。 - 头文件包含:已经覆盖了Opus所有核心目录(include、src、silk全子目录、celt全子目录),不会出现头文件缺失的编译错误。
- 源文件列表:包含了silk定点实现(fixed子目录下的源文件)、ARM架构优化文件、celt优化文件以及JNI桥接文件,定点版的核心代码都已齐全,这也是你能编译成功的关键。
小优化建议:可以把分散的编译选项用CMAKE_C_FLAGS统一管理,可读性和可维护性更强,比如:
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DOPUS_BUILD -DUSE_ALLOCA -DFIXED_POINT -D__OPTIMIZE__ -O3")
二、浮点版编译失败的修复方案(无需新增源文件)
浮点版编译失败的核心问题几乎都出在编译选项上,按以下步骤调整即可解决:
1. 移除定点专属宏
必须删除-DFIXED_POINT这个宏——Opus默认编译的就是浮点版,只要不定义FIXED_POINT,代码就会自动走浮点分支。保留这个宏的话,即使你想编译浮点版,代码也会强制调用定点实现逻辑,必然出现编译错误。
2. 添加浮点架构优化选项
针对Android不同CPU架构,添加对应的浮点编译参数,确保编译器能生成正确的硬件浮点指令:
- 对于armeabi-v7a:添加
-mfpu=neon -mfloat-abi=softfp(或者-mfloat-abi=hard,取决于你的NDK版本和目标设备支持) - 对于arm64-v8a:默认支持硬件浮点和NEON,无需额外参数,但可以添加
-O3开启最高级别优化 - 对于x86/x86_64:添加
-msse2(或更高指令集)优化浮点运算效率
3. 调整优化级别
把-D__OPTIMIZE__换成实际的编译器优化选项-O3——__OPTIMIZE__只是一个告知代码开启优化分支的宏,真正的编译优化需要编译器层面的-O3指令,浮点版对优化的依赖度更高。
4. 清理CMake缓存
CMake会缓存之前的定点版编译配置,直接修改选项可能不生效。建议删除build目录,或者执行cmake --build . --clean-first,强制重新生成编译配置。
修改后的浮点版CMakeLists.txt示例
cmake_minimum_required(VERSION 3.4.1) # 浮点版编译选项:移除FIXED_POINT,添加优化和架构参数 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DOPUS_BUILD -D__OPTIMIZE__ -O3") # 针对armeabi-v7a添加NEON浮点优化,根据你的目标架构选择开启 # set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfpu=neon -mfloat-abi=softfp") include_directories(opus/include opus/src opus/silk opus/silk/fixed opus/silk/arm opus/celt opus/celt/arm) add_library( jnopus SHARED # 源文件列表保持不变(符合你不新增源文件的要求) opus/src/analysis.c opus/src/mapping_matrix.c opus/src/mlp.c opus/src/mlp_data.c opus/src/opus.c opus/src/opus_compare.c opus/src/opus_decoder.c opus/src/opus_encoder.c opus/src/opus_multistream.c opus/src/opus_multistream_decoder.c opus/src/opus_multistream_encoder.c opus/src/opus_projection_decoder.c opus/src/opus_projection_encoder.c opus/src/repacketizer.c opus/silk/A2NLSF.c opus/silk/ana_filt_bank_1.c opus/silk/biquad_alt.c opus/silk/bwexpander.c opus/silk/bwexpander_32.c opus/silk/check_control_input.c opus/silk/CNG.c opus/silk/code_signs.c opus/silk/control_audio_bandwidth.c opus/silk/control_codec.c opus/silk/control_SNR.c opus/silk/debug.c opus/silk/dec_API.c opus/silk/decode_core.c opus/silk/decode_frame.c opus/silk/decode_indices.c opus/silk/decode_parameters.c opus/silk/decode_pitch.c opus/silk/decode_pulses.c opus/silk/decoder_set_fs.c opus/silk/enc_API.c opus/silk/encode_indices.c opus/silk/encode_pulses.c opus/silk/gain_quant.c opus/silk/HP_variable_cutoff.c opus/silk/init_decoder.c opus/silk/init_encoder.c opus/silk/inner_prod_aligned.c opus/silk/interpolate.c opus/silk/lin2log.c opus/silk/log2lin.c opus/silk/LP_variable_cutoff.c opus/silk/LPC_analysis_filter.c opus/silk/LPC_fit.c opus/silk/LPC_inv_pred_gain.c opus/silk/NLSF2A.c opus/silk/NLSF_decode.c opus/silk/NLSF_del_dec_quant.c opus/silk/NLSF_encode.c opus/silk/NLSF_stabilize.c opus/silk/NLSF_unpack.c opus/silk/NLSF_VQ.c opus/silk/NLSF_VQ_weights_laroia.c opus/silk/NSQ.c opus/silk/NSQ_del_dec.c opus/silk/pitch_est_tables.c opus/silk/PLC.c opus/silk/process_NLSFs.c opus/silk/quant_LTP_gains.c opus/silk/resampler.c opus/silk/resampler_down2.c opus/silk/resampler_down2_3.c opus/silk/resampler_private_AR2.c opus/silk/resampler_private_down_FIR.c opus/silk/resampler_private_IIR_FIR.c opus/silk/resampler_private_up2_HQ.c opus/silk/resampler_rom.c opus/silk/shell_coder.c opus/silk/sigm_Q15.c opus/silk/sort.c opus/silk/stereo_decode_pred.c opus/silk/stereo_encode_pred.c opus/silk/stereo_find_predictor.c opus/silk/stereo_LR_to_MS.c opus/silk/stereo_MS_to_LR.c opus/silk/stereo_quant_pred.c opus/silk/sum_sqr_shift.c opus/silk/table_LSF_cos.c opus/silk/tables_gain.c opus/silk/tables_LTP.c opus/silk/tables_NLSF_CB_NB_MB.c opus/silk/tables_NLSF_CB_WB.c opus/silk/tables_other.c opus/silk/tables_pitch_lag.c opus/silk/tables_pulses_per_block.c opus/silk/VAD.c opus/silk/VQ_WMat_EC.c opus/silk/fixed/apply_sine_window_FIX.c opus/silk/fixed/autocorr_FIX.c opus/silk/fixed/burg_modified_FIX.c opus/silk/fixed/corrMatrix_FIX.c opus/silk/fixed/encode_frame_FIX.c opus/silk/fixed/find_LPC_FIX.c opus/silk/fixed/find_LTP_FIX.c opus/silk/fixed/find_pitch_lags_FIX.c opus/silk/fixed/find_pred_coefs_FIX.c opus/silk/fixed/k2a_FIX.c opus/silk/fixed/k2a_Q16_FIX.c opus/silk/fixed/LTP_analysis_filter_FIX.c opus/silk/fixed/LTP_scale_ctrl_FIX.c opus/silk/fixed/noise_shape_analysis_FIX.c opus/silk/fixed/pitch_analysis_core_FIX.c opus/silk/fixed/process_gains_FIX.c opus/silk/fixed/regularize_correlations_FIX.c opus/silk/fixed/residual_energy16_FIX.c opus/silk/fixed/residual_energy_FIX.c opus/silk/fixed/schur_FIX.c opus/silk/fixed/schur64_FIX.c opus/silk/fixed/vector_ops_FIX.c opus/silk/fixed/warped_autocorrelation_FIX.c opus/silk/arm/arm_silk_map.c opus/silk/arm/biquad_alt_neon_intr.c opus/silk/arm/LPC_inv_pred_gain_neon_intr.c opus/silk/arm/NSQ_del_dec_neon_intr.c opus/silk/arm/NSQ_neon.c opus/celt/bands.c opus/celt/celt.c opus/celt/celt_decoder.c opus/celt/celt_encoder.c opus/celt/celt_lpc.c opus/celt/cwrs.c opus/celt/entcode.c opus/celt/entdec.c opus/celt/enc.c opus/celt/kiss_fft.c opus/celt/laplace.c opus/celt/mathops.c opus/celt/mdct.c opus/celt/modes.c opus/celt/pitch.c opus/celt/quant_bands.c opus/celt/rate.c opus/celt/vq.c opus/celt/arm/arm_celt_map.c opus/celt/arm/armcpu.c opus/celt/arm/celt_mdct_ne10.c opus/celt/arm/celt_neon_intr.c opus/celt/arm/pitch_neon_intr.c org_jitsi_impl_neomedia_codec_audio_opus_Opus.c) target_link_libraries(jnopus)
额外说明
虽然你要求不新增源文件,但还是要提一句:Opus的浮点版其实对应silk目录下非fixed后缀的源文件,如果你后续想获得完整的浮点性能,建议替换silk/fixed下的源文件为silk目录的普通源文件。不过按上面的方法调整后,应该能先解决编译失败的问题。
内容的提问来源于stack exchange,提问作者georgij
相关产品推荐
相关产品推荐

