下面是我初始化ffmpeg编码的代码:
void CVideoCompressTestDlg::OnSavefile()
{
// TODO: Add your command handler code here
CString path="C:\\123.h264";
char * ppath =(LPSTR)(LPCTSTR)path;
if(NULL == (pSaveVideoFile = fopen(ppath, "wb"))) //创建文件
{
TRACE("UYVYtoYUV420encode fopen error!\n");
}
ULONG fps = 0;
if ((fps<=0)||(fps>60))
{
fps = 50;
}
//压缩视频数据
/* avcodec init */
i_codec_id = CODEC_ID_H264;
const char* out_file = "src01.h264";
av_register_all(); //注册所有可用的文件格式和编解码库
pCodec = avcodec_find_encoder((CodecID)i_codec_id);//调用H264编码器
if (!pCodec)
{
return;
}
pCodecCtx = avcodec_alloc_context();
if (!pCodecCtx)
{
return;
}
/* avcodec frame alloc */
pFrame_420p = avcodec_alloc_frame();//为编码帧分配内存
if(!pFrame_420p)
{
return;
}
/* Init Codec Parameters */
pCodecCtx->codec_id = i_codec_id;
pCodecCtx->codec_type = CODEC_TYPE_VIDEO;
pCodecCtx->width = dwWidth;
pCodecCtx->height =dwHeight;
pCodecCtx->time_base.num = 1;
pCodecCtx->time_base.den = fps*7/10;
pCodecCtx->dct_algo = 0;
pCodecCtx->me_pre_cmp = 2;
if(CODEC_ID_H264 == i_codec_id)
{
pCodecCtx->bit_rate =400000 /*3*1024*1000*/;
pCodecCtx->cqp = 21;
pCodecCtx->me_method = 7; //For CODEC_ID_H264
pCodecCtx->qmin = 3; //x264 dislike(2)
pCodecCtx->qmax = 30; //x264 dislike(31)
}
else
{
return;
}
pCodecCtx->gop_size = 250/*250*/; //x264 dislike(12) --------keyframe interval 关键帧间隔
pCodecCtx->max_qdiff = 3;
pCodecCtx->qcompress = (float)0.6; //x264 dislike(0.5)
pCodecCtx->qblur = (float)0.5;
pCodecCtx->nsse_weight = 8;
pCodecCtx->i_quant_factor = (float)0.8;
pCodecCtx->b_quant_factor = (float)1.30; //x264 dislike(value - 1.25) < 0.01)
pCodecCtx->b_quant_offset = (float)1.30; //x264 dislike(value - 1.25) < 0.01)
pCodecCtx->pix_fmt = PIX_FMT_YUV420P;//当前YUV420
/* Obtain scale context */
p_sws_context = sws_getContext(pCodecCtx->width, pCodecCtx->height, PIX_FMT_YUV420P/*PIX_FMT_UYVY422*/, //Src
pCodecCtx->width, pCodecCtx->height, PIX_FMT_YUV420P, //Dst
SWS_BILINEAR, NULL, NULL, NULL);
if(!p_sws_context)
{
//printf("sws_getContext error, Exit\n", i_ret_fread, i_actual_stream_size);
return;
}
/* 打开 avcodec */
if(avcodec_open(pCodecCtx, pCodec) < 0)
{
return;
}
///////////////////////////////////////////////////////
p_video_buf = (unsigned char *)av_malloc(sizeof(UCHAR)*pCodecCtx->width * pCodecCtx->height * 3 /2);
pFrame_420p->data[0] = p_video_buf;
pFrame_420p->data[1] = p_video_buf + pCodecCtx->width * pCodecCtx->height;
pFrame_420p->data[2] = pFrame_420p->data[1] + (pCodecCtx->width * pCodecCtx->height / 4);
pFrame_420p->linesize[0] = pCodecCtx->width;
pFrame_420p->linesize[1] = pCodecCtx->width / 2;
pFrame_420p->linesize[2] = pCodecCtx->width / 2;
i_stream_buf_size = sizeof(UCHAR)*pCodecCtx->width * pCodecCtx->height * 3 /2;
p_stream_buf = (unsigned char *)av_malloc(i_stream_buf_size);
savevideoflag = 1;
////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
这里是我实时接收到摄像头的每一帧数据进行压缩编码,每秒采集25帧图像:
void CVideoCompressTestDlg::PlayVideo()
{
while (playflag)
{
// i++;
JMVSDK_GetVideo(pYUV420, CFormat_YUV420P, &ts, iChannelIndex);//采集卡采集到数据流
// fwrite(pYUV420, 1, dwWidth * dwHeight * 3 / 2, yuvfile);
pFrame_420p=avcodec_alloc_frame();//申请存储空间
// pCodecCtx = avcodec_alloc_context();
// avcodec_get_frame_defaults(pFrame_420p);
YUV420PToAVFrame(pYUV420,nLen,dwWidth,dwHeight, pFrame_420p);//将数据码流强制转换成YUV420P格式
pDDraw.DrawAllYUV((AVPicture*)pFrame_420p,CFormat_YUV420P,videorect,TRUE); //DDRAW上输出显示
if (savevideoflag)
{
/* encode one frame */ //压缩视频数据
int i_actual_stream_size = 0;
// int i_ret = sws_scale((SwsContext *)p_sws_context, pFrame_420p->data, pFrame_420p->linesize, 0, pCodecCtx->height,
// pFrame_420p->data, pFrame_420p->linesize); //将YUV422转YUV420P
i_actual_stream_size = avcodec_encode_video(pCodecCtx, p_stream_buf, i_stream_buf_size, pFrame_420p);
if(i_actual_stream_size < 0)
{
TRACE("Encode frame %d error, exit\n", 5555);
//break;
}
if (NULL != pSaveVideoFile) //将视频数据写入H264文件
{
if (0 == fwrite(p_stream_buf,sizeof(unsigned char), i_actual_stream_size, pSaveVideoFile))
{
TRACE("UYVYtoYUV420encode fwrite error!\n");
}
fflush(pSaveVideoFile);
}
else
{
TRACE("fopen failed!!!\n");
}
}
}
}
其他的编码部分就没有了,哪位大侠帮忙看下,多谢了,分全压上了!
12 个解决方案
#1
没有人知道吗?
#2
没有变化?你怎么推出来的没有变化?
720*576*1.5*25
720*576*1.5*25
#3
i_actual_stream_size
#4
avcodec_encode_video每次的返回值是多少? printf出来看看?
#5
我把得到的YUV420P保存文件,记录10分钟,然后再264文件保存成文件,也是10分钟,文件大小基本一样
#6
我把得到的YUV420P保存文件,记录10分钟,然后再264文件保存成文件,也是10分钟,文件大小基本一样
#7
应该是哪里写错了。。这个我也做过。弄完后要比较小的,你可以试试把这个文件用相应软件转成H264(不是你的代码)然后再来对比下,就可以知道你的有没有转错了
#8
文件大小多大,YUV420存10分钟应该是9331200000字节,约等于9个GB,你存了这么大的文件?
#9
我确实保存了这么大的文件做的测试,就是不知道哪里参数设置错了,有类似的例子吗?可以发我邮箱 hushuihao_ml@163。com
#10
我把得到的YUV420P保存文件,记录10分钟,然后再264文件保存成文件,也是10分钟,文件大小基本一样
应该是哪里写错了。。这个我也做过。弄完后要比较小的,你可以试试把这个文件用相应软件转成H264(不是你的代码)然后再来对比下,就可以知道你的有没有转错了
你有以前的例子吗?能发我邮箱hushuihao_ml@163.com看看吗?谢谢!
#11
avcodec_encode_video每次的返回值是多少? printf出来看看?
返回值在287至1868之间,基本都是随机的,没什么规律都是大于0的,小于0就出错了
#12
avcodec_encode_video每次的返回值是多少? printf出来看看?
返回值在287至1868之间,基本都是随机的,没什么规律都是大于0的,小于0就出错了
把它们加起来,十分钟的数据能到能到9g?
假设你30fps好了,最大也就是1868*30*60*10=,大概32m
楼主检查一下自己写文件的相关操作吧
#1
没有人知道吗?
#2
没有变化?你怎么推出来的没有变化?
720*576*1.5*25
720*576*1.5*25
#3
i_actual_stream_size
#4
avcodec_encode_video每次的返回值是多少? printf出来看看?
#5
我把得到的YUV420P保存文件,记录10分钟,然后再264文件保存成文件,也是10分钟,文件大小基本一样
#6
我把得到的YUV420P保存文件,记录10分钟,然后再264文件保存成文件,也是10分钟,文件大小基本一样
#7
我把得到的YUV420P保存文件,记录10分钟,然后再264文件保存成文件,也是10分钟,文件大小基本一样
应该是哪里写错了。。这个我也做过。弄完后要比较小的,你可以试试把这个文件用相应软件转成H264(不是你的代码)然后再来对比下,就可以知道你的有没有转错了
#8
我把得到的YUV420P保存文件,记录10分钟,然后再264文件保存成文件,也是10分钟,文件大小基本一样
文件大小多大,YUV420存10分钟应该是9331200000字节,约等于9个GB,你存了这么大的文件?
#9
我把得到的YUV420P保存文件,记录10分钟,然后再264文件保存成文件,也是10分钟,文件大小基本一样
文件大小多大,YUV420存10分钟应该是9331200000字节,约等于9个GB,你存了这么大的文件?
我确实保存了这么大的文件做的测试,就是不知道哪里参数设置错了,有类似的例子吗?可以发我邮箱 hushuihao_ml@163。com
#10
我把得到的YUV420P保存文件,记录10分钟,然后再264文件保存成文件,也是10分钟,文件大小基本一样
应该是哪里写错了。。这个我也做过。弄完后要比较小的,你可以试试把这个文件用相应软件转成H264(不是你的代码)然后再来对比下,就可以知道你的有没有转错了
你有以前的例子吗?能发我邮箱hushuihao_ml@163.com看看吗?谢谢!
#11
avcodec_encode_video每次的返回值是多少? printf出来看看?
返回值在287至1868之间,基本都是随机的,没什么规律都是大于0的,小于0就出错了
#12
avcodec_encode_video每次的返回值是多少? printf出来看看?
返回值在287至1868之间,基本都是随机的,没什么规律都是大于0的,小于0就出错了
把它们加起来,十分钟的数据能到能到9g?
假设你30fps好了,最大也就是1868*30*60*10=,大概32m
楼主检查一下自己写文件的相关操作吧