Example #1
0
        //////////////////////////////////////////////////////////////////////////
        //  Name: CPlayer::Invoke
        //  Description:
        //      Implementation of CAsyncCallback::Invoke.
        //      Callback for asynchronous BeginGetEvent method.
        //  Parameter:
        //      pAsyncResult: Pointer to the result.
        //
        /////////////////////////////////////////////////////////////////////////

        HResult IMFAsyncCallback.Invoke(IMFAsyncResult pAsyncResult)
        {
            MediaEventType eventType = MediaEventType.MEUnknown;
            IMFMediaEvent  pEvent;
            PropVariant    eventData = null;
            Exception      excpt     = null;
            HResult        hr        = HResult.S_OK;

            try
            {
                HResult eventStatus = 0;             // Event status
                eventData = new PropVariant();       // Event data

                // Get the event from the event queue.
                hr = m_pMediaSession.EndGetEvent(pAsyncResult, out pEvent);
                MFError.ThrowExceptionForHR(hr);

                // Get the event type.
                hr = pEvent.GetType(out eventType);
                MFError.ThrowExceptionForHR(hr);

                // Get the event data
                hr = pEvent.GetValue(eventData);
                MFError.ThrowExceptionForHR(hr);

                // Get the event status. If the operation that triggered the event
                // did not succeed, the status is a failure code.
                hr = pEvent.GetStatus(out eventStatus);
                MFError.ThrowExceptionForHR(hr);

                // Switch on the event type. Update the internal state of the CPlayer
                // as needed.

                switch (eventType)
                {
                // Session events
                case MediaEventType.MESessionStarted:
                {
                    Debug.WriteLine(string.Format("{0}: MESessionStarted, Status: 0x{1:x}", eventType.ToString(), eventStatus));

                    m_State = PlayerState.Playing;
                    PostMessage(m_hWnd, Form1.WM_NOTIFY_APP, new IntPtr((int)eventType), new IntPtr((int)m_State));

                    break;
                }

                case MediaEventType.MESessionPaused:
                {
                    Debug.WriteLine(string.Format("{0}: MESessionPaused, Status: 0x{1:x}", eventType.ToString(), eventStatus));

                    m_State = PlayerState.Paused;
                    PostMessage(m_hWnd, Form1.WM_NOTIFY_APP, new IntPtr((int)eventType), new IntPtr((int)m_State));

                    break;
                }

                case MediaEventType.MESessionStopped:
                {
                    Debug.WriteLine(string.Format("{0}: MESessionStopped, Status: 0x{1:x}", eventType.ToString(), eventStatus));

                    m_State = PlayerState.Stopped;
                    PostMessage(m_hWnd, Form1.WM_NOTIFY_APP, new IntPtr((int)eventType), new IntPtr((int)m_State));

                    break;
                }

                case MediaEventType.MESessionTopologyStatus:
                {
                    Debug.WriteLine(string.Format("{0}: MESessionTopologyStatus, Status: 0x{1:x}", eventType.ToString(), eventStatus));

                    int value = 0;

                    hr = pEvent.GetUINT32(MFAttributesClsid.MF_EVENT_TOPOLOGY_STATUS, out value);
                    MFError.ThrowExceptionForHR(hr);
                    int  SegmentID = 0;
                    long ID;

                    //Get information about the new segment
                    IMFTopology pTopology;

                    pTopology = (IMFTopology)eventData.GetIUnknown();

                    try
                    {
                        hr = pTopology.GetTopologyID(out ID);
                        MFError.ThrowExceptionForHR(hr);
                        m_Segments.GetSegmentIDByTopoID(ID, out SegmentID);

                        topostat.iTopologyStatusType = (MFTopoStatus)value;
                        topostat.iSegmentId          = SegmentID;

                        switch (topostat.iTopologyStatusType)
                        {
                        case MFTopoStatus.StartedSource:
                            m_ActiveSegment = SegmentID;
                            break;

                        case MFTopoStatus.Ended:
                            m_ActiveSegment = -1;
                            break;
                        }

                        GCHandle gc = GCHandle.Alloc(topostat);

                        PostMessage(m_hWnd, Form1.WM_NOTIFY_APP, new IntPtr((int)MediaEventType.MESessionTopologyStatus), GCHandle.ToIntPtr(gc));
                    }
                    finally
                    {
                        SafeRelease(pTopology);
                    }

                    break;
                }

                case MediaEventType.MENewPresentation:
                {
                    Debug.WriteLine(string.Format("{0}: MENewPresentation, Status: 0x{1:x}", eventType.ToString(), eventStatus));

                    IMFPresentationDescriptor pPresentationDescriptor;

                    int SegmentId = 0;

                    pPresentationDescriptor = (IMFPresentationDescriptor)eventData.GetIUnknown();

                    try
                    {
                        //Queue the next segment on the media session
                        QueueNextSegment(pPresentationDescriptor, out SegmentId);
                    }
                    finally
                    {
                        SafeRelease(pPresentationDescriptor);
                    }

                    PostMessage(m_hWnd, Form1.WM_NOTIFY_APP, new IntPtr((int)eventType), new IntPtr(SegmentId));

                    break;
                }

                case MediaEventType.MEEndOfPresentation:
                {
                    Debug.WriteLine(string.Format("{0}: MEEndOfPresentation, Status: 0x{1:x}", eventType.ToString(), eventStatus));

                    int value = 0;

                    try
                    {
                        hr = pEvent.GetUINT32(MFAttributesClsid.MF_EVENT_SOURCE_TOPOLOGY_CANCELED, out value);
                        MFError.ThrowExceptionForHR(hr);
                    }
                    catch { }

                    PostMessage(m_hWnd, Form1.WM_NOTIFY_APP, new IntPtr((int)eventType), new IntPtr(value));

                    break;
                }

                case MediaEventType.MEEndOfPresentationSegment:
                {
                    Debug.WriteLine(string.Format("{0}: MEEndOfPresentationSegment, Status: 0x{1:x}", eventType.ToString(), eventStatus));

                    int value = 0;

                    try
                    {
                        hr = pEvent.GetUINT32(MFAttributesClsid.MF_EVENT_SOURCE_TOPOLOGY_CANCELED, out value);
                        MFError.ThrowExceptionForHR(hr);
                    }
                    catch { }

                    PostMessage(m_hWnd, Form1.WM_NOTIFY_APP, new IntPtr((int)eventType), new IntPtr(value));

                    break;
                }

                case MediaEventType.MESessionNotifyPresentationTime:
                {
                    Debug.WriteLine(string.Format("{0}: MESessionNotifyPresentationTime, Status: 0x{1:x}", eventType.ToString(), eventStatus));

                    HandleNotifyPresentationTime(pEvent);
                    break;
                }

                case MediaEventType.MESessionClosed:
                {
                    Debug.WriteLine(string.Format("{0}: MESessionClosed, Status: 0x{1:x}", eventType.ToString(), eventStatus));

                    m_hCloseEvent.Set();

                    break;
                }

                default:
                    Debug.WriteLine(string.Format("{0}: Event", eventType.ToString()));
                    break;
                }
            }
            catch (Exception e)
            {
                excpt = e;
            }
            finally
            {
                if (eventData != null)
                {
                    eventData.Clear();
                }
            }

            // Request another event.
            if (eventType != MediaEventType.MESessionClosed)
            {
                hr = m_pMediaSession.BeginGetEvent(this, null);
                MFError.ThrowExceptionForHR(hr);
            }

            if (excpt == null)
            {
                hr = HResult.S_OK;
            }
            else
            {
                hr = (HResult)Marshal.GetHRForException(excpt);
            }

            return(hr);
        }
