Example #1
0
 private static void AddAttribute(IMFActivate mft, int index, StringBuilder sb)
 {
     var variantPtr = Marshal.AllocHGlobal(MarshalHelpers.SizeOf<PropVariant>());
     try
     {
         Guid key;
         mft.GetItemByIndex(index, out key, variantPtr);
         var value = MarshalHelpers.PtrToStructure<PropVariant>(variantPtr);
         string propertyName = FieldDescriptionHelper.Describe(typeof (MediaFoundationAttributes), key);
         if (key == MediaFoundationAttributes.MFT_INPUT_TYPES_Attributes ||
             key == MediaFoundationAttributes.MFT_OUTPUT_TYPES_Attributes)
         {
             var types = value.GetBlobAsArrayOf<MFT_REGISTER_TYPE_INFO>();
             sb.AppendFormat("{0}: {1} items:", propertyName, types.Length);
             sb.AppendLine();
             foreach (var t in types)
             {
                 sb.AppendFormat("    {0}-{1}",
                     FieldDescriptionHelper.Describe(typeof (MediaTypes), t.guidMajorType),
                     FieldDescriptionHelper.Describe(typeof (AudioSubtypes), t.guidSubtype));
                 sb.AppendLine();
             }
         }
         else if (key == MediaFoundationAttributes.MF_TRANSFORM_CATEGORY_Attribute)
         {
             sb.AppendFormat("{0}: {1}", propertyName,
                 FieldDescriptionHelper.Describe(typeof (MediaFoundationTransformCategories), (Guid) value.Value));
             sb.AppendLine();
         }
         else if (value.DataType == (VarEnum.VT_VECTOR | VarEnum.VT_UI1))
         {
             var b = (byte[]) value.Value;
             sb.AppendFormat("{0}: Blob of {1} bytes", propertyName, b.Length);
             sb.AppendLine();
         }
         else
         {
             sb.AppendFormat("{0}: {1}", propertyName, value.Value);
             sb.AppendLine();
         }
     }
     finally
     {
         PropVariant.Clear(variantPtr);
         Marshal.FreeHGlobal(variantPtr);
     }
 }
 private object CreateResamplerComObjectUsingActivator()
 {
     var transformActivators = MediaFoundationApi.EnumerateTransforms(MediaFoundationTransformCategories.AudioEffect);
     foreach (var activator in transformActivators)
     {
         Guid clsid;
         activator.GetGUID(MediaFoundationAttributes.MFT_TRANSFORM_CLSID_Attribute, out clsid);
         if (clsid.Equals(ResamplerClsid))
         {
             object comObject;
             activator.ActivateObject(IMFTransformIid, out comObject);
             activate = activator;
             return comObject;
         }
     }
     return null;
 }
        /// <summary>
        /// Enumerate the installed MediaFoundation transforms in the specified category
        /// </summary>
        /// <param name="category">A category from MediaFoundationTransformCategories</param>
        /// <returns></returns>
        public static IEnumerable<IMFActivate> EnumerateTransforms(Guid category)
        {
            IntPtr interfacesPointer;
            int interfaceCount;
            MediaFoundationInterop.MFTEnumEx(category, _MFT_ENUM_FLAG.MFT_ENUM_FLAG_ALL,
                null, null, out interfacesPointer, out interfaceCount);
            var interfaces = new IMFActivate[interfaceCount];
            for (int n = 0; n < interfaceCount; n++)
            {
                var ptr =
                    Marshal.ReadIntPtr(new IntPtr(interfacesPointer.ToInt64() + n*Marshal.SizeOf(interfacesPointer)));
                interfaces[n] = (IMFActivate) Marshal.GetObjectForIUnknown(ptr);
            }

            foreach (var i in interfaces)
            {
                yield return i;
            }
            Marshal.FreeCoTaskMem(interfacesPointer);
        }
