public override void Dispose()
 {
     FLLog.Info("Video", "Closing Windows Media Foundation backend");
     if (session != null)
     {
         session.Stop();
         session.ClearTopologies();
         //Sample grabber thread works asynchronously (as task), so we need give him a time, to understand, that session is closed
         //minimal time to wait: 33 ms (1000 ms / 30 fps), but I decide to use a little more
         System.Threading.Thread.Sleep(100);
         session.Close();
         session.Dispose();
         session = null;
     }
     if (topology != null)
     {
         topology.Dispose();
         topology = null;
     }
     if (videoSampler != null)
     {
         videoSampler.Dispose();
         videoSampler = null;
     }
     if (clock != null)
     {
         clock.Dispose();
         clock = null;
     }
     if (_texture != null)
     {
         _texture.Dispose();
         _texture = null;
     }
     if (cb != null)
     {
         cb.Dispose();
         cb = null;
     }
 }
        public override void PlayFile(string filename)
        {
            //Load the file
            MediaSource mediaSource;

            {
                var        resolver = new SourceResolver();
                ObjectType otype;
                var        source = new ComObject(resolver.CreateObjectFromURL(filename, SourceResolverFlags.MediaSource, null, out otype));
                try
                {
                    // Sometimes throws HRESULT: [0x80004002], Module: [General], ApiCode: [E_NOINTERFACE/No such interface supported], Message: No such interface supported. Bug?
                    mediaSource = source.QueryInterface <MediaSource>();
                }
                catch (SharpDXException)
                {
                    mediaSource = null;
                    FLLog.Error("VideoPlayerWMF", "QueryInterface failed on Media Foundation");
                }
                resolver.Dispose();
                source.Dispose();
            }
            if (mediaSource is null)
            {
                return;
            }

            PresentationDescriptor presDesc;

            mediaSource.CreatePresentationDescriptor(out presDesc);

            for (int i = 0; i < presDesc.StreamDescriptorCount; i++)
            {
                SharpDX.Mathematics.Interop.RawBool selected;
                StreamDescriptor desc;
                presDesc.GetStreamDescriptorByIndex(i, out selected, out desc);
                if (selected)
                {
                    TopologyNode sourceNode;
                    MediaFactory.CreateTopologyNode(TopologyType.SourceStreamNode, out sourceNode);

                    sourceNode.Set(TopologyNodeAttributeKeys.Source, mediaSource);
                    sourceNode.Set(TopologyNodeAttributeKeys.PresentationDescriptor, presDesc);
                    sourceNode.Set(TopologyNodeAttributeKeys.StreamDescriptor, desc);

                    TopologyNode outputNode;
                    MediaFactory.CreateTopologyNode(TopologyType.OutputNode, out outputNode);

                    var majorType = desc.MediaTypeHandler.MajorType;
                    if (majorType == MediaTypeGuids.Video)
                    {
                        Activate activate;

                        videoSampler = new MFSamples();
                        //retrieve size of video
                        long sz = desc.MediaTypeHandler.CurrentMediaType.Get <long>(new Guid("{1652c33d-d6b2-4012-b834-72030849a37d}"));
                        int  height = (int)(sz & uint.MaxValue), width = (int)(sz >> 32);
                        _texture = new Texture2D(width, height, false, SurfaceFormat.Color);
                        mt       = new MediaType();

                        mt.Set(MediaTypeAttributeKeys.MajorType, MediaTypeGuids.Video);

                        // Specify that we want the data to come in as RGB32.
                        mt.Set(MediaTypeAttributeKeys.Subtype, new Guid("00000016-0000-0010-8000-00AA00389B71"));
                        GetMethods();
                        MFCreateSampleGrabberSinkActivate(mt, videoSampler, out activate);
                        outputNode.Object = activate;
                    }

                    if (majorType == MediaTypeGuids.Audio)
                    {
                        Activate activate;
                        MediaFactory.CreateAudioRendererActivate(out activate);

                        outputNode.Object = activate;
                    }

                    topology.AddNode(sourceNode);
                    topology.AddNode(outputNode);
                    sourceNode.ConnectOutput(0, outputNode, 0);

                    sourceNode.Dispose();
                    outputNode.Dispose();
                }
                desc.Dispose();
            }

            presDesc.Dispose();
            mediaSource.Dispose();
            //Play the file
            cb = new MFCallback(this, session);
            session.BeginGetEvent(cb, null);
            session.SetTopology(SessionSetTopologyFlags.Immediate, topology);
            // Get the clock
            clock = session.Clock.QueryInterface <PresentationClock>();

            // Start playing.
            Playing = true;
        }