libx264编译

  1. 一、简介
  2. 二、编译
    1. 1.下载
    2. 2.编译
    3. 一次性打包?
  3. 三、使用

一、简介

源码下载地址
但是这里只能下载到最新版本,这里在编译时使用的是1.28版本的包。

我的环境:
mac+ndkr13b

二、编译

1.下载

这个就不说了
网站在上面

2.编译

脚本如下

#!/bin/bash

# 获取指定架构名称
if [ "$#" -lt 1 ]; then
THE_ARCH=armv7
else
THE_ARCH=$(tr [A-Z] [a-z] <<< "$1")
fi

# 查找指定架构参数信息
case "$THE_ARCH" in
arm|armv5|armv6|armv7|armeabi)
# 配置参数
# toolchain下的文件夹名称前缀
TOOLCHAIN_LEFT=arm-linux-androideabi
# android版本下的编译器
ANDROID_PLATFORMS=arm
# CMAKE_SYSTEM_PROCESSOR下的配置名称
PROCESSOR_PLATFORMS=arm
# prebuilt文件夹下的编译器名称
TOOLCHAIN_PLEBUILT=arm-linux-androideabi
# include下全名
INCLUDE_PLATFORMS=arm-linux-androideabi
# CFLAGS是否有配置项
CFLAGS_MARCH="-march=armv7-a -mfloat-abi=softfp -fprefetch-loop-arrays"
# 文件夹名称
BUILD_NAME=armeabi
;;
armv7a|armeabi-v7a)
# 配置参数
# toolchain下的文件夹名称前缀
TOOLCHAIN_LEFT=arm-linux-androideabi
# android版本下的编译器
ANDROID_PLATFORMS=arm
# CMAKE_SYSTEM_PROCESSOR下的配置名称
PROCESSOR_PLATFORMS=arm
# prebuilt文件夹下的编译器名称
TOOLCHAIN_PLEBUILT=arm-linux-androideabi
# include下全名
INCLUDE_PLATFORMS=arm-linux-androideabi
# CFLAGS是否有配置项
CFLAGS_MARCH="-march=armv7-a -mfloat-abi=softfp -fprefetch-loop-arrays"
BUILD_NAME=armeabi-v7a
;;
armv8|armv8a|aarch64|arm64|arm64-v8a)
# 配置参数
# toolchain下的文件夹名称前缀
TOOLCHAIN_LEFT=aarch64-linux-android
# android版本下的编译器
ANDROID_PLATFORMS=arm64
# CMAKE_SYSTEM_PROCESSOR下的配置名称
PROCESSOR_PLATFORMS=aarch64
# prebuilt文件夹下的编译器名称
TOOLCHAIN_PLEBUILT=aarch64-linux-android
# include下全名
INCLUDE_PLATFORMS=aarch64-linux-android
# CFLAGS是否有配置项
CFLAGS_MARCH=""
BUILD_NAME=arm64-v8a
;;
x86)
# 配置参数
# toolchain下的文件夹名称前缀
TOOLCHAIN_LEFT=x86
# android版本下的编译器
ANDROID_PLATFORMS=x86
# CMAKE_SYSTEM_PROCESSOR下的配置名称
PROCESSOR_PLATFORMS=x86
# prebuilt文件夹下的编译器名称
TOOLCHAIN_PLEBUILT=i686-linux-android
# include下全名
INCLUDE_PLATFORMS=i686-linux-android
# CFLAGS是否有配置项
CFLAGS_MARCH=""
BUILD_NAME=x86
;;
x86_64|x64)
# 配置参数
# toolchain下的文件夹名称前缀
TOOLCHAIN_LEFT=x86_64
# android版本下的编译器
ANDROID_PLATFORMS=x86_64
# CMAKE_SYSTEM_PROCESSOR下的配置名称
PROCESSOR_PLATFORMS=x86_64
# prebuilt文件夹下的编译器名称
TOOLCHAIN_PLEBUILT=x86_64-linux-android
# include下全名
INCLUDE_PLATFORMS=x86_64-linux-android
# CFLAGS是否有配置项
CFLAGS_MARCH=""
BUILD_NAME=x86_64
;;
esac
NDK_PATH=/Users/yangshiqu/Library/Android/sdk/ndk/android-ndk-r13b
BUILD_PLATFORM=darwin-x86_64
TOOLCHAIN_VERSION=4.9
ANDROID_VERSION=21

SYSROOT=${NDK_PATH}/platforms/android-${ANDROID_VERSION}/arch-${ANDROID_PLATFORMS}

