ffmpeg的H264编码问题,视频逐渐模糊

排山和倒海 2014-01-05 09:51:26
最近在看ffmpeg里的H264编码,然后试着去做了一下。但是目前发现一个问题,就是编码写入的.264文件,用播放器(VLC,暴风都试过)播放后,发现编码后的视频,开始很清晰,后面慢慢模糊,如下面三个图。
不知道为什么,可能是参数设置错误,希望大神给解决一下,谢谢!
下面是代码
memcpy(rgb_buff,frame->imageData,nDataLen);

avpicture_fill((AVPicture*)m_pRGBFrame, (uint8_t*)rgb_buff, PIX_FMT_RGB24, nWidth, nHeight);

//将YUV buffer 填充YUV Frame
avpicture_fill((AVPicture*)m_pYUVFrame, (uint8_t*)yuv_buff, PIX_FMT_YUV420P, nWidth, nHeight);
sws_scale(scxt,m_pRGBFrame->data,m_pRGBFrame->linesize,0,c->height,m_pYUVFrame->data,m_pYUVFrame->linesize);

int got_packet_ptr = 0;
av_init_packet(&avpkt);
avpkt.data = outbuf;
avpkt.size = outbuf_size;
u_size = avcodec_encode_video2(c, &avpkt, m_pYUVFrame, &got_packet_ptr);
if (u_size == 0)
{
fwrite(avpkt.data, 1, avpkt.size, f);
}else{
printf("error\n");
}


下面是图片



...全文
1295 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
neicole 2014-10-31
  • 打赏
  • 举报
回复
引用 4 楼 wangqing008 的回复:
我的问题解决了,只需要在 u_size = avcodec_encode_video2(c, &avpkt, m_pYUVFrame, &got_packet_ptr); 后面加上 m_pYUVFrame->pts++;就可以了。
那如果是需要写入到 AVFormatContext, 该设的是packet,在后面设frame不管用,如果想在encode前设frame,该如何设呢?
精分患者 2014-10-20
  • 打赏
  • 举报
回复
引用 4 楼 wangqing008 的回复:
我的问题解决了,只需要在 u_size = avcodec_encode_video2(c, &avpkt, m_pYUVFrame, &got_packet_ptr); 后面加上 m_pYUVFrame->pts++;就可以了。
您好,我也是这么做的,但是最后写入文件之后,不能播放了!
ztenv 版主 2014-01-05
  • 打赏
  • 举报
回复
解决了就好,本想给你找找原因的,
排山和倒海 2014-01-05
  • 打赏
  • 举报
回复
我的问题解决了,只需要在 u_size = avcodec_encode_video2(c, &avpkt, m_pYUVFrame, &got_packet_ptr); 后面加上 m_pYUVFrame->pts++;就可以了。
排山和倒海 2014-01-05
  • 打赏
  • 举报
回复
引用 2 楼 vipcxj 的回复:
问下LZ,我使用libvlc里的wxwidgets的例子,播放完全没问题,但在播放的过程中退出程序就会直接僵死。 我用的代码就是这个网址里的 http://git.videolan.org/?p=vlc.git;a=blob;f=doc/libvlc/wx_player.cpp 我调试后发现,程序卡在135行,主窗口的析构函数中:libvlc_media_player_release(media_player); 我一开始以为必须先stop才能release,于是加上了 libvlc_media_player_stop(media_player); 不过结果又卡在stop这里了。 于是我估计是不是因为 libvlc_media_player_set_hwnd(media_player, this->player_widget->GetHandle()); 将media_player和player_widget(一个子窗口)的hwnd绑定了,然后运行到stop或release时,那个hwnd已经失效了。于是我将media_player继续提前到那个子窗口被销毁前,结果更诡异的事发生了,直接运行,还是卡死,但在release前加断点,虽然函数耗时比较长,但最终还是能成功推出程序。现在我的解决办法是干脆将release放到整个主窗口的生命周期外面,也就是wxApp的OnExit里面,这样确实能正常退出了。不过还是一直没搞明白卡死的原因,难道是wxwidget和libvlc都背着我偷偷多线程,结果死锁了?
不好意思哈,我对这个ffmpeg也刚接触不是很了解。不过我觉得你这个错误应该和编解码没关系,是因为MFC的问题把,只是在程序的销毁变量等出错了。
vipcxj 2014-01-05
  • 打赏
  • 举报
