⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cvidc.cpp

📁 一个不错的视频压缩源码
💻 CPP
字号:
// CVIDC.CPP
// VIDEO CODEC MANAGER
//
//
// (c)V.Gorbatenko	1996-2000
// All rights reserved
// gvv@mail.tomsknet.ru
//C++ Builder ported by Ismael Bamba ismail.b@mangoosta.net

#include "cvidc.h"
#include "Vfw.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

//------------------------------------------------------------------------------
 tagString::tagString(void)
 {
 }

 tagString::tagString(tagString& a)
 {
  str_=a.str_;
 }

 tagString::tagString(const char* s)
 {
  str_=s;
 }

 tagString::tagString(const AnsiString& s)
 {
  str_=s;
 }

 tagString::~tagString(void)
 {
 }

 tagString::operator const char* ()const
 {
  return str_.c_str();
 }

 tagString::operator char* ()const
 {
  return str_.c_str();
 }

 BOOL operator ==(tagString a,tagString b)
 {
   return (a.str_==b.str_);
 }

 BOOL tagString::operator ==(const char* s)
 {
  AnsiString rhs=s;
  return (str_==rhs);
 }

 const char* tagString::c_str(void)const
 {
  return str_.c_str();
 }

 void tagString::operator =(const char* s)
 {
  str_=s;
 }

 void tagString::operator =(const AnsiString& s)
 {
  str_=s;
 }

 void tagString::Format(char* szFormat,...) //FIXME
 {
  char szBuffer[256]={'\0'};
  char *pArguments;
  pArguments=(char*)&szFormat+sizeof(szFormat);
  wvsprintf(szBuffer,szFormat,pArguments);
  TVarRec v[] = { szBuffer };
  str_=::Format("%s", v, ARRAYSIZE(v) - 1);
 }
//------------------------------------------------------------------------------
//misc
float	AE24(BYTE *buf1, BYTE *buf2, int cx, int cy)
{
	unsigned long sumdR=0;
	unsigned long sumdG=0;
	unsigned long sumdB=0;
	unsigned long sumR=0;
	unsigned long sumG=0;
	unsigned long sumB=0;
	int	cn = cx*cy;
	
	for(int i=0; i<cn;i++,buf1+=3,buf2+=3)
	{
		sumdR+=abs((int)buf1[0] - (int)buf2[0]);
		sumdG+=abs((int)buf1[1] - (int)buf2[1]);
		sumdB+=abs((int)buf1[2] - (int)buf2[2]);
		sumR+=buf1[0];
		sumG+=buf1[1];
		sumB+=buf1[2];

	}
	float	errR =  (float)sumdR/(float)sumR;
	float	errG =  (float)sumdG/(float)sumG;
	float	errB =  (float)sumdB/(float)sumB;

	return 100.0f*(errR + errG + errB)/3;

}

float	AE32(BYTE *buf1, BYTE *buf2, int cx, int cy)
{
	unsigned long sumdR=0;
	unsigned long sumdG=0;
	unsigned long sumdB=0;
	unsigned long sumR=0;
	unsigned long sumG=0;
	unsigned long sumB=0;
	int	cn = cx*cy;
	
	for(int i=0; i<cn;i++,buf1+=4,buf2+=4)
	{
		sumdR+=abs((int)buf1[0] - (int)buf2[0]);
		sumdG+=abs((int)buf1[1] - (int)buf2[1]);
		sumdB+=abs((int)buf1[2] - (int)buf2[2]);
		sumR+=buf1[0];
		sumG+=buf1[1];
		sumB+=buf1[2];

	}
	float	errR =  (float)sumdR/(float)sumR;
	float	errG =  (float)sumdG/(float)sumG;
	float	errB =  (float)sumdB/(float)sumB;
	
	return 100.0f*(errR + errG + errB)/3;

}
//------------------------------------------------------------------------------
LPCSTR	_Wstr2Mstr(LPCWSTR InStr);
int		_fstr(CStringArray &str, LPCSTR);


/////////////////////////////////////////////
LPCSTR _Wstr2Mstr(LPCWSTR InStr)
{

	static char OutStr[256];

	WideCharToMultiByte(	CP_ACP,
 			WC_COMPOSITECHECK|WC_DEFAULTCHAR, 
 			InStr, 
 			-1, 
 			OutStr, 
 			256, 
 			NULL, 
 			NULL);
	return 	   OutStr;
}

