static bool ChooseCodec(HWND hWnd, AVICOMPRESSOPTIONS *pOptionsVideo) { COMPVARS cv; ZeroMemory(&cv, sizeof(cv)); cv.cbSize = sizeof(cv); if(ICCompressorChoose(hWnd, ICMF_CHOOSE_DATARATE | ICMF_CHOOSE_KEYFRAME, NULL, NULL, &cv, ("Choose codec"))) { ZeroMemory(pOptionsVideo, sizeof(AVICOMPRESSOPTIONS)); pOptionsVideo->fccType = streamtypeVIDEO; pOptionsVideo->fccHandler = cv.fccHandler; if(cv.lKey) { pOptionsVideo->dwKeyFrameEvery = cv.lKey; pOptionsVideo->dwFlags |= AVICOMPRESSF_KEYFRAMES; } pOptionsVideo->dwQuality = cv.lQ; if(cv.lDataRate) { pOptionsVideo->dwFlags |= AVICOMPRESSF_DATARATE; pOptionsVideo->dwBytesPerSecond = cv.lDataRate * 1024; } ICCompressorFree(&cv); return true; } return false; }
BOOL CALLBACK RecordingDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) { case WM_INITDIALOG: { HWND hWC; CheckDlgButton(hW,IDC_REC_MODE1,RECORD_RECORDING_MODE==0); CheckDlgButton(hW,IDC_REC_MODE2,RECORD_RECORDING_MODE==1); hWC = GetDlgItem(hW,IDC_VIDEO_SIZE); ComboBox_ResetContent(hWC); ComboBox_AddString(hWC,"Full"); ComboBox_AddString(hWC,"Half"); ComboBox_AddString(hWC,"Quarter"); ComboBox_SetCurSel(hWC,RECORD_VIDEO_SIZE); SetDlgItemInt(hW,IDC_REC_WIDTH,RECORD_RECORDING_WIDTH,FALSE); SetDlgItemInt(hW,IDC_REC_HEIGHT,RECORD_RECORDING_HEIGHT,FALSE); hWC = GetDlgItem(hW,IDC_FRAME_RATE); ComboBox_ResetContent(hWC); ComboBox_AddString(hWC,"1"); ComboBox_AddString(hWC,"2"); ComboBox_AddString(hWC,"3"); ComboBox_AddString(hWC,"4"); ComboBox_AddString(hWC,"5"); ComboBox_AddString(hWC,"6"); ComboBox_AddString(hWC,"7"); ComboBox_AddString(hWC,"8"); ComboBox_SetCurSel(hWC,RECORD_FRAME_RATE_SCALE); CheckDlgButton(hW,IDC_COMPRESSION1,RECORD_COMPRESSION_MODE==0); CheckDlgButton(hW,IDC_COMPRESSION2,RECORD_COMPRESSION_MODE==1); RefreshCodec(hW); } case WM_COMMAND: { switch(LOWORD(wParam)) { case IDC_RECCFG: { if(IsDlgButtonChecked(hW,IDC_COMPRESSION1)) { BITMAPINFOHEADER bitmap = {40,640,480,1,16,0,640*480*2,2048,2048,0,0}; if(!ICCompressorChoose(hW,ICMF_CHOOSE_DATARATE|ICMF_CHOOSE_KEYFRAME,&bitmap,NULL,&RECORD_COMPRESSION1,"16 bit Compression")) return TRUE; if(RECORD_COMPRESSION1.cbState>sizeof(RECORD_COMPRESSION_STATE1)) { memset(&RECORD_COMPRESSION1,0,sizeof(RECORD_COMPRESSION1)); memset(&RECORD_COMPRESSION_STATE1,0,sizeof(RECORD_COMPRESSION_STATE1)); RECORD_COMPRESSION1.cbSize = sizeof(RECORD_COMPRESSION1); } else { if(RECORD_COMPRESSION1.lpState!=RECORD_COMPRESSION_STATE1) memcpy(RECORD_COMPRESSION_STATE1,RECORD_COMPRESSION1.lpState,RECORD_COMPRESSION1.cbState); } RECORD_COMPRESSION1.lpState = RECORD_COMPRESSION_STATE1; } else { BITMAPINFOHEADER bitmap = {40,640,480,1,24,0,640*480*3,2048,2048,0,0}; if(!ICCompressorChoose(hW,ICMF_CHOOSE_DATARATE|ICMF_CHOOSE_KEYFRAME,&bitmap,NULL,&RECORD_COMPRESSION2,"24 bit Compression")) return TRUE; if(RECORD_COMPRESSION2.cbState>sizeof(RECORD_COMPRESSION_STATE2)) { memset(&RECORD_COMPRESSION2,0,sizeof(RECORD_COMPRESSION2)); memset(&RECORD_COMPRESSION_STATE2,0,sizeof(RECORD_COMPRESSION_STATE2)); RECORD_COMPRESSION2.cbSize = sizeof(RECORD_COMPRESSION2); } else { if(RECORD_COMPRESSION2.lpState!=RECORD_COMPRESSION_STATE2) memcpy(RECORD_COMPRESSION_STATE2,RECORD_COMPRESSION2.lpState,RECORD_COMPRESSION2.cbState); } RECORD_COMPRESSION2.lpState = RECORD_COMPRESSION_STATE2; } RefreshCodec(hW); return TRUE; } case IDCANCEL: EndDialog(hW,FALSE);return TRUE; case IDOK: { HWND hWC; if(IsDlgButtonChecked(hW,IDC_REC_MODE1)) RECORD_RECORDING_MODE = 0; else RECORD_RECORDING_MODE = 1; hWC = GetDlgItem(hW,IDC_VIDEO_SIZE); RECORD_VIDEO_SIZE = ComboBox_GetCurSel(hWC); RECORD_RECORDING_WIDTH = GetDlgItemInt(hW,IDC_REC_WIDTH,NULL,FALSE); RECORD_RECORDING_HEIGHT = GetDlgItemInt(hW,IDC_REC_HEIGHT,NULL,FALSE); hWC = GetDlgItem(hW,IDC_FRAME_RATE); RECORD_FRAME_RATE_SCALE = ComboBox_GetCurSel(hWC); if(IsDlgButtonChecked(hW,IDC_COMPRESSION1)) RECORD_COMPRESSION_MODE = 0; else RECORD_COMPRESSION_MODE = 1; EndDialog(hW,TRUE); return TRUE; } } } } return FALSE; }
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; }
/** * AVIファイルを圧縮フォーマットを指定して開く * @param filename 保存ファイル名 * @param fps 秒間フレーム数 * @param return 圧縮ダイアログでキャンセルを押した場合false。 */ bool openCompressedAVI(const tjs_char *filename, int fps) { closeAVI(); // 録画開始時のサイズを記録しておく aviWidth = _width; aviHeight = _height; // ストリームに投げ込むデータフォーマットを指定 BITMAPINFOHEADER bih; bih.biSize = sizeof(bih); bih.biWidth = aviWidth; bih.biHeight = aviHeight; bih.biPlanes = 1; bih.biBitCount = 32; bih.biCompression = BI_RGB; bih.biSizeImage = 0; bih.biXPelsPerMeter = 0; bih.biYPelsPerMeter = 0; bih.biClrUsed = 0; bih.biClrImportant = 0; // 圧縮オプションを取得 memset(&cv,0,sizeof(COMPVARS)); cv.cbSize=sizeof(COMPVARS); cv.dwFlags=ICMF_COMPVARS_VALID; cv.fccHandler=comptypeDIB; cv.lQ=ICQUALITY_DEFAULT; if (!ICCompressorChoose(NULL,ICMF_CHOOSE_DATARATE | ICMF_CHOOSE_KEYFRAME, &bih,NULL,&cv,NULL)) { return false; } // オプションを指定 opt.fccType=streamtypeVIDEO; opt.fccHandler=cv.fccHandler; opt.dwKeyFrameEvery=cv.lKey; opt.dwQuality=cv.lQ; opt.dwBytesPerSecond=cv.lDataRate; opt.dwFlags=(cv.lDataRate>0?AVICOMPRESSF_DATARATE:0) |(cv.lKey>0?AVICOMPRESSF_KEYFRAMES:0); opt.lpFormat=NULL; opt.cbFormat=0; opt.lpParms=cv.lpState; opt.cbParms=cv.cbState; opt.dwInterleaveEvery=0; // AVIファイルを開く ttstr path = TVPNormalizeStorageName(ttstr(filename)); TVPGetLocalName(path); if (AVIFileOpen(&pavi, path.c_str(), OF_CREATE | OF_WRITE | OF_SHARE_DENY_NONE,NULL) != 0) { ttstr msg = filename; msg += ":can't open"; TVPThrowExceptionMessage(msg.c_str()); } // AVIストリームの生成 AVISTREAMINFO si = { streamtypeVIDEO, // Video Stream comptypeDIB, 0, // Stream Flag 0, 0, 0, 1, // 時間単位 dwScale fps, // フレーム dwRate 0, 10, // ストリームの長さ XXX 0, 0, (DWORD)-1, // -1: Default品質 [0-10000] 0, // 表示する矩形サイズ { 0, 0, aviWidth, aviHeight }, 0, 0, L"KIRIKIRI" }; si.fccHandler=cv.fccHandler; if (AVIFileCreateStream(pavi, &pstm, &si) != 0) { closeAVI(); TVPThrowExceptionMessage(L"AVIFileCreateStream"); } if (AVIMakeCompressedStream(&ptmp,pstm,&opt,NULL)!=AVIERR_OK) { closeAVI(); TVPThrowExceptionMessage(L"AVIMakeCompressedStream"); } if (AVIStreamSetFormat(ptmp, 0, &bih, sizeof(bih)) != 0 ) { closeAVI(); TVPThrowExceptionMessage(L"AVIFileCreateStream"); } // 先頭フレーム lastFrame = -1; hasCv = true; return true; }