TOOLCHAIN=${NDK_PATH}/toolchains/${TOOLCHAIN_LEFT}-${TOOLCHAIN_VERSION}/prebuilt/${BUILD_PLATFORM}/bin/${TOOLCHAIN_PLEBUILT}-
PREFIX=/Users/yangshiqu/Documents/Cache/AndroidCodeAndApp/NDKLib/libx264obj/${BUILD_NAME}
mkdir -p ${PREFIX}

./configure \
--prefix=$PREFIX \
--cross-prefix=$TOOLCHAIN \
--sysroot=$SYSROOT \
--enable-static \
--enable-pic \
--disable-asm \
--host=$PROCESSOR_PLATFORMS-linux \

make clean
make
make install

需要注意这里编译的都是静态库。(build.sh)

这里的脚本在后面添加想要的cpu架构名称就会开始编译对应的静态库。

一次性打包?

for arch in armeabi armeabi-v7a arm64-v8a x86 x86_64
do
bash build.sh $arch
done

添加上面的脚本信息在新脚本中即可(build_all.sh)。

三、使用

强烈推荐雷神的博客

下面是我的使用记录,方便后续使用

    // 初始化
if (x264_param_default_preset(&param, x264_preset_names[0], x264_tune_names[7]) < 0)
return -1;

// ----------CPU_FLUGS----------
// 取空缓冲区继续使用不死锁的保证;多线程 0:开启多线程 1:单线程
param.i_threads = 1;
// ----------视频选项------------
// 视频宽度
param.i_width = width;
// 视频高度
param.i_height = height;
// 编码总帧数.不知道用0
param.i_frame_total = 0;
// 视频图像数据格式
param.i_csp = X264_CSP_I420;
// ----------流参数---------------
// 关键帧间隔
param.i_keyint_max = fps * 10;
param.i_keyint_min = fps;
// 非B帧之间B帧个数 ,增加首开速度
param.i_bframe = 0;
// 某些解码器不完全支援open-gop资料流,这就是为什么此选项并未默认为启用。
param.b_open_gop = 0;
// 可参考B帧,0为关闭可参考B帧功能
param.i_bframe_pyramid = 0;
// B帧自适应算法
param.i_bframe_adaptive = X264_B_ADAPT_TRELLIS;
// ------------日志----------
// 不需要打印编码信息时直接注释掉就行
param.i_log_level = X264_LOG_DEBUG;
// ----------速率控制参数---------
param.rc.i_bitrate = bitrate / 1000; //* 码率(比特率,单位Kbps)
// 表示码率控制,CQP(恒定质量) ,CRF(恒定码率), ABR (平均码率)
param.rc.i_rc_method = X264_RC_ABR;
// CRF下调整f_rf_constant和f_rf_constant_max影响编码速度和图像质量(数据量),0表示无损
param.rc.i_qp_constant = 0;
// 瞬时最大码率
param.rc.i_vbv_max_bitrate = bitrate / 1000 * 1.2;
//设置了i_vbv_max_bitrate必须设置下面的buffer,码率控制区大小,单位Kbps
param.rc.i_vbv_buffer_size = bitrate/1000;
// ----------时间基-------------
// 帧率分母
param.i_fps_den = 1;
// 帧率分子
param.i_fps_num = fps;
// 帧率时间基为帧率的倒数
param.i_timebase_den = param.i_fps_num;
param.i_timebase_num = param.i_fps_den;

// 1前面为0x00000001,0为nal长度
param.b_annexb = 1;
// 关键帧前面是否放sps跟pps帧,0 否 1,放
param.b_repeat_headers = 1;



