HRESULT CMFCamCapture::stop() { HRESULT hr = S_OK; IMFMediaEvent *pEvent = NULL; m_spSession->Stop(); // wait for session to finish. while (1) { HRESULT hrStatus = S_OK; MediaEventType met; CHECK_HR(hr = m_spSession->GetEvent(0, &pEvent)); CHECK_HR(hr = pEvent->GetStatus(&hrStatus)); CHECK_HR(hr = pEvent->GetType(&met)); if (FAILED(hrStatus)) { DBGMSG(L"Session error: 0x%x (event id: %d)\n", hrStatus, met); hr = hrStatus; goto done; } if (met == MESessionEnded || met == MESessionStopped) { break; } SafeRelease(&pEvent); } done: return hr; }
HRESULT CPlayer::Invoke(IMFAsyncResult *pResult) { HRESULT hr = S_OK; MediaEventType meType = MEUnknown; // Event type IMFMediaEvent *pEvent = NULL; // Get the event from the event queue. CHECK_HR(hr = m_pSession->EndGetEvent(pResult, &pEvent)); // Get the event type. CHECK_HR(hr = pEvent->GetType(&meType)); // If the session is closed, the application is waiting on the // m_hCloseEvent event handle. Also, do not get any more // events from the session. if (meType == MESessionClosed) { SetEvent(m_hCloseEvent); } else { // For all other events, ask the media session for the // next event in the queue. CHECK_HR(hr = m_pSession->BeginGetEvent(this, NULL)); } // For most events, we post the event as a private window message to the // application. This lets the application process the event on it's // main thread. // However, if call to IMFMediaSession::Close is pending, it means the // application is waiting on the m_hCloseEvent event handle. (Blocking // call.) In that case, we simply discard the event. // NOTE: When IMFMediaSession::Close is called, MESessionClosed is NOT // necessarily the next event that we will receive. We may receive // any number of other events before receiving MESessionClosed. if (m_state != Closing) { // Leave a reference count on the event. pEvent->AddRef(); PostMessage(m_hwndEvent, WM_APP_PLAYER_EVENT, (WPARAM)pEvent, (LPARAM)0); } done: SAFE_RELEASE(pEvent); return S_OK; }
HRESULT CPlayer::HandleEvent(UINT_PTR pEventPtr) { HRESULT hrStatus = S_OK; HRESULT hr = S_OK; MediaEventType meType = MEUnknown; IMFMediaEvent *pEvent = (IMFMediaEvent*)pEventPtr; if (pEvent == NULL) { return E_POINTER; } // Get the event type. hr = pEvent->GetType(&meType); CHECK_HR( hr ); // Get the event status. If the operation that triggered the event // did not succeed, the status is a failure code. hr = pEvent->GetStatus(&hrStatus); // Check if the async operation succeeded. if (SUCCEEDED(hr) && FAILED(hrStatus)) { hr = hrStatus; } CHECK_HR( hr ); switch(meType) { case MESessionTopologyStatus: hr = OnTopologyStatus(pEvent); break; case MEEndOfPresentation: hr = OnPresentationEnded(pEvent); CI_LOG_V("Presentation Ended"); break; case MENewPresentation: hr = OnNewPresentation(pEvent); CI_LOG_V( "New Presentation" ); break; case MESessionTopologySet: IMFTopology * topology; GetEventObject<IMFTopology> (pEvent,&topology); WORD nodeCount; topology->GetNodeCount(&nodeCount); CI_LOG_V( "Topo set and we have " << nodeCount << " nodes" ); //cout << "Topo set and we have " << nodeCount << " nodes" << endl; SafeRelease(&topology); break; case MESessionStarted: CI_LOG_V( "Started Session" ); break; case MEBufferingStarted: CI_LOG_I( "Buffering..." ); break; case MEBufferingStopped: CI_LOG_I( "Finished Buffering..." ); break; default: hr = OnSessionEvent(pEvent, meType); break; } done: SafeRelease(&pEvent); return hr; }
// Callback for the asynchronous BeginGetEvent method. HRESULT CPlayer::Invoke(IMFAsyncResult *pResult) { MediaEventType meType = MEUnknown; // Event type IMFMediaEvent *pEvent = NULL; HRESULT hr; if ( !m_pSession ) { CI_LOG_W("Called with a null session"); return -1; //Sometimes Invoke is called but m_pSession is closed } // Handle async-loading if ( m_state == OpenAsyncPending ) { if ( !&m_pSourceResolver ) { CI_LOG_E("Async request returned with NULL session"); //ofLogError( "CPlayer::Invoke" ) << "Async request returned with NULL session"; return -1; } MF_OBJECT_TYPE ObjectType = MF_OBJECT_INVALID; IUnknown *pSourceUnk = NULL; //CheckPointer(m_pSource, E_POINTER); hr = m_pSourceResolver->EndCreateObjectFromURL( pResult, // Invoke result &ObjectType, // Receives the created object type. &pSourceUnk // Receives a pointer to the media source. ); // Get the IMFMediaSource interface from the media source. if ( SUCCEEDED( hr ) ) { hr = pSourceUnk->QueryInterface( __uuidof( IMFMediaSource ), (void**) ( &m_pSource ) ); m_state = OpenAsyncComplete; // Session finished opening URL } SafeRelease( &pSourceUnk ); return hr; } // Get the event from the event queue. hr = m_pSession->EndGetEvent(pResult, &pEvent); CHECK_HR( hr ); // Get the event type. hr = pEvent->GetType(&meType); CHECK_HR( hr ); if (meType == MESessionClosed) { // The session was closed. // The application is waiting on the m_hCloseEvent event handle. SetEvent(m_hCloseEvent); } else { // For all other events, get the next event in the queue. hr = m_pSession->BeginGetEvent(this, NULL); CHECK_HR( hr ); } // Check the application state. // If a call to IMFMediaSession::Close is pending, it means the // application is waiting on the m_hCloseEvent event and // the application's message loop is blocked. // Otherwise, post a private window message to the application. if (m_state != Closing) { // Leave a reference count on the event. pEvent->AddRef(); PostMessage(m_hwndEvent, WM_APP_PLAYER_EVENT, (WPARAM)pEvent, (LPARAM)meType); } done: SafeRelease(&pEvent); return S_OK; }
HRESULT CPlayer::HandleEvent(UINT_PTR pUnkPtr) { HRESULT hr = S_OK; HRESULT hrStatus = S_OK; // Event status MediaEventType meType = MEUnknown; // Event type MF_TOPOSTATUS TopoStatus = MF_TOPOSTATUS_INVALID; // Used with MESessionTopologyStatus event. IUnknown *pUnk = NULL; IMFMediaEvent *pEvent = NULL; // pUnkPtr is really an IUnknown pointer. pUnk = (IUnknown*)pUnkPtr; if (pUnk == NULL) { return E_POINTER; } CHECK_HR(hr = pUnk->QueryInterface(__uuidof(IMFMediaEvent), (void**)&pEvent)); // Get the event type. CHECK_HR(hr = pEvent->GetType(&meType)); // Get the event status. If the operation that triggered the event did // not succeed, the status is a failure code. CHECK_HR(hr = pEvent->GetStatus(&hrStatus)); TRACE((L"Media event: %s\n", EventName(meType))); // Check if the async operation succeeded. if (SUCCEEDED(hrStatus)) { // Switch on the event type. Update the internal state of the CPlayer as needed. switch(meType) { case MESessionTopologyStatus: // Get the status code. CHECK_HR(hr = pEvent->GetUINT32(MF_EVENT_TOPOLOGY_STATUS, (UINT32*)&TopoStatus)); switch (TopoStatus) { case MF_TOPOSTATUS_READY: hr = OnTopologyReady(pEvent); break; default: // Nothing to do. break; } break; case MEEndOfPresentation: CHECK_HR(hr = OnPresentationEnded(pEvent)); break; } } else { hr = hrStatus; } done: SAFE_RELEASE(pUnk); SAFE_RELEASE(pEvent); return hr; }
HRESULT CTranscoder::Transcode() { assert (m_pSession); IMFMediaEvent* pEvent = NULL; MediaEventType meType = MEUnknown; // Event type HRESULT hr = S_OK; HRESULT hrStatus = S_OK; // Event status //Get media session events synchronously while (meType != MESessionClosed) { hr = m_pSession->GetEvent(0, &pEvent); if (FAILED(hr)) { break; } // Get the event type. hr = pEvent->GetType(&meType); if (FAILED(hr)) { break; } hr = pEvent->GetStatus(&hrStatus); if (FAILED(hr)) { break; } if (FAILED(hrStatus)) { wprintf_s(L"Failed. 0x%X error condition triggered this event.\n", hrStatus); hr = hrStatus; break; } switch (meType) { case MESessionTopologySet: hr = Start(); if (SUCCEEDED(hr)) { wprintf_s(L"Ready to start.\n"); } break; case MESessionStarted: wprintf_s(L"Started encoding...\n"); break; case MESessionEnded: hr = m_pSession->Close(); if (SUCCEEDED(hr)) { wprintf_s(L"Finished encoding.\n"); } break; case MESessionClosed: wprintf_s(L"Output file created.\n"); break; } if (FAILED(hr)) { break; } SafeRelease(&pEvent); } SafeRelease(&pEvent); return hr; }
/** Asyncronous callback */ HRESULT FImfVideoPlayer::Invoke( IMFAsyncResult* AsyncResult ) { IMFMediaEvent* Event = NULL; HRESULT HResult = MediaSession->EndGetEvent( AsyncResult, &Event ); if( FAILED( HResult ) ) { Event->Release( ); return S_OK; } MediaEventType EventType = MEUnknown; HResult = Event->GetType( &EventType ); //Moving lower because it is referenced below to GetStatus if there was a problem: Event->Release( ); if( FAILED( HResult ) ) { Event->Release( ); return S_OK; } /* Closed */ if( EventType == MESessionClosed ) { MovieIsFinished.Set( 1 ); CloseIsPosted.Set( 1 ); } else { HResult = MediaSession->BeginGetEvent( this, NULL ); if( FAILED( HResult ) ) { Event->Release( ); return S_OK; } if( MovieIsRunning( ) ) { /* End of clip */ if( EventType == MEEndOfPresentation ) { if( Looping ) StartPlayback( ); else MovieIsFinished.Set( 1 ); } /* Unknown error, dont continue */ else if( EventType == MEError ) { HRESULT HReturnCode = S_OK; Event->GetStatus( &HReturnCode ); /* Log error HResult */ UE_LOG( LogImfVideoPlayer, Log, TEXT( "ImfVideoPlayer error recieved: %i" ), HReturnCode ); MovieIsFinished.Set( 1 ); CloseIsPosted.Set( 1 ); } } /* DEBUG: Displays all event ID's in log */ //UE_LOG( LogImfVideoPlayer, Log, TEXT( "ImfVideoPlayer event id: %i" ), EventType ); } Event->Release( ); return S_OK; }