码率控制:
ffmpeg/x264 码率控制 分析
ffmpeg编码:
ffmpeg 编码示例
x264编码定义三个接口。
调用流程图:
一 初始化
x264_param_t param;
x264_param_default_preset(¶m, "superfast", "zerolatency");//根据preset和tune 申请设置param
//修改部分默认参数
param.i_threads = 15;
param.i_width = h264_width;
param.i_height = h264_height;
param.i_fps_num = FPS;
param.i_fps_den = 1;
param.i_csp = X264_CSP_I420;
param.i_keyint_min = FPS * 1;
param.i_keyint_max = FPS * 2;
param.i_bframe = 30;
param.i_bframe_bias = 100;
param.rc.i_qp_min = 16; //质量区间
param.rc.i_qp_max =24;
param.analyse.i_me_range = 16;
//param.b_intra_refresh = 1;
param.rc.f_qcompress = 0.6;
//图片质量损失损失 越小越清晰,默认23 最小0
param.rc.f_rf_constant = 1;
x264_param_apply_profile(¶m, "baseline");
encoder = x264_encoder_open(¶m);
//初始化输入文件描述符
outf = open(filename, O_CREAT | O_WRONLY, 444);
if (outf < 0) {
x264_encoder_close(encoder);
close(inf);
return -1;
}
//申請處理的緩存内存
yuv = (uint8_t *) malloc(h264_width * h264_height * 3 / 2);
//初始化pic——in
x264_picture_alloc(&pic_in, X264_CSP_I420, h264_width, h264_height); //申请picture 内存
主要是设置编码参数,打开编码器,申请需要的内存。
设置编码参数用到三个重要函数:
x264_param_apply_profile()源码分析;
x264_param_default()设置默认参数值。x264_param_default_preset()根据所给preset和tune选取现有的编码模型。
x264_param_apply_profile();再打开编码器之前调用该函数是必要的,会检测参数的合法性并修改。
二 喂数据
int x264encode_addframe(uint8_t* jb, int nw, int nh) {
uint8_t* buffer = (uint8_t*) jb;
detailYuvPic(buffer, yuv, nw, nh, h264_width,h264_height , orientation , isInversion);
//yuv420:将yuvbuff 填充进pic_in
pic_in.img.plane[0] = yuv;
pic_in.img.plane[1] = yuv+(h264_height * h264_width);
pic_in.img.plane[2] = yuv+(h264_height * h264_width * 5 / 4);
pic_in.img.i_plane = 3;
pic_in.img.i_stride[0] = h264_width;
pic_in.img.i_stride[1] = h264_width / 2;
pic_in.img.i_stride[2] = h264_width / 2;
pic_in.img.i_csp = X264_CSP_I420;
//编码
x264_nal_t *nals;
int nnal;
pic_in.i_pts = i_pts++;
x264_encoder_encode(encoder, &nals, &nnal, &pic_in, &pic_out);
x264_nal_t *nal;
for (nal = nals; nal < nals + nnal; nal++) {
write(outf, nal->p_payload, nal->i_payload);
}
return 0;
}
detailYuvPic()函数中yuvI420所做的某些处理,比如缩放,旋转,裁剪,镜像,滤镜什么的。
如果android /ios平台处理参看:
针对android&ios yuv旋转、镜像、格式转换、裁剪 算法实现。
3 结束释放
int x264encode_finish() {
//关闭编码器
x264_encoder_close(encoder);
if (yuv != NULL) {
free(yuv);
yuv = NULL;
}
close(outf);
return 0;
}
关闭编码器,释放所申请内存。