void RefreshCodec(HWND hW) { char buffer[255]; union { char chFCC[5]; DWORD dwFCC; } fcc; ICINFO icinfo; memset(&icinfo,0,sizeof(icinfo)); icinfo.dwSize = sizeof(icinfo); strcpy(fcc.chFCC,"VIDC"); RECORD_COMPRESSION1.hic = ICOpen(fcc.dwFCC,RECORD_COMPRESSION1.fccHandler,ICMODE_QUERY); if(RECORD_COMPRESSION1.hic) { ICGetInfo(RECORD_COMPRESSION1.hic,&icinfo,sizeof(icinfo)); ICClose(RECORD_COMPRESSION1.hic); wsprintf(buffer,"16 bit Compression: %ws",icinfo.szDescription); } else wsprintf(buffer,"16 bit Compression: Full Frames (Uncompressed)"); SetDlgItemText(hW,IDC_COMPRESSION1,buffer); memset(&icinfo,0,sizeof(icinfo)); icinfo.dwSize = sizeof(icinfo); RECORD_COMPRESSION2.hic = ICOpen(fcc.dwFCC,RECORD_COMPRESSION2.fccHandler,ICMODE_QUERY); if(RECORD_COMPRESSION2.hic) { ICGetInfo(RECORD_COMPRESSION2.hic,&icinfo,sizeof(icinfo)); ICClose(RECORD_COMPRESSION2.hic); wsprintf(buffer,"24 bit Compression: %ws",icinfo.szDescription); } else wsprintf(buffer,"24 bit Compression: Full Frames (Uncompressed)"); SetDlgItemText(hW,IDC_COMPRESSION2,buffer); }
static void test_OpenCase(void) { HIC h; ICINFO info; /* Check if default handler works */ h = ICOpen(mmioFOURCC('v','i','d','c'),0,ICMODE_DECOMPRESS); ok(0!=h,"ICOpen(vidc.0) failed\n"); if (h) { info.dwSize = sizeof(info); info.szName[0] = 0; ICGetInfo(h, &info, sizeof(info)); trace("The default decompressor is %s\n", wine_dbgstr_w(info.szName)); ok(ICClose(h)==ICERR_OK,"ICClose failed\n"); } h = ICOpen(mmioFOURCC('v','i','d','c'),0,ICMODE_COMPRESS); ok(0!=h || broken(h == 0),"ICOpen(vidc.0) failed\n"); /* Not present in Win8 */ if (h) { info.dwSize = sizeof(info); info.szName[0] = 0; ICGetInfo(h, &info, sizeof(info)); trace("The default compressor is %s\n", wine_dbgstr_w(info.szName)); ok(ICClose(h)==ICERR_OK,"ICClose failed\n"); } /* Open a compressor with combinations of lowercase * and uppercase compressortype and handler. */ h = ICOpen(mmioFOURCC('v','i','d','c'),mmioFOURCC('m','s','v','c'),ICMODE_DECOMPRESS); ok(0!=h,"ICOpen(vidc.msvc) failed\n"); if (h) { ok(ICClose(h)==ICERR_OK,"ICClose failed\n"); } h = ICOpen(mmioFOURCC('v','i','d','c'),mmioFOURCC('M','S','V','C'),ICMODE_DECOMPRESS); ok(0!=h,"ICOpen(vidc.MSVC) failed\n"); if (h) { ok(ICClose(h)==ICERR_OK,"ICClose failed\n"); } h = ICOpen(mmioFOURCC('V','I','D','C'),mmioFOURCC('m','s','v','c'),ICMODE_DECOMPRESS); ok(0!=h,"ICOpen(VIDC.msvc) failed\n"); if (h) { ok(ICClose(h)==ICERR_OK,"ICClose failed\n"); } h = ICOpen(mmioFOURCC('V','I','D','C'),mmioFOURCC('M','S','V','C'),ICMODE_DECOMPRESS); ok(0!=h,"ICOpen(VIDC.MSVC) failed\n"); if (h) { ok(ICClose(h)==ICERR_OK,"ICClose failed\n"); } h = ICOpen(mmioFOURCC('v','i','d','c'),mmioFOURCC('m','S','v','C'),ICMODE_DECOMPRESS); ok(0!=h,"ICOpen(vidc.mSvC) failed\n"); if (h) { ok(ICClose(h)==ICERR_OK,"ICClose failed\n"); } h = ICOpen(mmioFOURCC('v','I','d','C'),mmioFOURCC('m','s','v','c'),ICMODE_DECOMPRESS); ok(0!=h,"ICOpen(vIdC.msvc) failed\n"); if (h) { ok(ICClose(h)==ICERR_OK,"ICClose failed\n"); } }
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 }
static HRESULT fill_format_info(AVICompressor *This, VIDEOINFOHEADER *src_videoinfo) { DWORD size; ICINFO icinfo; HRESULT hres; hres = ensure_driver(This); if(hres != S_OK) return hres; size = ICGetInfo(This->hic, &icinfo, sizeof(icinfo)); if(size != sizeof(icinfo)) return E_FAIL; size = ICCompressGetFormatSize(This->hic, &src_videoinfo->bmiHeader); if(!size) { FIXME("ICCompressGetFormatSize failed\n"); return E_FAIL; } size += FIELD_OFFSET(VIDEOINFOHEADER, bmiHeader); This->videoinfo = heap_alloc(size); if(!This->videoinfo) return E_OUTOFMEMORY; This->videoinfo_size = size; This->driver_flags = icinfo.dwFlags; memset(This->videoinfo, 0, sizeof(*This->videoinfo)); ICCompressGetFormat(This->hic, &src_videoinfo->bmiHeader, &This->videoinfo->bmiHeader); This->videoinfo->dwBitRate = 10000000/src_videoinfo->AvgTimePerFrame * This->videoinfo->bmiHeader.biSizeImage * 8; This->videoinfo->AvgTimePerFrame = src_videoinfo->AvgTimePerFrame; This->max_frame_size = This->videoinfo->bmiHeader.biSizeImage; return S_OK; }
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; }
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; }
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); } } }
//int init_vfw_encoder(char *dll_name, BITMAPINFOHEADER *input_bih, BITMAPINFOHEADER *output_bih) static BITMAPINFOHEADER* vfw_open_encoder(char *dll_name, char *compdatafile, BITMAPINFOHEADER *input_bih,unsigned int out_fourcc) { HRESULT ret; BITMAPINFOHEADER* output_bih=NULL; int temp_len; FILE *fd=NULL; char *drvdata=NULL; struct stat st; //sh_video = malloc(sizeof(sh_video_t)); mp_msg(MSGT_WIN32,MSGL_V,"======= Win32 (VFW) VIDEO Encoder init =======\n"); CoInitRes = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); // memset(&sh_video->o_bih, 0, sizeof(BITMAPINFOHEADER)); // output_bih->biSize = sizeof(BITMAPINFOHEADER); // encoder_hic = ICOpen( 0x63646976, out_fourcc, ICMODE_COMPRESS); encoder_hic = ICOpen( (long) dll_name, out_fourcc, ICMODE_COMPRESS); if(!encoder_hic){ mp_msg(MSGT_WIN32,MSGL_ERR,"ICOpen failed! unknown codec / wrong parameters?\n"); return NULL; } mp_msg(MSGT_WIN32,MSGL_INFO,"HIC: %x\n", encoder_hic); #if 1 { ICINFO icinfo; ret = ICGetInfo(encoder_hic, &icinfo, sizeof(ICINFO)); mp_msg(MSGT_WIN32,MSGL_INFO,"%ld - %ld - %d\n", ret, icinfo.dwSize, sizeof(ICINFO)); mp_msg(MSGT_WIN32,MSGL_INFO,MSGTR_MPCODECS_CompressorType, icinfo.fccType); mp_msg(MSGT_WIN32,MSGL_INFO,MSGTR_MPCODECS_CompressorSubtype, icinfo.fccHandler); mp_msg(MSGT_WIN32,MSGL_INFO,MSGTR_MPCODECS_CompressorFlags, icinfo.dwFlags, icinfo.dwVersion, icinfo.dwVersionICM); //printf("Compressor name: %s\n", icinfo.szName); //printf("Compressor description: %s\n", icinfo.szDescription); mp_msg(MSGT_WIN32,MSGL_INFO,MSGTR_MPCODECS_Flags); if (icinfo.dwFlags & VIDCF_QUALITY) mp_msg(MSGT_WIN32,MSGL_INFO,MSGTR_MPCODECS_Quality); if (icinfo.dwFlags & VIDCF_FASTTEMPORALD) mp_msg(MSGT_WIN32,MSGL_INFO," fast-decompr"); if (icinfo.dwFlags & VIDCF_QUALITYTIME) mp_msg(MSGT_WIN32,MSGL_INFO," temp-quality"); mp_msg(MSGT_WIN32,MSGL_INFO,"\n"); } #endif if(compdatafile){ if (!strncmp(compdatafile, "dialog", 6)){ if (ICSendMessage(encoder_hic, ICM_CONFIGURE, -1, 0) != ICERR_OK){ mp_msg(MSGT_WIN32,MSGL_ERR,"Compressor doesn't have a configure dialog!\n"); return NULL; } if (ICSendMessage(encoder_hic, ICM_CONFIGURE, 0, 0) != ICERR_OK){ mp_msg(MSGT_WIN32,MSGL_ERR,"Compressor configure dialog failed!\n"); return NULL; } } else { if (stat(compdatafile, &st) < 0){ mp_msg(MSGT_WIN32,MSGL_ERR,"Compressor data file not found!\n"); return NULL; } fd = fopen(compdatafile, "rb"); if (!fd){ mp_msg(MSGT_WIN32,MSGL_ERR,"Cannot open Compressor data file!\n"); return NULL; } drvdata = (char *) malloc(st.st_size); if (fread(drvdata, st.st_size, 1, fd) != 1) { mp_msg(MSGT_WIN32,MSGL_ERR,"Cannot read Compressor data file!\n"); fclose(fd); free(drvdata); return NULL; } fclose(fd); mp_msg(MSGT_WIN32,MSGL_ERR,"Compressor data %d bytes\n", st.st_size); if (!(temp_len = (unsigned int) ICSendMessage(encoder_hic, ICM_SETSTATE, (LPARAM) drvdata, (int) st.st_size))){ mp_msg(MSGT_WIN32,MSGL_ERR,"ICSetState failed!\n"); free(drvdata); return NULL; } free(drvdata); mp_msg(MSGT_WIN32,MSGL_INFO,"ICSetState ret: %d\n", temp_len); } } temp_len = ICCompressGetFormatSize(encoder_hic, input_bih); mp_msg(MSGT_WIN32,MSGL_INFO,"ICCompressGetFormatSize ret: %d\n", temp_len); if (temp_len < sizeof(BITMAPINFOHEADER)) temp_len=sizeof(BITMAPINFOHEADER); output_bih = malloc(temp_len+4); memset(output_bih,0,temp_len); output_bih->biSize = temp_len; //sizeof(BITMAPINFOHEADER); return output_bih; }
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; }
/* lParam1: PAVISTREAM * lParam2: LPAVICOMPRESSOPTIONS */ static HRESULT WINAPI ICMStream_fnCreate(IAVIStream *iface, LPARAM lParam1, LPARAM lParam2) { IAVIStreamImpl *This = impl_from_IAVIStream(iface); ICINFO icinfo; ICCOMPRESSFRAMES icFrames; LPAVICOMPRESSOPTIONS pco = (LPAVICOMPRESSOPTIONS)lParam2; TRACE("(%p,0x%08lX,0x%08lX)\n", iface, lParam1, lParam2); /* check parameter */ if ((LPVOID)lParam1 == NULL) return AVIERR_BADPARAM; /* get infos from stream */ IAVIStream_Info((PAVISTREAM)lParam1, &This->sInfo, sizeof(This->sInfo)); if (This->sInfo.fccType != streamtypeVIDEO) return AVIERR_ERROR; /* error in registry or AVIMakeCompressedStream */ /* add reference to the stream */ This->pStream = (PAVISTREAM)lParam1; IAVIStream_AddRef(This->pStream); AVIFILE_Reset(This); if (pco != NULL && pco->fccHandler != comptypeDIB) { /* we should compress */ This->sInfo.fccHandler = pco->fccHandler; This->hic = ICOpen(ICTYPE_VIDEO, pco->fccHandler, ICMODE_COMPRESS); if (This->hic == NULL) return AVIERR_NOCOMPRESSOR; /* restore saved state of codec */ if (pco->cbParms > 0 && pco->lpParms != NULL) { ICSetState(This->hic, pco->lpParms, pco->cbParms); } /* set quality -- resolve default quality */ This->sInfo.dwQuality = pco->dwQuality; if (pco->dwQuality == ICQUALITY_DEFAULT) This->sInfo.dwQuality = ICGetDefaultQuality(This->hic); /* get capabilities of codec */ ICGetInfo(This->hic, &icinfo, sizeof(icinfo)); This->dwICMFlags = icinfo.dwFlags; /* use keyframes? */ if ((pco->dwFlags & AVICOMPRESSF_KEYFRAMES) && (icinfo.dwFlags & (VIDCF_TEMPORAL|VIDCF_FASTTEMPORALC))) { This->lKeyFrameEvery = pco->dwKeyFrameEvery; } else This->lKeyFrameEvery = 1; /* use datarate? */ if ((pco->dwFlags & AVICOMPRESSF_DATARATE)) { /* Do we have a chance to reduce size to desired one? */ if ((icinfo.dwFlags & (VIDCF_CRUNCH|VIDCF_QUALITY)) == 0) return AVIERR_NOCOMPRESSOR; assert(This->sInfo.dwRate != 0); This->dwBytesPerFrame = MulDiv(pco->dwBytesPerSecond, This->sInfo.dwScale, This->sInfo.dwRate); } else { pco->dwBytesPerSecond = 0; This->dwBytesPerFrame = 0; } if (icinfo.dwFlags & VIDCF_COMPRESSFRAMES) { memset(&icFrames, 0, sizeof(icFrames)); icFrames.lpbiOutput = This->lpbiOutput; icFrames.lpbiInput = This->lpbiInput; icFrames.lFrameCount = This->sInfo.dwLength; icFrames.lQuality = This->sInfo.dwQuality; icFrames.lDataRate = pco->dwBytesPerSecond; icFrames.lKeyRate = This->lKeyFrameEvery; icFrames.dwRate = This->sInfo.dwRate; icFrames.dwScale = This->sInfo.dwScale; ICSendMessage(This->hic, ICM_COMPRESS_FRAMES_INFO, (LPARAM)&icFrames, (LPARAM)sizeof(icFrames)); } } else This->sInfo.fccHandler = comptypeDIB; return AVIERR_OK; }