在上一篇博客《x264代码学习笔记(三):x264_slicetype_decide函数》里,在解读x264_slicetype_decide函数过程中,一直有这样的疑问,即B帧是何时被确定类型的,具体是怎样将视频帧由输入序列(播放序列)转换为编码序列呢?
为求解答案,我书写了一个实例进行代码调试,如下所示:
#include <assert.h>
#include <iostream>
extern "C"
{
#include "x264.h"
#include "x264_config.h"
}
using namespace std;
#pragma comment(lib,"D:\\H264_VideoCode\\x264_lib\\lib\\libx264.lib")
int main(void)
{
int frame_size = 0;
x264_t* pX264Handle = NULL;
x264_param_t* pX264Param = new x264_param_t; // 涉及到命令字所有参数
assert(pX264Param);
//* 打开源文件
FILE* pInputFile = fopen("D://company project//素材//YUV//bus_cif.yuv", "rb");
assert(pInputFile);
//* 创建文件,用于存储编码数据
FILE* pOutFile = fopen("E:\\PictureVideoDatabase\\264\\test.264", "wb");
assert(pOutFile);
//* 配置参数
x264_param_default(pX264Param); //* 设置默认参数
x264_param_default_preset(pX264Param, "veryfast", "zerolatency");
//* cpuFlags
pX264Param->i_threads = X264_SYNC_LOOKAHEAD_AUTO;//* 取空缓冲区继续使用不死锁的保证.
//* 视频选项
pX264Param->i_width = 352; //* 要编码的图像宽度.
pX264Param->i_height = 288; //* 要编码的图像高度
pX264Param->i_frame_total = 0; //* 编码总帧数.不知道用0.
//* 流参数
pX264Param->i_keyint_max = 10; //* 关键帧间隔
pX264Param->i_bframe = 5; //* 非B帧之间B帧个数
pX264Param->b_open_gop = 0; //* 关闭Open_gop模式,Open_gop模式可以跨GOP参考
pX264Param->i_bframe_pyramid = 0;//* 可参考B帧,0为关闭可参考B帧功能
pX264Param->i_bframe_adaptive = X264_B_ADAPT_TRELLIS; //* B帧自适应算法
//* Log参数,不需要打印编码信息时直接注释掉就行
pX264Param->i_log_level = X264_LOG_DEBUG;
//* 速率控制参数
pX264Param->rc.i_bitrate = 1024 * 10;//* 码率(比特率,单位Kbps)
//* muxing parameters
pX264Param->i_fps_den = 1; //* 帧率分母
pX264Param->i_fps_num = 25;//* 帧率分子
pX264Param->i_timebase_den = pX264Param->i_fps_num; // 帧率时间基为帧率的倒数
pX264Param->i_timebase_num = pX264Param->i_fps_den;
//* 设置Profile.使用Baseline profile
x264_param_apply_profile(pX264Param, x264_profile_names[0]); // baseline profile(不支持B帧功能)
//* 编码需要的辅助变量
int iNal = 0; // NAL数据包个数
x264_nal_t* pNals = NULL; // NAL数据指针
x264_picture_t* pPicIn = new x264_picture_t; // 输入图像
x264_picture_t* pPicOut = new x264_picture_t; // 输出图像
x264_picture_init(pPicOut); // 初始化图像内存
x264_picture_alloc(pPicIn, X264_CSP_I420, pX264Param->i_width, pX264Param->i_height);
pPicIn->img.i_csp = X264_CSP_I420;
pPicIn->img.i_plane = 3;
//* 打开编码器句柄
pX264Handle = x264_encoder_open(pX264Param);
assert(pX264Handle); // 判断pX264Handle是否为空
if(pInputFile == NULL || pOutFile == NULL) {
printf("Error open files.\n");
return -1;
}
int y_size = pX264Param->i_width*pX264Param->i_height;
int nFrames = 0; // 编码帧数
if (0 == nFrames)
{
fseek(pInputFile, 0L, SEEK_END); // 指针指到文件尾
switch (pX264Param->i_csp)
{
case X264_CSP_I444:
nFrames = ftell(pInputFile) / (3*y_size); // 计算总帧数
break;
case X264_CSP_I420:
nFrames = ftell(pInputFile) / (3*y_size/2);
break;
default:
printf("Colorspace Not Support.\n");
return -1;
}
fseek(pInputFile, 0L, SEEK_SET); //