FFmpeg 解码,OpenCV 显示,MFC图片控件,颜色不正确,问题出在什么地方啊?

落日流沙 2014-10-30 11:55:44
代码如下:


void CMFC_FFPDlg::OnBnClickedOpen()
{
// TODO: 在此添加控件通知处理程序代码

CFileDialog dlgFile(
TRUE, NULL, NULL,
OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR,
"视频文件格式AVI file format (*.*)|*.*|", NULL);

CString filein;

if(dlgFile.DoModal() != IDOK)
{
filein = "";
return;
}
filein = dlgFile.GetPathName();
filename = (LPSTR)(LPCSTR)filein;

av_register_all();
avformat_network_init();

pFormatCtx = avformat_alloc_context();
if(avformat_open_input(&pFormatCtx, filename, NULL, NULL)!=0)
{
AfxMessageBox("open input file faile !");
return ;
}

for(int i=0; i<pFormatCtx->nb_streams; i++)
{
if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO)
{
videoStream = i;
break;
}
}
if(videoStream == -1)
{
AfxMessageBox("could not find video stream !");
return ;
}

pCodecCtx=pFormatCtx->streams[videoStream]->codec;
pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
if(pCodec==NULL)
{
AfxMessageBox("could not find decoder");
return ;
}

if(avcodec_open2(pCodecCtx, pCodec,NULL)<0)
{
AfxMessageBox("could not open decoder");
return ;
}

av_dump_format(pFormatCtx, 0, filename, 0);

pFrame=avcodec_alloc_frame();
pFrameRGB=avcodec_alloc_frame();
packet=(AVPacket *)av_malloc(sizeof(AVPacket));
if(pFrameRGB==NULL)
{
AfxMessageBox("open mem faile");
return ;
}

numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);

buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));

avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);

SetTimer(1, 10, NULL);
}

void CMFC_FFPDlg::OnTimer(UINT nIDEvent)
{
if(av_read_frame(pFormatCtx, packet)>=0)
{
if(packet->stream_index==videoStream)
{
avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet);

if(frameFinished)
{
struct SwsContext * img_convert_ctx;

img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);
if(img_convert_ctx == NULL)
{
AfxMessageBox("Cannot initialize the conversion context !");
return ;
}

sws_scale(img_convert_ctx,
pFrame->data, pFrame->linesize, 0, pCodecCtx->height,
pFrameRGB->data, pFrameRGB->linesize);

if (img_convert_ctx)
{
sws_freeContext (img_convert_ctx);
img_convert_ctx = NULL;
}

IplImage * Image;
CvSize Size = cvSize(pCodecCtx->width, pCodecCtx->height);
Image = cvCreateImage(Size, IPL_DEPTH_8U, 3);
memcpy(Image->imageData, buffer, pCodecCtx->width*pCodecCtx->height*24/8);
Image->widthStep = pCodecCtx->width*3;
Image->origin = 0;
cvShowImage("video", Image);
DrawPicToHDC(Image, IDC_PIC);
UpdateData(FALSE);

cvReleaseImage( &Image);
}
}
}
}

void CMFC_FFPDlg::DrawPicToHDC(IplImage *img, UINT ID)
{
CDC *pDC = GetDlgItem(ID)->GetDC();
HDC hDC= pDC->GetSafeHdc();
CRect rect;
GetDlgItem(ID)->GetClientRect(&rect);
CvvImage cimg;
cimg.CopyOf(img,1);

cimg.DrawToHDC(hDC,&rect);
ReleaseDC(pDC);
}


...全文
231 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
落日流沙 2014-11-03
  • 打赏
  • 举报
回复
引用 2 楼 robertbo 的回复:
memcpy(Image->imageData, buffer这块的拷贝数量,换成逐行拷贝试试,图像的每一行字节长度必须是4的倍数,不是的话需要在最后补齐,你计算拷贝数量的地方可能会出错 如果是颜色不一样的话,可以看看是不是解码的数据率中RGB三个颜色分量的位置是不是不一致,opencv里面的顺序的GBR,不清楚FFmpeg里面解码出来是什么顺序
嗯,解决了。谢谢你的建议。
落日流沙 2014-11-03
  • 打赏
  • 举报
回复
引用 4 楼 hubo86915531 的回复:
上面是颜色图像倒置说错了 加这个试试

static uchar *p = NULL;

				p = pFrame->data[1];
				pFrame->data[1] = pFrame->data[2];
				pFrame->data[2] = p;
  sws_scale(img_convert_ctx,
                        pFrame->data, pFrame->linesize, 0, pCodecCtx->height,
                        pFrameRGB->data, pFrameRGB->linesize);
确实是啊,谢谢了。
落日流沙 2014-10-30
  • 打赏
  • 举报
回复
也算不上偏色,但是和正常播放时的颜色有明显差异
hubo86915531 2014-10-30
  • 打赏
  • 举报
回复
上面是颜色图像倒置说错了 加这个试试

static uchar *p = NULL;

				p = pFrame->data[1];
				pFrame->data[1] = pFrame->data[2];
				pFrame->data[2] = p;
  sws_scale(img_convert_ctx,
                        pFrame->data, pFrame->linesize, 0, pCodecCtx->height,
                        pFrameRGB->data, pFrameRGB->linesize);
hubo86915531 2014-10-30
  • 打赏
  • 举报
回复

	pFrame->data[0] += pFrame->linesize[0]*(pCodecCtx->height-1);
	pFrame->linesize[0] *= -1;			
	pFrame->data[1] += pFrame->linesize[1]*(pCodecCtx->height/2-1);
	pFrame->linesize[1] *= -1;					
	pFrame->data[2] += pFrame->linesize[2]*(pCodecCtx->height/2-1);
	pFrame->linesize[2] *= -1;
 sws_scale(img_convert_ctx,
                        pFrame->data, pFrame->linesize, 0, pCodecCtx->height,
                        pFrameRGB->data, pFrameRGB->linesize);
robertbo 2014-10-30
  • 打赏
  • 举报
回复
memcpy(Image->imageData, buffer这块的拷贝数量,换成逐行拷贝试试,图像的每一行字节长度必须是4的倍数,不是的话需要在最后补齐,你计算拷贝数量的地方可能会出错 如果是颜色不一样的话,可以看看是不是解码的数据率中RGB三个颜色分量的位置是不是不一致,opencv里面的顺序的GBR,不清楚FFmpeg里面解码出来是什么顺序

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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