Example #2
0
        void IMFAsyncCallback.Invoke(IMFAsyncResult pResult)
        {
            IMFMediaEvent  pEvent     = null;
            MediaEventType meType     = MediaEventType.MEUnknown; // Event type
            int            hrStatus   = 0;                        // Event status
            MFTopoStatus   TopoStatus = MFTopoStatus.Invalid;     // Used with MESessionTopologyStatus event.

            try
            {
                // Get the event from the event queue.
                m_pSession.EndGetEvent(pResult, out pEvent);

                // Get the event type.
                pEvent.GetType(out meType);

                // Get the event status. If the operation that triggered the event did
                // not succeed, the status is a failure code.
                pEvent.GetStatus(out hrStatus);

                TRACE(string.Format("Media Event: " + meType.ToString()));

                // Check if the async operation succeeded.
                if (Succeeded(hrStatus))
                {
                    // Switch on the event type. Update the internal state of the Media as needed.
                    switch (meType)
                    {
                    case MediaEventType.MESessionTopologyStatus:
                        // Get the status code.
                        int i;
                        pEvent.GetUINT32(MFAttributesClsid.MF_EVENT_TOPOLOGY_STATUS, out i);
                        TopoStatus = (MFTopoStatus)i;
                        switch (TopoStatus)
                        {
                        case MFTopoStatus.Ready:
                            OnTopologyReady(pEvent);
                            break;

                        default:
                            // Nothing to do.
                            break;
                        }
                        break;

                    case MediaEventType.MESessionStarted:
                        OnSessionStarted(pEvent);
                        break;

                    case MediaEventType.MESessionPaused:
                        OnSessionPaused(pEvent);
                        break;

                    case MediaEventType.MESessionClosed:
                        OnSessionClosed(pEvent);
                        break;

                    case MediaEventType.MEEndOfPresentation:
                        OnPresentationEnded(pEvent);
                        break;
                    }
                }
                else
                {
                    // The async operation failed. Notify the application
                    NotifyError(hrStatus);
                }
            }
            finally
            {
                // Request another event.
                if (meType != MediaEventType.MESessionClosed)
                {
                    m_pSession.BeginGetEvent(this, null);
                }

                SafeRelease(pEvent);
            }
        }