📄 videocodec.cpp
字号:
/*********************************
* VideoCodec.cpp
* By L0op8ack@
*********************************/
#include "stdafx.h"
#include "VideoCodec.h"
CVideoCodec::CVideoCodec()
{
m_Codec = -1;
m_CodecType[0].codec = MS_H261; m_CodecType[0].Fourcc = "M261";
m_CodecType[1].codec = MS_H263; m_CodecType[1].Fourcc = "M263";
m_CodecType[2].codec = DIVX; m_CodecType[2].Fourcc = "DIVX";
m_CodecType[3].codec = MS_MPEG4V1; m_CodecType[3].Fourcc = "MPG4";
m_CodecType[4].codec = MS_MPEG4V2; m_CodecType[4].Fourcc = "MP42";
m_CodecType[5].codec = MS_MPEG4V3; m_CodecType[5].Fourcc = "MP43";
m_CodecType[6].codec = XVID; m_CodecType[6].Fourcc = "XVID";
m_CodecType[7].codec = -1; m_CodecType[7].Fourcc = NULL;
}
CVideoCodec::~CVideoCodec()
{
}
BOOL CVideoCodec::SetCodecType(int type)
{ // change range if codec added !
if(type>=MS_H261 && type <=XVID) m_Codec=type;
return (m_Codec!=-1);
}
BOOL CVideoCodec::Init()
{
// TRACE("CVideoCodec::Init\n");
Destroy();
BOOL bRet=FALSE;
if(m_Codec == -1) return FALSE;
// 建议安装 K-liteCodecPack2.24FullRC7.rar
// 简易 m_cv.fccHandler 探测,m263/m261/mpg4/divx/xvid......
// ICINFO icinfo; CString tmp; char *p=NULL;
// ZeroMemory(&icinfo,sizeof(icinfo));
// if(ICInfo(ICTYPE_VIDEO,mmioFOURCC(m_CodecType[m_Codec].Fourcc[0],m_CodecType[m_Codec].Fourcc[1], \
// m_CodecType[m_Codec].Fourcc[2],m_CodecType[m_Codec].Fourcc[3]),&icinfo))
// {
// p=(char*)(&(icinfo.fccType));
// tmp.Format ("CVideoCodec::Init ,ICInfo:\ndwSize=%u\nfccType=%C%C%C%C\nfccHandler=%C%C%C%C\ndwFlags=%08X\ndwVersion=%08X\ndwVersionICM=%08X\nszName=[%s]\nszDescription=[%S]\nszDriver=[%S]\n",\
// icinfo.dwSize ,*p,*(p+1),*(p+2),*(p+3),*(p+4),*(p+5),*(p+6),*(p+7),icinfo.dwFlags ,\
// icinfo.dwVersion ,icinfo.dwVersionICM ,icinfo.szName ,icinfo.szDescription ,icinfo.szDriver );
// TRACE(tmp);
// }
// 图像压缩/解压缩参数 m_cv 初始化,lKey建议少一点
ZeroMemory(&m_cv,sizeof(m_cv));
m_cv.cbSize=sizeof(m_cv);
m_cv.dwFlags=ICMF_COMPVARS_VALID ;
m_cv.hic=m_hIC;
m_cv.fccType=ICTYPE_VIDEO ; //"vidc"
m_cv.fccHandler=
mmioFOURCC(m_CodecType[m_Codec].Fourcc[0],m_CodecType[m_Codec].Fourcc[1], \
m_CodecType[m_Codec].Fourcc[2],m_CodecType[m_Codec].Fourcc[3]);
m_cv.lpbiOut=0;
m_cv.lKey=1; // I帧产生速率,越大占用带宽越厉害
m_cv.lDataRate=4; // KBPS
m_cv.lQ=100;//1-10000
//将视频格式固定,一般的视频捕捉设备应该会支持(176*144/320x240),I pray... >:-/
ZeroMemory(&m_BmpU,sizeof(m_BmpU));
m_BmpU.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); //176*144*24
m_BmpU.bmiHeader.biWidth=176;//IMAGE_WIDTH
m_BmpU.bmiHeader.biHeight=144;//IMAGE_HEIGH
m_BmpU.bmiHeader.biPlanes=1;
m_BmpU.bmiHeader.biBitCount=24;
m_BmpU.bmiHeader.biSizeImage=76032; //176*144*24,所以需要大约80,000字节缓冲
// View your local 'vidc'
// ICCompressorChoose(pDlg->m_hWnd ,ICMF_CHOOSE_ALLCOMPRESSORS,&m_BmpU,NULL,&m_cv,NULL);
m_hIC=ICOpen(ICTYPE_VIDEO,m_cv.fccHandler,ICMODE_COMPRESS|ICMODE_DECOMPRESS);
if(!m_hIC) goto RET;
ICCompressGetFormat(m_hIC,&m_BmpU,&m_BmpC);
// MS H.263 需要消息确认! MPEG4可不用
ICSendMessage(m_hIC,0x60c9,0xf7329ace,0xacdeaea2);
m_cv.hic=m_hIC;
m_cv.dwFlags=ICMF_COMPVARS_VALID;
if(!ICSeqCompressFrameStart(&m_cv,&m_BmpU)) goto RET;
if(ICDecompressBegin(m_hIC,&m_BmpC,&m_BmpU)!=ICERR_OK) goto RET;
bRet=TRUE;
RET:
if(!bRet) Destroy();
return bRet;
}
void CVideoCodec::Destroy()
{
// TRACE("CVideoCodec::Destroy\n");
if(m_hIC)
{
ICDecompressEnd(m_hIC);
ICSeqCompressFrameEnd(&m_cv);
ICCompressorFree(&m_cv);
ICClose(m_hIC);
m_hIC=NULL;
}
}
BOOL CVideoCodec::EncodeVideoData(char* pin,int len,char* pout,int* lenr,BOOL* pKey)
{
// TRACE("CVideoCodec::EncodeVideoData\n");
BOOL bRet=FALSE;
char*p;
long s=2000;
BOOL k;
if(!pin||!pout||len!=(int)m_BmpU.bmiHeader.biSizeImage||!m_hIC)
goto RET;
p=(char*)ICSeqCompressFrame(&m_cv,0,pin,&k,&s);
if(!p) goto RET;
if(lenr) *lenr=s;
if(pKey) *pKey=k;
CopyMemory(pout,p,s);
bRet=TRUE;
RET:
return bRet;
}
BOOL CVideoCodec::DecodeVideoData(char *pin,int len,char* pout,int *lenr,DWORD flag)
{
//TRACE("CVideoCodec::DecodeVideoData\n");
BOOL bRet=FALSE;
if(!pin||!pout||!m_hIC)
goto RET;
if(ICDecompress(m_hIC,flag,&m_BmpC.bmiHeader,pin,&m_BmpU.bmiHeader,pout)!=ICERR_OK)
goto RET;
if(lenr) *lenr=m_BmpU.bmiHeader.biSizeImage;
bRet=TRUE;
RET:
return bRet;
}
void CVideoCodec::SetParent(CDialog *dlg)
{
pDlg=dlg;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -