x264代码学习笔记(四):B帧是何时被确定帧类型的?怎样进行编码的?

本文通过代码调试和分析,探讨了x264编码器中B帧的确定时机及编码过程。在baseline profile下,GOP结构为IPPP,不包含B帧;而在main profile下,GOP结构为IPBBP,并在编码前缓存一定帧数。关键在于`x264_encoder_encode`函数中,当输入帧序号大于延迟帧数时开始编码。B帧类型在当前GOP编码完毕后,通过`x264_slicetype_decide`函数统一决定。
摘要由CSDN通过智能技术生成

       在上一篇博客《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); //
  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lifei092

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值