采集视频后在本地直接进行编码、解码(不进行网传),为什么显示出来有大量马赛克

博主在本地使用VFW API和mpg4c32.dll进行视频编码解码时遇到大量马赛克问题。经过讨论,可能的原因包括:编码解码过程中的错误、解码后数据缓冲区大小不正确、压缩比特率过低、编码后的数据与预期不符。建议检查编解码算法、数据缓冲区大小和比特率设置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

RT  
  本人用VFW   API写的,编解码库采用微软的mpg4c32.dll,部分代码如下:  
   
  //初始化编码  
  BOOL   CSkySunDlg::InitVideoEncoder()  
  {  
  m_hicEnc   =   ICOpen(ICTYPE_VIDEO,   m_dwCompressor,   ICMODE_FASTCOMPRESS);  
  if(!m_hicEnc)  
  {  
  AfxMessageBox("ICOpen   Enc   Error!");  
  return   false;  
  }  
   
  m_biEncInput.bmiHeader.biSize                         =   sizeof(BITMAPINFOHEADER);  
  m_biEncInput.bmiHeader.biCompression           =   BI_RGB;  
  m_biEncInput.bmiHeader.biWidth                       =   QCIF_WIDTH;  
  m_biEncInput.bmiHeader.biHeight                     =   QCIF_HEIGHT;  
  m_biEncInput.bmiHeader.biPlanes                     =   1;  
  m_biEncInput.bmiHeader.biBitCount                 =   24;  
  m_biEncInput.bmiHeader.biSizeImage               =   QCIF_WIDTH*QCIF_HEIGHT*1*(24/8);  
  m_biEncInput.bmiHeader.biXPelsPerMeter       =   0;  
  m_biEncInput.bmiHeader.biYPelsPerMeter       =   0;  
  m_biEncInput.bmiHeader.biClrUsed                   =   0;  
  m_biEncInput.bmiHeader.biClrImportant         =   0;  
   
  m_biEncOutput.bmiHeader.biSize                       =   sizeof(BITMAPINFOHEADER);  
  m_biEncOutput.bmiHeader.biCompression         =   mmioFOURCC('M','P','4','3');  
  m_biEncOutput.bmiHeader.biWidth                     =   QCIF_WIDTH;  
  m_biEncOutput.bmiHeader.biHeight                   =   QCIF_HEIGHT;  
  m_biEncOutput.bmiHeader.biPlanes                   =   1;  
  m_biEncOutput.bmiHeader.biBitCount               =   24;  
  m_biEncOutput.bmiHeader.biSizeImage             =   QCIF_WIDTH*QCIF_HEIGHT*1*(24/8);  
  m_biEncOutput.bmiHeader.biXPelsPerMeter     =   0;  
  m_biEncOutput.bmiHeader.biYPelsPerMeter     =   0;  
  m_biEncOutput.bmiHeader.biClrUsed                 =   0;  
  m_biEncOutput.bmiHeader.biClrImportant       =   0;  
   
  if(   ICERR_OK   !=   ICCompressBegin(m_hicEnc,   &m_biEncInput,   &m_biEncOutput)   )  
  {  
  AfxMessageBox("ICCompressBegin   Error!");  
  return   false;  
  }  
   
  return   true;  
  }  
   
  //初始化解码  
  BOOL   CSkySunDlg::InitVideoDecoder()  
  {  
  m_hicDec   =   ICOpen(ICTYPE_VIDEO,   m_dwCompressor,   ICMODE_FASTDECOMPRESS);  
  if(!m_hicDec)  
  {  
  AfxMessageBox("ICOpen   Dec   error!");  
  return   false;  
  }  
   
  m_biDecInput.bmiHeader.biSize                         =   sizeof(BITMAPINFOHEADER);  
  m_biDecInput.bmiHeader.biCompression           =   mmioFOURCC('M','P','4','3');  
  m_biDecInput.bmiHeader.biWidth                       =   QCIF_WIDTH;  
  m_biDecInput.bmiHeader.biHeight                     =   QCIF_HEIGHT;  
  m_biDecInput.bmiHeader.biPlanes                     =   1;  
  m_biDecInput.bmiHeader.biBitCount                 =   24;  
  m_biDecInput.bmiHeader.biSizeImage               =   QCIF_WIDTH*QCIF_HEIGHT*1*(24/8);  
  m_biDecInput.bmiHeader.biXPelsPerMeter       =   0;  
  m_biDecInput.bmiHeader.biYPelsPerMeter       =   0;  
  m_biDecInput.bmiHeader.biClrUsed                   =   0;  
  m_biDecInput.bmiHeader.biClrImportant         =   0;  
   
  m_biDecOutput.bmiHeader.biSize                       =   sizeof(BITMAPINFOHEADER);  
  m_biDecOutput.bmiHeader.biCompression         =   BI_RGB;  
  m_biDecOutput.bmiHeader.biWidth                     =   QCIF_WIDTH;  
  m_biDecOutput.bmiHeader.biHeight                   =   QCIF_HEIGHT;  
  m_biDecOutput.bmiHeader.biPlanes                   =   1;  
  m_biDecOutput.bmiHeader.biBitCount               =   24;  
  m_biDecOutput.bmiHeader.biSizeImage             =   QCIF_WIDTH*QCIF_HEIGHT*1*(24/8);  
  m_biDecOutput.bmiHeader.biXPelsPerMeter     =   0;  
  m_biDecOutput.bmiHeader.biYPelsPerMeter     =   0;  
  m_biDecOutput.bmiHeader.biClrUsed                 =   0;  
  m_biDecOutput.bmiHeader.biClrImportant       =   0;  
   
  if(ICERR_OK   !=   ICDecompressBegin(m_hicDec,   &m_biDecInput,   &m_biDecOutput))  
  {  
  AfxMessageBox("ICDecompressBegin   Error!");  
  return   false;  
  }  
   
  return   true;  
  }  
   
  //视频采集  
  ......  
  capSetCallbackOnVideoStream(m_capWnd,OnVideoStream);//设置回调  
  ......  
   
  LRESULT   CALLBACK   OnVideoStream(HWND   mwnd,LPVIDEOHDR   lphdr)  
  {  
  VideoCapture   *vidcap   =   (VideoCapture   *)(capGetUserData(mwnd));  
   
  if(vidcap   !=   NULL)  
  {  
  ((CSkySunDlg   *)vidcap->m_pDlg)->ProcessVideo(lphdr->lpData,   lphdr->dwBytesUsed);  
  }  
   
  return   TRUE;  
  }  
   
  void   CSkySunDlg::ProcessVideo(BYTE   *pData,   int   nSize)  
  {  
  //显示本地视频(采集到的未经压缩、解压处理的)  
  ::DrawDibDraw(m_hDib,   m_hDC,   m_localWndX,   m_localWndY,   -1,   -1,    
  &m_bitmapinfo->bmiHeader,   pData,   0,   0,   QCIF_WIDTH,   QCIF_HEIGHT,  
  DDF_SAME_DRAW);  
   
  //压缩视频  
  long   videosize   =   QCIF_WIDTH*QCIF_HEIGHT*3;  
  char   OutputBuf[QCIF_WIDTH*QCIF_HEIGHT*3];  
  memset(OutputBuf,   0,   QCIF_WIDTH*QCIF_HEIGHT*3);  
  DWORD   dwFlag;  
  static   long   lFrameNum   =   0;  
   
  DWORD   dwResult   =   ICCompress(m_hicEnc,   0,   &m_biEncOutput.bmiHeader,   OutputBuf,  
  &m_biEncInput.bmiHeader,   (LPVOID)pData,   NULL,   &dwFlag,   lFrameNum++,  
  0,   0,   NULL,   NULL);  
   
  int   nCompressedSize   =   m_biEncOutput.bmiHeader.biSizeImage;  
  if(   (dwResult   ==   ICERR_OK)   &&   (nCompressedSize   >   0)   )  
  {  
  //解压视频  
  char   OutputData[512];  
  memset(OutputData,   0,   512);  
   
  DWORD   dwRet;  
  dwRet   =   ICDecompress(m_hicDec,   0,   &m_biDecInput.bmiHeader,    
  OutputBuf,   &m_biDecOutput.bmiHeader,   OutputData);  
  if(   ICERR_OK   ==   dwRet   )  
  {  
  //显示解压后视频  
  ::DrawDibDraw(m_hDib,  
  m_hDC,  
  m_remoteWndX,  
  m_remoteWndY,  
  -1,  
  -1,  
  &m_biDecOutput.bmiHeader,  
  OutputData,  
  0,  
  0,  
  QCIF_WIDTH,  
  QCIF_HEIGHT,  
  DDF_SAME_DRAW  
  );  
  }  
  }  
  } 问题 点数:100、回复次数:10Top

