/*   再生専用スレッドでの動画再生 1999/11/29 宍戸 輝光 */ #include #include #define WM_END_PLAY (WM_USER+1) void video(void); LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); DWORD WINAPI play(LPVOID); HINSTANCE hInst; HWND hwMain; HANDLE hThread; LPBITMAPINFO lpInfo; LPBYTE lpBuf,lpFrame; RGBQUAD* lpRGB; char lpszStr[128]; DWORD dwLength=240; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){ MSG msg; WNDCLASSEX wndclass ; int i; hInst=hInstance; lpBuf=GlobalAlloc /* 必要なメモリをまとめて確保 */ (GPTR,sizeof(BITMAPINFO)+255*sizeof(RGBQUAD)+256*256); lpInfo=(LPBITMAPINFO)lpBuf; lpRGB=(RGBQUAD*)(lpBuf+sizeof(BITMAPINFOHEADER)); lpFrame=lpBuf+sizeof(BITMAPINFO)+255*sizeof(RGBQUAD); lpInfo->bmiHeader.biSize=sizeof(BITMAPINFOHEADER); /* BITMAPINFO構造体 */ lpInfo->bmiHeader.biWidth=256; lpInfo->bmiHeader.biHeight=256; lpInfo->bmiHeader.biPlanes=1; lpInfo->bmiHeader.biBitCount=8; lpInfo->bmiHeader.biCompression=BI_RGB; lpInfo->bmiColors[0]=lpRGB[0]; /* カラーテーブルの先頭 */ for (i=0;i<256;i++) { /* カラーテーブル作成 */ lpRGB[i].rgbRed=i; lpRGB[i].rgbGreen=i; lpRGB[i].rgbBlue=i; } srand((unsigned)time(NULL)); wndclass.cbSize = sizeof(wndclass); wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = NULL; wndclass.hCursor = LoadCursor(NULL,IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = "CWindow"; wndclass.hIconSm = NULL; RegisterClassEx (&wndclass); hwMain=CreateWindow ("CWindow",NULL, WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,288,360, NULL,NULL,hInstance,NULL); ShowWindow (hwMain,iCmdShow); /* ウインドウを表示 */ UpdateWindow (hwMain); while (GetMessage (&msg,NULL,0,0)) { /* メッセージループ */ TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } void video(void) { /* 動画ファイル作成 */ LPBYTE lpBuf; HANDLE hFile; DWORD i,j,l,dwDummy; int d; /* 1フレーム分のバッファ確保 */ lpBuf=GlobalAlloc(GPTR,256*256); /* ファイル作成 */ hFile=CreateFile("test.vid",GENERIC_READ|GENERIC_WRITE,0,NULL, CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL); if (hFile==INVALID_HANDLE_VALUE) { MessageBox(NULL,"ファイルを作成できませんでした。","失敗",MB_OK); CloseHandle(hFile); GlobalFree(lpBuf); return; } for (i=0;i<16;i++) { /* 最初の画面暗転 */ FillMemory(lpBuf,256*256,255-i*16); /* ファイルに作成した動画データを書き込み */ WriteFile(hFile,lpBuf,256*256,&dwDummy,NULL); wsprintf(lpszStr,"作成中 %03d/600フレーム",i+1); InvalidateRect(hwMain,NULL,FALSE); UpdateWindow (hwMain); } d=1; l=1; for (i=16;i<600;i++) { /* 背景をスクロール */ MoveMemory(lpBuf+256,lpBuf,256*255); FillMemory(lpBuf,256,l); for (j=0;j<16;j++) lpBuf[rand() % 256]=rand() % 256; WriteFile(hFile,lpBuf,256*256,&dwDummy,NULL); if (l==255) d=-1; else if (l==0) d=1; l+=d; wsprintf(lpszStr,"作成中 %03d/600フレーム",i+1); InvalidateRect(hwMain,NULL,FALSE); UpdateWindow (hwMain); } CloseHandle(hFile); GlobalFree(lpBuf); MessageBox(NULL,"ファイルの作成が終わりました。","終了",MB_OK); } DWORD WINAPI play(LPVOID lpDummy) { /* 再生スレッド */ DWORD dwIndex,dwPIndex,dwFFrame,dwStart,dwDummy; HANDLE hFile; dwStart=timeGetTime(); dwIndex=0; dwPIndex=0; dwFFrame=0; dwLength=600; /* ファイルオープン */ hFile=CreateFile("test.vid",GENERIC_READ,0,NULL, OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if (hFile==INVALID_HANDLE_VALUE) { MessageBox(NULL,"ファイルを開けませんでした。","失敗",MB_OK); CloseHandle(hFile); /* メインウインドウに終了メッセージをポスト */ PostMessage(hwMain,WM_END_PLAY,0,0); /* スレッド終了 */ ExitThread(0); return 0; } do { /* 再生ループ */ /* 次の描画タイミングまで待つ */ while((DWORD)((timeGetTime()-dwStart)/40.0)==dwIndex) Sleep(1); /* 描画するフレーム計算 */ dwIndex=(int)((timeGetTime()-dwStart)/40.0); if (dwIndex>dwLength-1) dwIndex=dwLength-1; if (dwIndex>dwPIndex+1) /* コマ落ち判定 */ dwFFrame+=dwIndex-dwPIndex-1; dwPIndex=dwIndex; /* 今回再生したフレームを記録 */ /* フレームをファイルから読みこむ */ SetFilePointer(hFile,256*256*dwIndex,&dwDummy,FILE_BEGIN); ReadFile(hFile,lpFrame,256*256,&dwDummy,NULL); wsprintf(lpszStr,"フレーム %03d/ コマ落ち %03d",dwIndex,dwFFrame); InvalidateRect(hwMain,NULL,FALSE); UpdateWindow (hwMain); /* フレーム表示 */ } while (dwIndex