Example #1
0
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;
}