LRESULT CALLBACK FrameCallBack( HWND hWnd, LPVIDEOHDR lpVHdr ) { char *afterCompression; // указатель на сжатые данные long OutActSize; afterCompression = (char*)ICSeqCompressFrame( &CapVar , 0 , MainBuffer , // данные кадра для сжатия &bKeyFrame , // bKeyFrame = 1 если кадр ключевой &OutActSize ); // OutActSize - содержит размер полученных данных memcpy( MainBuffer , afterCompression , OutActSize ); // теперь MainBuffer[] содержит сжатые данные frameSize = OutActSize; return (LRESULT)TRUE ; }
// Function name : PASCAL VideoCallbackProc // Description : Encode the captured frame // Return type : LRESULT FAR // Argument : HWND hWnd // Argument : LPVIDEOHDR lpVHdr LRESULT FAR PASCAL VideoCallbackProc(HWND hWnd, LPVIDEOHDR lpVHdr) { unsigned char *bufi, *buf; int type=0; int quant=0; int declen=0; int enclen=0; bufi = new unsigned char[lpVHdr->dwBytesUsed+40]; //original image buf = new unsigned char[lpVHdr->dwBytesUsed]; //coded stream memcpy((void *)(bufi), lpVHdr->lpData, lpVHdr->dwBytesUsed); unsigned char *buf1; buf1 = buf; if (m_vfwState==ENCDEC) { //Encode buf1 = (unsigned char*)ICSeqCompressFrame(&pc,0,bufi, &IsKeyFrame,&FrameSize); //enc_main(bufi, buf, (int *)&FrameSize, &IsKeyFrame, -1); //////////////////////////////// if (bSaveAVI){ AVIStreamSetFormat(pMainFrame->ps,pMainFrame->m_Frame++,lpbiTmp,sizeof(BITMAPINFO)); AVIStreamWrite(pMainFrame->ps,pMainFrame->m_Frame, 1, (LPBYTE)buf1, lpbiTmp->bmiHeader.biSizeImage,AVIIF_KEYFRAME,NULL,NULL); } //////////////////////////////// //Decode ICDecompress(hic2,0,&lpbiTmp->bmiHeader,buf1,&lpbiOut->bmiHeader,&bufo[40]); } else { enc_main(bufi,buf, &IsKeyFrame,&type,&quant,&enclen); declen = dec_main(buf, bufi, enclen,lpbiIn->bmiHeader.biWidth); pMainFrame->conv.YV12_to_RGB24(bufi, bufi+(lpbiIn->bmiHeader.biWidth*lpbiIn->bmiHeader.biHeight), bufi+(lpbiIn->bmiHeader.biWidth*lpbiIn->bmiHeader.biHeight*5/4), &bufo[40], lpbiIn->bmiHeader.biWidth, lpbiIn->bmiHeader.biHeight); } pMainFrame->GetActiveView()->InvalidateRect(NULL,FALSE); delete bufi; delete buf; return (LRESULT) TRUE; }
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); }