int	_fstr(CStringArray &str, LPCSTR s)
{
	for(int i=0;i<str.GetSize();i++)
		if(str[i]==s)	return i;
	return -1;
}


////////////////////////////////////////////
// CVidc	class	implementation
//
CVidc::CVidc()
{
	_selfInit();
}


CVidc::~CVidc()
{
	Close();
}

//static method
LPSTR	CVidc::GetCompressorName(DWORD dwfccOut)
{
	//open
	HIC hic = ICOpen(ICTYPE_VIDEO, dwfccOut,  ICMODE_QUERY);
 	if(!hic)	return NULL;

	ICINFO icinfo;
    
	//get info
	ICGetInfo(hic, &icinfo, sizeof(icinfo));
    
	//convert "info"
    LPSTR ret= (LPSTR)_Wstr2Mstr(icinfo.szDescription);
	
	ICClose(hic);
	return ret;
}

BOOL	CVidc::OpenCompressor(DWORD dwfccOut, BOOL fQuery)
{
		

		DWORD mode;

		if(fQuery)
		
			mode=ICMODE_QUERY;
		
		else
		
			mode=ICMODE_FASTCOMPRESS; //Although,  i've found no diff's with ICMODE_COMPRESS!!! :-)
		

		if(m_hIC)	
			if( mode==m_dwMode && m_dwFcc==dwfccOut)
				return TRUE;
			else	return FALSE;
	
	    m_dwMode=0;
		m_dwFcc =0;
	
	    m_hIC = ICOpen(ICTYPE_VIDEO, dwfccOut, mode);
	
		if(m_hIC)
		{
		 _getName();
			m_dwMode=mode;			// actual mode
				m_dwFcc=dwfccOut;	// actual fcc
		}
	
	return (BOOL)m_hIC;
}

BOOL	CVidc::OpenDecompressor(DWORD fcc)
{

	
	DWORD mode=ICMODE_FASTDECOMPRESS; //same note as for OpenCompressor!
	
	//is already opened?
	if(m_hIC)	
		if(mode==m_dwMode&&m_dwFcc==fcc)
			return TRUE;
				else	return FALSE;
	
	    	m_dwMode=0;
			m_dwFcc =0;
	
	    m_hIC = ICOpen(ICTYPE_VIDEO, fcc, mode);
	
	if(m_hIC) {
				_getName();
				m_dwMode=mode;
				m_dwFcc=fcc;
				}
		
		return (BOOL)m_hIC;

}

BOOL	CVidc::OpenDecompressor(LPBITMAPINFOHEADER lpInputBmp)
{

		ICINFO icinfo;
		if(!lpInputBmp||m_hIC)	return FALSE;
		
		//walk over all codecs, find desired 
		for (int i=0; ICInfo(ICTYPE_VIDEO, i, &icinfo); i++)
		{
		m_hIC=ICLocate(icinfo.fccType, icinfo.fccHandler, lpInputBmp, 
			NULL, ICMODE_FASTDECOMPRESS);
	
			if (m_hIC) {
				//this one!
	    		_getName();
	    		m_dwMode=ICMODE_FASTDECOMPRESS;
	    		m_dwFcc=icinfo.fccHandler;
	    		return TRUE;}
		}	
		return FALSE;

}

/////////////////////////////////////////////////////////////
#define DibPtr(lpbi)            (LPBYTE)(DibColors(lpbi) + (UINT)(lpbi)->biClrUsed)
#define DibColors(lpbi)         ((LPRGBQUAD)((LPBYTE)(lpbi) + (int)(lpbi)->biSize))

int DIBNumColors (LPBITMAPINFOHEADER lpbi)
{
      if (lpbi->biClrUsed)
         return (int)lpbi->biClrUsed;
   switch (lpbi->biBitCount)
      {
      case 1:
         return 2;
      case 4:
         return 16;
      case 8:
         return 256;
      default:
         return 0;	//16,24,32 bits bitmap has no color table
      }
}

// static
// Just a small service
LPBYTE	CVidc::LockDIB(HDIB dib, LPBITMAPINFO *lpBI)
{
	if(!dib)	return NULL;
    *lpBI=(LPBITMAPINFO)GlobalLock(dib);
	LPBITMAPINFOHEADER  lpBIF=(LPBITMAPINFOHEADER)(*lpBI);
    return	DibPtr(lpBIF);
}
HDIB	CVidc::UnlockDIB(HDIB hdib)
{
	if(!hdib)	return NULL;
    while(GlobalUnlock(hdib));
    return	hdib;
}
///
#define WIDTHBYTES(bits)        (((bits) + 31) / 32 * 4)
#define IM_SBI_RB(lpbi)			(WIDTHBYTES(((LPBITMAPINFOHEADER)lpbi)->biWidth * ((LPBITMAPINFOHEADER)lpbi)->biBitCount)*((LPBITMAPINFOHEADER)lpbi)->biHeight)
#define IM_S(lpbi)	((LPBITMAPINFOHEADER)lpbi)->biCompression == BI_RGB ?\
					IM_SBI_RB(lpbi) :((LPBITMAPINFOHEADER)lpbi)->biSizeImage

