Пример #1
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 CPlayer 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);
            }
        }
Пример #2
0
        private static HResult RunMediaSession(IMFMediaSession mediaSession)
        {
            HResult hr = S_OK;

            bool receiveSessionEvent = true;

            while (receiveSessionEvent)
            {
                HResult        hrStatus   = S_OK;
                IMFMediaEvent  mediaEvent = null;
                MediaEventType eventType  = MediaEventType.MEUnknown;

                MFTopoStatus topoStatus = MFTopoStatus.Invalid;

                hr = mediaSession.GetEvent(MFEventFlag.None, out mediaEvent);

                if (Succeeded(hr))
                {
                    hr = mediaEvent.GetStatus(out hrStatus);
                }

                if (Succeeded(hr))
                {
                    hr = mediaEvent.GetType(out eventType);
                }

                if (Succeeded(hr) && Succeeded(hrStatus))
                {
                    switch (eventType)
                    {
                    case MediaEventType.MESessionTopologySet:
                        Debug.WriteLine("MediaSession:TopologySetEvent");
                        break;

                    case MediaEventType.MESessionTopologyStatus:
                        Debug.WriteLine("MediaSession:TopologStatusEvent");

                        hr = mediaEvent.GetUINT32(MF_EVENT_TOPOLOGY_STATUS, out int topoStatusInt);

                        if (Succeeded(hr))
                        {
                            topoStatus = (MFTopoStatus)topoStatusInt;
                            switch (topoStatus)
                            {
                            case MFTopoStatus.Ready:
                                Debug.WriteLine("MediaSession:TopologyStatus: MFTopoStatus.Ready");
                                hr = mediaSession.Start();
                                break;

                            default:
                                Debug.WriteLine("MediaSession:TopologyStatus: MFTopoStatus." + topoStatus);
                                break;
                            }
                        }
                        break;

                    case MediaEventType.MESessionClosed:
                        Debug.WriteLine("MediaSession:SessionClosedEvent");
                        receiveSessionEvent = false;
                        break;

                    case MediaEventType.MESessionStopped:
                        Debug.WriteLine("MediaSession:SesssionStoppedEvent");
                        hr = mediaSession.Stop();
                        break;

                    default:
                        Debug.WriteLine("MediaSession:Event: " + eventType);
                        break;
                    }

                    mediaEvent = null;

                    if (Failed(hr) || Failed(hrStatus))
                    {
                        receiveSessionEvent = false;
                    }
                }
            }

            return(hr);
        }
Пример #3
0
        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Handles events reported by the media session TantaAsyncCallbackHandler
        /// </summary>
        /// <param name="sender">the object sending the event</param>
        /// <param name="mediaEvent">the event generated by the media session. Do NOT release this here.</param>
        /// <param name="mediaEventType">the eventType, this is just an enum</param>
        /// <history>
        ///    01 Nov 18  Cynic - Originally Written
        /// </history>
        private void HandleMediaSessionAsyncCallBackEvent(object sender, IMFMediaEvent pEvent, MediaEventType mediaEventType)
        {
            LogMessage("Media Event Type " + mediaEventType.ToString());

            switch (mediaEventType)
            {
            case MediaEventType.MESessionTopologyStatus:
                // Raised by the Media Session when the status of a topology changes.
                // Get the topology changed status code. This is an enum in the event
                int     i;
                HResult hr = pEvent.GetUINT32(MFAttributesClsid.MF_EVENT_TOPOLOGY_STATUS, out i);
                if (hr != HResult.S_OK)
                {
                    throw new Exception("HandleMediaSessionAsyncCallBackEvent call to pEvent to get the status code failed. Err=" + hr.ToString());
                }
                // the one we are most interested in is i == MFTopoStatus.Ready
                // which we get then the Topology is built and ready to run
                HandleTopologyStatusChanged(pEvent, mediaEventType, (MFTopoStatus)i);
                break;

            case MediaEventType.MESessionStarted:
                // Raised when the IMFMediaSession::Start method completes asynchronously.
                //       PlayerState = TantaEVRPlayerStateEnum.Started;
                break;

            case MediaEventType.MESessionPaused:
                // Raised when the IMFMediaSession::Pause method completes asynchronously.
                //        PlayerState = TantaEVRPlayerStateEnum.Paused;
                break;

            case MediaEventType.MESessionStopped:
                // Raised when the IMFMediaSession::Stop method completes asynchronously.
                break;

            case MediaEventType.MESessionClosed:
                // Raised when the IMFMediaSession::Close method completes asynchronously.
                break;

            case MediaEventType.MESessionCapabilitiesChanged:
                // Raised by the Media Session when the session capabilities change.
                // You can use IMFMediaEvent::GetValue to figure out what they are
                break;

            case MediaEventType.MESessionTopologySet:
                // Raised after the IMFMediaSession::SetTopology method completes asynchronously.
                // The Media Session raises this event after it resolves the topology into a full topology and queues the topology for playback.
                break;

            case MediaEventType.MESessionNotifyPresentationTime:
                // Raised by the Media Session when a new presentation starts.
                // This event indicates when the presentation will start and the offset between the presentation time and the source time.
                break;

            case MediaEventType.MEEndOfPresentation:
                // Raised by a media source when a presentation ends. This event signals that all streams
                // in the presentation are complete. The Media Session forwards this event to the application.

                // we cannot sucessfully .Finalize_ on the SinkWriter
                // if we call CloseAllMediaDevices directly from this thread
                // so we use an asynchronous method
                Task taskA = Task.Run(() => CloseAllMediaDevices());
                // we have to be on the form thread to update the screen
                ThreadSafeScreenUpdate(this, false, "Done");
                break;

            case MediaEventType.MESessionRateChanged:
                // Raised by the Media Session when the playback rate changes. This event is sent after the
                // IMFRateControl::SetRate method completes asynchronously.
                break;

            default:
                LogMessage("Unhandled Media Event Type " + mediaEventType.ToString());
                break;
            }
        }