示例#1
0
void CloseClip()
{
    HRESULT hr;

    // Stop media playback
    if(pMC)
        hr = pMC->Stop();

    // Clear global flags
    g_psCurrent = Stopped;
    g_bAudioOnly = TRUE;
    g_bFullscreen = FALSE;

    // Free DirectShow interfaces
    CloseInterfaces();

    // Clear file name to allow selection of new file with open dialog
    g_szFileName[0] = L'\0';

    // No current media state
    g_psCurrent = Init;

    // Reset the player window
    RECT rect;
    GetClientRect(ghApp, &rect);
    InvalidateRect(ghApp, &rect, TRUE);

    UpdateMainTitle();
    InitPlayerWindow();
}
示例#2
0
HRESULT ToggleMute(void)
{
    HRESULT hr=S_OK;

    if ((!pGB) || (!pBA))
        return S_OK;

    // Read current volume
    hr = pBA->get_Volume(&g_lVolume);
    if (hr == E_NOTIMPL)
    {
        // Fail quietly if this is a video-only media file
        return S_OK;
    }
    else if (FAILED(hr))
    {
        Msg(TEXT("Failed to read audio volume!  hr=0x%x\r\n"), hr);
        return hr;
    }

    // Switch volume levels
    if (g_lVolume == VOLUME_FULL)
        g_lVolume = VOLUME_SILENCE;
    else
        g_lVolume = VOLUME_FULL;

    // Set new volume
    JIF(pBA->put_Volume(g_lVolume));

    UpdateMainTitle();
    return hr;
}
示例#3
0
HRESULT ModifyRate(double dRateAdjust)
{
    HRESULT hr=S_OK;
    double dRate;

    // If the IMediaPosition interface exists, use it to set rate
    if ((pMP) && (dRateAdjust != 0))
    {
		if ((hr = pMP->get_Rate(&dRate)) == S_OK)
		{
            // Add current rate to adjustment value
            double dNewRate = dRate + dRateAdjust;
			hr = pMP->put_Rate(dNewRate);

            // Save global rate
            if (SUCCEEDED(hr))
            {
                g_PlaybackRate = dNewRate;
                UpdateMainTitle();
            }
		}
    }

    return hr;
}
示例#4
0
void OpenClip()
{
    HRESULT hr;

    // If no filename specified by command line, show file open dialog
    if(g_szFileName[0] == L'\0')
    {
        TCHAR szFilename[MAX_PATH];

        UpdateMainTitle();

        // If no filename was specified on the command line, then our video
        // window has not been created or made visible.  Make our main window
        // visible and bring to the front to allow file selection.
        InitPlayerWindow();
        ShowWindow(ghApp, SW_SHOWNORMAL);
        SetForegroundWindow(ghApp);

        if (! GetClipFileName(szFilename))
        {
            DWORD dwDlgErr = CommDlgExtendedError();

            // Don't show output if user cancelled the selection (no dlg error)
            if (dwDlgErr)
            {
                Msg(TEXT("GetClipFileName Failed! Error=0x%x\r\n"), GetLastError());
            }
            return;
        }

        // This sample does not support playback of ASX playlists.
        // Since this could be confusing to a user, display a warning
        // message if an ASX file was opened.
        if (_tcsstr((_tcslwr(szFilename)), TEXT(".asx")))
        {
            Msg(TEXT("ASX Playlists are not supported by this application.\n\n")
                TEXT("Please select a valid media file.\0"));
            return;
        }

        lstrcpy(g_szFileName, szFilename);
    }

    // Reset status variables
    g_psCurrent = Stopped;
    g_lVolume = VOLUME_FULL;
    
    // Start playing the media file
    hr = PlayMovieInWindow(g_szFileName, FALSE);

    // If we couldn't play the clip, clean up
    if (FAILED(hr) && ( hr != NS_E_LICENSE_REQUIRED ) )
        CloseClip();
}
void OpenClip()
{
    HRESULT hr;

    // If no filename specified by command line, show file open dialog
    if(g_szFileName[0] == L'\0')
    {
        TCHAR szFilename[MAX_PATH];

        UpdateMainTitle();

        InitPlayerWindow();
        SetForegroundWindow(ghApp);

        if (! GetClipFileName(szFilename))
        {
            DWORD dwDlgErr = CommDlgExtendedError();

            // Don't show output if user cancelled the selection (no dlg error)
            if (dwDlgErr)
            {
                Msg(TEXT("GetClipFileName Failed! Error=0x%x\r\n"), GetLastError());
            }
            return;
        }

        // This sample does not support playback of ASX playlists.
        // Since this could be confusing to a user, display a warning
        // message if an ASX file was opened.
        if (_tcsnicmp(szFilename, TEXT(".asx"), 4) == 0)
        {
            Msg(TEXT("ASX Playlists are not supported by this application.\n\n")
                TEXT("Please select a valid media file.\0"));
            return;
        }

        StringCchCopy(g_szFileName, NUMELMS(g_szFileName), szFilename);
    }

    // Reset status variables
    g_psCurrent = Stopped;
    g_lVolume = VOLUME_FULL;
    EnableWatermarkMenu(TRUE);

    // Start playing the media file
    hr = PlayMovieInWindow(g_szFileName);

    // If we couldn't play the clip, clean up
    if (FAILED(hr))
        CloseClip();
}
示例#6
0
void PauseClip(void)
{
    if (!pMC)
        return;

    // Toggle play/pause behavior
    if((g_psCurrent == Paused) || (g_psCurrent == Stopped))
    {
        if (SUCCEEDED(pMC->Run()))
            g_psCurrent = Running;
    }
    else
    {
        if (SUCCEEDED(pMC->Pause()))
            g_psCurrent = Paused;
    }

    UpdateMainTitle();
}
示例#7
0
HRESULT SetRate(double dRate)
{
    HRESULT hr=S_OK;

    // If the IMediaPosition interface exists, use it to set rate
    if (pMP)
    {
	    hr = pMP->put_Rate(dRate);

        // Save global rate
        if (SUCCEEDED(hr))
        {
            g_PlaybackRate = dRate;
            UpdateMainTitle();
        }
    }

    return hr;
}
示例#8
0
void StopClip(void)
{
    HRESULT hr;
    
    if ((!pMC) || (!pMS))
        return;

    // Stop and reset postion to beginning
    if((g_psCurrent == Paused) || (g_psCurrent == Running))
    {
        LONGLONG pos = 0;
        hr = pMC->Stop();
        g_psCurrent = Stopped;

        // Seek to the beginning
        hr = pMS->SetPositions(&pos, AM_SEEKING_AbsolutePositioning ,
            NULL, AM_SEEKING_NoPositioning);

        // Display the first frame to indicate the reset condition
        hr = pMC->Pause();
    }

    UpdateMainTitle();
}
示例#9
0
LRESULT OnDvdEvent(LONG lEvent, LONG lParam1, LONG lParam2)
{
    // Field DVD-specific events
    switch(lEvent)
    {
        case EC_DVD_CURRENT_HMSF_TIME:
        {
            DVD_HMSF_TIMECODE * pTC = reinterpret_cast<DVD_HMSF_TIMECODE *>(&lParam1);
            g_CurTime = *pTC;
            // If we have reached the beginning of the movie, perhaps through
            // seeking backward, then reset the rate to 1.0
            if (lParam1 == 0)
                ResetRate();

            UpdateMainTitle();  // Update the current time on the title bar
        }
        break;

        case EC_DVD_CHAPTER_START:
            g_ulCurChapter = lParam1;

            // Indicate the change of chapter
            UpdateChapterCount(g_ulCurTitle);
            UpdateCurrentChapter(g_ulCurChapter);
            break;

        case EC_DVD_TITLE_CHANGE:
            g_ulCurTitle = lParam1;
            ResetRate();

            // Indicate the change of title and refresh the chapter list
            UpdateCurrentTitle(g_ulCurTitle);
            GetAudioInfo();
            UpdateAudioInfo();
            UpdateMainTitle();
            break;

        case EC_DVD_NO_FP_PGC:
            ResetRate();
            PostMessage(ghApp, WM_COMMAND, ID_DVD_STARTMOVIE, 0);
            break;

        case EC_DVD_SUBPICTURE_STREAM_CHANGE:
            // Update the subpicture menu settings (on/off, current language, etc.)
            g_nCurrentSubpicture = lParam1;
            UpdateSubpictureInfo();
            break;

        case EC_DVD_AUDIO_STREAM_CHANGE:
            g_nCurrentAudioStream = lParam1;
            UpdateAudioInfo();
            break;

        case EC_DVD_ANGLE_CHANGE:
            // lParam1 is the number of available angles (1 means no multiangle support)
            // lParam2 is the current angle
            g_nCurrentAngle = lParam2;  
            UpdateAngleInfo();
            break;

        case EC_DVD_ANGLES_AVAILABLE:
            // Read the number of available angles
            GetAngleInfo();
            UpdateAngleInfo();

            // Enable or gray out the angle menu, depending on whether
            // we are in an angle block and angles are available.
            // Zero (0) indicates that playback is not in an angle block 
            // and angles are not available, One (1) indicates that an angle
            // block is being played back and angle changes can be performed. 
            EnableAngleMenu((BOOL) lParam1);
            break;

        case EC_DVD_STILL_ON:
            ResetRate();
            // if there is a still without buttons, we can call StillOff
            if (TRUE == lParam1)    
                g_bStillOn = true;
            break;

        case EC_DVD_STILL_OFF:
            ResetRate();
            g_bStillOn = false;     // we are no longer in a still
            break;

        case EC_DVD_PLAYBACK_STOPPED:
            ResetRate();
            break;

        case EC_DVD_DISC_EJECTED:
            HandleDiscEject();
            break;

        // When the valid UOPS values change, this event is generated.
        // Processing this event and saving the value is more efficient
        // than polling the GetCurrentUOPS() method (and prevents race conditions).
        //
        // This event indicates only which operations are explicitly disabled 
        // by the content on the DVD disc. It does not guarantee that it is 
        // valid to call methods that are not disabled. 
        case EC_DVD_VALID_UOPS_CHANGE:
            g_ulValidUOPS = (ULONG) lParam1;
            break;

        case EC_DVD_DOMAIN_CHANGE:
            switch (lParam1)
            {
                // The DVD started playing outside of the main title
                case DVD_DOMAIN_FirstPlay:  // = 1
                    // Read information about this DVD volume
                    // (audio, angles, subpicture, titles, presentation caps)
                    ReadDVDInformation();

                    // Now that the DVD volume is rendered and has started
                    // playing content, enable the options/navigation menus.
                    EnablePlaybackMenu(TRUE);
                    break;

                case DVD_DOMAIN_Stop:       // = 5
                    break ;
        
                case DVD_DOMAIN_VideoManagerMenu:  // = 2
                case DVD_DOMAIN_VideoTitleSetMenu: // = 3
                    g_bMenuOn = true;       // now menu is "On"

                    // Disable and gray out specific menus
                    EnableOptionsMenus(FALSE);
                    break ;
        
                case DVD_DOMAIN_Title:      // = 4
                    g_bMenuOn = false ;     // we are no longer in a menu

                    // Enable specific menus
                    EnableOptionsMenus(TRUE);

                    // Find out whether this title supports 4x3 PanScan, Letterbox, etc.
                    GetPresentationCaps();
                    break ;
            }

            // Remember the current domain
            g_DVDDomain = (DVD_DOMAIN) lParam1;
            ResetRate();
            break;

        case EC_DVD_ERROR:
            DbgLog((LOG_TRACE, 3, TEXT("DVD Event: Error event received (code %ld)!\0"), lParam1)) ;
            switch (lParam1)
            {
                case DVD_ERROR_Unexpected:
                    MessageBox(ghApp, 
                        TEXT("An unexpected error (possibly incorrectly authored content)")
                        TEXT("\nwas encountered.")
                        TEXT("\n\nCan't playback this DVD-Video disc.\0"),
                        TEXT("Error"), MB_OK | MB_ICONINFORMATION) ;
                    StopDVD();
                    break ;
            
                case DVD_ERROR_CopyProtectFail:
                    MessageBox(ghApp, 
                        TEXT("Key exchange for DVD copy protection failed.")
                        TEXT("\n\nCan't playback this DVD-Video disc.\0"),
                        TEXT("Error"), MB_OK | MB_ICONINFORMATION) ;
                    StopDVD();
                    break ;
            
                case DVD_ERROR_InvalidDVD1_0Disc:
                    MessageBox(ghApp, 
                        TEXT("This DVD-Video disc is incorrectly authored for v1.0  of the spec.")
                        TEXT("\n\nCan't playback this disc.\0"),
                        TEXT("Error"), MB_OK | MB_ICONINFORMATION) ;
                    StopDVD();
                    break ;
            
                case DVD_ERROR_InvalidDiscRegion:
                    MessageBox(ghApp, 
                        TEXT("This DVD-Video disc cannot be played, because it is not")
                        TEXT("\nauthored to play in the current system region.")
                        TEXT("\nThe region mismatch may be fixed by changing the")
                        TEXT("\nsystem region (with DVDRgn.exe).\0"),
                        TEXT("Error"), MB_OK | MB_ICONINFORMATION) ;
                    StopDVD();
                    break ;
            
                case DVD_ERROR_LowParentalLevel:
                    MessageBox(ghApp, 
                        TEXT("Player parental level is set lower than the lowest parental")
                        TEXT("\nlevel available in this DVD-Video content.")
                        TEXT("\n\nCan't playback this DVD-Video disc.\0"),
                        TEXT("Error"), MB_OK | MB_ICONINFORMATION) ;
                    StopDVD();
                    break ;
            
                case DVD_ERROR_MacrovisionFail:
                    MessageBox(ghApp, 
                        TEXT("This DVD-Video content is protected by Macrovision.")
                        TEXT("\nThe system does not satisfy Macrovision requirement.")
                        TEXT("\n\nCan't continue playing this disc.\0"),
                        TEXT("Error"), MB_OK | MB_ICONINFORMATION) ;
                    StopDVD();
                    break ;
            
                case DVD_ERROR_IncompatibleSystemAndDecoderRegions:
                    MessageBox(ghApp, 
                        TEXT("No DVD-Video disc can be played on this system, because ")
                        TEXT("\nthe system region does not match the decoder region.")
                        TEXT("\n\nPlease contact the manufacturer of this system.\0"),
                        TEXT("Error"), MB_OK | MB_ICONINFORMATION) ;
                    StopDVD();
                    break ;
            
                case DVD_ERROR_IncompatibleDiscAndDecoderRegions:
                    MessageBox(ghApp, 
                        TEXT("This DVD-Video disc cannot be played on this system, because it is")
                        TEXT("\nnot authored to be played in the installed decoder's region.\0"),
                        TEXT("Error"), MB_OK | MB_ICONINFORMATION) ;
                    StopDVD();
                    break ;
            }  // end of switch (lParam1)
            break ;
        

        case EC_DVD_WARNING:
            switch (lParam1)
            {
                case DVD_WARNING_InvalidDVD1_0Disc:
                    DbgLog((LOG_ERROR, 1, TEXT("DVD Warning: Current disc is not v1.0 spec compliant"))) ;
                    break ;

                case DVD_WARNING_FormatNotSupported:
                    DbgLog((LOG_ERROR, 1, TEXT("DVD Warning: The decoder does not support the new format."))) ;
                    break ;

                case DVD_WARNING_IllegalNavCommand:
                    DbgLog((LOG_ERROR, 1, TEXT("DVD Warning: An illegal navigation command was encountered."))) ;
                    break ;

                case DVD_WARNING_Open:
                    DbgLog((LOG_ERROR, 1, TEXT("DVD Warning: Could not open a file on the DVD disc."))) ;
                    MessageBox(ghApp, 
                        TEXT("A file on the DVD disc could not be opened.  ")
                        TEXT("Playback may not continue.\0"), 
                        TEXT("Warning"), MB_OK | MB_ICONINFORMATION) ;
                    break ;

                case DVD_WARNING_Seek:
                    DbgLog((LOG_ERROR, 1, TEXT("DVD Warning: Could not seek in a file on the DVD disc."))) ;
                    MessageBox(ghApp, 
                        TEXT("Could not move to a different part of a file on the DVD disc.  ")
                        TEXT("Playback may not continue.\0"), 
                        TEXT("Warning"), MB_OK | MB_ICONINFORMATION) ;
                    break ;

                case DVD_WARNING_Read:
                    DbgLog((LOG_ERROR, 1, TEXT("DVD Warning: Could not read a file on the DVD disc."))) ;
                    MessageBox(ghApp, 
                        TEXT("Could not read part of a file on the DVD disc.  ")
                        TEXT("Playback may not continue.\0"), 
                        TEXT("Warning"), MB_OK | MB_ICONINFORMATION) ;
                    break ;

                default:
                    DbgLog((LOG_ERROR, 1, TEXT("DVD Warning: An unknown warning (%ld) was received."), lParam1)) ;
                    break ;
            }
            break ;

        //
        // Ignore some messages for this sample application
        //
        case EC_DVD_PLAYBACK_RATE_CHANGE:
        case EC_DVD_BUTTON_CHANGE:
        case EC_DVD_PARENTAL_LEVEL_CHANGE:
        case EC_DVD_CHAPTER_AUTOSTOP:
        case EC_DVD_PLAYPERIOD_AUTOSTOP:
            break;

    } // end of switch(lEvent)

    return 0;
}
示例#10
0
HRESULT PlayMovieInWindow(LPTSTR szFile, BOOL bReOpenAfterLicenseAcquired)
{
    USES_CONVERSION;
    WCHAR wFile[MAX_PATH];
    HRESULT hr;

    // Check input string
    if (!szFile)
        return E_POINTER;

    // Clear open dialog remnants before calling RenderFile()
    UpdateWindow(ghApp);

    // Convert filename to wide character string
    wcsncpy(wFile, T2W(szFile), NUMELMS(wFile)-1);
    wFile[MAX_PATH-1] = 0;

    // First pass of rendering the media file.  If a DRM license must
    // be acquired before the file can be loaded, then the reopen flag
    // will be set.
    if( !bReOpenAfterLicenseAcquired )
    {
        // Get the interface for DirectShow's GraphBuilder
        JIF(CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, 
                             IID_IGraphBuilder, (void **)&pGB));

        JIF(pGB->QueryInterface(IID_IMediaEventEx, (void **)&pME));

        if(SUCCEEDED(hr))
        {
            // Have the graph signal event via window callbacks
            //
            // Start this before we insert the reader filter, since we may need
            // to monitor DRM license acquistion messages on reader creation
            //
            JIF(pME->SetNotifyWindow((OAHWND)ghApp, WM_GRAPHNOTIFY, 0));

            // Use special handling for Windows Media files
            if (IsWindowsMediaFile(szFile))
            {
                // Load the improved ASF reader filter by CLSID
                hr = CreateFilter(CLSID_WMAsfReader, &g_pReader);
                if(FAILED(hr))
                {
                    Msg(TEXT("Failed to create WMAsfWriter filter!  hr=0x%x\0"), hr);
                    return hr;
                }

                // Add the ASF reader filter to the graph.  For ASF/WMV/WMA content,
                // this filter is NOT the default and must be added explicitly.
                hr = pGB->AddFilter(g_pReader, L"ASF Reader");
                if(FAILED(hr))
                {
                    Msg(TEXT("Failed to add ASF reader filter to graph!  hr=0x%x\0"), hr);
                    return hr;
                }

                // Create the key provider that will be used to unlock the WM SDK
                JIF(AddKeyProvider(pGB));
            
                // Create the DRM license event
                g_hLicenseEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
                if( !g_hLicenseEvent )
                {
                    return E_OUTOFMEMORY;
                }

                // Set its source filename
                JIF(g_pReader->QueryInterface(IID_IFileSourceFilter, (void **) &g_pFileSource));

                // Attempt to load this file
                hr = g_pFileSource->Load(wFile, NULL);

                // Handle Digital Rights Management (DRM) errors
                if(NS_E_LICENSE_REQUIRED == hr)
                {
                    Msg(TEXT("This media file is protected by DRM and needs a license.\r\n\r\n")
                        TEXT("Attempting to acquire a license...\0"));
                    g_bWaitingForLicense = TRUE;
                    return hr;
                }
                else if(NS_E_PROTECTED_CONTENT == hr)
                {
                    Msg(TEXT("This media file is protected by DRM and needs a license.\r\n\r\n")
                        TEXT("In order to play DRM-encoded content, you must acquire a DRM stub library\r\n")
                        TEXT("from Microsoft and link it with this application.  The default version of\r\n")
                        TEXT("the WMStub.lib library does not support Digital Rights Management (DRM)."));
                    return hr;
                }
                else if (FAILED(hr))
                {
                    Msg(TEXT("Failed to load file in source filter (g_pFileSource->Load())!  hr=0x%x\0"), hr);
                    return hr;
                }

                // Render the output pins of the ASF reader to build the
                // remainder of the graph automatically
                JIF(RenderOutputPins(pGB, g_pReader));

                // Since the graph is built and the filters are added to the graph,
                // the WM ASF reader interface can be released.
                g_pReader->Release();
                g_pReader = NULL;
            }

            // Not a Windows Media file, so just render the standard way
            else
            {
                // Have the graph builder construct the appropriate graph automatically
                JIF(pGB->RenderFile(wFile, NULL));
            }
        }
    }    
    else
    {
        hr = g_pFileSource->Load(wFile, NULL);
        if( SUCCEEDED( hr ) )
        {
            Msg(TEXT("Successfully loaded file after DRM license acquisition!"));

            // Render the output pins of the ASF reader to build the
            // remainder of the graph automatically
            JIF(RenderOutputPins(pGB, g_pReader));

            // Since the graph is built and the filters are added to the graph,
            // the WM ASF reader interface can be released.
            g_pReader->Release(); // not really necessary
            g_pReader = NULL;
        }
        else
        {
            Msg(TEXT("Failed to Load file after acquiring license!  hr=0x%x\0"), hr);
        }
    }

    if( SUCCEEDED( hr ) )
    {
        // QueryInterface for DirectShow interfaces
        JIF(pGB->QueryInterface(IID_IMediaControl, (void **)&pMC));
        JIF(pGB->QueryInterface(IID_IMediaSeeking, (void **)&pMS));

        // Query for video interfaces, which may not be relevant for audio files
        JIF(pGB->QueryInterface(IID_IVideoWindow, (void **)&pVW));
        JIF(pGB->QueryInterface(IID_IBasicVideo,  (void **)&pBV));

        // Query for audio interfaces, which may not be relevant for video-only files
        JIF(pGB->QueryInterface(IID_IBasicAudio, (void **)&pBA));

        // Is this an audio-only file (no video component)?
        CheckVisibility();

        if (!g_bAudioOnly)
        {
            // Setup the video window
            JIF(pVW->put_Owner((OAHWND)ghApp));
            JIF(pVW->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN));

            JIF(InitVideoWindow(1, 1));
            GetFrameStepInterface();
        }
        else
        {
            // Initialize the default player size and enable playback menu items
            JIF(InitPlayerWindow());
            EnablePlaybackMenu(TRUE, AUDIO);
        }

        // Complete window initialization
        CheckSizeMenu(ID_FILE_SIZE_NORMAL);
        ShowWindow(ghApp, SW_SHOWNORMAL);
        UpdateWindow(ghApp);
        SetForegroundWindow(ghApp);
        g_bFullscreen = FALSE;
        UpdateMainTitle();

