// // list502a.cpp (ver1.1 エラー処理を追加,2008.08) // // 動画の処理例 // 動作:AVIファイルから1フレームを表示する // 処理部分を書きやすくするため // コンソールアプリケーションの形態をとり //   ウィンドウ関係の処理はスレッドに任せる // 注意:入力ファイルに対応したVFWのコーディックが必要 //   リンク設定、vfw32.libの追加が必要 // 構成プロパティ/全般/文字セットを「設定なし」に変更 // #include #include // getch()の宣言 #include "list502.h" void main() { char cbuf[256]; OPENFILENAME fname; static char pfn[256]; // 入力AVIファイルのパス+名前 memset(&fname, 0, sizeof(OPENFILENAME)); fname.lStructSize = sizeof(OPENFILENAME); fname.lpstrFilter = "*.*\0*.*\0\0"; fname.nFilterIndex = 1; // 1番目のファイルフィルタを使う fname.lpstrFile = pfn; // パス付きファイル名が格納されるアドレス fname.nMaxFile = sizeof(pfn); fname.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; if( ! GetOpenFileName( &fname ) ) return ; AVISTREAMINFO sivi; PAVISTREAM pvis; HRESULT rc; AVIFileInit(); rc = AVIStreamOpenFromFile( &pvis, pfn, streamtypeVIDEO, 0, OF_READ, NULL); // Videoストリームをオープン if( rc ) { printf( "open err\n" ); AVIFileExit(); printf( "quit? push any key" ); getch(); return; } AVIStreamAddRef( pvis ); // ストリームの参照カウントを1増やす AVIStreamInfo( pvis, &sivi, sizeof(AVISTREAMINFO) ); PGETFRAME pvf; LPBITMAPINFOHEADER pbmpih; IMG0 img00; // 1フレーム読み出してフレームの情報を得る pvf = AVIStreamGetFrameOpen( pvis, // 解凍の準備 (LPBITMAPINFOHEADER)AVIGETFRAMEF_BESTDISPLAYFMT); if( pvf == NULL ){ printf("解凍のエラー\n"); AVIStreamRelease( pvis ); AVIFileExit(); printf( "quit? push any key" ); getch(); return; } pbmpih = (LPBITMAPINFOHEADER)AVIStreamGetFrame( pvf, 0 ); // 0フレームを読み出し img00.lpBmpData = (BYTE *)pbmpih + sizeof(BITMAPINFOHEADER); img00.hi = (HINSTANCE)GetWindowLong( HWND_DESKTOP, GWL_HINSTANCE ); img00.x = 100; img00.y = 100; img00.bih = *pbmpih; gr_reg(); // グラフィックウィンドウの登録 gr_init(&img00); // グラフィックウィンドウを1枚生成 printf( "vi_Rate %7d(単位時間あたりのフレーム数) \n", sivi.dwRate ); printf( "vi_Scale %6d(単位時間の秒数) \n", sivi.dwScale); printf( "vi_Length %d(フレーム数) \n", sivi.dwLength); printf( "フレーム番号を入力、負の数で終了\n"); int i; while( 1 ){ // フレームのループ printf( "フレーム番号?" ); scanf("%d", &i); if( i < 0 ) break; if( i >= sivi.dwLength) continue; pbmpih = (LPBITMAPINFOHEADER)AVIStreamGetFrame( pvf, i ); // iフレームを取り出す img00.lpBmpData = (BYTE *)pbmpih + sizeof(BITMAPINFOHEADER); // データ部分をセット wsprintf(cbuf,"[%s] frame %d/%d ", pfn, i, sivi.dwLength); SetWindowText( img00.hwnd, cbuf ); // キャプションのセット InvalidateRect( img00.hwnd, NULL, FALSE); // 再描画を要求 // 全面書換、背景は書き換えない } AVIStreamGetFrameClose( pvf ); // VFWからのデータのリリース AVIStreamRelease( pvis ); AVIFileExit(); printf( "quit? push any key" ); getch(); SendMessage( img00.hwnd, WM_CLOSE, 0, 0 ); // グラフィック画面の終了 // PostMessage( hwnd, WM_QUIT, 0, 0 ) でもスレッドのメッセージループは終了するが // PostQuitMessage()ではスレッドのメッセージループは終了しない。 // PostMessage( hwnd, WM_QUIT, 0, 0 ) の場合、 // ループ終了時点ではウィンドウは存在するが、スレッド終了とともに // ウィンドウは強制終了する。 // これらの処理をしなくとも、main関数の終了に伴いスレッド、 // 及びウィンドウも強制終了する  return ; }