protected IMFTopologyNode CreateSourceStreamNode(IMFPresentationDescriptor pSourcePD, IMFStreamDescriptor pSourceSD) { int hr; //Debug.Assert(m_pSource != null); IMFTopologyNode pNode = null; try { // Create the source-stream node. hr = MFExtern.MFCreateTopologyNode(MFTopologyType.SourcestreamNode, out pNode); MFError.ThrowExceptionForHR(hr); // Set attribute: Pointer to the media source. hr = pNode.SetUnknown(MFAttributesClsid.MF_TOPONODE_SOURCE, m_pSource); MFError.ThrowExceptionForHR(hr); // Set attribute: Pointer to the presentation descriptor. hr = pNode.SetUnknown(MFAttributesClsid.MF_TOPONODE_PRESENTATION_DESCRIPTOR, pSourcePD); MFError.ThrowExceptionForHR(hr); // Set attribute: Pointer to the stream descriptor. hr = pNode.SetUnknown(MFAttributesClsid.MF_TOPONODE_STREAM_DESCRIPTOR, pSourceSD); MFError.ThrowExceptionForHR(hr); // Return the IMFTopologyNode pointer to the caller. return(pNode); } catch { // If we failed, release the pnode COMBase.SafeRelease(pNode); throw; } }
////////////////////////////////////////////////////////////////////// // Name: CreateSourceNode // Creates a source node for a media stream. // // pSource: Pointer to the media source. // pSourcePD: Pointer to the source's presentation descriptor. // pSourceSD: Pointer to the stream descriptor. // ppNode: Receives the IMFTopologyNode pointer. /////////////////////////////////////////////////////////////////////// static void CreateSourceNode( IMFMediaSource pSource, // Media source. IMFPresentationDescriptor pPD, // Presentation descriptor. IMFStreamDescriptor pSD, // Stream descriptor. out IMFTopologyNode ppNode // Receives the node pointer. ) { HResult hr; // Create the node. hr = MFExtern.MFCreateTopologyNode( MFTopologyType.SourcestreamNode, out ppNode); MFError.ThrowExceptionForHR(hr); // Set the attributes. hr = ppNode.SetUnknown( MFAttributesClsid.MF_TOPONODE_SOURCE, pSource); MFError.ThrowExceptionForHR(hr); hr = ppNode.SetUnknown( MFAttributesClsid.MF_TOPONODE_PRESENTATION_DESCRIPTOR, pPD); MFError.ThrowExceptionForHR(hr); hr = ppNode.SetUnknown( MFAttributesClsid.MF_TOPONODE_STREAM_DESCRIPTOR, pSD); MFError.ThrowExceptionForHR(hr); }
//////////////////////////////////////////////////////////////////////////////////////// // Name: CPlayer::CreateSourceNode (Private) // Description: // Creates the source node for a stream // Parameter: // pPresentationDescriptor: [in] Pointer to the presentation descriptor for the media source // pStreamDescriptor: [in] Stream descriptor for the stream // pMediaSource: [in] Pointer to the media source // ppSourceNode: [out] Receives a pointer to the new node /////////////////////////////////////////////////////////////////////////////////////////// private void CreateSourceNode( IMFPresentationDescriptor pPresentationDescriptor, IMFStreamDescriptor pStreamDescriptor, IMFMediaSource pMediaSource, out IMFTopologyNode ppSourceNode) { if (pPresentationDescriptor == null || pMediaSource == null || pStreamDescriptor == null) { throw new COMException("null pointer", (int)HResult.E_POINTER); } HResult hr; // Create the source-stream node. hr = MFExtern.MFCreateTopologyNode(MFTopologyType.SourcestreamNode, out ppSourceNode); MFError.ThrowExceptionForHR(hr); // Set attribute: Pointer to the media source. Necessary. hr = ppSourceNode.SetUnknown(MFAttributesClsid.MF_TOPONODE_SOURCE, pMediaSource); MFError.ThrowExceptionForHR(hr); // Set attribute: Pointer to the presentation descriptor. Necessary. hr = ppSourceNode.SetUnknown(MFAttributesClsid.MF_TOPONODE_PRESENTATION_DESCRIPTOR, pPresentationDescriptor); MFError.ThrowExceptionForHR(hr); // Set attribute: Pointer to the stream descriptor. Necessary. hr = ppSourceNode.SetUnknown(MFAttributesClsid.MF_TOPONODE_STREAM_DESCRIPTOR, pStreamDescriptor); MFError.ThrowExceptionForHR(hr); }
protected void CreateSourceStreamNode( IMFPresentationDescriptor pSourcePD, IMFStreamDescriptor pSourceSD, out IMFTopologyNode ppNode ) { MFError throwonhr; IMFTopologyNode pNode = null; try { // Create the source-stream node. throwonhr = MFExtern.MFCreateTopologyNode(MFTopologyType.SourcestreamNode, out pNode); // Set attribute: Pointer to the media source. throwonhr = pNode.SetUnknown(MFAttributesClsid.MF_TOPONODE_SOURCE, m_pSource); // Set attribute: Pointer to the presentation descriptor. throwonhr = pNode.SetUnknown(MFAttributesClsid.MF_TOPONODE_PRESENTATION_DESCRIPTOR, pSourcePD); // Set attribute: Pointer to the stream descriptor. throwonhr = pNode.SetUnknown(MFAttributesClsid.MF_TOPONODE_STREAM_DESCRIPTOR, pSourceSD); // Return the IMFTopologyNode pointer to the caller. ppNode = pNode; } catch { // If we failed, release the pnode //SafeRelease(pNode); throw; } }
/////////////////////////////////////////////////////////////////////// // Name: CreateAudioBranch // Description: // Adds and connects the nodes downstream from an audio source node. // // pTopology: Pointer to the topology. // pSourceNode: Pointer to the source node. // clsidTransform: CLSID of an effect transform. ///////////////////////////////////////////////////////////////////////// void CreateAudioBranch( IMFTopology pTopology, IMFTopologyNode pSourceNode, Guid clsidTransform // GUID_NULL = No transform. ) { TRACE("CreateAudioBranch"); IMFTopologyNode pOutputNode = null; IMFActivate pRendererActivate = null; // Create a downstream node. MFError throwonhr; throwonhr = MFExtern.MFCreateTopologyNode(MFTopologyType.OutputNode, out pOutputNode); try { // Create an IMFActivate object for the audio renderer. throwonhr = MFExtern.MFCreateAudioRendererActivate(out pRendererActivate); // Set the IActivate object on the output node. throwonhr = pOutputNode.SetObject(pRendererActivate); // Add the output node to the topology. throwonhr = pTopology.AddNode(pOutputNode); ConnectSourceToOutput(pTopology, pSourceNode, pOutputNode, clsidTransform); } finally { // Connect the source to the output. SafeRelease(pOutputNode); SafeRelease(pRendererActivate); } }
/////////////////////////////////////////////////////////////////////// // Name: CreateSourceStreamNode // Description: Creates a source-stream node for a stream. // // pSource: Media source. // pSourcePD: Presentation descriptor for the media source. // pSourceSD: Stream descriptor for the stream. // ppNode: Receives a pointer to the new node. // // Pre-conditions: Create the media source. ///////////////////////////////////////////////////////////////////////// void CreateSourceStreamNode( IMFMediaSource pSource, IMFPresentationDescriptor pSourcePD, IMFStreamDescriptor pSourceSD, out IMFTopologyNode ppNode ) { HResult hr; // Create the source-stream node. hr = MFExtern.MFCreateTopologyNode(MFTopologyType.SourcestreamNode, out ppNode); MFError.ThrowExceptionForHR(hr); // Set attribute: Pointer to the media source. hr = ppNode.SetUnknown(MFAttributesClsid.MF_TOPONODE_SOURCE, pSource); MFError.ThrowExceptionForHR(hr); // Set attribute: Pointer to the presentation descriptor. hr = ppNode.SetUnknown(MFAttributesClsid.MF_TOPONODE_PRESENTATION_DESCRIPTOR, pSourcePD); MFError.ThrowExceptionForHR(hr); // Set attribute: Pointer to the stream descriptor. hr = ppNode.SetUnknown(MFAttributesClsid.MF_TOPONODE_STREAM_DESCRIPTOR, pSourceSD); MFError.ThrowExceptionForHR(hr); }
/////////////////////////////////////////////////////////////////////// // Name: ConnectSourceToOutput // Description: // Connects the source node to the output node. // // pTopology: Pointer to the topology. // pSourceNode: Pointer to the source node. // pOutputNode: Pointer to the output node. // clsidTransform: CLSID of an effect transform. ///////////////////////////////////////////////////////////////////////// void ConnectSourceToOutput( IMFTopology pTopology, IMFTopologyNode pSourceNode, IMFTopologyNode pOutputNode, Guid clsidTransform ) { HResult hr; if (clsidTransform == Guid.Empty) { // There is no effect specified, so connect the source node // directly to the output node. hr = pSourceNode.ConnectOutput(0, pOutputNode, 0); MFError.ThrowExceptionForHR(hr); } else { IMFTopologyNode pTransformNode = null; object pTransformUnk = null; // Create a transform node. hr = MFExtern.MFCreateTopologyNode(MFTopologyType.TransformNode, out pTransformNode); MFError.ThrowExceptionForHR(hr); try { Type type = Type.GetTypeFromCLSID(clsidTransform); pTransformUnk = Activator.CreateInstance(type); hr = pTransformNode.SetObject(pTransformUnk); MFError.ThrowExceptionForHR(hr); //// Set the CLSID of the transform. //if (SUCCEEDED(hr)) //{ // hr = pTransformNode->SetGUID(MF_TOPONODE_TRANSFORM_OBJECTID, clsidTransform); //} // Add the transform node to the topology. hr = pTopology.AddNode(pTransformNode); MFError.ThrowExceptionForHR(hr); // Connect the source node to the transform node. hr = pSourceNode.ConnectOutput(0, pTransformNode, 0); MFError.ThrowExceptionForHR(hr); // Connect the transform node to the output node. hr = pTransformNode.ConnectOutput(0, pOutputNode, 0); MFError.ThrowExceptionForHR(hr); } finally { SafeRelease(pTransformNode); //SafeRelease(pTransformUnk); } } }
public static HResult SetObject(this IMFTopologyNode topologyNode, IMFStreamSink streamSink) { if (topologyNode == null) { throw new ArgumentNullException("topologyNode"); } return(topologyNode.SetObject(streamSink)); }
public static HResult SetObject(this IMFTopologyNode topologyNode, IMFTransform transform) { if (topologyNode == null) { throw new ArgumentNullException("topologyNode"); } return(topologyNode.SetObject(transform)); }
public static HResult SetObject(this IMFTopologyNode topologyNode, IMFActivate activate) { if (topologyNode == null) { throw new ArgumentNullException("topologyNode"); } return(topologyNode.SetObject(activate)); }
/////////////////////////////////////////////////////////////////////// // Name: AddBranchToPartialTopology // Description: Adds a topology branch for one stream. // // pTopology: Pointer to the topology object. // hVideoWindow: Handle to the video window (for video streams). // pSource: Media source. // pSourcePD: The source's presentation descriptor. // iStream: Index of the stream to render. // // Pre-conditions: The topology must be created already. // // Notes: For each stream, we must do the following: // 1. Create a source node associated with the stream. // 2. Create an output node for the renderer. // 3. Connect the two nodes. // // Optionally we can also add an effect transform between the source // and output nodes. // // The media session will resolve the topology, so we do not have // to worry about decoders or color converters. ///////////////////////////////////////////////////////////////////////// void AddBranchToPartialTopology( IMFTopology pTopology, IntPtr hVideoWindow, IMFMediaSource pSource, IMFPresentationDescriptor pSourcePD, int iStream) { TRACE("Player::RenderStream"); IMFStreamDescriptor pSourceSD = null; IMFTopologyNode pSourceNode = null; MFError throwonhr; Guid majorType; bool fSelected = false; // Get the stream descriptor for this stream. throwonhr = pSourcePD.GetStreamDescriptorByIndex(iStream, out fSelected, out pSourceSD); // First check if the stream is selected by default. If not, ignore it. // More sophisticated applications can change the default selections. if (fSelected) { try { // Create a source node for this stream. CreateSourceStreamNode(pSource, pSourcePD, pSourceSD, out pSourceNode); // Add the source node to the topology. throwonhr = pTopology.AddNode(pSourceNode); // Get the major media type for the stream. GetStreamType(pSourceSD, out majorType); if (majorType == MFMediaType.Video) { // For video, use the grayscale transform. CreateVideoBranch(pTopology, pSourceNode, hVideoWindow, m_VideoEffect); } else if (majorType == MFMediaType.Audio) { if (!m_Audio) { CreateAudioBranch(pTopology, pSourceNode, m_AudioEffect); } } } finally { // Clean up. SafeRelease(pSourceSD); SafeRelease(pSourceNode); } } }
protected void AddBranchToPartialTopology(IMFTopology pTopology, IMFPresentationDescriptor pSourcePD, int iStream) { int hr; //TRACE("CPlayer::AddBranchToPartialTopology"); //Debug.Assert(pTopology != null); IMFStreamDescriptor pSourceSD = null; IMFTopologyNode pSourceNode = null; IMFTopologyNode pOutputNode = null; bool fSelected = false; try { // Get the stream descriptor for this stream. hr = pSourcePD.GetStreamDescriptorByIndex(iStream, out fSelected, out pSourceSD); MFError.ThrowExceptionForHR(hr); // Create the topology branch only if the stream is selected. // Otherwise, do nothing. if (fSelected) { // Create a source node for this stream. pSourceNode = CreateSourceStreamNode(pSourcePD, pSourceSD); // Add both nodes to the topology. hr = pTopology.AddNode(pSourceNode); MFError.ThrowExceptionForHR(hr); // Create the output node for the renderer. pOutputNode = CreateOutputNode(pSourceSD); if (pOutputNode == null) { throw new Exception("Could not create output node"); } hr = pTopology.AddNode(pOutputNode); MFError.ThrowExceptionForHR(hr); // Connect the source node to the output node. hr = pSourceNode.ConnectOutput(0, pOutputNode, 0); MFError.ThrowExceptionForHR(hr); } } finally { // Clean up. COMBase.SafeRelease(pSourceSD); COMBase.SafeRelease(pSourceNode); COMBase.SafeRelease(pOutputNode); } }
/////////////////////////////////////////////////////////////////////// // Name: ConnectSourceToOutput // Description: // Connects the source node to the output node. // // pTopology: Pointer to the topology. // pSourceNode: Pointer to the source node. // pOutputNode: Pointer to the output node. // clsidTransform: CLSID of an effect transform. ///////////////////////////////////////////////////////////////////////// void ConnectSourceToOutput( IMFTopology pTopology, IMFTopologyNode pSourceNode, IMFTopologyNode pOutputNode, Guid clsidTransform ) { MFError throwonhr; if (clsidTransform == Guid.Empty) { // There is no effect specified, so connect the source node // directly to the output node. throwonhr = pSourceNode.ConnectOutput(0, pOutputNode, 0); } else { IMFTopologyNode pTransformNode = null; // Create a transform node. throwonhr = MFExtern.MFCreateTopologyNode(MFTopologyType.TransformNode, out pTransformNode); if (clsidTransform == m_VideoEffect) { m_VideoNode = pTransformNode; } else if (clsidTransform == m_AudioEffect) { m_AudioNode = pTransformNode; } try { // Set the CLSID of the transform. throwonhr = pTransformNode.SetGUID(MFAttributesClsid.MF_TOPONODE_TRANSFORM_OBJECTID, clsidTransform); // Add the transform node to the topology. throwonhr = pTopology.AddNode(pTransformNode); // Connect the source node to the transform node. throwonhr = pSourceNode.ConnectOutput(0, pTransformNode, 0); // Connect the transform node to the output node. throwonhr = pTransformNode.ConnectOutput(0, pOutputNode, 0); } finally { //SafeRelease(pTransformNode); } } }
public static HResult GetObject(this IMFTopologyNode topologyNode, out IMFStreamSink streamSink) { if (topologyNode == null) { throw new ArgumentNullException("topologyNode"); } object tmp; HResult hr = topologyNode.GetObject(out tmp); streamSink = hr.Succeeded() ? tmp as IMFStreamSink : null; return(hr); }
public static HResult GetObject(this IMFTopologyNode topologyNode, out IMFActivate activate) { if (topologyNode == null) { throw new ArgumentNullException("topologyNode"); } object tmp; HResult hr = topologyNode.GetObject(out tmp); activate = hr.Succeeded() ? tmp as IMFActivate : null; return(hr); }
protected void AddBranchToPartialTopology( IMFTopology pTopology, IMFPresentationDescriptor pSourcePD, int iStream ) { MFError throwonhr; TRACE("CPlayer::AddBranchToPartialTopology"); Debug.Assert(pTopology != null); IMFStreamDescriptor pSourceSD = null; IMFTopologyNode pSourceNode = null; IMFTopologyNode pOutputNode = null; bool fSelected = false; try { // Get the stream descriptor for this stream. throwonhr = pSourcePD.GetStreamDescriptorByIndex(iStream, out fSelected, out pSourceSD); // Create the topology branch only if the stream is selected. // Otherwise, do nothing. if (fSelected) { // Create a source node for this stream. CreateSourceStreamNode(pSourcePD, pSourceSD, out pSourceNode); // Create the output node for the renderer. CreateOutputNode(pSourceSD, out pOutputNode); // Add both nodes to the topology. throwonhr = pTopology.AddNode(pSourceNode); throwonhr = pTopology.AddNode(pOutputNode); // Connect the source node to the output node. throwonhr = pSourceNode.ConnectOutput(0, pOutputNode, 0); } } finally { // Clean up. SafeRelease(pSourceSD); SafeRelease(pSourceNode); SafeRelease(pOutputNode); } }
/////////////////////////////////////////////////////////////////////// // Name: CreateOutputNode // Description: Creates an output node for a stream sink. // // pSink: The media sink. // iStream: Index of the stream sink on the media sink. // ppNode: Receives a pointer to the topology node. /////////////////////////////////////////////////////////////////////// static void CreateOutputNode(IMFMediaSinkAlt pSink, int iStream, out IMFTopologyNode ppNode) { int hr; IMFStreamSinkAlt pStream = null; hr = pSink.GetStreamSinkByIndex(iStream, out pStream); MFError.ThrowExceptionForHR(hr); hr = MFExtern.MFCreateTopologyNode(MFTopologyType.OutputNode, out ppNode); MFError.ThrowExceptionForHR(hr); hr = ppNode.SetObject(pStream); MFError.ThrowExceptionForHR(hr); //Marshal.ReleaseComObject(pStream); }
/////////////////////////////////////////////////////////////////////// // Name: CreateOutputNode // Description: Creates an output node for a stream sink. // // pSink: The media sink. // iStream: Index of the stream sink on the media sink. // ppNode: Receives a pointer to the topology node. /////////////////////////////////////////////////////////////////////// static void CreateOutputNode(IMFMediaSinkAlt pSink, int iStream, out IMFTopologyNode ppNode) { HResult hr; IMFStreamSinkAlt pStream = null; hr = pSink.GetStreamSinkByIndex(iStream, out pStream); MFError.ThrowExceptionForHR(hr); hr = MFExtern.MFCreateTopologyNode(MFTopologyType.OutputNode, out ppNode); MFError.ThrowExceptionForHR(hr); hr = ppNode.SetObject(pStream); MFError.ThrowExceptionForHR(hr); //Marshal.ReleaseComObject(pStream); }
//////////////////////////////////////////////////////////////////////////////////////// // Name: CPlayer::CreateOutputNode (Private) // Description: // Creates an output node for a stream // Sets the IActivate pointer on the node // Parameter: // pStreamDescriptor: [in] Stream descriptor for the stream // ppSourceNode: [out] Receives a pointer to the new node //////////////////////////////////////////////////////////////////////////////////////// private void CreateOutputNode( IMFStreamDescriptor pStreamDescriptor, out IMFTopologyNode ppOutputNode) { if (pStreamDescriptor == null) { throw new COMException("null pointer", (int)HResult.E_POINTER); } IMFMediaTypeHandler pHandler; Guid guidMajorType = Guid.Empty; // Create a downstream node. HResult hr = MFExtern.MFCreateTopologyNode(MFTopologyType.OutputNode, out ppOutputNode); MFError.ThrowExceptionForHR(hr); // Get the media type handler for the stream. hr = pStreamDescriptor.GetMediaTypeHandler(out pHandler); MFError.ThrowExceptionForHR(hr); try { // Get the major media type. pHandler.GetMajorType(out guidMajorType); // Set the IActivate object on the output node. if (MFMediaType.Audio == guidMajorType) { hr = ppOutputNode.SetObject(m_pAudioRendererActivate); MFError.ThrowExceptionForHR(hr); Debug.WriteLine(("Audio stream")); } //Only audio is implemented, if guidMajorType is any other type, return E_NOTIMPL else { Debug.WriteLine(("Unsupported stream")); throw new COMException("Unsupported stream", (int)HResult.E_NOTIMPL); } } finally { // Clean up. SafeRelease(pHandler); } }
/////////////////////////////////////////////////////////////////////// // Name: CreateTopologyBranch // Description: Adds a source and sink to the topology and // connects them. // // pTopology: The topology. // pSource: The media source. // pPD: The source's presentation descriptor. // pSD: The stream descriptor for the stream. // pSink: The media sink. // /////////////////////////////////////////////////////////////////////// static void CreateTopologyBranch( IMFTopology pTopology, IMFMediaSource pSource, // Media source. IMFPresentationDescriptor pPD, // Presentation descriptor. IMFStreamDescriptor pSD, // Stream descriptor. IMFMediaSinkAlt pSink ) { HResult hr; IMFTopologyNode pSourceNode = null; IMFTopologyNode pOutputNode = null; CreateSourceNode(pSource, pPD, pSD, out pSourceNode); try { CreateOutputNode(pSink, 0, out pOutputNode); try { hr = pTopology.AddNode(pSourceNode); MFError.ThrowExceptionForHR(hr); hr = pTopology.AddNode(pOutputNode); MFError.ThrowExceptionForHR(hr); hr = pSourceNode.ConnectOutput(0, pOutputNode, 0); MFError.ThrowExceptionForHR(hr); } finally { if (pOutputNode != null) { Marshal.ReleaseComObject(pOutputNode); } } } finally { if (pSourceNode != null) { Marshal.ReleaseComObject(pSourceNode); } } }
/////////////////////////////////////////////////////////////////////// // Name: CreateVideoBranch // Description: // Adds and connects the nodes downstream from a video source node. // // pTopology: Pointer to the topology. // pSourceNode: Pointer to the source node. // hVideoWindow: Handle to the video window. // clsidTransform: CLSID of an effect transform. ///////////////////////////////////////////////////////////////////////// void CreateVideoBranch( IMFTopology pTopology, IMFTopologyNode pSourceNode, IntPtr hVideoWindow, Guid clsidTransform // GUID_NULL = No effect transform. ) { TRACE("CreateVideoBranch"); IMFTopologyNode pOutputNode = null; IMFActivate pRendererActivate = null; // Create a downstream node. HResult hr = MFExtern.MFCreateTopologyNode(MFTopologyType.OutputNode, out pOutputNode); MFError.ThrowExceptionForHR(hr); try { // Create an IMFActivate object for the video renderer. hr = MFExtern.MFCreateVideoRendererActivate(hVideoWindow, out pRendererActivate); MFError.ThrowExceptionForHR(hr); // Set the IActivate object on the output node. hr = pOutputNode.SetObject(pRendererActivate); MFError.ThrowExceptionForHR(hr); // Add the output node to the topology. hr = pTopology.AddNode(pOutputNode); MFError.ThrowExceptionForHR(hr); // Connect the source to the output. ConnectSourceToOutput(pTopology, pSourceNode, pOutputNode, clsidTransform); } finally { SafeRelease(pOutputNode); SafeRelease(pRendererActivate); } }
/////////////////////////////////////////////////////////////////////// // Name: ConnectSourceToOutput // Description: // Connects the source node to the output node. // // pTopology: Pointer to the topology. // pSourceNode: Pointer to the source node. // pOutputNode: Pointer to the output node. // clsidTransform: CLSID of an effect transform. ///////////////////////////////////////////////////////////////////////// void ConnectSourceToOutput( IMFTopology pTopology, IMFTopologyNode pSourceNode, IMFTopologyNode pOutputNode, Guid clsidTransform ) { int hr; if (clsidTransform == Guid.Empty) { // There is no effect specified, so connect the source node // directly to the output node. hr = pSourceNode.ConnectOutput(0, pOutputNode, 0); MFError.ThrowExceptionForHR(hr); } else { IMFTopologyNode pTransformNode = null; object pTransformUnk = null; // Create a transform node. hr = MFExtern.MFCreateTopologyNode(MFTopologyType.TransformNode, out pTransformNode); MFError.ThrowExceptionForHR(hr); try { Type type = Type.GetTypeFromCLSID(clsidTransform); pTransformUnk = Activator.CreateInstance(type); hr = pTransformNode.SetObject(pTransformUnk); MFError.ThrowExceptionForHR(hr); //// Set the CLSID of the transform. //if (SUCCEEDED(hr)) //{ // hr = pTransformNode->SetGUID(MF_TOPONODE_TRANSFORM_OBJECTID, clsidTransform); //} // Add the transform node to the topology. hr = pTopology.AddNode(pTransformNode); MFError.ThrowExceptionForHR(hr); // Connect the source node to the transform node. hr = pSourceNode.ConnectOutput(0, pTransformNode, 0); MFError.ThrowExceptionForHR(hr); // Connect the transform node to the output node. hr = pTransformNode.ConnectOutput(0, pOutputNode, 0); MFError.ThrowExceptionForHR(hr); } finally { SafeRelease(pTransformNode); //SafeRelease(pTransformUnk); } } }
public static extern void MFCreateTopologyNode(MF_TOPOLOGY_TYPE NodeType, out IMFTopologyNode ppNode);
/// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+= /// <summary> /// Opens prepares the media session and topology and opens the media source /// and media sink. /// /// Once the session and topology are setup, a MESessionTopologySet event /// will be triggered in the callback handler. After that the events there /// trigger other events and everything rolls along automatically. /// </summary> /// <param name="sourceFileName">the source file name</param> /// <param name="outputFileName">the name of the output file</param> /// <history> /// 01 Nov 18 Cynic - Originally Written /// </history> public void PrepareSessionAndTopology(string sourceFileName, string outputFileName) { HResult hr; IMFSourceResolver pSourceResolver = null; IMFTopology pTopology = null; IMFPresentationDescriptor sourcePresentationDescriptor = null; int sourceStreamCount = 0; IMFStreamDescriptor audioStreamDescriptor = null; bool streamIsSelected = false; IMFTopologyNode sourceAudioNode = null; IMFTopologyNode outputSinkNode = null; IMFMediaType currentAudioMediaType = null; int audioStreamIndex = -1; LogMessage("PrepareSessionAndTopology "); // we sanity check the filenames - the existence of the path and if the file already exists // should have been checked before this call if ((sourceFileName == null) || (sourceFileName.Length == 0)) { throw new Exception("PrepareSessionAndTopology: source file name is invalid. Cannot continue."); } if ((outputFileName == null) || (outputFileName.Length == 0)) { throw new Exception("PrepareSessionAndTopology: output file name is invalid. Cannot continue."); } 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()); } if (mediaSession == null) { throw new Exception("PrepareSessionAndTopology call to MFExtern.MFCreateMediaSession failed. mediaSession == null"); } // set up our media session call back handler. mediaSessionAsyncCallbackHandler = new TantaAsyncCallbackHandler(); 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()); } // Create a new topology. A topology describes a collection of media sources, sinks, and transforms that are // connected in a certain order. These objects are represented within the topology by topology nodes, // which expose the IMFTopologyNode interface. A topology describes the path of multimedia data through these nodes. hr = MFExtern.MFCreateTopology(out pTopology); if (hr != HResult.S_OK) { throw new Exception("PrepareSessionAndTopology call to MFExtern.MFCreateTopology failed. Err=" + hr.ToString()); } if (pTopology == null) { throw new Exception("PrepareSessionAndTopology call to MFExtern.MFCreateTopology failed. pTopology == null"); } // #### // #### we now create the media source, this is an audio file // #### // use the file name to create the media source for the audio device. Media sources are objects that generate media data. // For example, the data might come from a video file, a network stream, or a hardware device, such as a camera. Each // media source contains one or more streams, and each stream delivers data of one type, such as audio or video. mediaSource = TantaWMFUtils.GetMediaSourceFromFile(sourceFileName); if (mediaSource == null) { throw new Exception("PrepareSessionAndTopology call to mediaSource == null"); } // A presentation is a set of related media streams that share a common presentation time. We now get a copy of the media // source's presentation descriptor. Applications can use the presentation descriptor to select streams // and to get information about the source content. hr = mediaSource.CreatePresentationDescriptor(out sourcePresentationDescriptor); if (hr != HResult.S_OK) { throw new Exception("PrepareSessionAndTopology call to mediaSource.CreatePresentationDescriptor failed. Err=" + hr.ToString()); } if (sourcePresentationDescriptor == null) { throw new Exception("PrepareSessionAndTopology call to mediaSource.CreatePresentationDescriptor failed. sourcePresentationDescriptor == null"); } // Now we get the number of stream descriptors in the presentation. A presentation descriptor contains a list of one or more // stream descriptors. These describe the streams in the presentation. Streams can be either selected or deselected. Only the // selected streams produce data. Deselected streams are not active and do not produce any data. hr = sourcePresentationDescriptor.GetStreamDescriptorCount(out sourceStreamCount); if (hr != HResult.S_OK) { throw new Exception("PrepareSessionAndTopology call to sourcePresentationDescriptor.GetStreamDescriptorCount failed. Err=" + hr.ToString()); } if (sourceStreamCount == 0) { throw new Exception("PrepareSessionAndTopology call to sourcePresentationDescriptor.GetStreamDescriptorCount failed. sourceStreamCount == 0"); } // Look at each stream, there can be more than one stream here // Usually only one is enabled. This app uses the first "selected" // stream we come to which has the appropriate media type for (int i = 0; i < sourceStreamCount; i++) { // we require the major type to be audio Guid guidMajorType = TantaWMFUtils.GetMajorMediaTypeFromPresentationDescriptor(sourcePresentationDescriptor, i); if (guidMajorType != MFMediaType.Audio) { continue; } // we also require the stream to be enabled hr = sourcePresentationDescriptor.GetStreamDescriptorByIndex(i, out streamIsSelected, out audioStreamDescriptor); if (hr != HResult.S_OK) { throw new Exception("PrepareSessionAndTopology call to sourcePresentationDescriptor.GetStreamDescriptorByIndex failed. Err=" + hr.ToString()); } if (audioStreamDescriptor == null) { throw new Exception("PrepareSessionAndTopology call to sourcePresentationDescriptor.GetStreamDescriptorByIndex failed. audioStreamDescriptor == null"); } // if the stream is selected, leave now we will release the audioStream descriptor later if (streamIsSelected == true) { audioStreamIndex = i; // record this break; } // release the one we are not using if (audioStreamDescriptor != null) { Marshal.ReleaseComObject(audioStreamDescriptor); audioStreamDescriptor = null; } audioStreamIndex = -1; } // by the time we get here we should have a audioStreamDescriptor if // we do not, then we cannot proceed if (audioStreamDescriptor == null) { throw new Exception("PrepareSessionAndTopology call to sourcePresentationDescriptor.GetStreamDescriptorByIndex failed. audioStreamDescriptor == null"); } if (audioStreamIndex < 0) { throw new Exception("PrepareSessionAndTopology call to sourcePresentationDescriptor.GetStreamDescriptorByIndex failed. audioStreamIndex < 0"); } // #### // #### we now create the media sink, we need the type from the stream to do // #### this which is why we wait until now to set it up // #### currentAudioMediaType = TantaWMFUtils.GetCurrentMediaTypeFromStreamDescriptor(audioStreamDescriptor); if (currentAudioMediaType == null) { throw new Exception("PrepareSessionAndTopology call to currentAudioMediaType == null"); } mediaSink = OpenMediaFileSink(outputFileName); if (mediaSink == null) { throw new Exception("PrepareSessionAndTopology call to mediaSink == null"); } // #### // #### we now make up a topology branch for the audio stream // #### // Create a source node for this stream. sourceAudioNode = TantaWMFUtils.CreateSourceNodeForStream(mediaSource, sourcePresentationDescriptor, audioStreamDescriptor); if (sourceAudioNode == null) { throw new Exception("PrepareSessionAndTopology call to CreateSourceNodeForStream failed. pSourceNode == null"); } // Create the output node - this is a file sink in this case. outputSinkNode = TantaWMFUtils.CreateSinkNodeForStream(mediaSink); if (outputSinkNode == null) { throw new Exception("PrepareSessionAndTopology call to CreateOutputNodeForStream failed. outputSinkNode == null"); } // Add the nodes to the topology. First the source hr = pTopology.AddNode(sourceAudioNode); if (hr != HResult.S_OK) { throw new Exception("PrepareSessionAndTopology call to pTopology.AddNode(sourceAudioNode) failed. Err=" + hr.ToString()); } // then add the output hr = pTopology.AddNode(outputSinkNode); if (hr != HResult.S_OK) { throw new Exception("PrepareSessionAndTopology call to pTopology.AddNode(outputSinkNode) failed. Err=" + hr.ToString()); } // Connect the output stream from the source node to the input stream of the output node. The parameters are: // dwOutputIndex - Zero-based index of the output stream on this node. // *pDownstreamNode - Pointer to the IMFTopologyNode interface of the node to connect to. // dwInputIndexOnDownstreamNode - Zero-based index of the input stream on the other node. hr = sourceAudioNode.ConnectOutput(0, outputSinkNode, 0); if (hr != HResult.S_OK) { throw new Exception("PrepareSessionAndTopology call to pSourceNode.ConnectOutput failed. Err=" + hr.ToString()); } // Set the topology on the media session. // If SetTopology succeeds, the media session will queue an // MESessionTopologySet event. hr = mediaSession.SetTopology(0, pTopology); MFError.ThrowExceptionForHR(hr); // Release the topology if (pTopology != null) { Marshal.ReleaseComObject(pTopology); } } catch (Exception ex) { LogMessage("Error: " + ex.Message); OISMessageBox(ex.Message); } finally { // Clean up if (pSourceResolver != null) { Marshal.ReleaseComObject(pSourceResolver); } if (sourcePresentationDescriptor != null) { Marshal.ReleaseComObject(sourcePresentationDescriptor); } if (audioStreamDescriptor != null) { Marshal.ReleaseComObject(audioStreamDescriptor); } if (sourceAudioNode != null) { Marshal.ReleaseComObject(sourceAudioNode); } if (outputSinkNode != null) { Marshal.ReleaseComObject(outputSinkNode); } if (currentAudioMediaType != null) { Marshal.ReleaseComObject(currentAudioMediaType); } } }
/// <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); } }
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); object ppv; pRendererActivate.ActivateObject(typeof(IMFVideoRenderer).GUID, out ppv); var renderer = ppv as IMFVideoRenderer; m_customPresenter = EvrPresenter.CreateNew(); m_customPresenter.NewAllocatorFrame += m_customPresenter_NewAllocatorFrame; m_customPresenter.NewAllocatorSurface += m_customPresenter_NewAllocatorSurface; var presenter = m_customPresenter.VideoPresenter as IMFVideoDisplayControl; hr = presenter.SetVideoWindow(m_hwndVideo); hr = renderer.InitializeRenderer(null, m_customPresenter.VideoPresenter); var settings = presenter as IEVRPresenterSettings; settings.SetBufferCount(5); } 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); } }
//////////////////////////////////////////////////////////////////////////////////////// // Name: CPlayer::CreateSourceNode (Private) // Description: // Creates the source node for a stream // Parameter: // pPresentationDescriptor: [in] Pointer to the presentation descriptor for the media source // pStreamDescriptor: [in] Stream descriptor for the stream // pMediaSource: [in] Pointer to the media source // ppSourceNode: [out] Receives a pointer to the new node /////////////////////////////////////////////////////////////////////////////////////////// private void CreateSourceNode( IMFPresentationDescriptor pPresentationDescriptor, IMFStreamDescriptor pStreamDescriptor, IMFMediaSource pMediaSource, out IMFTopologyNode ppSourceNode) { if (pPresentationDescriptor == null || pMediaSource == null || pStreamDescriptor == null) { throw new COMException("null pointer", E_Pointer); } int hr; // Create the source-stream node. hr = MFExtern.MFCreateTopologyNode(MFTopologyType.SourcestreamNode, out ppSourceNode); MFError.ThrowExceptionForHR(hr); // Set attribute: Pointer to the media source. Necessary. hr = ppSourceNode.SetUnknown(MFAttributesClsid.MF_TOPONODE_SOURCE, pMediaSource); MFError.ThrowExceptionForHR(hr); // Set attribute: Pointer to the presentation descriptor. Necessary. hr = ppSourceNode.SetUnknown(MFAttributesClsid.MF_TOPONODE_PRESENTATION_DESCRIPTOR, pPresentationDescriptor); MFError.ThrowExceptionForHR(hr); // Set attribute: Pointer to the stream descriptor. Necessary. hr = ppSourceNode.SetUnknown(MFAttributesClsid.MF_TOPONODE_STREAM_DESCRIPTOR, pStreamDescriptor); MFError.ThrowExceptionForHR(hr); }
////////////////////////////////////////////////////////////////////// // Name: CreateSourceNode // Creates a source node for a media stream. // // pSource: Pointer to the media source. // pSourcePD: Pointer to the source's presentation descriptor. // pSourceSD: Pointer to the stream descriptor. // ppNode: Receives the IMFTopologyNode pointer. /////////////////////////////////////////////////////////////////////// static void CreateSourceNode( IMFMediaSource pSource, // Media source. IMFPresentationDescriptor pPD, // Presentation descriptor. IMFStreamDescriptor pSD, // Stream descriptor. out IMFTopologyNode ppNode // Receives the node pointer. ) { int hr; // Create the node. hr = MFExtern.MFCreateTopologyNode( MFTopologyType.SourcestreamNode, out ppNode); MFError.ThrowExceptionForHR(hr); // Set the attributes. hr = ppNode.SetUnknown( MFAttributesClsid.MF_TOPONODE_SOURCE, pSource); MFError.ThrowExceptionForHR(hr); hr = ppNode.SetUnknown( MFAttributesClsid.MF_TOPONODE_PRESENTATION_DESCRIPTOR, pPD); MFError.ThrowExceptionForHR(hr); hr = ppNode.SetUnknown( MFAttributesClsid.MF_TOPONODE_STREAM_DESCRIPTOR, pSD); MFError.ThrowExceptionForHR(hr); }
public static extern void MFCreateTopologyNode( MFTopologyType NodeType, out IMFTopologyNode ppNode );
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); }
/////////////////////////////////////////////////////////////////////// // Name: CreateVideoBranch // Description: // Adds and connects the nodes downstream from a video source node. // // pTopology: Pointer to the topology. // pSourceNode: Pointer to the source node. // hVideoWindow: Handle to the video window. // clsidTransform: CLSID of an effect transform. ///////////////////////////////////////////////////////////////////////// void CreateVideoBranch( IMFTopology pTopology, IMFTopologyNode pSourceNode, IntPtr hVideoWindow, Guid clsidTransform // GUID_NULL = No effect transform. ) { TRACE("CreateVideoBranch"); IMFTopologyNode pOutputNode = null; IMFActivate pRendererActivate = null; // Create a downstream node. int hr = MFExtern.MFCreateTopologyNode(MFTopologyType.OutputNode, out pOutputNode); MFError.ThrowExceptionForHR(hr); try { // Create an IMFActivate object for the video renderer. hr = MFExtern.MFCreateVideoRendererActivate(hVideoWindow, out pRendererActivate); MFError.ThrowExceptionForHR(hr); // Set the IActivate object on the output node. hr = pOutputNode.SetObject(pRendererActivate); MFError.ThrowExceptionForHR(hr); // Add the output node to the topology. hr = pTopology.AddNode(pOutputNode); MFError.ThrowExceptionForHR(hr); // Connect the source to the output. ConnectSourceToOutput(pTopology, pSourceNode, pOutputNode, clsidTransform); } finally { SafeRelease(pOutputNode); SafeRelease(pRendererActivate); } }
private static HResult CreateSourceStreamNode(IMFMediaSource source, IMFStreamDescriptor streamDescriptor, IMFPresentationDescriptor presentationDescriptor, out IMFTopologyNode node) { HResult hr = S_OK; node = null; hr = MF.CreateTopologyNode(MFTopologyType.SourcestreamNode, out node); if (Failed(hr)) { return(hr); } hr = node.SetUnknown(MF_TOPONODE_SOURCE, source); if (Failed(hr)) { SafeRelease(node); return(hr); } hr = node.SetUnknown(MF_TOPONODE_PRESENTATION_DESCRIPTOR, presentationDescriptor); if (Failed(hr)) { SafeRelease(node); return(hr); } hr = node.SetUnknown(MF_TOPONODE_STREAM_DESCRIPTOR, streamDescriptor); if (Failed(hr)) { SafeRelease(node); return(hr); } return(hr); }
protected void CreateSourceStreamNode( IMFPresentationDescriptor pSourcePD, IMFStreamDescriptor pSourceSD, out IMFTopologyNode ppNode ) { Debug.Assert(m_pSource != null); IMFTopologyNode pNode = null; try { // Create the source-stream node. MFExtern.MFCreateTopologyNode(MFTopologyType.SourcestreamNode, out pNode); // Set attribute: Pointer to the media source. pNode.SetUnknown(MFAttributesClsid.MF_TOPONODE_SOURCE, m_pSource); // Set attribute: Pointer to the presentation descriptor. pNode.SetUnknown(MFAttributesClsid.MF_TOPONODE_PRESENTATION_DESCRIPTOR, pSourcePD); // Set attribute: Pointer to the stream descriptor. pNode.SetUnknown(MFAttributesClsid.MF_TOPONODE_STREAM_DESCRIPTOR, pSourceSD); // Return the IMFTopologyNode pointer to the caller. ppNode = pNode; } catch { // If we failed, release the pnode SafeRelease(pNode); throw; } }
protected void CreateOutputNode( IMFStreamDescriptor pSourceSD, out IMFTopologyNode ppNode ) { IMFTopologyNode pNode = null; IMFMediaTypeHandler pHandler = null; IMFActivate pRendererActivate = null; Guid guidMajorType = Guid.Empty; MFError throwonhr; // Get the stream ID. int streamID = 0; try { HResult hr; hr = pSourceSD.GetStreamIdentifier(out streamID); // Just for debugging, ignore any failures. if (MFError.Failed(hr)) { //TRACE("IMFStreamDescriptor::GetStreamIdentifier" + hr.ToString()); } // Get the media type handler for the stream. throwonhr = pSourceSD.GetMediaTypeHandler(out pHandler); // Get the major media type. throwonhr = pHandler.GetMajorType(out guidMajorType); // Create a downstream node. throwonhr = 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)); throwonhr = MFExtern.MFCreateAudioRendererActivate(out pRendererActivate); // Set the IActivate object on the output node. throwonhr = pNode.SetObject(pRendererActivate); } else if (MFMediaType.Video == guidMajorType) { // Create the video renderer. //TRACE(string.Format("Stream {0}: video stream", streamID)); //throwonhr = MFExtern.MFCreateVideoRendererActivate(m_hwndVideo, out pRendererActivate); mIMFTopologyNode.GetObject(out pRendererActivate); throwonhr = pNode.SetObject(pRendererActivate); } else { //TRACE(string.Format("Stream {0}: Unknown format", streamID)); //throw new COMException("Unknown format", (int)HResult.E_FAIL); } // 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); } }
//////////////////////////////////////////////////////////////////////////////////////// // Name: CPlayer::CreateOutputNode (Private) // Description: // Creates an output node for a stream // Sets the IActivate pointer on the node // Parameter: // pStreamDescriptor: [in] Stream descriptor for the stream // ppSourceNode: [out] Receives a pointer to the new node //////////////////////////////////////////////////////////////////////////////////////// private void CreateOutputNode( IMFStreamDescriptor pStreamDescriptor, out IMFTopologyNode ppOutputNode) { if (pStreamDescriptor == null) { throw new COMException("null pointer", E_Pointer); } IMFMediaTypeHandler pHandler; Guid guidMajorType = Guid.Empty; // Create a downstream node. int hr = MFExtern.MFCreateTopologyNode(MFTopologyType.OutputNode, out ppOutputNode); MFError.ThrowExceptionForHR(hr); // Get the media type handler for the stream. hr = pStreamDescriptor.GetMediaTypeHandler(out pHandler); MFError.ThrowExceptionForHR(hr); try { // Get the major media type. pHandler.GetMajorType(out guidMajorType); // Set the IActivate object on the output node. if (MFMediaType.Audio == guidMajorType) { hr = ppOutputNode.SetObject(m_pAudioRendererActivate); MFError.ThrowExceptionForHR(hr); Debug.WriteLine(("Audio stream")); } //Only audio is implemented, if guidMajorType is any other type, return E_NOTIMPL else { Debug.WriteLine(("Unsupported stream")); throw new COMException("Unsupported stream", E_NotImplemented); } } finally { // Clean up. SafeRelease(pHandler); } }
private static HResult BuildTopology(out IMFMediaSinkAlt mediaSink, IMFTopology topology, IMFPresentationDescriptor presentationDescriptor, IMFMediaSource source) { HResult hr = S_OK; mediaSink = null; IMFMediaSinkAlt tempMediaSink = null; IMFStreamDescriptor streamDescriptor = null; IMFTopologyNode sourceNode = null; IMFTopologyNode outputNode = null; bool selected = false; int streamCount = 0; hr = presentationDescriptor.GetStreamDescriptorCount(out streamCount); if (Failed(hr)) { return(hr); } for (int i = 0; i < streamCount; i++) { hr = presentationDescriptor.GetStreamDescriptorByIndex(i, out selected, out streamDescriptor); if (Failed(hr)) { return(hr); } if (selected) { hr = CreateSourceStreamNode(source, streamDescriptor, presentationDescriptor, out sourceNode); if (Failed(hr)) { return(hr); } hr = CreateOutputNode(streamDescriptor, out tempMediaSink, out outputNode); if (Failed(hr)) { mediaSink = null; return(hr); } if (tempMediaSink != null) { mediaSink = tempMediaSink; } hr = topology.AddNode(sourceNode); if (Failed(hr)) { mediaSink = null; return(hr); } hr = topology.AddNode(outputNode); if (Failed(hr)) { mediaSink = null; return(hr); } hr = sourceNode.ConnectOutput(0, outputNode, 0); if (Failed(hr)) { mediaSink = null; return(hr); } } } return(hr); }
public static extern int MFCreateTopologyNode(uint NodeType, out IMFTopologyNode ppNode);
private static HResult CreateOutputNode(IMFStreamDescriptor streamDescriptor, out IMFMediaSinkAlt mediaSink, out IMFTopologyNode node) { HResult hr = S_OK; mediaSink = null; node = null; IMFMediaTypeHandler mediaTypeHandler = null; IMFActivate activate = null; IMFStreamSinkAlt streamSink = null; Guid majorType = Guid.Empty; int streamSinkCount = 0; hr = streamDescriptor.GetMediaTypeHandler(out mediaTypeHandler); if (Failed(hr)) { return(hr); } hr = mediaTypeHandler.GetMajorType(out majorType); if (Failed(hr)) { SafeRelease(mediaTypeHandler); return(hr); } hr = MF.CreateTopologyNode(MFTopologyType.OutputNode, out node); if (Failed(hr)) { SafeRelease(mediaTypeHandler); return(hr); } if (majorType == MFMediaType.Video) { ExternalMediaSink extMediaSink = new ExternalMediaSink(); mediaSink = (IMFMediaSinkAlt)extMediaSink; hr = mediaSink.GetStreamSinkCount(out streamSinkCount); if (Failed(hr)) { mediaSink = null; return(hr); } hr = mediaSink.GetStreamSinkByIndex(0, out streamSink); if (Failed(hr)) { mediaSink = null; return(hr); } hr = node.SetObject(streamSink); if (Failed(hr)) { mediaSink = null; return(hr); } } else if (majorType == MFMediaType.Audio) { hr = MF.CreateAudioRendererActivate(out activate); if (Failed(hr)) { return(hr); } hr = node.SetObject(activate); if (Failed(hr)) { return(hr); } } mediaTypeHandler = null; activate = null; streamSink = null; return(hr); }
/////////////////////////////////////////////////////////////////////// // Name: CreateSourceStreamNode // Description: Creates a source-stream node for a stream. // // pSource: Media source. // pSourcePD: Presentation descriptor for the media source. // pSourceSD: Stream descriptor for the stream. // ppNode: Receives a pointer to the new node. // // Pre-conditions: Create the media source. ///////////////////////////////////////////////////////////////////////// void CreateSourceStreamNode( IMFMediaSource pSource, IMFPresentationDescriptor pSourcePD, IMFStreamDescriptor pSourceSD, out IMFTopologyNode ppNode ) { int hr; // Create the source-stream node. hr = MFExtern.MFCreateTopologyNode(MFTopologyType.SourcestreamNode, out ppNode); MFError.ThrowExceptionForHR(hr); // Set attribute: Pointer to the media source. hr = ppNode.SetUnknown(MFAttributesClsid.MF_TOPONODE_SOURCE, pSource); MFError.ThrowExceptionForHR(hr); // Set attribute: Pointer to the presentation descriptor. hr = ppNode.SetUnknown(MFAttributesClsid.MF_TOPONODE_PRESENTATION_DESCRIPTOR, pSourcePD); MFError.ThrowExceptionForHR(hr); // Set attribute: Pointer to the stream descriptor. hr = ppNode.SetUnknown(MFAttributesClsid.MF_TOPONODE_STREAM_DESCRIPTOR, pSourceSD); MFError.ThrowExceptionForHR(hr); }