Virtual U.org
Get Personal Training on VU Today
    
Top shadow
 
 register/help
User Name:

Password:

Ovideo.cpp Source File
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

Ovideo.cpp

Go to the documentation of this file.
00001 //Filename    : OVIDEO.CPP
00002 //Description : Video for Windows playback class
00003 //Owner       : Gilbert
00004 
00005 // for some .h files to define some IIDs
00006 #include <windows.h>
00007 #include <windowsx.h>
00008 #include <commdlg.h>
00009 #include <string.h>
00010 #include <objbase.h>
00011 #include <strmif.h>
00012 #include <evcode.h>
00013 #include <control.h>
00014 
00015 #include <amvideo.h>
00016 #include <uuids.h>
00017 
00018 //#include <mmsystem.h>
00019 //#include <digitalv.h>
00020 
00021 #include <ALL.H>
00022 #include <OSTR.H>
00023 #include <OVIDEO.H>
00024 #include <OVGA.H>
00025 #include <OSYS.H>
00026 
00027 // --------- Define constant -------//
00028 // OATRUE and OAFALSE are defined in classes\base\ctlutil.h under active movie SDK
00029 #define OATRUE -1
00030 #define OAFALSE 0
00031 
00032 static long FAR PASCAL video_win_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
00033 static void create_dummy_window(HINSTANCE hInstance);
00034 
00035 #define FULL_SCREEN_VIDEO
00036 #define CREATE_DUMMY_WINDOW
00037 
00038 /*
00039 //--------- Begin of function Video::play() ----------//
00046 void Video::play(char* aviFileName, DWORD waitTime)
00047 {
00048 char     resultStr[101];
00049 String str;
00050 
00051 str  = "open ";
00052 str += aviFileName;
00053 str += " alias mov";
00054 
00055 mciSendString(str, NULL, 0, NULL);
00056 mciSendString("play mov fullscreen", NULL, 0, NULL);
00057 
00058 //------ wait until the whole video playback process is complete ------//
00059 
00060 while( 1 )
00061 {
00062     mciSendString( "status mov mode", resultStr, 100, NULL );
00063 
00064     if( strcmp(resultStr, "stopped")==0 )
00065         break;
00066 }
00067 
00068 //-------- wait still after playing the movie ------//
00069 
00070  DWORD curTime = m.get_time();
00071 
00072  while( m.get_time() < curTime+waitTime );
00073 
00074 //------------ close the MCI ---------------//
00075 
00076  mciSendString("close mov"              , NULL, 0, NULL);
00077  mciSendString("close avivideo", NULL, 0, NULL);
00078 }
00079 //--------- End of function Video::play() ----------//
00080 */
00081 
00082 Video::Video() {
00083     CoInitialize(NULL);
00084     state = UNINITIALIZED;
00085     pGraph = NULL;
00086     hGraphNotifyEvent = NULL;
00087     init_success = 0;
00088     skip_on_fail_flag = 0;
00089 }
00090 
00091 Video::~Video() {
00092     CoUninitialize();
00093 }
00094 
00095 void Video::set_skip_on_fail() {
00096     skip_on_fail_flag = 1;
00097 }
00098 
00099 void Video::clear_skip_on_fail() {
00100     skip_on_fail_flag = 0;
00101 }
00102 
00103 void Video::init() {
00104     IMediaEvent *pME;
00105     HRESULT hr;
00106 
00107     init_success = 0;
00108     hwnd = NULL;
00109     if( ( hr = CoCreateInstance(CLSID_FilterGraph,  // CLSID of object
00110                                 NULL,                                         // Outer unknown
00111                                 CLSCTX_INPROC_SERVER,                         // Type of server
00112                                 IID_IGraphBuilder,                            // Interface wanted
00113                                 (void **) &pGraph)                            // Returned object
00114         ) == 0 ) {
00115         // We use this to find out events sent by the filtergraph
00116         if( (hr = pGraph->QueryInterface(IID_IMediaEvent, (void **) &pME)) == 0) {
00117             if( (hr = pME->GetEventHandle( (OAEVENT*) &hGraphNotifyEvent)) == 0) {
00118                 init_success = 1;
00119                 state = STOPPED;
00120             }
00121             pME->Release();
00122         }
00123     }
00124 
00125     if( hr && !skip_on_fail_flag) {
00126         err.run("video.init error %ld", hr );
00127     }
00128 }
00129 
00130 void Video::deinit() {
00131     if( pGraph ) {
00132         pGraph->Release();
00133         pGraph = NULL;
00134     }
00135     hGraphNotifyEvent = NULL;
00136     state = UNINITIALIZED;
00137 }
00138 
00139 void Video::play( char *fileName, DWORD ) {
00140     WCHAR wPath[100];
00141     HRESULT hr;
00142     IMediaControl *pMC;
00143 
00144     if(!init_success)
00145         return;
00146 
00147     MultiByteToWideChar( CP_ACP, 0, fileName, -1, wPath, 100 );
00148 
00149     if( (hr = pGraph->RenderFile(wPath, NULL)) == 0) {
00150 
00151         // use full screen video interface
00152         // try to change display mode
00153         IVideoWindow *iVideoWindow = NULL;
00154         if( (hr = pGraph->QueryInterface(IID_IVideoWindow, (void **) &iVideoWindow)) == 0) {
00155 #ifdef CREATE_DUMMY_WINDOW
00156             if(hwnd) {
00157                 HRESULT hr2 = iVideoWindow->put_MessageDrain((OAHWND) hwnd);
00158                 hr2 = 0;
00159             }
00160 #endif
00161 
00162 #ifdef FULL_SCREEN_VIDEO
00163             IBaseFilter *iFilter;
00164             if( pGraph->FindFilterByName(L"Video Renderer", &iFilter) == 0) {
00165                 IBasicVideo *iBasicVideo;
00166                 if( iFilter->QueryInterface(IID_IBasicVideo, (void **)&iBasicVideo) == 0) {
00167                     IFullScreenVideo *iFullScreenVideo;
00168                     IDirectDrawVideo *iDirectDrawVideo;
00169                     if( iFilter->QueryInterface(IID_IFullScreenVideo, (void **)&iFullScreenVideo) == 0) {
00170                         iFullScreenVideo->Release();
00171                     }
00172                     else if( iFilter->QueryInterface(IID_IDirectDrawVideo, (void **)&iDirectDrawVideo) == 0) {
00173                         HRESULT hr2;
00174                         hr2 = iDirectDrawVideo->UseWhenFullScreen(OATRUE);
00175                         // ##### begin Gilbert 26/05/2001 ######//
00176                         iDirectDrawVideo->Release();
00177                         // ##### end Gilbert 26/05/2001 ######//
00178                     }
00179 
00180                     iBasicVideo->Release();
00181                 }
00182                 iFilter->Release();
00183             }
00184             hr=iVideoWindow->put_FullScreenMode(OATRUE);
00185 #endif
00186 
00187             /* // code to find all filter in the filter graph
00188                {
00189                IEnumFilters *iEnumFilters;
00190                pGraph->EnumFilters(&iEnumFilters);
00191 
00192                ULONG filterCount = 16;
00193                IFilter *iFilters[16];
00194                iEnumFilters->Next(filterCount, iFilters, &filterCount);
00195 
00196                for( ULONG j = 0; j < filterCount; ++j )
00197                {
00198                FILTER_INFO filterInfo;
00199                iFilters[j]->QueryFilterInfo(&filterInfo);
00200                filterInfo.pGraph->Release();
00201                iFilters[j]->Release();
00202                }
00203 
00204                iEnumFilters->Release();
00205                }*/
00206 
00207             iVideoWindow->HideCursor(OATRUE);
00208             iVideoWindow->put_Visible( OAFALSE );
00209             iVideoWindow->put_AutoShow( OAFALSE );
00210             long windowStyle;
00211             iVideoWindow->get_WindowStyle( &windowStyle);
00212             windowStyle &= ~WS_BORDER & ~WS_CAPTION & ~WS_SIZEBOX & ~WS_THICKFRAME &
00213                 ~WS_HSCROLL & ~WS_VSCROLL & ~WS_VISIBLE;
00214             iVideoWindow->put_WindowStyle( windowStyle);
00215         }
00216         else
00217             iVideoWindow = NULL;
00218 
00219         if( (hr = pGraph->QueryInterface(IID_IMediaControl, (void **) &pMC)) == 0) {
00220             pMC->Run();                                 // sometimes it returns 1, but still ok
00221             state = PLAYING;
00222             pMC->Release();
00223         }
00224 
00225         if( iVideoWindow ) {
00226             iVideoWindow->put_Visible( OAFALSE );
00227             long windowStyle;
00228             iVideoWindow->get_WindowStyle( &windowStyle);
00229             windowStyle &= ~WS_BORDER & ~WS_CAPTION & ~WS_SIZEBOX & ~WS_THICKFRAME &
00230                 ~WS_HSCROLL & ~WS_VSCROLL & ~WS_VISIBLE;
00231             iVideoWindow->put_WindowStyle( windowStyle);
00232 
00233             long maxWidth;
00234             long maxHeight;
00235             hr=iVideoWindow->GetMaxIdealImageSize( &maxWidth, &maxHeight);
00236 #ifdef FULL_SCREEN_VIDEO
00237 #else
00238             iVideoWindow->put_BorderColor( RGB(0,0,0) );
00239             iVideoWindow->put_WindowState(SW_MAXIMIZE);
00240 
00241             IBaseFilter *iFilter;
00242             if( pGraph->FindFilterByName(L"Video Renderer", &iFilter) == 0) {
00243                 IBasicVideo *iBasicVideo;
00244                 if( iFilter->QueryInterface(IID_IBasicVideo, (void **)&iBasicVideo) == 0) {
00245                     long screenWidth;
00246                     long screenHeight;
00247                     long videoWidth;
00248                     long videoHeight;
00249                     if( iVideoWindow->get_Width(&screenWidth) == 0 &&
00250                         iVideoWindow->get_Height(&screenHeight) == 0 &&
00251                         iBasicVideo->GetVideoSize(&videoWidth, &videoHeight) == 0) {
00252                         // zoom in by 2 if possible
00253                         if( screenWidth >= videoWidth * 2 &&
00254                             screenHeight >= videoHeight * 2) {
00255                             videoWidth *= 2;
00256                             videoHeight *= 2;
00257                         }
00258 
00259                         // center the video client area
00260                         iBasicVideo->SetDestinationPosition(
00261                             (screenWidth-videoWidth)/2, (screenHeight-videoHeight)/2,
00262                             videoWidth, videoHeight);
00263                     }
00264 
00265                     iBasicVideo->Release();
00266                 }
00267                 iFilter->Release();
00268             }
00269 #endif
00270             iVideoWindow->HideCursor(OATRUE);
00271             iVideoWindow->SetWindowForeground(OATRUE);
00272         }
00273 
00274         if(iVideoWindow) {
00275             iVideoWindow->Release();
00276             iVideoWindow = NULL;
00277         }
00278     }
00279 
00280     if( hr && !skip_on_fail_flag)
00281         err.run("video.play error %d", hr );
00282 }
00283 
00284 void Video::play_until_end( char *fileName, HINSTANCE hInstance, DWORD t) {
00285     HANDLE  ahObjects[1];                           // Handles that need to be waited on
00286     const int cObjects = 1;                         // Number of objects that we have
00287 
00288     if(!init_success)
00289         return;
00290 
00291     hwnd = NULL;
00292 #ifdef CREATE_DUMMY_WINDOW
00293     create_dummy_window(hInstance);
00294 #endif
00295 
00296     play(fileName, t);
00297 
00298     while( state == PLAYING ) {
00299         if( (ahObjects[ 0 ] = hGraphNotifyEvent) == NULL) {
00300             state = STOPPED;
00301             break;
00302         }
00303         DWORD Result = MsgWaitForMultipleObjects( cObjects, ahObjects,
00304                                                   FALSE, INFINITE, QS_ALLINPUT);
00305 
00306         // Have we received an event notification
00307         if( Result >= WAIT_OBJECT_0 && Result < (WAIT_OBJECT_0 + cObjects) ) {
00308             if( Result == WAIT_OBJECT_0 )
00309                 on_graph_notify();
00310         }
00311         else if( Result == WAIT_OBJECT_0 + cObjects ) {
00312             if( hwnd ) {
00313                 // message in the message queue
00314                 MSG msg;
00315                 // ########## patch begin Gilbert 7/4 ########//
00316                 while( PeekMessage(&msg, hwnd, 0, 0, PM_NOREMOVE) ) {
00317                     if( !GetMessage(&msg, hwnd, 0, 0) )
00318                         break;
00319                     TranslateMessage(&msg);
00320                     DispatchMessage(&msg);
00321                 }
00322                 // ########## patch end Gilbert 7/4 ########//
00323             }
00324         }
00325         else {
00326             // other event to wait ...
00327         }
00328     }
00329 
00330     if( hwnd ) {
00331         //PostMessage( hwnd, WM_CLOSE, 0, 0 );
00332 
00333         //handle outstanding message
00334         //MSG msg;
00335         //while( GetMessage(&msg, hwnd, 0, ~0UL) )
00336         //{
00337         //      TranslateMessage(&msg);
00338         //      DispatchMessage(&msg);
00339         //}
00340 
00341         DestroyWindow(hwnd);
00342     }
00343     hwnd = NULL;
00344 
00345     // after video end, go back to the game
00346     //  if( sys.init_flag && sys.main_hwnd )
00347     if(sys.main_hwnd ) {
00348         ShowWindow( sys.main_hwnd, SW_RESTORE );
00349         SetFocus( sys.main_hwnd );
00350     }
00351 }
00352 
00353 void Video::stop() {
00354 
00355     HRESULT hr;
00356     IMediaControl *pMC;
00357 
00358     if(!init_success)
00359         return;
00360 
00361     // Obtain the interface to our filter graph
00362     if( (hr = pGraph->QueryInterface(IID_IMediaControl, (void **) &pMC))== 0 ) {
00363         hr = pMC->Stop();
00364         pMC->Release();
00365 
00366         // rewind to the beginning
00367         IMediaPosition *pMP;
00368         if( (hr=pGraph->QueryInterface( IID_IMediaPosition, (void **) &pMP))==0) {
00369             pMP->put_CurrentPosition( 0);
00370             pMP->Release();
00371         }
00372     }
00373     // force it to stop
00374     state = STOPPED;
00375 
00376     if( hr && !skip_on_fail_flag)
00377         err.run("video.stop error %d", hr );
00378 }
00379 
00380 void Video::abort() {
00381     HRESULT hr;
00382     IMediaControl *pMC;
00383 
00384     if(!init_success)
00385         return;
00386 
00387     // Obtain the interface to our filter graph
00388     if( (hr = pGraph->QueryInterface(IID_IMediaControl, (void **) &pMC)) == 0) {
00389         // Ask the filter graph to stop and release the interface
00390         hr = pMC->Stop();
00391         pMC->Release();
00392 
00393         // rewind to the beginning
00394         IMediaPosition *pMP;
00395         if( (hr=pGraph->QueryInterface( IID_IMediaPosition, (void **) &pMP))==0) {
00396             pMP->put_CurrentPosition( 0);
00397             pMP->Release();
00398         }
00399     }
00400     state = STOPPED;
00401 
00402     if( hr && !skip_on_fail_flag)
00403         err.run("video.abort error %d", hr);
00404 }
00405 
00406 void Video::on_graph_notify() {
00407     IMediaEvent *pME;
00408     long lEventCode, lParam1, lParam2;
00409     HRESULT hr;
00410 
00411     if( (hr=pGraph->QueryInterface(IID_IMediaEvent, (void **) &pME)) == 0) {
00412         if( (hr=pME->GetEvent(&lEventCode, &lParam1, &lParam2, 0)) == 0) {
00413             switch(lEventCode) {
00414             case EC_COMPLETE:
00415                 stop();
00416                 break;
00417 
00418             case EC_USERABORT:
00419             case EC_ERRORABORT:
00420                 abort();
00421                 break;
00422             }
00423         }
00424         pME->Release();
00425     }
00426 
00427     if( hr && !skip_on_fail_flag)
00428         err.run("video.on_graph_notify error %d", hr);
00429 }
00430 
00431 static void create_dummy_window(HINSTANCE hInstance) {
00432     static ATOM classRegistered = 0;
00433 
00434     if( !classRegistered ) {                        // no need to register again
00435         //--------- register window class --------//
00436 
00437         WNDCLASS    wc;
00438         ATOM        rc;
00439 
00440         wc.style          = CS_DBLCLKS;
00441         wc.lpfnWndProc    = video_win_proc;
00442         wc.cbClsExtra     = 0;
00443         wc.cbWndExtra     = 0;
00444         wc.hInstance      = hInstance;
00445         wc.hIcon          = NULL;                     // LoadIcon( hInstance, MAKEINTATOM(IDI_ICON1));
00446         wc.hCursor        = LoadCursor( NULL, IDC_ARROW );
00447         //      #ifdef VC5
00448         wc.hbrBackground  = (HBRUSH)GetStockObject(BLACK_BRUSH);
00449         //      #else
00450         //              wc.hbrBackground  = (HBRUSH__*) GetStockObject(BLACK_BRUSH);
00451         //      #endif
00452         wc.lpszMenuName   = NULL;
00453         wc.lpszClassName  = "Virtual U Video Window";
00454 
00455         rc = RegisterClass( &wc );
00456 
00457         if( rc != 0 )
00458             classRegistered = rc;
00459         else
00460             return;
00461     }
00462 
00463     video.hwnd = CreateWindowEx(
00464         // ## begin zb 02/22/99
00465 #ifdef _DEBUG
00466         NULL,
00467 #else
00468         WS_EX_APPWINDOW | WS_EX_TOPMOST,
00469 #endif
00470         // ## end zb 02/22/99
00471         "Virtual U Video Window",
00472         "Virtual U",
00473         WS_POPUP,
00474         0,
00475         0,
00476         GetSystemMetrics(SM_CXSCREEN),
00477         GetSystemMetrics(SM_CYSCREEN),
00478         NULL,
00479         NULL,
00480         hInstance,
00481         NULL );
00482 
00483     if( !video.hwnd)
00484         return;
00485 
00486     UpdateWindow( video.hwnd );
00487     SetFocus( video.hwnd );
00488 
00489     return;
00490 }
00491 
00492 static long FAR PASCAL video_win_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
00493     switch( message ) {
00494     case WM_CREATE:
00495         video.hwnd = hWnd;
00496         break;
00497 
00498         //case WM_SYSKEYUP:
00499         //      if( (wParam==27 && lParam==0x80010001) || (wParam==9 && lParam==0xa00f0001) )
00500         //              pause();
00501         //      break;
00502 
00503     case WM_DESTROY:
00504         video.hwnd = NULL;
00505         // PostQuitMessage( 0 );
00506         break;
00507 
00508     case WM_LBUTTONDOWN:
00509         video.stop();
00510         PostMessage(hWnd, WM_CLOSE, 0, 0);
00511         break;
00512 
00513     default:
00514         break;
00515     }
00516 
00517     return DefWindowProc(hWnd, message, wParam, lParam);
00518 }

Generated on Fri Aug 23 01:38:35 2002 for VirtualU by doxygen1.2.17