/* 对捕获的视频做编码、解码处理 */ 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; }
static void test_ICSeqCompress(void) { /* The purpose of this test is to validate sequential frame compressing * functions. The MRLE codec will be used because Wine supports it and * it is present in any Windows. */ HIC h; DWORD err, vidc = mmioFOURCC('v','i','d','c'), mrle = mmioFOURCC('m', 'r', 'l', 'e'); DWORD i; LONG frame_len; BOOL key_frame, ret; char *frame; COMPVARS pc; struct { BITMAPINFOHEADER header; RGBQUAD map[256]; } input_header = { {sizeof(BITMAPINFOHEADER), 32, 1, 1, 8, 0, 32*8, 0, 0, 256, 256}, {{255,0,0}, {0,255,0}, {0,0,255}, {255,255,255}}}; PBITMAPINFO bitmap = (PBITMAPINFO) &input_header; static BYTE input[32] = {1,2,3,3,3,3,2,3,1}; static const BYTE output_kf[] = {1,1,1,2,4,3,0,3,2,3,1,0,23,0,0,0,0,1}, /* key frame*/ output_nkf[] = {0,0,0,1}; /* non key frame */ h = ICOpen(vidc, mrle, ICMODE_COMPRESS); ok(h != NULL, "Expected non-NULL\n"); pc.cbSize = sizeof(pc); pc.dwFlags = ICMF_COMPVARS_VALID; pc.fccType = vidc; pc.fccHandler = mrle; pc.hic = h; pc.lpbiIn = NULL; pc.lpbiOut = NULL; pc.lpBitsOut = pc.lpBitsPrev = pc.lpState = NULL; pc.lQ = ICQUALITY_DEFAULT; pc.lKey = 1; pc.lDataRate = 300; pc.lpState = NULL; pc.cbState = 0; ret = ICSeqCompressFrameStart(&pc, bitmap); ok(ret == TRUE, "Expected TRUE\n"); /* Check that reserved pointers were allocated */ ok(pc.lpbiIn != NULL, "Expected non-NULL\n"); ok(pc.lpbiOut != NULL, "Expected non-NULL\n"); for(i = 0; i < 9; i++) { frame_len = 0; frame = ICSeqCompressFrame(&pc, 0, input, &key_frame, &frame_len); ok(frame != NULL, "Frame[%d]: Expected non-NULL\n", i); if (frame_len == sizeof(output_nkf)) ok(!memcmp(output_nkf, frame, frame_len), "Frame[%d]: Contents do not match\n", i); else if (frame_len == sizeof(output_kf)) ok(!memcmp(output_kf, frame, frame_len), "Frame[%d]: Contents do not match\n", i); else ok(0, "Unknown frame size of %d byten\n", frame_len); } ICSeqCompressFrameEnd(&pc); ICCompressorFree(&pc); /* ICCompressorFree already closed the HIC */ err = ICClose(h); ok(err == ICERR_BADHANDLE, "Expected -8, got %d\n", err); }
int imFileFormatAVI::WriteImageInfo() { if (dib) { if (dib->bmih->biWidth != width || dib->bmih->biHeight != height || imColorModeSpace(file_color_mode) != imColorModeSpace(user_color_mode)) return IM_ERR_DATA; return IM_ERR_NONE; // parameters can be set only once } // force bottom up orientation this->file_data_type = IM_BYTE; this->file_color_mode = imColorModeSpace(this->user_color_mode); int bpp; if (this->file_color_mode == IM_RGB) { this->file_color_mode |= IM_PACKED; bpp = 24; if (imColorModeHasAlpha(this->user_color_mode)) { this->file_color_mode |= IM_ALPHA; bpp = 32; this->rmask = 0x00FF0000; this->roff = 16; this->gmask = 0x0000FF00; this->goff = 8; this->bmask = 0x000000FF; this->boff = 0; } } else bpp = 8; this->line_buffer_extra = 4; // room enough for padding imAttribTable* attrib_table = AttribTable(); const void* attrib_data = attrib_table->Get("FPS"); if (attrib_data) fps = *(float*)attrib_data; else fps = 15; if (this->compression[0] == 0 || imStrEqual(this->compression, "NONE")) this->use_compressor = 0; else this->use_compressor = 1; dib = imDibCreate(width, height, bpp); if (use_compressor) { memset(&compvars, 0, sizeof(COMPVARS)); compvars.cbSize = sizeof(COMPVARS); if (imStrEqual(this->compression, "CUSTOM")) { if (ICCompressorChoose(NULL, ICMF_CHOOSE_DATARATE | ICMF_CHOOSE_KEYFRAME, dib->dib, NULL, &compvars, "Choose Compression") == FALSE) return IM_ERR_COMPRESS; } else { compvars.dwFlags = ICMF_COMPVARS_VALID; compvars.fccType = ICTYPE_VIDEO; int* attrib = (int*)attrib_table->Get("KeyFrameRate"); if (attrib) compvars.lKey = *attrib; else compvars.lKey = 15; // same defaults of the dialog attrib = (int*)attrib_table->Get("DataRate"); if (attrib) compvars.lDataRate = *attrib / 8; else compvars.lDataRate = 300; // same defaults of the dialog attrib = (int*)attrib_table->Get("AVIQuality"); if (attrib) compvars.lQ = *attrib; else compvars.lQ = (DWORD)ICQUALITY_DEFAULT; if (imStrEqual(this->compression, "RLE")) compvars.fccHandler = mmioFOURCC('M','R','L','E'); else if (imStrEqual(this->compression, "CINEPACK")) compvars.fccHandler = mmioFOURCC('c','v','i','d'); else compvars.fccHandler = mmioFOURCC(compression[0],compression[1],compression[2],compression[3]); compvars.hic = ICOpen(ICTYPE_VIDEO, compvars.fccHandler, ICMODE_COMPRESS); } if (compvars.hic == NULL) use_compressor = 0; } AVISTREAMINFO streaminfo; memset(&streaminfo, 0, sizeof(AVISTREAMINFO)); streaminfo.fccType = streamtypeVIDEO; streaminfo.dwScale = 1000; streaminfo.dwRate = (DWORD)(fps*1000); SetRect(&streaminfo.rcFrame, 0, 0, width, height); if (use_compressor) { streaminfo.fccHandler = compvars.fccHandler; streaminfo.dwQuality = compvars.lQ; } else { streaminfo.fccHandler = mmioFOURCC('D','I','B',' '); streaminfo.dwQuality = (DWORD)ICQUALITY_DEFAULT; } /* creates a new stream in the new file */ HRESULT hr = AVIFileCreateStream(file, &stream, &streaminfo); if (hr != 0) return IM_ERR_ACCESS; /* set stream format */ if (use_compressor) { if (!ICSeqCompressFrameStart(&compvars, dib->bmi)) return IM_ERR_COMPRESS; hr = AVIStreamSetFormat(stream, 0, compvars.lpbiOut, dib->size - dib->bits_size); } else hr = AVIStreamSetFormat(stream, 0, dib->dib, dib->size - dib->bits_size); if (hr != 0) return IM_ERR_ACCESS; return IM_ERR_NONE; }
long __stdcall DlgProc ( HWND hWnd , unsigned msg , unsigned wParam , long lParam ) { switch(msg) { case WM_INITDIALOG: //hEdit = GetDlgItem( hWnd , I_EDIT ); //GetClientRect( hEdit , &rect ); hWndCap = capCreateCaptureWindow ( NULL, WS_CHILD | WS_VISIBLE , 0, 0, 320, 240, hWnd, 1235 ); //hWndCap = capCreateCaptureWindow ( NULL, WS_CHILD | WS_VISIBLE , 0, 0, (rect.right-rect.left ), (rect.bottom-rect.top), hEdit, 1235); // вручную заполняем структуру CapVar ZeroMemory( &CapVar, sizeof(COMPVARS) ); CapVar.cbSize = sizeof(COMPVARS); CapVar.dwFlags = ICMF_COMPVARS_VALID; CapVar.cbState = 0; CapVar.fccHandler = mmioFOURCC( 'x', '2', '6', '4' ); CapVar.fccType = ICTYPE_VIDEO; // открываем декомпрессор (долго) CapVar.hic = ICOpen( ICTYPE_VIDEO, CapVar.fccHandler, ICMODE_COMPRESS ); hThread = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)SendThread, NULL, 0, 0 ); return -1 ; case WM_COMMAND: switch(LOWORD(wParam)) { case I_BUTTON_CONN : if( !capDriverConnect( hWndCap, 0 ) ) { EndDialog ( hWnd, 0 ); return -1; } capCaptureGetSetup( hWndCap, &CapParms, sizeof(CAPTUREPARMS) ); CapParms.dwRequestMicroSecPerFrame = 66000; CapParms.fLimitEnabled = FALSE; CapParms.fCaptureAudio = FALSE; CapParms.fMCIControl = FALSE; CapParms.fYield = TRUE; CapParms.vKeyAbort = VK_ESCAPE; CapParms.fAbortLeftMouse = FALSE; CapParms.fAbortRightMouse = FALSE; capCaptureSetSetup( hWndCap, &CapParms, sizeof(CAPTUREPARMS) ); capPreviewScale( hWndCap, 1 ); capPreviewRate( hWndCap, 66 ); capPreviewScale( hWndCap, FALSE ); capPreview( hWndCap, 1 ); //added by jimmy // OPTIONAL STEP: Setup resolution capGetVideoFormat( hWndCap, &InputBmpInfo ,sizeof(InputBmpInfo) ); //InputBmpInfo.bmiHeader.biWidth = 320; //(rect.right-rect.left ); //InputBmpInfo.bmiHeader.biHeight = 240; //(rect.bottom-rect.top); //InputBmpInfo.bmiHeader.biBitCount = 24; capSetVideoFormat( hWndCap, &InputBmpInfo, sizeof(InputBmpInfo) ); //capDriverDisconnect (hWndCap, 0);//Can we do better? //capDriverConnect (hWndCap, 0); capSetCallbackOnFrame( hWndCap, FrameCallBack ); if(CapVar.hic > 0 ) { OutFormatSize = ICCompressGetFormatSize( CapVar.hic, &InputBmpInfo.bmiHeader ); // BITMAPINFO возвращает размер структуры исходных данных InputBmpInfo ICCompressGetFormat( CapVar.hic, &InputBmpInfo.bmiHeader, &OutputBmpInfo.bmiHeader ); // заполняет структуру получаемых данных OutputBmpInfo OutBufferSize = ICCompressGetSize( CapVar.hic, &InputBmpInfo.bmiHeader, &OutputBmpInfo.bmiHeader ); // максимальный размер одного сжатого кадра (полученного) ICSeqCompressFrameStart( &CapVar, &InputBmpInfo ); // начало сжатия } break; case I_BUTTON_EXIT : ICSeqCompressFrameEnd(&CapVar); // конец сжатия ICCompressorFree(&CapVar); ICClose(CapVar.hic); capPreview( hWndCap , false ); capDriverDisconnect( hWndCap ); EndDialog ( hWnd , 0 ) ; break; } return -1 ; case WM_CLOSE : ICSeqCompressFrameEnd(&CapVar); // конец сжатия ICCompressorFree(&CapVar); ICClose(CapVar.hic); capPreview( hWndCap , false ); capDriverDisconnect( hWndCap ); EndDialog ( hWnd , 0 ) ; return -1 ; } return 0 ; }