#ifdef REGISTER_FILTERGRAPH
        hr = AddGraphToRot(pGB, &g_dwGraphRegister);
        if (FAILED(hr))
        {
            Msg(TEXT("Failed to register filter graph with ROT!  hr=0x%x"), hr);
            g_dwGraphRegister = 0;
        }
#endif

        // Run the graph to play the media file
        JIF(pMC->Run());

        g_psCurrent=Running;
        SetFocus(ghApp);
    }

    return hr;
}
示例#11
0
HRESULT PlayMovieInWindow(LPTSTR szFile)
{
    USES_CONVERSION;
    WCHAR wFile[MAX_PATH];
    HRESULT hr;

    // Clear open dialog remnants before calling RenderFile()
    UpdateWindow(ghApp);

    // Convert filename to wide character string
    wcscpy(wFile, T2W(szFile));

    // Get the interface for DirectShow's GraphBuilder
    JIF(CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, 
                         IID_IGraphBuilder, (void **)&pGB));

    if(SUCCEEDED(hr))
    {
        // Have the graph builder construct its the appropriate graph automatically
        JIF(pGB->RenderFile(wFile, NULL));

        // QueryInterface for DirectShow interfaces
        JIF(pGB->QueryInterface(IID_IMediaControl, (void **)&pMC));
        JIF(pGB->QueryInterface(IID_IMediaEventEx, (void **)&pME));
        JIF(pGB->QueryInterface(IID_IMediaSeeking, (void **)&pMS));
        JIF(pGB->QueryInterface(IID_IMediaPosition, (void **)&pMP));

        // Query for video interfaces, which may not be relevant for audio files
        JIF(pGB->QueryInterface(IID_IVideoWindow, (void **)&pVW));
        JIF(pGB->QueryInterface(IID_IBasicVideo, (void **)&pBV));

        // Query for audio interfaces, which may not be relevant for video-only files
        JIF(pGB->QueryInterface(IID_IBasicAudio, (void **)&pBA));

        // Is this an audio-only file (no video component)?
        CheckVisibility();

        // Have the graph signal event via window callbacks for performance
        JIF(pME->SetNotifyWindow((OAHWND)ghApp, WM_GRAPHNOTIFY, 0));

        if (!g_bAudioOnly)
        {
            JIF(pVW->put_Owner((OAHWND)ghApp));
            JIF(pVW->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN));

            JIF(InitVideoWindow(1, 1));
            GetFrameStepInterface();
        }
        else
        {
            JIF(InitPlayerWindow());
        }

        // Let's get ready to rumble!
        CheckSizeMenu(ID_FILE_SIZE_NORMAL);
        ShowWindow(ghApp, SW_SHOWNORMAL);
        UpdateWindow(ghApp);
        SetForegroundWindow(ghApp);
        SetFocus(ghApp);
        g_bFullscreen = FALSE;
        g_PlaybackRate = 1.0;
        UpdateMainTitle();

