private void CloseAllMediaDevices() { HResult hr; Console.WriteLine("CloseAllMediaDevices"); // close and release our call back handler if (mediaSessionAsyncCallbackHandler != null) { // stop any messaging or events in the call back handler mediaSessionAsyncCallbackHandler.ShutDown(); mediaSessionAsyncCallbackHandler = null; } // Shut down the source reader if (StreamReader != null) { Marshal.ReleaseComObject(StreamReader); StreamReader = null; } // close the session (this is NOT the same as shutting it down) if (mediaSession != null) { hr = mediaSession.Close(); if (hr != HResult.S_OK) { // just log it Console.WriteLine("CloseAllMediaDevices call to mediaSession.Close failed. Err=" + hr.ToString()); } } // Shut down the media source if (MediaSource != null) { hr = MediaSource.Shutdown(); if (hr != HResult.S_OK) { // just log it Console.WriteLine("CloseAllMediaDevices call to mediaSource.Shutdown failed. Err=" + hr.ToString()); } Marshal.ReleaseComObject(MediaSource); MediaSource = null; } // Shut down the media session (note we only closed it before). if (mediaSession != null) { hr = mediaSession.Shutdown(); if (hr != HResult.S_OK) { // just log it Console.WriteLine("CloseAllMediaDevices call to mediaSession.Shutdown failed. Err=" + hr.ToString()); } Marshal.ReleaseComObject(mediaSession); mediaSession = null; } if (currentVideoMediaType != null) { Marshal.ReleaseComObject(currentVideoMediaType); currentVideoMediaType = null; } }
public override void StartStream() { Task.Run(() => { // check our source filename is correct and usable StreamReaderHandler = new StreamHandler(ProcessFrame, MFBPressed); HResult hr; IMFSourceResolver pSourceResolver = null; IMFPresentationDescriptor sourcePresentationDescriptor = null; IMFStreamDescriptor videoStreamDescriptor = null; try { // reset everything CloseAllMediaDevices(); // Create the media session. hr = MFExtern.MFCreateMediaSession(null, out mediaSession); if (hr != HResult.S_OK) { throw new Exception("PrepareSessionAndTopology call to MFExtern.MFCreateMediaSession failed. Err=" + hr.ToString()); } // set up our media session call back handler. mediaSessionAsyncCallbackHandler = new AsyncCallbackHandler(); mediaSessionAsyncCallbackHandler.Initialize(); mediaSessionAsyncCallbackHandler.MediaSession = mediaSession; mediaSessionAsyncCallbackHandler.MediaSessionAsyncCallBackError = HandleMediaSessionAsyncCallBackErrors; mediaSessionAsyncCallbackHandler.MediaSessionAsyncCallBackEvent = HandleMediaSessionAsyncCallBackEvent; // Register the callback handler with the session and tell it that events can // start. This does not actually trigger an event it just lets the media session // know that it can now send them if it wishes to do so. hr = mediaSession.BeginGetEvent(mediaSessionAsyncCallbackHandler, null); if (hr != HResult.S_OK) { throw new Exception("PrepareSessionAndTopology call to mediaSession.BeginGetEvent failed. Err=" + hr.ToString()); } StreamReader = WMFUtils.CreateSourceReaderAsyncFromDevice(UnderlyingDevice, StreamReaderHandler); try { SetCurrentMediaType(StreamReader, IMFStreamIndex, 0); } catch { } try { SetCurrentMediaType(StreamReader, IMFSnapIndex, 1); } catch { } StreamReaderHandler.StreamReader = StreamReader; StreamReader.GetCurrentMediaType(1, out IMFMediaType ppMediaType); StreamReader.GetNativeMediaType(1, 0, out IMFMediaType PPMediaType); StreamReader.GetCurrentMediaType(0, out IMFMediaType ppMediaType1); StreamReader.GetNativeMediaType(0, 0, out IMFMediaType PPMediaType1); ppMediaType.GetMajorType(out Guid ppMediaTypeMGUID); PPMediaType.GetMajorType(out Guid PPMediaTypeMGUID); ppMediaType.GetGUID(MFAttributesClsid.MF_MT_SUBTYPE, out Guid ppMediaTypeSGUID); PPMediaType.GetGUID(MFAttributesClsid.MF_MT_SUBTYPE, out Guid PPMediaTypeSGUID); Console.WriteLine(WMFUtils.ConvertGuidToName(ppMediaTypeMGUID)); Console.WriteLine(WMFUtils.ConvertGuidToName(PPMediaTypeMGUID)); Console.WriteLine(WMFUtils.ConvertGuidToName(ppMediaTypeSGUID)); Console.WriteLine(WMFUtils.ConvertGuidToName(PPMediaTypeSGUID)); ppMediaType1.GetMajorType(out Guid ppMediaTypeMGUID1); PPMediaType1.GetMajorType(out Guid PPMediaTypeMGUID1); ppMediaType1.GetGUID(MFAttributesClsid.MF_MT_SUBTYPE, out Guid ppMediaTypeSGUID1); PPMediaType1.GetGUID(MFAttributesClsid.MF_MT_SUBTYPE, out Guid PPMediaTypeSGUID1); Console.WriteLine(WMFUtils.ConvertGuidToName(ppMediaTypeMGUID1)); Console.WriteLine(WMFUtils.ConvertGuidToName(PPMediaTypeMGUID1)); Console.WriteLine(WMFUtils.ConvertGuidToName(ppMediaTypeSGUID1)); Console.WriteLine(WMFUtils.ConvertGuidToName(PPMediaTypeSGUID1)); Paused = false; StreamReader.SetStreamSelection(0, true); StreamReader.SetStreamSelection(1, true); hr = StreamReader.ReadSample( 0, MediaFoundation.ReadWrite.MF_SOURCE_READER_CONTROL_FLAG.None, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero ); hr = StreamReader.ReadSample(1, MediaFoundation.ReadWrite.MF_SOURCE_READER_CONTROL_FLAG.None, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero ); if (hr != HResult.S_OK) { // we failed throw new Exception("Failed on calling the first ReadSample on the reader, retVal=" + hr.ToString()); } } catch (Exception ex) { Console.WriteLine("PrepareSessionAndTopology Error: " + ex.Message); } finally { // Clean up if (pSourceResolver != null) { Marshal.ReleaseComObject(pSourceResolver); } if (sourcePresentationDescriptor != null) { Marshal.ReleaseComObject(sourcePresentationDescriptor); } if (videoStreamDescriptor != null) { Marshal.ReleaseComObject(videoStreamDescriptor); } } }); }