HDIB	CVidc::Compress(LPBITMAPINFO lpInBmp,LPBYTE lpData, BOOL bUse_any)
{
	

	if(!m_hIC) return FALSE;
	if( m_dwMode!=ICMODE_FASTCOMPRESS&&
	    m_dwMode!=ICMODE_COMPRESS)	
	   	return FALSE;
	if(!lpInBmp||!lpData)	return FALSE;
	
	HDIB retd;

	m_dwMode=ICMODE_COMPRESS;
	
	if(!bUse_any) 
	{
		retd =  (HDIB)ICImageCompress(
                            m_hIC,			// compressor to use (this!)
                            0,
                            lpInBmp, 		// format to compress from
                            lpData,  		// bits to compress
                            NULL,           // output format (default)
                            100*m_iCompressionQuality,  // quality to use.
                            NULL);          // size of output (whatever)

	}
	else
	{
	//Let ICM to select codec...
	retd =(HDIB)ICImageCompress(
                            NULL,		// Any codec!
                            0,          
                            lpInBmp, 	// format to compress from
                            lpData,  	// bits to compress
                            NULL,       // output format (default)
                            100*m_iCompressionQuality,// quality to use (0-10000)
                            NULL);		// size of output (whatever)
	}
	
	if(!retd)	
	{// strange things...

       //iba	TRACE("WARNING! Compression with %s failed. preforms direct copy",GetName());
	return NULL;

	}

	return retd;		
}

////
HDIB	CVidc::Decompress(LPBITMAPINFO lpInputBmp,
						  LPBITMAPINFO lpOutputBmp, 
						  LPBYTE lpInputBits)
{

	if( m_dwMode!=ICMODE_FASTDECOMPRESS&&
	    m_dwMode!=ICMODE_DECOMPRESS)	

		return NULL;

	if(((LPBITMAPINFOHEADER)lpInputBmp)->biCompression == BI_RGB)

		return NULL;
	
	if(!lpInputBmp||!lpInputBits)	
		
		return NULL;
	
	HDIB retd;
	
    retd = (HDIB)ICImageDecompress(
                            m_hIC,          // codec to use
                            0,				// codec flags
                            lpInputBmp,		// format to decompress from
                            lpInputBits,	// bits to decompress
                            lpOutputBmp);	// format to compress to.

	if(retd )	
		return retd;
	else
	//Let ICM to select codec...
	retd = (HDIB)ICImageDecompress(
                            NULL,			// Any codec!
                            0,				// codec flags
                            lpInputBmp,		// format to decompress from
                            lpInputBits,	// bits to decompress
                            NULL);			// format to compress to (any!).
  return retd;		

}

//Other version for decompressing with "key frames"
BOOL	CVidc::DecompressEx(LPBITMAPINFO lpInputBmp, LPBYTE lpInputBits, 
							LPBITMAPINFO lpOutputBmp, LPBYTE lpOutputBits, DWORD dwFlags)
{
	if( m_dwMode!=ICMODE_FASTDECOMPRESS&&
	    m_dwMode!=ICMODE_DECOMPRESS)	

		return FALSE;

	if(((LPBITMAPINFOHEADER)lpInputBmp)->biCompression == BI_RGB)

		return FALSE;
	
	if( !lpInputBmp|| !lpInputBits ||
		!lpOutputBmp || !lpOutputBits)	
		
		return FALSE;
	return ICDecompressEx(	m_hIC,
							dwFlags,
							(LPBITMAPINFOHEADER)lpInputBmp,
							lpInputBits,
							0,
							0,
							((LPBITMAPINFOHEADER)lpInputBmp)->biHeight,  
							((LPBITMAPINFOHEADER)lpInputBmp)->biWidth,   
							(LPBITMAPINFOHEADER) lpOutputBmp,  
							lpOutputBits,                
							0,                    
							0,                    
							((LPBITMAPINFOHEADER)lpInputBmp)->biHeight,
							((LPBITMAPINFOHEADER)lpInputBmp)->biWidth) == ICERR_OK;                    

}

