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
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,我试过了,就是按你上面的代码来修改的:)