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