VOID	CVidc::Close()
{
	if(m_hIC)
			ICClose(m_hIC);
	//clean up manager state
	_selfInit();
}

BOOL	CVidc::SetProgressCallback(LONG lParam, VOID *cb)
{
	if(!m_hIC)	return FALSE;
	return ICSetStatusProc(m_hIC, 0, 
		lParam, (long(__stdcall *)(long,unsigned int,long))cb)==ICERR_OK;
}


//static
//Fill string array with installed codecs names
BOOL	CVidc::EnumCodecs(CStringArray &names, 
						  CDWordArray &fcc, 
						  CDWordArray &QualitySupport)
{
	HIC hic;
	ICINFO icinfo;
	
	names.RemoveAll( );
	 fcc.RemoveAll( );
	  QualitySupport.RemoveAll();

	for (int i=0; ICInfo(ICTYPE_VIDEO, i, &icinfo); i++)
	{
    hic = ICOpen(icinfo.fccType, icinfo.fccHandler, ICMODE_QUERY);

     if (hic)
     {
        // find out the compressor name.
        ICGetInfo(hic, &icinfo, sizeof(icinfo));
        DWORD sup=icinfo.dwFlags&VIDCF_QUALITY;
        // add codec name to the list
        LPCSTR	my=_Wstr2Mstr(icinfo.szDescription);
	
        int ff=_fstr(names, my);
		if(ff!=-1)
		{//remove duplicate
		 names.RemoveAt( ff);
		  fcc.RemoveAt( ff);
			QualitySupport.RemoveAt( ff);
		}

     names.Add(my);
	  fcc.Add(icinfo.fccHandler);
	   QualitySupport.Add(sup);
    	ICClose(hic);
     }
	}//end loop

	return (BOOL)fcc.GetSize();
}


BOOL	CVidc::QueryAboutDlg()
{
		if(!m_hIC)	return FALSE;
		// WARNING! Here is a mistake in SDK documentaion!
		// This macro returns TRUE/FALSE instead of ICERR_OK/ICERR_UNSUPPORTED 
		// see also definition in "VFW.H"
		return ICQueryAbout(m_hIC);
}

BOOL	CVidc::QueryConfigDlg()
{
		if(!m_hIC)	return FALSE;
		// WARNING! Here is a mistake in SDK documentaion!
		// This macro returns TRUE/FALSE instead of ICERR_OK/ICERR_UNSUPPORTED 
		// see also definition in "VFW.H"
		return ICQueryConfigure(m_hIC);
}


BOOL	CVidc::QueryCompressInputFormat(LPBITMAPINFOHEADER   lpInputBmp)
{
	if(!m_hIC) return FALSE;
	if( m_dwMode==ICMODE_FASTDECOMPRESS||
	    m_dwMode==ICMODE_DECOMPRESS)
	   	return FALSE;

	return ICCompressQuery(m_hIC, lpInputBmp, NULL)==ICERR_OK;
}

BOOL	CVidc::AboutDlg(HWND hwnd)
{
	if(!m_hIC)	return FALSE;
	return ICAbout(m_hIC, hwnd) == ICERR_OK;
}

BOOL	CVidc::ConfigDlg(HWND hParentWnd)
{
	if(!m_hIC)	return FALSE;
	
	if(ICConfigure(m_hIC, hParentWnd)==ICERR_OK){
			m_iCompressionQuality=ICGetDefaultQuality(m_hIC)/1000;
			return TRUE;
	}
	return FALSE;
}

///////////////////// PROTECTED ////////////////////////////////
HIC	CVidc::_open4Query(int Indx)
{

	ICINFO icinfo;
	if(!ICInfo(ICTYPE_VIDEO, Indx, &icinfo))
				return FALSE;
    return ICOpen(icinfo.fccType, icinfo.fccHandler, ICMODE_QUERY);
}

void CVidc::_selfInit()
{
 	m_dwMode	= 0;
	m_dwFcc		= BI_RGB;
	m_hIC		= NULL;
	m_Name		= "";
	m_iCompressionQuality	= 100;//maximum
}

void	CVidc::_getName()
{
		ICINFO icinfo;
        ICGetInfo(m_hIC, &icinfo, sizeof(icinfo));
        
		m_Name=_Wstr2Mstr(icinfo.szDescription);
		m_dwFcc=icinfo.fccHandler;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -