废了我4天总算在win平台下 QT上实现x264编码成功,对于那个bug 认为还是要先了解程序的原理才好排错,但是正是这个bug让我学到了很多,学会了如何可以将lib编译成可以包含调试信息,学会了在VS下反编码,学会了extern "C" 的作用,学会了VS里面牛b的汇编编码……
第一步
windows下编译配置x264 :http://blog.csdn.net/liushu1231/article/details/8936894
第二步 编译源码 http://blog.csdn.net/liushu1231/article/details/9203239
上面两步带我走进了x264编码谢谢那个作者:一个健忘症患者的记忆备份
下面才是我学习中的一点bug:
1 注意那个y4m.c 文件在上面那个博客里面
2 那个程序我修改了如下:可以直接复制(我的平台 win64 QT5.3.1 库x264-snapshot-20140803-2245)y4m.c用那个作者的
\
#include <QCoreApplication>
#include "stdint.h"//处理字符定义的 //stdint.h是c99中引进的一个标准C库的头文件.
extern "C"
{
#include <assert.h>
#include "x264.h"
#include "x264_config.h"
#include "y4m.c"
}
#include "iostream"
#include "time.h"
using namespace std;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
int iResult = 0;
x264_t* pX264Handle = NULL; //编码器句柄
x264_param_t* pX264Param = new x264_param_t;//x264_param_t为结构体的名字,见文件X264.h
// x264_param_default(pX264Param);
assert(pX264Param);
//* 配置参数
//* 使用默认参数,在这里因为我的是实时网络传输,所以我使用了zerolatency(零延迟)的选项,使用这个选项之后就不会有delayed_frames,如果你使用的不是这样的话,还需要在编码完成之后得到缓存的编码帧
int res=x264_param_default_preset(pX264Param,"veryfast" , "zerolatency");//"veryfast"
//* cpuFlags
// pX264Param->i_threads = X264_SYNC_LOOKAHEAD_AUTO;//* 取空缓冲区继续使用不死锁的保证.
//* 视频选项
pX264Param->i_width = 384; //* 要编码的图像宽度.
pX264Param->i_height = 288; //* 要编码的图像高度
pX264Param->i_frame_total = 0; //* 编码总帧数.不知道用0.
pX264Param->i_keyint_max = 10;
//* 流参数
pX264Param->i_bframe = 5;
pX264Param->b_open_gop = 0;
pX264Param->i_bframe_pyramid = 1;
pX264Param->i_bframe_adaptive = X264_B_ADAPT_TRELLIS;
//* Log参数,不需要打印编码信息时直接注释掉就行
pX264Param->i_log_level = X264_LOG_DEBUG;
//X264_LOG_NONE
//* 速率控制参数
pX264Param->rc.i_bitrate = 1024 * 10;//* 码率(比特率,单位Kbps)
//* muxing parameters
pX264Param->i_fps_den = 1; //* 帧率分母
pX264Param->i_fps_num = 10;//* 帧率分子
pX264Param->i_timebase_den = pX264Param->i_fps_num;
pX264Param->i_timebase_num = pX264Param->i_fps_den;
//* 设置Profile.使用Baseline profile
int res2= x264_param_apply_profile(pX264Param, x264_profile_names[0]);
//* 编码需要的辅助变量
int iNal = 0; //修改部分
x264_nal_t *pNals = NULL; //修改部分
x264_picture_t* pPicIn = new x264_picture_t;
x264_picture_t* pPicOut = new x264_picture_t;
x264_picture_init(pPicOut); //输出图像的初始化
int res3= x264_picture_alloc(pPicIn, X264_CSP_I420, pX264Param->i_width, pX264Param->i_height); //输入图像分配数据
pPicIn->img.i_csp = X264_CSP_I420; //设置初始化图片格式 YUV420p
pPicIn->img.i_plane = 3; //用于保存YUV分量
//* 打开编码器句柄,通过x264_encoder_parameters得到设置给X264
//* 的参数.通过x264_encoder_reconfig更新X264的参数
pX264Handle = x264_encoder_open(pX264Param);
cout<<"pX264Param:"<<sizeof(pX264Param)<<endl;
assert(pX264Handle);
//* 创建文件,用于存储编码数据
FILE* pFile = fopen("test.264", "wb");
assert(pFile);
//设置y4m文件参数
y4m_input_t *y4m_hnd = (y4m_input_t*)malloc(sizeof(y4m_input_t));
//打开y4m文件
iResult = open_file_y4m("example1_352x288.y4m",(hnd_t**)&y4m_hnd,pX264Param);
if(iResult < 0 )
{
printf("Failed to open file y4m!\n");
system("PAUSE");
return 0;
}
//得到文件总得帧数
int nFrames = ::get_frame_total_y4m((hnd_t*)y4m_hnd);//9150
cout<<"*************"<<nFrames<<"*************"<<endl;
//printf( "start: %ld ms\n", start );
//开始编码
for(int i = 0; i < nFrames;i++ )
{
//读取一帧
// i++;
read_frame_y4m(pPicIn,(hnd_t*)y4m_hnd,i);
if( i ==0 )
pPicIn->i_pts = i;
else
pPicIn->i_pts = i - 1;
//编码
int frame_size = x264_encoder_encode(pX264Handle,&pNals,&iNal,pPicIn,pPicOut);
cout<<"frame_size"<<frame_size<<endl;
if(frame_size >0)
{
for (int i = 0; i < iNal; ++i)
{//将编码数据写入文件.
fwrite(pNals[i].p_payload, 1, pNals[i].i_payload, pFile);
}
}
}
//}
//* 清除图像区域
// x264_picture_clean(pPicIn);
//* 关闭编码器句柄
// x264_encoder_close(pX264Handle);
pX264Handle = NULL;
delete pPicIn ;
pPicIn = NULL;
delete pPicOut;
pPicOut = NULL;
delete pX264Param;
pX264Param = NULL;
return a.exec();
}
我的修改部分:
//* 视频选项
pX264Param->i_width = 384; //* 要编码的图像宽度.
pX264Param->i_height = 288; //* 要编码的图像高度
<pre name="code" class="cpp"> //* 编码需要的辅助变量
int iNal = 0; //修改部分
x264_nal_t *pNals = NULL; //修改部分
如果想单步调试进源码时
用这句话
configure--enable-shared --enable-debug
替代
configure--enable-shared