// // 自动场景切换门限,根据其含义,表示场景变换的百分比。计算场景间的相似度,如果相似度小于该门限值则认为检测到场景切换。如果此时距离上一个IDR帧的距离小于最小IDR帧间隔,则插入一个I帧,否则插入一个IDR帧。
// param.i_scenecut_threshold = 0;
// // 压缩级别1~7
// param.analyse.i_subpel_refine = 0;
// // 编码器并不是对每来一帧就对一帧进行编码,而是先存储一定的帧,将该缓存填充满之后再开始编码。该参数的设置会影响压缩的效果,同时调大该参数也能够使得VBV获得更精确的码率控制,但同时也会增加编码的时间,提高实时编码的时延。
// param.rc.i_lookahead = 10;
// // 分别对应inter和intra,取值范围1~32
// param.analyse.i_luma_deadzone[0] = 32;
// param.analyse.i_luma_deadzone[1] = 32;
// // 自适应量化器模式。不使用自适应量化的话,x264趋向于使用较少的bit在缺乏细节的场景里。自适应量化可以在整个视频的宏块里更好地分配比特。
// // 0-完全关闭自适应量化器;1-允许自适应量化器在所有视频帧内部分配比特;2-根据前一帧强度决策的自变量化器(实验性的)。默认值=1
// param.rc.i_aq_mode = 0;
// // 为’direct’类型的运动矢量设定预测模式。有两种可选的模式:spatial(空间预测)和temporal(时间预测)。默认:’spatial’
// // 可以设置为’none’关闭预测,也可以设置为’auto’让x264去选择它认为更好的模式,x264会在编码结束时告诉你它的选择。
// param.analyse.i_direct_mv_pred = X264_DIRECT_PRED_NONE;
// // 开启明确的权重预测以增进P帧压缩。越高级的模式越耗时
// // 0 : 关闭; 1 : 静态补偿(永远为-1); 2 : 智能统计静态帧,特别为增进淡入淡出效果的压缩率而设计
// param.analyse.i_weighted_pred = X264_WEIGHTP_NONE;
// // 设置全局的运动预测方法,有以下5种选择:dia(四边形搜索), hex(六边形搜索), umh(不均匀的多六边形搜索),esa(全局搜索),tesa(变换全局搜索),默认:’hex’
// param.analyse.i_me_method = X264_ME_DIA;
// // merange控制运动搜索的最大像素范围。
// // 对于hex和dia,范围被控制在4-16像素,默认就是16。
// // 对于umh和esa,可以超过默认的 16像素进行大范围的运行搜索,这对高分辨率视频和快速运动视频而言很有用。
// // 注意,对于umh、esa、tesa,增大merange会显著地增加编码耗时。默认:16
// param.analyse.i_me_range = 4;
// // 关闭或启动为了心理视觉而降低psnr或ssim的优化。此选项同时也会关闭一些不能通过x264命令行设置的内部的心理视觉优化方法。
// param.analyse.b_psy = 0;
// // Mixed refs(混合参照)会以8×8的切块为参照取代以整个宏块为参照。会增进多帧参照的帧的质量,会有一些时间耗用.
// param.analyse.b_mixed_references = 0;
// // 通常运动估计都会同时考虑亮度和色度因素。开启此选项将会忽略色度因素换取一些速度的提升。
// param.analyse.b_chroma_me = 1;
//// // 使用网格编码量化以增进编码效率:0-关闭, 1-仅在宏块最终编码时启用, 2-所有模式下均启用.
//// // 选项1提供了速度和效率间较好的均衡,选项2大幅降低速度.
//// // 注意:需要开启 –cabac选项生效.
// param.b_cabac = 1;
// param.analyse.i_trellis = 1;
//// // 停用弹性内容的二进制算数编码 CABAC ,切换回效率较低的弹性内容的可变长度编码CAVLC。
//// // 大幅降低压缩效率(通常10~20%)和解码的硬件需求
//// param.b_cabac = 1;
//// param.i_cabac_init_idc = 0;
// // 关闭P帧的早期跳过决策。大量的时耗换回非常小的质量提升
// param.analyse.b_fast_pskip = 0;
// // DCT抽样会丢弃看上去“多余”的DCT块。会增加编码效率,通常质量损失可以忽略
// param.analyse.b_dct_decimate = 1;
// // 完全关闭内置去块滤镜,不推荐使用
// // 调节H.264标准中的内置去块滤镜。这是个性价比很高的选则, 关闭
// param.b_deblocking_filter = 1;
// param.i_deblocking_filter_alphac0 = 0;
// param.i_deblocking_filter_beta = 0;
// // 是否使用信噪比
// param.analyse.b_psnr = 0;
// // P帧参考I帧数量
// param.i_frame_reference = 1;
// // 用fps而不是时间戳来计算帧间距离
// param.b_vfr_input = 0;
// // 不使用8x8dct
// param.analyse.b_transform_8x8 = 0;

//设置编码质量
if (x264_param_apply_profile(&param, x264_profile_names[0]) < 0)
return -1;

x264_picture_init(&pic_out);
if (x264_picture_alloc(&pic, param.i_csp, param.i_width, param.i_height) < 0)
return -1;
pic.i_pts = 0;
h = x264_encoder_open(&param);
if (!h)
return -1;

LOGE("x264初始化成功");