Example #4
0
    ///////////////////////////////////////////////////////////////////////
    //  Name: BeginEnableContent
    //  Description:  Called by the PMP session to start the enable action.
    /////////////////////////////////////////////////////////////////////////
    public int BeginEnableContent(
        IMFActivate pEnablerActivate,
        IMFTopology pTopo,
        IMFAsyncCallback pCallback,
        object punkState
        )
    {
        // Make sure we *never* leave this entry point with an exception
        try
        {
            Debug.WriteLine("ContentProtectionManager::BeginEnableContent");

            if (m_pEnabler != null)
            {
                throw new COMException("A previous call is still pending", E_Fail);
            }

            int hr;

            // Save so we can create an async result later
            m_pCallback = pCallback;
            m_punkState = punkState;

            // Create the enabler from the IMFActivate pointer.
            object o;
            hr = pEnablerActivate.ActivateObject(typeof(IMFContentEnabler).GUID, out o);
            MFError.ThrowExceptionForHR(hr);
            m_pEnabler = o as IMFContentEnabler;

            // Notify the application. The application will call DoEnable from the app thread.
            m_state = Enabler.Ready; // Reset the state.
            PostMessage(m_hwnd, WM_APP_CONTENT_ENABLER, IntPtr.Zero, IntPtr.Zero);

            return S_Ok;
        }
        catch (Exception e)
        {
            return Marshal.GetHRForException(e);
        }
    }
Example #5
0
 public static extern void MFCreateAudioRendererActivate(
     out IMFActivate ppActivate
     );
Example #6
0
 //-------------------------------------------------------------------
 //  CloseDevice
 //
 //  Releases all resources held by this object.
 //-------------------------------------------------------------------
 public virtual int CloseDevice()
 {
     lock (LockSync)
     {
         SafeRelease(PReader);
         PReader = null;
         pActivate?.ShutdownObject();
         pActivate = null;
         PwszSymbolicLink = null;
         Draw.DrawNullFrame();
     }
     return S_Ok;
 }
        /// <summary>
        /// Disposes this resampler
        /// </summary>
        protected override void Dispose(bool disposing)
        {
            if (activate != null)
            {
                activate.ShutdownObject();
                activate = null;
            }

            base.Dispose(disposing);
        }
Example #8
0
        /// <summary>
        /// Create media ouput node
        /// </summary>
        /// <param name="pSourceSD"></param>
        /// <param name="ppNode"></param>
        protected void CreateOutputNode(
            IMFStreamDescriptor pSourceSD,
            out IMFTopologyNode ppNode)
        {
            IMFTopologyNode     pNode             = null;
            IMFMediaTypeHandler pHandler          = null;
            IMFActivate         pRendererActivate = null;

            Guid guidMajorType = Guid.Empty;
            int  hr            = S_Ok;

            // Get the stream ID.
            int streamID = 0;

            try
            {
                try
                {
                    pSourceSD.GetStreamIdentifier(out streamID); // Just for debugging, ignore any failures.
                }
                catch
                {
                    TRACE("IMFStreamDescriptor::GetStreamIdentifier" + hr.ToString());
                }

                // Get the media type handler for the stream.
                pSourceSD.GetMediaTypeHandler(out pHandler);

                // Get the major media type.
                pHandler.GetMajorType(out guidMajorType);

                // Create a downstream node.
                MFExtern.MFCreateTopologyNode(MFTopologyType.OutputNode, out pNode);

                // Create an IMFActivate object for the renderer, based on the media type.
                if (MFMediaType.Audio == guidMajorType)
                {
                    // Create the audio renderer.
                    TRACE(string.Format("Stream {0}: Audio Stream", streamID));
                    MFExtern.MFCreateAudioRendererActivate(out pRendererActivate);
                }
                else if (MFMediaType.Video == guidMajorType)
                {
                    // Create the video renderer.
                    TRACE(string.Format("Stream {0}: Video Stream", streamID));
                    MFExtern.MFCreateVideoRendererActivate(m_hwndVideo, out pRendererActivate);
                }
                else
                {
                    TRACE(string.Format("Stream {0}: Unknown Format", streamID));
                    throw new COMException("Unknown Format", E_Fail);
                }

                // Set the IActivate object on the output node.
                pNode.SetObject(pRendererActivate);

                // Return the IMFTopologyNode pointer to the caller.
                ppNode = pNode;
            }
            catch
            {
                // If we failed, release the pNode
                SafeRelease(pNode);
                throw;
            }
            finally
            {
                // Clean up.
                SafeRelease(pHandler);
                SafeRelease(pRendererActivate);
            }
        }
Example #9
0
 // ----- Public Methods -----------------------------------------------
 //////////////////////////////////////////////////////////////////////////
 //  Name: CPlayer
 //  Description: Constructor
 //
 /////////////////////////////////////////////////////////////////////////
 public CPlayer(IntPtr hWnd)
 {
     m_hWnd = hWnd;
     m_pMediaSession = null;
     m_pSequencerSource = null;
     m_pAudioRendererActivate = null;
     m_pPresentationClock = null;
     m_PresentationTimeOffset = 0;
     m_phnsTimePairStart = null;
     m_phnsTimePairEnd = null;
     m_State = PlayerState.PlayerCreated;
     m_ActiveSegment = -1;
     m_hCloseEvent = new AutoResetEvent(false);
 }
