////////////////////////////////////////////////////////////////////////// // 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); }
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); } }