static void test_ICInfo(void) { ICINFO info, info2; DWORD i, found; unsigned char *fcc; for (i = found = 0; ICInfo(0, i, &info); i++) { trace("Codec name: %s, fccHandler: 0x%08x\n", wine_dbgstr_w(info.szName), info.fccHandler); ok(info.fccType, "expected nonzero fccType\n"); ok(ICInfo(info.fccType, info.fccHandler, &info2), "ICInfo failed on fcc 0x%08x\n", info.fccHandler); fcc = (unsigned char *)&info.fccHandler; if (!isalpha(fcc[0])) continue; found++; /* Test getting info with a different case - bug 41602 */ fcc[0] ^= 0x20; ok(ICInfo(info.fccType, info.fccHandler, &info2), "ICInfo failed on fcc 0x%08x\n", info.fccHandler); } ok(found != 0, "expected at least one codec\n"); memset(&info, 0, sizeof(info)); ok(!ICInfo(ICTYPE_VIDEO, mmioFOURCC('f','a','k','e'), &info), "expected failure\n"); ok(info.fccType == ICTYPE_VIDEO, "got 0x%08x\n", info.fccType); ok(info.fccHandler == mmioFOURCC('f','a','k','e'), "got 0x%08x\n", info.fccHandler); }
void CPgPubExtra::FillCodecs() { m_comboCodec.ResetContent(); m_codecs.Destroy(); BITMAPINFOHEADER bih; ZeroMemory( &bih, sizeof( bih ) ); bih.biSize = sizeof( bih ); bih.biPlanes = 1; bih.biCompression = BI_RGB; bih.biBitCount = 24; ICINFO ii; ZeroMemory( &ii, sizeof( ii ) ); ii.dwSize = sizeof( ii ); for ( DWORD i = 0; ICInfo( ICTYPE_VIDEO, i, &ii ); i++ ) { // This one is valid DWORD fourCC = ii.fccHandler; HIC hIc = ICOpen( ii.fccType, ii.fccHandler, ICMODE_QUERY ); if ( hIc != NULL ) { // Ensure it supports our video type if ( ii.fccType == ICTYPE_VIDEO && // ICCompressQuery( hIc, &bih, NULL ) == ICERR_OK && ICGetInfo( hIc, &ii, sizeof( ii ) ) ) { char str[ 256 ] = { 0 }; wcstombs( str, ii.szDescription, sizeof( str ) ); // Save codec info LPCODECINFO pci = (LPCODECINFO)m_codecs.NewObj( sizeof( CODECINFO ), NULL, i, str ); if ( pci != NULL ) { // Save data pci->bConfig = ICQueryConfigure( hIc ) != ICERR_OK; // Backwards??? pci->fourCC = fourCC; // Get settings int item = m_comboCodec.AddString( str ); if ( item != CB_ERR ) m_comboCodec.SetItemData( item, (DWORD)pci ); } // end if } // end if ICClose( hIc ); } // end if // Next codec ZeroMemory( &ii, sizeof( ii ) ); ii.dwSize = sizeof( ii ); i++; } // end while }
/*********************************************************************** * ICGetInfo [MSVFW32.@] */ LRESULT VFWAPI ICGetInfo(HIC hic, ICINFO *picinfo, DWORD cb) { LRESULT ret; WINE_HIC* whic = MSVIDEO_GetHicPtr(hic); TRACE("(%p,%p,%d)\n", hic, picinfo, cb); if (!whic) return ICERR_BADHANDLE; if (!picinfo) return MMSYSERR_INVALPARAM; /* (WS) The field szDriver should be initialized because the driver * is not obliged and often will not do it. Some applications, like * VirtualDub, rely on this field and will occasionally crash if it * goes uninitialized. */ if (cb >= sizeof(ICINFO)) picinfo->szDriver[0] = '\0'; ret = ICSendMessage(hic, ICM_GETINFO, (DWORD_PTR)picinfo, cb); /* (WS) When szDriver was not supplied by the driver itself, apparently * Windows will set its value equal to the driver file name. This can * be obtained from the registry as we do here. */ if (cb >= sizeof(ICINFO) && picinfo->szDriver[0] == 0) { ICINFO ii; memset(&ii, 0, sizeof(ii)); ii.dwSize = sizeof(ii); ICInfo(picinfo->fccType, picinfo->fccHandler, &ii); lstrcpyW(picinfo->szDriver, ii.szDriver); } return ret; }
static bool DetectDriver(const char *pszName) { char szDriverANSI[256]; ICINFO info = { sizeof(ICINFO) }; for(int i=0; ICInfo(ICTYPE_VIDEO, i, &info); ++i) { if (WideCharToMultiByte(CP_ACP, 0, info.szDriver, -1, szDriverANSI, sizeof szDriverANSI, NULL, NULL) && !_stricmp(szDriverANSI, pszName)) return true; } return false; }
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; }
/*********************************************************************** * ICInfo [MSVIDEO.200] */ BOOL16 VFWAPI ICInfo16(DWORD fccType, DWORD fccHandler, ICINFO16 *lpicinfo) { BOOL16 ret; LPVOID lpv; DWORD lParam = (DWORD)lpicinfo; DWORD size = ((ICINFO*)(MapSL((SEGPTR)lpicinfo)))->dwSize; /* Use the mapping functions to map the ICINFO structure */ lpv = MSVIDEO_MapMsg16To32(ICM_GETINFO, &lParam, &size); ret = ICInfo(fccType, fccHandler, (ICINFO*)lParam); MSVIDEO_UnmapMsg16To32(ICM_GETINFO, lpv, &lParam, &size); return ret; }
void EnumVCM(bool bEnc) { ICINFO info; char buf[256]; for (int i = 0; ICInfo(ICTYPE_VIDEO, i, &info); i++) { HIC hic = ICOpen(ICTYPE_VIDEO, info.fccHandler, bEnc ? ICMODE_COMPRESS : ICMODE_DECOMPRESS); if (hic == NULL) continue; ICGetInfo(hic, &info, sizeof(info)); ICClose(hic); wsprintf(buf, "VCM\t%d\t%S\t%c%c%c%c\n", bEnc, info.szDescription, FCC4PRINTF(info.fccHandler)); printf("%s", buf); } }
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; }
int LBXGL_CodecVFW_Init() { LBXGL_VidCodec *codec; ICINFO *info; int i, j; short *sw; char buf[256]; char *t; printf("VFW: Init\n"); codec=LBXGL_VidCodec_New(); codec->begin_decompress=&vfw_begin_decompress; PDGL_RegisterShutdown(&vfw_shutdown); #if 1 info=malloc(sizeof(ICINFO)); memset(info, 0, sizeof(ICINFO)); for(i=0; i<1024; i++) { // info->dwSize=sizeof(ICINFO); j=ICInfo(0, i, info); if(j!=1)break; // kprint("%d: %d %p\n", i, j, info); // kprint("dwSize: %d (%d)\n", info->dwSize, sizeof(ICINFO)); printf("fccType: %04.4s\n", &info->fccType); printf("fccHandler: %04.4s\n", &info->fccHandler); // kprint("dwFlags: %d\n", info->dwFlags); if(info->szName[0]) printf("szName: %S\n", info->szName); if(info->szDescription[0]) printf("szDescription: %S\n", info->szDescription); } #endif return(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); } } }
static void register_vfw_codecs(void) { WCHAR avico_clsid_str[CHARS_IN_GUID]; HKEY basekey, key; ICINFO icinfo; DWORD i, res; static const WCHAR CLSIDW[] = {'C','L','S','I','D',0}; static const WCHAR FccHandlerW[] = {'F','c','c','H','a','n','d','l','e','r',0}; static const WCHAR FriendlyNameW[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0}; StringFromGUID2(&CLSID_AVICo, avico_clsid_str, sizeof(avico_clsid_str)/sizeof(WCHAR)); basekey = open_special_category_key(&CLSID_VideoCompressorCategory, TRUE); if(!basekey) { ERR("Could not create key\n"); return; } for(i=0; ICInfo(FCC('v','i','d','c'), i, &icinfo); i++) { WCHAR fcc_str[5] = {LOBYTE(LOWORD(icinfo.fccHandler)), HIBYTE(LOWORD(icinfo.fccHandler)), LOBYTE(HIWORD(icinfo.fccHandler)), HIBYTE(HIWORD(icinfo.fccHandler))}; res = RegCreateKeyW(basekey, fcc_str, &key); if(res != ERROR_SUCCESS) continue; RegSetValueExW(key, CLSIDW, 0, REG_SZ, (const BYTE*)avico_clsid_str, sizeof(avico_clsid_str)); RegSetValueExW(key, FccHandlerW, 0, REG_SZ, (const BYTE*)fcc_str, sizeof(fcc_str)); RegSetValueExW(key, FriendlyNameW, 0, REG_SZ, (const BYTE*)icinfo.szName, (strlenW(icinfo.szName)+1)*sizeof(WCHAR)); /* FIXME: Set ClassManagerFlags and FilterData values */ RegCloseKey(key); } RegCloseKey(basekey); }
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; }
/*********************************************************************** * ICOpen [MSVFW32.@] * Opens an installable compressor. Return special handle. */ HIC VFWAPI ICOpen(DWORD fccType, DWORD fccHandler, UINT wMode) { WCHAR codecname[10]; ICOPEN icopen; HDRVR hdrv; WINE_HIC* whic; static const WCHAR drv32W[] = {'d','r','i','v','e','r','s','3','2','\0'}; reg_driver* driver; TRACE("(%s,%s,0x%08x)\n", wine_dbgstr_fcc(fccType), wine_dbgstr_fcc(fccHandler), wMode); if (!fccHandler) /* No specific handler, return the first valid for wMode */ { HIC local; ICINFO info; DWORD loop = 0; info.dwSize = sizeof(info); while(ICInfo(fccType, loop++, &info)) { /* Ensure fccHandler is not 0x0 because we will recurse on ICOpen */ if(!info.fccHandler) continue; local = ICOpen(fccType, info.fccHandler, wMode); if (local != 0) { TRACE("Returning %s as default handler for %s\n", wine_dbgstr_fcc(info.fccHandler), wine_dbgstr_fcc(fccType)); return local; } } } /* Check if there is a registered driver that matches */ driver = reg_driver_list; while(driver) if (!compare_fourcc(fccType, driver->fccType) && !compare_fourcc(fccHandler, driver->fccHandler)) { fccType = driver->fccType; fccHandler = driver->fccHandler; break; } else driver = driver->next; if (driver && driver->proc) /* The driver has been registered at runtime with its driverproc */ return ICOpenFunction(fccType, fccHandler, wMode, driver->proc); /* Well, lParam2 is in fact a LPVIDEO_OPEN_PARMS, but it has the * same layout as ICOPEN */ icopen.dwSize = sizeof(ICOPEN); icopen.fccType = fccType; icopen.fccHandler = fccHandler; icopen.dwVersion = 0x00001000; /* FIXME */ icopen.dwFlags = wMode; icopen.dwError = 0; icopen.pV1Reserved = NULL; icopen.pV2Reserved = NULL; icopen.dnDevNode = 0; /* FIXME */ if (!driver) { /* normalize to lower case as in 'vidc' */ ((char*)&fccType)[0] = tolower(((char*)&fccType)[0]); ((char*)&fccType)[1] = tolower(((char*)&fccType)[1]); ((char*)&fccType)[2] = tolower(((char*)&fccType)[2]); ((char*)&fccType)[3] = tolower(((char*)&fccType)[3]); icopen.fccType = fccType; /* Seek the driver in the registry */ fourcc_to_string(codecname, fccType); codecname[4] = '.'; fourcc_to_string(codecname + 5, fccHandler); codecname[9] = '\0'; hdrv = OpenDriver(codecname, drv32W, (LPARAM)&icopen); if (!hdrv) return 0; } else { /* The driver has been registered at runtime with its name */ hdrv = OpenDriver(driver->name, NULL, (LPARAM)&icopen); if (!hdrv) return 0; } whic = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_HIC)); if (!whic) { CloseDriver(hdrv, 0, 0); return FALSE; } whic->hdrv = hdrv; whic->driverproc = NULL; whic->type = fccType; whic->handler = fccHandler; while (MSVIDEO_GetHicPtr((HIC)(ULONG_PTR)IC_HandleRef) != NULL) IC_HandleRef++; whic->hic = (HIC)(ULONG_PTR)IC_HandleRef++; whic->next = MSVIDEO_FirstHic; MSVIDEO_FirstHic = whic; TRACE("=> %p\n", whic->hic); return whic->hic; }