Example #10
0
        protected IMFTopologyNode CreateOutputNode(IMFStreamDescriptor pSourceSD)
        {
            IMFTopologyNode     pNode             = null;
            IMFMediaTypeHandler pHandler          = null;
            IMFActivate         pRendererActivate = null;

            Guid guidMajorType = Guid.Empty;
            int  hr            = 0;

            // Get the stream ID.
            int streamID = 0;

            try
            {
                try
                {
                    hr = pSourceSD.GetStreamIdentifier(out streamID); // Just for debugging, ignore any failures.
                    MFError.ThrowExceptionForHR(hr);
                }
                catch
                {
                    //TRACE("IMFStreamDescriptor::GetStreamIdentifier" + hr.ToString());
                }

                // Get the media type handler for the stream.
                hr = pSourceSD.GetMediaTypeHandler(out pHandler);
                MFError.ThrowExceptionForHR(hr);

                // Get the major media type.
                hr = pHandler.GetMajorType(out guidMajorType);
                MFError.ThrowExceptionForHR(hr);

                // Create a downstream node.
                hr = MFExtern.MFCreateTopologyNode(MFTopologyType.OutputNode, out pNode);
                MFError.ThrowExceptionForHR(hr);

                // Create an IMFActivate object for the renderer, based on the media type.
                if (MFMediaType.Audio == guidMajorType)
                {
                    // Create the audio renderer.
                    hr = MFExtern.MFCreateAudioRendererActivate(out pRendererActivate);
                    MFError.ThrowExceptionForHR(hr);
                    object sar;
                    pRendererActivate.ActivateObject(typeof(IMFMediaSink).GUID, out sar);
                    StreamingAudioRenderer = sar as IMFMediaSink;
                }
                else if (MFMediaType.Video == guidMajorType)
                {
                    // Create the video renderer.
                    pRendererActivate = CreateVideoRenderer();
                }
                else
                {
                    //TRACE(string.Format("Stream {0}: Unknown format", streamID));
                    throw new COMException("Unknown format");
                }

                // Set the IActivate object on the output node.
                hr = pNode.SetObject(pRendererActivate);
                MFError.ThrowExceptionForHR(hr);
            }
            catch (Exception ex)
            {
                // If we failed, release the pNode
                COMBase.SafeRelease(pNode);
                throw;
            }
            finally
            {
                // Clean up.
                COMBase.SafeRelease(pHandler);
                COMBase.SafeRelease(pRendererActivate);
            }
            return(pNode);
        }
Example #11
0
 public static extern void MFCreateASFMediaSinkActivate(
     [MarshalAs(UnmanagedType.LPWStr)] string pwszFileName,
     IMFASFContentInfo pContentInfo,
     out IMFActivate ppIActivate
     );
Example #12
0
        public HResult StartCapture(
            IMFActivate pActivate,
            string pwszFileName,
            EncodingParameters param
            )
        {
            HResult hr = HResult.S_OK;

            IMFMediaSource pSource = null;
            object         pS;

            lock (this)
            {
                // Create the media source for the device.
                hr = pActivate.ActivateObject(
                    typeof(IMFMediaSource).GUID,
                    out pS
                    );
                pSource = (IMFMediaSource)pS;

                // Get the symbolic link. This is needed to handle device-
                // loss notifications. (See CheckDeviceLost.)

                if (Succeeded(hr))
                {
                    int iSize;
                    hr = pActivate.GetAllocatedString(
                        MFAttributesClsid.MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK,
                        out m_pwszSymbolicLink,
                        out iSize
                        );
                }

                if (Succeeded(hr))
                {
                    hr = OpenMediaSource(pSource);
                }

                // Create the sink writer
                if (Succeeded(hr))
                {
                    hr = MFExtern.MFCreateSinkWriterFromURL(
                        pwszFileName,
                        null,
                        null,
                        out m_pWriter
                        );
                }

                // Set up the encoding parameters.
                if (Succeeded(hr))
                {
                    hr = ConfigureCapture(param);
                }

                if (Succeeded(hr))
                {
                    m_bFirstSample = true;
                    m_llBaseTime   = 0;

                    // Request the first video frame.

                    hr = m_pReader.ReadSample(
                        MF_SOURCE_READER_FIRST_VIDEO_STREAM,
                        0,
                        IntPtr.Zero,
                        IntPtr.Zero,
                        IntPtr.Zero,
                        IntPtr.Zero
                        );
                }

                SafeRelease(pSource);
            }

            return(hr);
        }
