private static bool AddBranchToPartialTopology(Topology topology, MediaSource source, PresentationDescriptor descriptor, int streamIndex, IntPtr hVideoWnd) { StreamDescriptor?streamDescriptor = null; Activate? activate = null; TopologyNode? sourceNode = null, outputNode = null; try { streamDescriptor = descriptor.GetStreamDescriptorByIndex(streamIndex, out var isSelected); if (isSelected) { CreateMediaSinkActivate(descriptor, streamDescriptor, streamIndex, hVideoWnd, out activate); if (activate != null) { var sourceNodePtr = Marshal.AllocHGlobal(Marshal.SizeOf(source)); MediaFactory.CreateTopologyNode(TopologyType.SourceStreamNode, out sourceNode); sourceNode.Object = source; topology.AddNode(sourceNode); MediaFactory.CreateTopologyNode(TopologyType.OutputNode, out outputNode); outputNode.Object = activate; topology.AddNode(outputNode); sourceNode.ConnectOutput(0, outputNode, 0); return(true); } else { return(false); } } else { return(false); } } catch (SharpDXException ex) { Debug.Print(ex.ToString()); return(false); } finally { streamDescriptor?.Dispose(); activate?.Dispose(); sourceNode?.Dispose(); outputNode?.Dispose(); } }
public void Load(object customSource) { Close(); AfterClose(); if (Hwnd == IntPtr.Zero) { throw new InvalidOperationException(); } Trace.WriteLine("HwndRenderSession::Load()"); MediaSource source = null; Topology topo = null; PresentationDescriptor pdesc = null; try { // Create MediaSource(check argument) source = ComObject.As <MediaSource>(Marshal.GetIUnknownForObject(customSource)); // GetIUnknownForObject adds reference count // Create MediaSession MediaFactory.CreateMediaSession(null, out _mediaSession); _callback = new MediaSessionCallback(_mediaSession, OnMediaEvent); // Create Topology MediaFactory.CreateTopology(out topo); // Get PresentationDescriptor from MediaSource source.CreatePresentationDescriptor(out pdesc); // Connect each stream for (var i = 0; i < pdesc.StreamDescriptorCount; i++) { RawBool isSelected; using (var sdesc = pdesc.GetStreamDescriptorByIndex(i, out isSelected)) { if (!isSelected) { continue; } Activate renderer = null; TopologyNode srcnode = null; TopologyNode outnode = null; try { // Renderer if (sdesc.MediaTypeHandler.MajorType == MediaTypeGuids.Video) { MediaFactory.CreateVideoRendererActivate(Hwnd, out renderer); } else if (sdesc.MediaTypeHandler.MajorType == MediaTypeGuids.Audio) { MediaFactory.CreateAudioRendererActivate(out renderer); } else { // not supported continue; } // Source Node MediaFactory.CreateTopologyNode(TopologyType.SourceStreamNode, out srcnode); srcnode.Set(TopologyNodeAttributeKeys.Source, source); srcnode.Set(TopologyNodeAttributeKeys.PresentationDescriptor, pdesc); srcnode.Set(TopologyNodeAttributeKeys.StreamDescriptor, sdesc); // Output Node MediaFactory.CreateTopologyNode(TopologyType.OutputNode, out outnode); outnode.Object = renderer; // Connect topo.AddNode(srcnode); topo.AddNode(outnode); srcnode.ConnectOutput(0, outnode, 0); } finally { srcnode?.Dispose(); outnode?.Dispose(); renderer?.Dispose(); } } } // Set to session _mediaSession.SetTopology(SessionSetTopologyFlags.None, topo); } catch { Close(); AfterClose(); throw; } finally { pdesc?.Dispose(); topo?.Dispose(); source?.Dispose(); } }