Exemple #1
0
static HRESULT WINAPI AVICompressorIn_CheckMediaType(BasePin *base, const AM_MEDIA_TYPE *pmt)
{
    AVICompressor *This = impl_from_BasePin(base);
    VIDEOINFOHEADER *videoinfo;
    HRESULT hres;
    DWORD res;

    TRACE("(%p)->(AM_MEDIA_TYPE(%p))\n", base, pmt);
    dump_AM_MEDIA_TYPE(pmt);

    if(!IsEqualIID(&pmt->majortype, &MEDIATYPE_Video))
        return S_FALSE;

    if(!IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo)) {
        FIXME("formattype %s unsupported\n", debugstr_guid(&pmt->formattype));
        return S_FALSE;
    }

    hres = ensure_driver(This);
    if(hres != S_OK)
        return hres;

    videoinfo = (VIDEOINFOHEADER*)pmt->pbFormat;
    res = ICCompressQuery(This->hic, &videoinfo->bmiHeader, NULL);
    return res == ICERR_OK ? S_OK : S_FALSE;
}
Exemple #2
0
/* 对捕获的视频做编码、解码处理 */
void CMainFrame::OnVfwCodec()
{
	// TODO: 在此添加命令处理程序代码
	DWORD fsize;
	/* VCM initialization */
	hic1 = ICOpen(mmioFOURCC('v','i','d','c'),  mmioFOURCC('X','V','I','D'),  ICMODE_COMPRESS);
	if (hic1 == 0) 
		AfxMessageBox(_T("打开编码器失败!"));

	hic2 = ICOpen(mmioFOURCC('v','i','d','c'),  mmioFOURCC('X','V','I','D'),  ICMODE_DECOMPRESS);
	if (hic2 == 0) 
		AfxMessageBox(_T("打开解码器失败!"));

	fsize = capGetVideoFormatSize(m_hWndCap);
	capGetVideoFormat(m_hWndCap, lpbiIn, fsize);
	
	InitAVIWriteOpt();

	lpbiOut->bmiHeader.biSize          = sizeof(BITMAPINFOHEADER);
	lpbiOut->bmiHeader.biWidth         = lpbiIn->bmiHeader.biWidth;
	lpbiOut->bmiHeader.biHeight        = lpbiIn->bmiHeader.biHeight;
	lpbiOut->bmiHeader.biPlanes        = 1;
	lpbiOut->bmiHeader.biBitCount      = 24;
	lpbiOut->bmiHeader.biCompression   = BI_RGB;
	lpbiOut->bmiHeader.biSizeImage     = lpbiIn->bmiHeader.biWidth*lpbiIn->bmiHeader.biHeight*3;
	lpbiOut->bmiHeader.biXPelsPerMeter = 0;
	lpbiOut->bmiHeader.biYPelsPerMeter = 0;
	lpbiOut->bmiHeader.biClrUsed       = 0;
	lpbiOut->bmiHeader.biClrImportant  = 0;

//	get the format of the input video
	if (ICCompressGetFormat(hic1,lpbiIn,lpbiTmp)!=ICERR_OK) 
		AfxMessageBox(_T("编码器不能读取输出格式!"));
	if (ICCompressQuery(hic1,lpbiIn,lpbiTmp) != ICERR_OK)   
		AfxMessageBox(_T("不能处理编码器输入输出格式!"));

//	set the parameters of the CODEC
	pc.cbSize         = sizeof(COMPVARS);			//结构体大小
	pc.dwFlags        = ICMF_COMPVARS_VALID;
	pc.hic            = hic1;						//编码器句柄
	pc.fccType        = mmioFOURCC('v','i','d','c');
	pc.fccHandler     = mmioFOURCC('X','V','I','D');
	pc.lpbiOut        = lpbiTmp;					//输出格式
	pc.lKey           = 100;						//key帧频率
	pc.lQ             = 10000;						//图像质量

	if(!ICSeqCompressFrameStart(&pc, lpbiIn))
		return;
	ICDecompressBegin(hic2,lpbiTmp,lpbiOut);
	m_vfwState  = ENCDEC;
}
Exemple #3
0
static BOOL enum_compressors(HWND list, COMPVARS *pcv, BOOL enum_all)
{
    UINT id, total = 0;
    ICINFO icinfo;

    id = 0;

    while (ICInfo(pcv->fccType, id, &icinfo))
    {
        struct codec_info *ic;
        DWORD idx;
        HIC hic;

        id++;

        hic = ICOpen(icinfo.fccType, icinfo.fccHandler, ICMODE_COMPRESS);

        if (hic)
        {
            /* for unknown reason fccHandler reported by the driver
             * doesn't always work, use the one returned by ICInfo instead.
             */
            DWORD fccHandler = icinfo.fccHandler;

            if (!enum_all && pcv->lpbiIn)
            {
                if (ICCompressQuery(hic, pcv->lpbiIn, NULL) != ICERR_OK)
                {
                    TRACE("fccHandler %s doesn't support input DIB format %d\n",
                          wine_dbgstr_fcc(icinfo.fccHandler), pcv->lpbiIn->bmiHeader.biCompression);
                    ICClose(hic);
                    continue;
                }
            }

            ICGetInfo(hic, &icinfo, sizeof(icinfo));
            icinfo.fccHandler = fccHandler;

            idx = SendMessageW(list, CB_ADDSTRING, 0, (LPARAM)icinfo.szDescription);

            ic = HeapAlloc(GetProcessHeap(), 0, sizeof(struct codec_info));
            ic->icinfo = icinfo;
            ic->hic = hic;
            SendMessageW(list, CB_SETITEMDATA, idx, (LPARAM)ic);
        }
        total++;
    }

    return total != 0;
}
QMap<std::wstring, bool> AviCodecRestrictions::getUsableCodecs(const TDimension &resolution)
{
	QMap<std::wstring, bool> codecs;

	HIC hic = 0;
	ICINFO icinfo;
	memset(&icinfo, 0, sizeof(ICINFO));

	char descr[2048], name[2048];
	DWORD fccType = 0;

	BITMAPINFO inFmt;
	memset(&inFmt, 0, sizeof(BITMAPINFO));

	inFmt.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	inFmt.bmiHeader.biWidth = inFmt.bmiHeader.biHeight = 100;
	inFmt.bmiHeader.biPlanes = 1;
	inFmt.bmiHeader.biCompression = BI_RGB;
	int bpp;
	for (bpp = 32; (bpp >= 24); bpp -= 8) {
		//find the codec.
		inFmt.bmiHeader.biBitCount = bpp;
		for (int i = 0; ICInfo(fccType, i, &icinfo); i++) {
			hic = ICOpen(icinfo.fccType, icinfo.fccHandler, ICMODE_COMPRESS);

			ICGetInfo(hic, &icinfo, sizeof(ICINFO)); // Find out the compressor name
			WideCharToMultiByte(CP_ACP, 0, icinfo.szDescription, -1, descr, sizeof(descr), 0, 0);
			WideCharToMultiByte(CP_ACP, 0, icinfo.szName, -1, name, sizeof(name), 0, 0);

			std::wstring compressorName;
			compressorName = toWideString(std::string(name) + " '" + toString(bpp) + "' " + std::string(descr));

			if (hic) {
				if (ICCompressQuery(hic, &inFmt, NULL) != ICERR_OK) {
					ICClose(hic);
					continue; // Skip this compressor if it can't handle the format.
				}
				codecs[compressorName] = canWork(hic, resolution, bpp);
				ICClose(hic);
			}
		}
	}
	return codecs;
}
Exemple #5
0
void CAviFile::GetCompressorList( CStringList &List, BITMAPINFO &SourceBitmapInfo )
{
	///////////////////////////////////////////////////////////
	LPBITMAPINFOHEADER lpbi = 0;
	HIC hIC;
	ICINFO icinfo;

	int fccType = ICTYPE_VIDEO;	//0 to get all installed codecs
	for (int i=0; ICInfo(fccType, i, &icinfo); i++) {
		hIC = ICOpen(icinfo.fccType, icinfo.fccHandler, ICMODE_QUERY);

		if (hIC) {
			//Find out the compressor name.
			ICGetInfo(hIC, &icinfo, sizeof(icinfo));

			//Skip this compressor if it can't handle the format.
			if (fccType == ICTYPE_VIDEO )
			{
				if( icinfo.dwFlags != 0 )
				{
					if( ICCompressQuery( hIC, &SourceBitmapInfo, NULL ) == ICERR_OK )
					{
						CString Temp = CString( icinfo.szDescription );
						if( icinfo.fccHandler == 1129730893 )
							Temp += " - Low Resolution";
						Temp += " (";
						Temp.Append( (const char*)&icinfo.fccHandler, 4 ); // Assuming little endian system.
						Temp += ")";
						List.AddTail( Temp );
					}
				}
			}

			//check here whether it is the driver you want
			ICClose(hIC);
		}
	}
}
Exemple #6
0
static int vfw_start_encoder(BITMAPINFOHEADER *input_bih, BITMAPINFOHEADER *output_bih){
  HRESULT ret;
  int temp_len=output_bih->biSize;
  int i;

  ret = ICCompressGetFormat(encoder_hic, input_bih, output_bih);
  if(ret < 0){
    unsigned char* temp=(unsigned char*)output_bih;
    mp_msg(MSGT_WIN32,MSGL_ERR,"ICCompressGetFormat failed: Error %d  (0x%X)\n", (int)ret, (int)ret);
    for (i=0; i < temp_len; i++) mp_msg(MSGT_WIN32, MSGL_DBG2, "%02x ", temp[i]);
    return 0;
  }
  mp_msg(MSGT_WIN32,MSGL_V,"ICCompressGetFormat OK\n");

  if (temp_len > sizeof(BITMAPINFOHEADER))
  {
    unsigned char* temp=(unsigned char*)output_bih;
    mp_msg(MSGT_WIN32, MSGL_V, "Extra info in o_bih (%d bytes)!\n",
	temp_len-sizeof(BITMAPINFOHEADER));
    for(i=sizeof(output_bih);i<temp_len;i++) mp_msg(MSGT_WIN32, MSGL_DBG2, "%02X ",temp[i]);
  }

//  if( mp_msg_test(MSGT_WIN32,MSGL_V) ) {
    printf("Starting compression:\n");
    printf(" Input format:\n");
	printf("  biSize %ld\n", input_bih->biSize);
	printf("  biWidth %ld\n", input_bih->biWidth);
	printf("  biHeight %ld\n", input_bih->biHeight);
	printf("  biPlanes %d\n", input_bih->biPlanes);
	printf("  biBitCount %d\n", input_bih->biBitCount);
	printf("  biCompression 0x%lx ('%.4s')\n", input_bih->biCompression, (char *)&input_bih->biCompression);
	printf("  biSizeImage %ld\n", input_bih->biSizeImage);
    printf(" Output format:\n");
	printf("  biSize %ld\n", output_bih->biSize);
	printf("  biWidth %ld\n", output_bih->biWidth);
	printf("  biHeight %ld\n", output_bih->biHeight);
	printf("  biPlanes %d\n", output_bih->biPlanes);
	printf("  biBitCount %d\n", output_bih->biBitCount);
	printf("  biCompression 0x%lx ('%.4s')\n", output_bih->biCompression, (char *)&output_bih->biCompression);
	printf("  biSizeImage %ld\n", output_bih->biSizeImage);
//  }

  output_bih->biWidth=input_bih->biWidth;
  output_bih->biHeight=input_bih->biHeight;

  ret = ICCompressQuery(encoder_hic, input_bih, output_bih);
  if(ret){
    mp_msg(MSGT_WIN32,MSGL_ERR,"ICCompressQuery failed: Error %d\n", (int)ret);
    return 0;
  } else
  mp_msg(MSGT_WIN32,MSGL_V,"ICCompressQuery OK\n");

  ret = ICCompressBegin(encoder_hic, input_bih, output_bih);
  if(ret){
    mp_msg(MSGT_WIN32,MSGL_ERR,"ICCompressBegin failed: Error %d\n", (int)ret);
//    return 0;
  } else
    mp_msg(MSGT_WIN32,MSGL_V,"ICCompressBegin OK\n");
    mp_msg(MSGT_WIN32,MSGL_INFO," Output format after query/begin:\n");
    mp_msg(MSGT_WIN32,MSGL_INFO,"  biSize %ld\n", output_bih->biSize);
    mp_msg(MSGT_WIN32,MSGL_INFO,"  biWidth %ld\n", output_bih->biWidth);
    mp_msg(MSGT_WIN32,MSGL_INFO,"  biHeight %ld\n", output_bih->biHeight);
    mp_msg(MSGT_WIN32,MSGL_INFO,"  biPlanes %d\n", output_bih->biPlanes);
    mp_msg(MSGT_WIN32,MSGL_INFO,"  biBitCount %d\n", output_bih->biBitCount);
    mp_msg(MSGT_WIN32,MSGL_INFO,"  biCompression 0x%lx ('%.4s')\n", output_bih->biCompression, (char *)&output_bih->biCompression);
    mp_msg(MSGT_WIN32,MSGL_INFO,"  biSizeImage %ld\n", output_bih->biSizeImage);

  encoder_buf_size=input_bih->biSizeImage;
  encoder_buf=malloc(encoder_buf_size);
  encoder_frameno=0;

  mp_msg(MSGT_WIN32,MSGL_V,"VIDEO CODEC Init OK!!! ;-)\n");
  return 1;
}
Exemple #7
0
int AVInfo::GetCodecListSize(int width, int height)
{
    if (m_plCodecList)
    {
        for (int i=0; i<m_codecListSize; ++i)
            delete m_plCodecList[i];
        delete[] m_plCodecList;
        m_plCodecList = NULL;
        m_codecListSize = 0;
    }

    BITMAPINFO bmi;
    Make24BitRGB(&bmi.bmiHeader, width, height);

    ICINFO icInfo;
    ZeroMemory(&icInfo, sizeof ICINFO);
    icInfo.dwSize = sizeof ICINFO;
    int count = 0;

    std::vector<CODECINFO *> codecList;

    // The first codec is always uncompressed RGB
    // data. We can be sure this is the case here
    CODECINFO *pInfo = new CODECINFO;
    pInfo->fcc = MAKEFOURCC('D', 'I', 'B', ' ');
    pInfo->alternativeFcc = BI_RGB;
    pInfo->bHasAboutDialog = false;
    pInfo->bHasConfigureDialog = false;
    pInfo->bSupportsKeyframes = false;
    pInfo->bSupportsQuality = false;
    pInfo->nDefaultKeyframeRate = 1;
    pInfo->nDefaultQuality = 100;
    _tcscpy(pInfo->tszDescription, _T("DIB : <uncompressed>"));
    codecList.push_back(pInfo);

    while (ICInfo(ICTYPE_VIDEO, count, &icInfo))
    {
        HIC hic = ICOpen(icInfo.fccType, icInfo.fccHandler, ICMODE_QUERY);
        if (hic)
        {
            ICINFO moreInfo;
            ZeroMemory(&moreInfo, sizeof ICINFO);
            moreInfo.dwSize = sizeof ICINFO;

            if (ICGetInfo(hic, &moreInfo, sizeof ICINFO) > 0)
            {
                // Ignore MSVC/CRAM
                if (moreInfo.fccHandler != 'CVSM' &&
                        moreInfo.fccHandler != 'MARC')
                {
                    if (ICERR_OK == ICCompressQuery(hic, &bmi, NULL))
                    {
                        // Ok, this codec seems to be ok; put that
                        // into the list
                        CODECINFO *pInfo = new CODECINFO;
                        ZeroMemory(pInfo, sizeof CODECINFO);

                        char szFcc[5];
                        if (moreInfo.fccHandler != BI_RGB)
                        {
                            szFcc[0] = (moreInfo.fccHandler & 0x000000ff);
                            szFcc[1] = (moreInfo.fccHandler & 0x0000ff00) >> 8;
                            szFcc[2] = (moreInfo.fccHandler & 0x00ff0000) >> 16;
                            szFcc[3] = (moreInfo.fccHandler & 0xff000000) >> 24;
                            szFcc[4] = 0;
                        }
                        else
                            strcpy(szFcc, "DIB ");

                        bool bIsReallyOk = true;

                        // We know that IV50 has restrictions.
                        if (moreInfo.fccHandler == '05vi' ||
                                moreInfo.fccHandler == '05VI')
                        {
                            if (width % 4 != 0 ||
                                    height % 4 != 0)
                                bIsReallyOk = false;
                        }

                        // The following code should normally check if the codec
                        // is really able encode a certain BITMAPINFO type. But,
                        // This will fail for the HuffYUV codec. Thus, we have to
                        // assume that it might fail for other codecs, too.
                        /*
                        if (moreInfo.fccHandler == BI_RGB)
                        {
                           bIsReallyOk = true;
                        }
                        else
                        {
                           // The codec says that the input format is ok.
                           // Let's try to create an output format and try
                           // again. For some resolutions, e.g. Indeo Video 5
                           // now fails to compress the format.
                           AM_MEDIA_TYPE mtTmp;
                           ZeroMemory(&mtTmp, sizeof AM_MEDIA_TYPE);
                           bool cool = CreateStreamFormat(moreInfo.fccHandler, width, height, &mtTmp);

                           if (cool)
                           {
                              BITMAPINFO bmiOut;
                              ZeroMemory(&bmiOut, sizeof BITMAPINFO);
                              bmiOut.bmiHeader = ((VIDEOINFOHEADER *) mtTmp.pbFormat)->bmiHeader;
                              DWORD dwOk = ICCompressBegin(hic, &bmi, &bmiOut);
                              if (ICERR_OK == dwOk)
                              {
                                 // It's really ok to use this codec.
                                 bIsReallyOk = true;
                                 ICCompressEnd(hic);
                              }
                           }

                           FreeMediaType(mtTmp);
                        }
                        */

                        if (bIsReallyOk)
                        {
                            // Copy the name
#ifndef _UNICODE
                            _TCHAR tszDesc[128];
                            if (WideCharToMultiByte(CP_ACP, 0, moreInfo.szDescription, -1, tszDesc, 128, NULL, NULL) == 0)
                                strcpy(tszDesc, "<unknown>");
                            sprintf(pInfo->tszDescription, "(%s): %s", szFcc, tszDesc);
#else
                            _stprintf(pInfo->tszDescription, _T("(%S): %s"), szFcc, moreInfo.szDescription);
#endif

                            pInfo->fcc = moreInfo.fccHandler;
                            pInfo->alternativeFcc = icInfo.fccHandler;
                            pInfo->bSupportsKeyframes = (moreInfo.dwFlags & VIDCF_TEMPORAL) > 0;
                            pInfo->bSupportsQuality = (moreInfo.dwFlags & VIDCF_QUALITY) > 0;
                            if (pInfo->bSupportsKeyframes)
                                pInfo->nDefaultKeyframeRate = ICGetDefaultKeyFrameRate(hic);
                            else
                                pInfo->nDefaultKeyframeRate = 0;
                            if (pInfo->bSupportsQuality)
                                pInfo->nDefaultQuality = ICGetDefaultQuality(hic) / 100;
                            else
                                pInfo->nDefaultQuality = 0;

                            pInfo->bHasConfigureDialog = ICQueryConfigure(hic) == TRUE ? true : false;
                            pInfo->bHasAboutDialog = ICQueryAbout(hic) == TRUE ? true : false;

                            codecList.push_back(pInfo);
                        }
                    }
                }
            }
int
PGRAviFile::enumerateCompressors( int  iRows, int iCols, int iBPP, 
                                  ICINFO* picinfo, int iNumICInfo )
{
   // If picinfo is NULL, then we are retreiving the number of
   // usable compressors at the current settings so we can allocate
   // enough memory.
   bool bpicinfoNull = picinfo == NULL;

   ICINFO* picinfoTemp = new ICINFO[ 50 ];

   HIC hic;
   
   BITMAPINFOHEADER bih; 
   
   // Initialize the bitmap structure. 
   bih.biSize          = sizeof( BITMAPINFOHEADER );
   bih.biPlanes        = 1;
   bih.biCompression   = BI_RGB;
   bih.biXPelsPerMeter = 100;
   bih.biYPelsPerMeter = 100;
   bih.biClrUsed       = 0;
   bih.biClrImportant  = 0;
   bih.biWidth         = iCols;
   bih.biHeight        = iRows;
   bih.biBitCount      = (unsigned short)iBPP;
   
   bih.biSizeImage = 
      bih.biWidth * bih.biHeight * ( bih.biBitCount / 8 );

   int  iNumCompressors = 0;
   bool bICInfoFull     = false;
   
   for( int i = 0; ICInfo( 0, i, &picinfoTemp[ i ] ) && !bICInfoFull; i++ ) 
   { 
      // Open the compressor so we can query it.
      hic = ICOpen( picinfoTemp[ i ].fccType, 
         picinfoTemp[ i ].fccHandler, ICMODE_QUERY ); 
      
      if( hic ) 
      { 
         // Skip this compressor if it can't handle the format. 
         if( ICCompressQuery( hic, &bih, 0 ) != ICERR_OK ) 
         { 
            ICClose( hic ); 
            continue; 
         } 
         
         // Find out the compressor info. 
         if( !bpicinfoNull )
         {
            ICGetInfo( hic, &picinfo[ iNumCompressors ], sizeof( ICINFO ) );
         }

         iNumCompressors++;

         if( !bpicinfoNull && (iNumCompressors == iNumICInfo) )
         {
            bICInfoFull = true;
         }
         
         // Close the compressor.
         ICClose( hic ); 
      } 
   } 

   delete [] picinfoTemp;

   return iNumCompressors;
}
void AviCodecRestrictions::getRestrictions(const std::wstring &codecName, QString &restrictions)
{
	restrictions.clear();
	if (codecName == L"Uncompressed") {
		restrictions = QObject::tr("No restrictions for uncompressed avi video");
		return;
	}
	//find the codec
	int bpp;
	HIC hic = getCodec(codecName, bpp);
	if (!hic) {
		restrictions = QObject::tr("It is not possible to communicate with the codec.\n Probably the codec cannot work correctly.");
		return;
	}

	BITMAPINFO bi;
	bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	bi.bmiHeader.biPlanes = 1;
	bi.bmiHeader.biCompression = BI_RGB;
	bi.bmiHeader.biXPelsPerMeter = 80;
	bi.bmiHeader.biYPelsPerMeter = 72;
	bi.bmiHeader.biClrUsed = 0;
	bi.bmiHeader.biClrImportant = 0;

	int lx = 640, ly = 480;
	bi.bmiHeader.biWidth = lx;
	bi.bmiHeader.biHeight = ly;

	// Loop until we can find a width, height, and depth that works!
	int i;

	// check the x lenght
	bi.bmiHeader.biBitCount = bpp;
	for (i = 3; i >= 0; i--) {
		bi.bmiHeader.biWidth = lx + (1 << i);
		bi.bmiHeader.biSizeImage = ((bi.bmiHeader.biWidth * bi.bmiHeader.biBitCount + 31) / 32) * 4 * ly;

		if (ICERR_OK != ICCompressQuery(hic, &bi.bmiHeader, NULL))
			break;
	}
	if (i >= 0)
		restrictions = QObject::tr("video width must be a multiple of %1").arg(QString::number(1 << (i + 1)));

	// check the y lenght
	bi.bmiHeader.biWidth = 640;
	for (i = 3; i >= 0; i--) {
		bi.bmiHeader.biHeight = ly + (1 << i);
		bi.bmiHeader.biSizeImage = ((lx * bi.bmiHeader.biBitCount + 31) / 32) * 4 * bi.bmiHeader.biHeight;

		if (ICERR_OK != ICCompressQuery(hic, &bi.bmiHeader, NULL))
			break;
	}
	if (i >= 0)
		restrictions = restrictions + "\n" + QObject::tr("video lenght must be a multiple of %1").arg(QString::number(1 << (i + 1)));

	ICClose(hic);

	if (restrictions.isEmpty())
		restrictions = QObject::tr("No restrictions for this codec");
	else
		restrictions.prepend(QObject::tr("Resolution restrictions:") + "\n");
}