Example #13
0
 public MFDevice(IMFActivate Mon)
 {
     m_Activator    = Mon;
     m_FriendlyName = null;
     m_SymbolicName = null;
 }
Example #14
0
 public void Dispose()
 {
     if (m_Activator != null)
     {
         Marshal.ReleaseComObject(m_Activator);
         m_Activator = null;
         GC.SuppressFinalize(this);
     }
     m_FriendlyName = null;
 }
Example #15
0
 public MFDevice(IMFActivate Mon)
 {
     m_Activator = Mon;
     m_FriendlyName = null;
     m_SymbolicName = null;
 }
Example #16
0
        public int StartCapture(
            IMFActivate pActivate,
            string pwszFileName,
            EncodingParameters param
            )
        {
            int hr = S_Ok;

            IMFMediaSource pSource = null;
            object pS;

            lock (this)
            {
                // Create the media source for the device.
                hr = pActivate.ActivateObject(
                    typeof(IMFMediaSource).GUID,
                    out pS
                    );
                pSource = (IMFMediaSource)pS;

                // Get the symbolic link. This is needed to handle device-
                // loss notifications. (See CheckDeviceLost.)

                if (Succeeded(hr))
                {
                    int iSize;
                    hr = pActivate.GetAllocatedString(
                        MFAttributesClsid.MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK,
                        out m_pwszSymbolicLink,
                        out iSize
                        );
                }

                if (Succeeded(hr))
                {
                    hr = OpenMediaSource(pSource);
                }

                // Create the sink writer
                if (Succeeded(hr))
                {
                    hr = MFExtern.MFCreateSinkWriterFromURL(
                        pwszFileName,
                        null,
                        null,
                        out m_pWriter
                        );
                }

                // Set up the encoding parameters.
                if (Succeeded(hr))
                {
                    hr = ConfigureCapture(param);
                }

                if (Succeeded(hr))
                {
                    m_bFirstSample = true;
                    m_llBaseTime = 0;

                    // Request the first video frame.

                    hr = m_pReader.ReadSample(
                        MF_SOURCE_READER_FIRST_VIDEO_STREAM,
                        0,
                        IntPtr.Zero,
                        IntPtr.Zero,
                        IntPtr.Zero,
                        IntPtr.Zero
                        );
                }

                SafeRelease(pSource);
            }

            return hr;
        }
Example #17
0
        /// <summary>
        /// Adds an effect to a capture streamIndex.
        /// </summary>
        /// <param name="captureSource">A valid IMFCaptureSource instance.</param>
        /// <param name="sourceStream">A member of the <see cref="CaptureEngineStreams"/> enumeration.</param>
        /// <param name="activate">An MFT activation instance.</param>
        /// <returns>If this function succeeds, it returns the S_OK member. Otherwise, it returns another HResult's member that describe the error.</returns>
        public static HResult AddEffect(this IMFCaptureSource captureSource, CaptureEngineStreams sourceStream, IMFActivate activate)
        {
            if (captureSource == null)
            {
                throw new ArgumentNullException("captureSource");
            }

            return(captureSource.AddEffect((int)sourceStream, activate));
        }
Example #18
0
        /// <summary>
        /// Adds an effect to a capture streamIndex.
        /// </summary>
        /// <param name="captureSource">A valid IMFCaptureSource instance.</param>
        /// <param name="sourceStreamIndex">The capture streamIndex.</param>
        /// <param name="activate">An MFT activation instance.</param>
        /// <returns>If this function succeeds, it returns the S_OK member. Otherwise, it returns another HResult's member that describe the error.</returns>
        public static HResult AddEffect(this IMFCaptureSource captureSource, int sourceStreamIndex, IMFActivate activate)
        {
            if (captureSource == null)
            {
                throw new ArgumentNullException("captureSource");
            }

            return(captureSource.AddEffect(sourceStreamIndex, activate));
        }
Example #19
0
 public static extern void MFCreatePMPMediaSession(
     MFPMPSessionCreationFlags dwCreationFlags,
     IMFAttributes pConfiguration,
     out IMFMediaSession ppMediaSession,
     out IMFActivate ppEnablerActivate
     );