回复
问下LZ,我使用libvlc里的wxwidgets的例子,播放完全没问题,但在播放的过程中退出程序就会直接僵死。 我用的代码就是这个网址里的 http://git.videolan.org/?p=vlc.git;a=blob;f=doc/libvlc/wx_player.cpp 我调试后发现,程序卡在135行,主窗口的析构函数中:libvlc_media_player_release(media_player); 我一开始以为必须先stop才能release,于是加上了 libvlc_media_player_stop(media_player); 不过结果又卡在stop这里了。 于是我估计是不是因为 libvlc_media_player_set_hwnd(media_player, this->player_widget->GetHandle()); 将media_player和player_widget(一个子窗口)的hwnd绑定了,然后运行到stop或release时,那个hwnd已经失效了。于是我将media_player继续提前到那个子窗口被销毁前,结果更诡异的事发生了,直接运行,还是卡死,但在release前加断点,虽然函数耗时比较长,但最终还是能成功推出程序。现在我的解决办法是干脆将release放到整个主窗口的生命周期外面,也就是wxApp的OnExit里面,这样确实能正常退出了。不过还是一直没搞明白卡死的原因,难道是wxwidget和libvlc都背着我偷偷多线程,结果死锁了?
排山和倒海 2014-01-05
  • 打赏
  • 举报
回复
这是一开始的初始化的代码
av_register_all();
	avcodec_register_all();
	AVFrame *m_pRGBFrame =  new AVFrame[1];  //RGB帧数据  
	AVFrame *m_pYUVFrame = new AVFrame[1];;  //YUV帧数据
	AVCodecContext *c= NULL;
	AVCodecContext *in_c= NULL;
	AVCodec *pCodecH264; //编码器
	uint8_t * yuv_buff;//

	//查找h264编码器
	pCodecH264 = avcodec_find_encoder(CODEC_ID_H264);
	if(!pCodecH264)
	{
	  fprintf(stderr, "h264 codec not found\n");
	  exit(1);
	}
	else
		printf("find\n");
	c= avcodec_alloc_context3(pCodecH264);
	c->bit_rate = 3000000;// put sample parameters 
	c->width =nWidth;// 
	c->height = nHeight;// 

	// frames per second 
	AVRational rate;
	rate.num = 1;
	rate.den = 25;
	c->time_base= rate;//(AVRational){1,25};
	c->gop_size = 10; // emit one intra frame every ten frames 
	c->max_b_frames=1;
	c->thread_count = 1;
	c->pix_fmt = PIX_FMT_YUV420P;//PIX_FMT_RGB24;

	//av_opt_set(c->priv_data, /*"preset"*/"libvpx-1080p.ffpreset", /*"slow"*/NULL, 0);
	//打开编码器
	if(avcodec_open2(c,pCodecH264,NULL)<0)
	  printf("不能打开编码库");

	int size = c->width * c->height;

	yuv_buff = (uint8_t *) malloc((size * 3) / 2); // size for YUV 420 


	//将rgb图像数据填充rgb帧
	uint8_t * rgb_buff = new uint8_t[nDataLen];

	//图象编码
	int outbuf_size=100000;
	uint8_t * outbuf= (uint8_t*)malloc(outbuf_size); 
	int u_size = 0;
	FILE *f=NULL; 
	char * filename = "myData.h264";
	f = fopen(filename, "wb");
	if (!f)
	{
	  printf( "could not open %s\n", filename);
	  exit(1);
	}

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