#ifdef REGISTER_FILTERGRAPH
        hr = AddGraphToRot(pGB, &g_dwGraphRegister);
        if (FAILED(hr))
        {
            Msg(TEXT("Failed to register filter graph with ROT!  hr=0x%x"), hr);
            g_dwGraphRegister = 0;
        }
#endif

        // Run the graph to play the media file
        JIF(pMC->Run());
        g_psCurrent=Running;

        SetFocus(ghApp);
    }

    return hr;
}
HRESULT PlayMovieInWindow(LPTSTR szFile)
{
    HRESULT hr;

    // Check input string
    if (szFile == NULL)
        return E_POINTER;

    // Clear open dialog remnants before calling RenderFile()
    UpdateWindow(ghApp);

    // Get the interface for DirectShow's GraphBuilder
    JIF(CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
                         IID_IGraphBuilder, (void **)&pGB));

    if(SUCCEEDED(hr))
    {
        SmartPtr <IBaseFilter> pVmr;

        // Create the Video Mixing Renderer and add it to the graph
        JIF(InitializeWindowlessVMR(&pVmr));

        // Render the file programmatically to use the VMR9 as renderer.
        // Pass TRUE to create an audio renderer also.
        if (FAILED(hr = RenderFileToVideoRenderer(pGB, szFile, TRUE)))
            return hr;

        // QueryInterface for DirectShow interfaces
        JIF(pGB->QueryInterface(IID_IMediaControl, (void **)&pMC));
        JIF(pGB->QueryInterface(IID_IMediaEventEx, (void **)&pME));
        JIF(pGB->QueryInterface(IID_IMediaSeeking, (void **)&pMS));
        JIF(pGB->QueryInterface(IID_IBasicAudio, (void **)&pBA));

        // Is this an audio-only file (no video component)?
        if (CheckVideoVisibility())
        {
            JIF(InitVideoWindow(1, 1));
        }
        else
        {
            // This sample requires a video clip to be loaded
            Msg(TEXT("This sample requires media with a video component.  ")
                TEXT("Please select another file."));
            return E_FAIL;
        }

        // Add the bitmap to the VMR's input
        BlendApplicationImage(ghApp);

        // Have the graph signal event via window callbacks for performance
        JIF(pME->SetNotifyWindow((OAHWND)ghApp, WM_GRAPHNOTIFY, 0));

        // Complete the window setup
        ShowWindow(ghApp, SW_SHOWNORMAL);
        UpdateWindow(ghApp);
        SetForegroundWindow(ghApp);
        SetFocus(ghApp);
        UpdateMainTitle();

#ifdef REGISTER_FILTERGRAPH
        hr = AddGraphToRot(pGB, &g_dwGraphRegister);
        if (FAILED(hr))
        {
            Msg(TEXT("Failed to register filter graph with ROT!  hr=0x%x"), hr);
            g_dwGraphRegister = 0;
        }
#endif

        // Run the graph to play the media file
        JIF(pMC->Run());
        g_psCurrent=Running;
    }

    return hr;
}