Example #20
0
 public static extern void MFCreateSampleGrabberSinkActivate(
     IMFMediaType pIMFMediaType,
     IMFSampleGrabberSinkCallback pIMFSampleGrabberSinkCallback,
     out IMFActivate ppIActivate
     );
Example #21
0
 public MfDevice(IMFActivate moniker)
 {
     Activator = moniker;
     friendlyName = null;
     symbolicName = null;
 }
Example #22
0
 public static extern void MFCreateWMAEncoderActivate(
     IMFMediaType pMediaType,
     IPropertyStore pEncodingConfigurationProperties,
     out IMFActivate ppActivate
     );
Example #23
0
        //-------------------------------------------------------------------
        // SetDevice
        //
        // Set up preview for a specified video capture device.
        //-------------------------------------------------------------------

        public HResult SetDevice(MFDevice pDevice)
        {
            HResult hr = HResult.S_OK;

            IMFActivate    pActivate   = pDevice.Activator;
            IMFMediaSource pSource     = null;
            IMFAttributes  pAttributes = null;
            object         o           = null;

            lock (this)
            {
                try
                {
                    // Release the current device, if any.
                    hr = CloseDevice();

                    if (Succeeded(hr))
                    {
                        // Create the media source for the device.
                        hr = pActivate.ActivateObject(typeof(IMFMediaSource).GUID, out o);
                    }

                    if (Succeeded(hr))
                    {
                        pSource = (IMFMediaSource)o;
                    }

                    // Get Symbolic device link
                    m_pwszSymbolicLink = pDevice.SymbolicName;

                    //
                    // Create the source reader.
                    //

                    // Create an attribute store to hold initialization settings.

                    if (Succeeded(hr))
                    {
                        hr = MFExtern.MFCreateAttributes(out pAttributes, 2);
                    }

                    if (Succeeded(hr))
                    {
                        hr = pAttributes.SetUINT32(MFAttributesClsid.MF_READWRITE_DISABLE_CONVERTERS, 1);
                    }

                    if (Succeeded(hr))
                    {
                        hr = pAttributes.SetUnknown(MFAttributesClsid.MF_SOURCE_READER_ASYNC_CALLBACK, this);
                    }

                    IMFSourceReader pRead = null;
                    if (Succeeded(hr))
                    {
                        hr = MFExtern.MFCreateSourceReaderFromMediaSource(pSource, pAttributes, out pRead);
                    }

                    if (Succeeded(hr))
                    {
                        m_pReader = (IMFSourceReaderAsync)pRead;
                    }

                    if (Succeeded(hr))
                    {
                        // Try to find a suitable output type.
                        for (int i = 0; ; i++)
                        {
                            IMFMediaType pType;
                            hr = m_pReader.GetNativeMediaType((int)MF_SOURCE_READER.FirstVideoStream, i, out pType);
                            if (Failed(hr))
                            {
                                break;
                            }

                            try
                            {
                                hr = TryMediaType(pType);
                                if (Succeeded(hr))
                                {
                                    // Found an output type.
                                    break;
                                }
                            }
                            finally
                            {
                                SafeRelease(pType);
                            }
                        }
                    }

                    if (Succeeded(hr))
                    {
                        hr = ConfigWriter();
                        if (Succeeded(hr))
                        {
                            m_draw.SetBitmap(BitmapOverlayFile);

                            // Ask for the first sample.
                            hr = m_pReader.ReadSample((int)MF_SOURCE_READER.FirstVideoStream, 0, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
                        }
                    }

                    if (Failed(hr))
                    {
                        if (pSource != null)
                        {
                            pSource.Shutdown();

                            // NOTE: The source reader shuts down the media source
                            // by default, but we might not have gotten that far.
                        }
                        CloseDevice();
                    }
                }
                finally
                {
                    SafeRelease(pSource);
                    SafeRelease(pAttributes);
                }
            }

            return(hr);
        }
Example #24
0
        /// <summary>
        /// Creates a new renderer and configures it with a custom allocator
        /// </summary>
        /// <param name="rendererType">The type of renderer we wish to choose</param>
        /// <param name="graph">The DirectShow graph to add the renderer to</param>
        /// <returns>An initialized DirectShow renderer</returns>
        protected IMFActivate CreateVideoRenderer()
        {
            //register the allocator and get the events
            //presenter = EvrPresenter.CreateNew();
            //RegisterCustomAllocator(CustomEVR as ICustomAllocator);
            //return hr;
            MediaFoundation.MediaPlayers.EVR.EvrPresenter presenter;
            IMFActivate activate = null;

            int hr = 0;

            lock (m_videoRendererInitLock)
            {
                IntPtr handle = GetDesktopWindow();//HwndHelper.Handle;

                try
                {
                    hr = MFExtern.MFCreateVideoRendererActivate(handle, out activate);
                }
                catch (Exception ex)
                {
                    throw ex;
                }
                //var evr = new EnhancedVideoRenderer();


                /* Create a new EVR presenter */
                presenter = MediaFoundation.MediaPlayers.EVR.EvrPresenter.CreateNew(activate);


                var presenterSettings = presenter.VideoPresenter as IEVRPresenterSettings;
                if (presenterSettings == null)
                {
                    throw new Exception("Could not QueryInterface for the IEVRPresenterSettings");
                }

                //presenterSettings.SetBufferCount(3);
                presenterSettings.SetBufferCount(4);

                /* Use our interop hWnd */


                /* QueryInterface the IMFVideoDisplayControl */
                var displayControl = presenter.VideoPresenter as IMFVideoDisplayControl;

                if (displayControl == null)
                {
                    throw new Exception("Could not QueryInterface the IMFVideoDisplayControl");
                }

                /* Configure the presenter with our hWnd */
                hr = displayControl.SetVideoWindow(handle);
                //DsError.ThrowExceptionForHR(hr);

                /*var filterConfig = evr as IEVRFilterConfig;
                 *
                 * if (filterConfig != null)
                 *  filterConfig.SetNumberOfStreams(1/*streamCount);*/
            }


            RegisterCustomAllocator(presenter as ICustomAllocator);

            return(activate);
        }
Example #25
0
 public static ComObject <T> ActivateObject <T>(this IMFActivate input) => ActivateObject <T>(input, typeof(T).GUID);
Example #26
0
 public MfDevice(IMFActivate moniker)
 {
     Activator    = moniker;
     friendlyName = null;
     symbolicName = null;
 }
Example #27
0
 public static extern HResult MFCreateAudioRendererActivate(
     out IMFActivate ppActivate
     );
Example #28
0
        private int GetSelectedDevice(out IMFActivate ppActivate)
        {
            // First get the index of the selected item in the combo box.
            int iListIndex = cbDeviceList.SelectedIndex;

            if (iListIndex < 0)
            {
                ppActivate = null;
                return -1;
            }

            // Parse out the IMFActivate
            MFDevice di = cbDeviceList.SelectedItem as MFDevice;
            ppActivate = di.Activator;

            return 0;
        }
Example #29
0
 public static extern void MFCreateVideoRendererActivate(
     IntPtr hwndVideo,
     out IMFActivate ppActivate
     );
Example #30
0
 public static ComObject <T> ActivateObject <T>(this IMFActivate obj) => ActivateObject <T>(obj, typeof(T).GUID);
Example #31
0
        //-------------------------------------------------------------------
        // SetDevice
        //
        // Set up preview for a specified video capture device.
        //-------------------------------------------------------------------
        public int SetDevice(MfDevice pDevice, ref string format)
        {
            int hr;
            IMFMediaSource pSource = null;
            lock (LockSync)
            {
                try
                {
                    // Release the current device, if any.
                    hr = CloseDevice();
                    pActivate = pDevice.Activator;
                    object o = null;
                    if (Succeeded(hr))
                    {
                        // Create the media source for the device.
                        hr = pActivate.ActivateObject(typeof(IMFMediaSource).GUID, out o);
                    }

                    if (Succeeded(hr))
                    {
                        pSource = (IMFMediaSource)o;
                    }

                    // Get Symbolic device link
                    PwszSymbolicLink = pDevice.SymbolicName;

                    // Create the source reader.
                    if (Succeeded(hr))
                    {
                        hr = OpenMediaSource(pSource, ref PReader);
                    }

                    if (Succeeded(hr))
                    {
                        var index = GetOptimizedFormatIndex(ref format);
                        if (index>=0)
                            hr = ConfigureSourceReader(index);
                    }

                    if (Failed(hr))
                    {

                        pSource?.Shutdown();
                        //pActivate.ShutdownObject();
                        // NOTE: The source reader shuts down the media source
                        // by default, but we might not have gotten that far.
                        CloseDevice();
                    }
                }
                finally
                {
                    SafeRelease(pSource);
                }
            }

            return hr;
        }