src="/Include/Board.htm?Tags=" frameborder="0" scrolling="no">

1 楼ccxian123(力挽狂澜)回复于 2005-07-14 17:02:48 得分 0

先试下不编码直接显示看有没马塞克啊。。Top

2 楼edoch(逸刀客)回复于 2005-07-14 20:01:19 得分 0

不编码试过了,没有的Top

3 楼beipiao(北漂)回复于 2005-07-15 14:04:01 得分 0

把编码前的 数据 和解码后的数据比较一下,看是否相同,不同的话,说明编解码有问题,否则就是显示有问题Top

4 楼psusong(栀子花开)回复于 2005-07-15 17:36:31 得分 0

楼上的做法是错误的,根本没有办法进行比较!,因为编码是个有损压缩的过程,解码后不可能完全复原!  
   
  我怀疑楼主的代码在实际中会有异常,因为解码的输出buffer的大小错误!  
   
  if(   (dwResult   ==   ICERR_OK)   &&   (nCompressedSize   >   0)   )  
  {  
  //解压视频  
  char   OutputData[512];//数据buffer的大小应该是176x144x3!  
  memset(OutputData,   0,   512);  
   
  DWORD   dwRet;  
  dwRet   =   ICDecompress(m_hicDec,   0,   &m_biDecInput.bmiHeader,    
  OutputBuf,   &m_biDecOutput.bmiHeader,   OutputData);  
  Top

5 楼daizq()回复于 2005-07-15 22:10:45 得分 0

用文件先试验,如果有马赛克,算法有问题;如没有,效率有问题。Top

6 楼13501384036(板砖)回复于 2005-11-16 15:19:57 得分 0

兄弟,解决后请发一个解决 方法 ,小弟也碰到此问题。Top

7 楼happydeer(消失中...)回复于 2005-11-16 15:36:51 得分 0

压缩的bitrate设得太低了?Top

8 楼lianhuiyong(阳关故人)回复于 2005-11-25 15:44:52 得分 0

压缩比特率太低也不会全是马赛克,向楼上说的你可以在编码后存储成文件,然后需要使用相应的工具打开,看看存储的数据对不对。然后解码后采用同样的方法。我以前就是这样确定问题然后解决问题的。  
  最后祝搂住好运!Top

9 楼lianhuiyong(阳关故人)回复于 2005-11-25 15:47:31 得分 0

另外既然你编码前的m_biEncInput.bmiHeader参数已经设置,要确保采集到的数据与这里设置的数据参数一致!Top

10 楼vikern(vikern)回复于 2006-03-14 00:04:38 得分 0

我解决了你上面的问题,应该是mpg4c32.dll的问题,  
  如果你将所有mmioFOURCC('M','P','4','3');   换成   mmioFOURCC('D','I','V','X');  
  则一定OK,我试过了,就是按你上面的代码来修改的:) 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值