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: 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: 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); }
private void SelectStreams(IMFPresentationDescriptor pPD) { for (int nStream = 0; nStream < _streams.Count; ++nStream) { IMFStreamDescriptor spSD; MediaStream spStream; int nStreamId; bool fSelected; // Get next stream descriptor ThrowIfError(pPD.GetStreamDescriptorByIndex(nStream, out fSelected, out spSD)); // Get stream id ThrowIfError(spSD.GetStreamIdentifier(out nStreamId)); // Get simple net media stream ThrowIfError(GetStreamById(nStreamId, out spStream)); // Remember if stream was selected bool fWasSelected = spStream.IsActive; ThrowIfError(spStream.SetActive(fSelected)); if (fSelected) { // Choose event type to send MediaEventType met = fWasSelected ? MediaEventType.MEUpdatedStream : MediaEventType.MENewStream; ThrowIfError(_spEventQueue.QueueEventParamUnk(met, Guid.Empty, HResult.S_OK, spStream)); // Start the stream. The stream will send the appropriate event. ThrowIfError(spStream.Start()); } } }
//////////////////////////////////////////////////////////////////////////////////////// // 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); }
public void SetDeviceFormat(int dwFormatIndex) { if (m_pSource == null) { CreateVideoCaptureSource(); } IMFPresentationDescriptor pPD = null; IMFStreamDescriptor pSD = null; IMFMediaTypeHandler pHandler = null; IMFMediaType pType = null; int hr = m_pSource.CreatePresentationDescriptor(out pPD); MFError.ThrowExceptionForHR(hr); bool fSelected; hr = pPD.GetStreamDescriptorByIndex(0, out fSelected, out pSD); MFError.ThrowExceptionForHR(hr); hr = pSD.GetMediaTypeHandler(out pHandler); MFError.ThrowExceptionForHR(hr); hr = pHandler.GetMediaTypeByIndex(dwFormatIndex, out pType); MFError.ThrowExceptionForHR(hr); hr = pHandler.SetCurrentMediaType(pType); MFError.ThrowExceptionForHR(hr); Marshal.FinalReleaseComObject(pPD); Marshal.FinalReleaseComObject(pSD); Marshal.FinalReleaseComObject(pHandler); Marshal.FinalReleaseComObject(pType); }
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; } }
private static HResult CreateTopology(out IMFTopology topology, out IMFMediaSinkAlt mediaSink, IMFMediaSource source) { HResult hr = S_OK; topology = null; mediaSink = null; IMFPresentationDescriptor presentationDescriptor = null; hr = MF.CreateTopology(out topology); if (Failed(hr)) { return(hr); } hr = source.CreatePresentationDescriptor(out presentationDescriptor); if (Failed(hr)) { topology = null; return(hr); } hr = BuildTopology(out mediaSink, topology, presentationDescriptor, source); if (Failed(hr)) { mediaSink = null; topology = null; return(hr); } return(hr); }
/// <summary> /// Determines if the media presentation requires the Protected Media Path (PMP). /// </summary> /// <param name="presentationDescriptor">A valid IMFPresentationDescriptor 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 RequireProtectedEnvironment(this IMFPresentationDescriptor presentationDescriptor) { if (presentationDescriptor == null) { throw new ArgumentNullException("presentationDescriptor"); } return(MFExtern.MFRequireProtectedEnvironment(presentationDescriptor)); }
public HResult GetMFMetadata( IMFPresentationDescriptor pPresentationDescriptor, int dwStreamIdentifier, int dwFlags, out IMFMetadata ppMFMetadata) { ppMFMetadata = this; return(HResult.S_OK); }
/////////////////////////////////////////////////////////////////////// // 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); } }
/// <summary> /// Starts, seeks, or restarts the media source by specifying where to start playback. /// </summary> /// <param name="mediaSource">A valid IMFMediaSource instance.</param> /// <param name="presentationDescriptor">An IMFPresentationDescriptor instance of the media source's presentation descriptor.</param> /// <returns>If this function succeeds, it returns the S_OK member. Otherwise, it returns another HResult's member that describe the error.</returns> /// <remarks>This method starts the media source at its beginning.</remarks> public static HResult Start(this IMFMediaSource mediaSource, IMFPresentationDescriptor presentationDescriptor) { if (mediaSource == null) { throw new ArgumentNullException("mediaSource"); } using (PropVariant start = new PropVariant(0)) { return(mediaSource.Start(presentationDescriptor, Guid.Empty, start)); } }
public CaptureFormat[] GetCaptureFormats() { if (m_pSource == null) { CreateVideoCaptureSource(); } IMFPresentationDescriptor pPD = null; IMFStreamDescriptor pSD = null; IMFMediaTypeHandler pHandler = null; IMFMediaType pType = null; int hr = m_pSource.CreatePresentationDescriptor(out pPD); MFError.ThrowExceptionForHR(hr); bool fSelected; hr = pPD.GetStreamDescriptorByIndex(0, out fSelected, out pSD); MFError.ThrowExceptionForHR(hr); hr = pSD.GetMediaTypeHandler(out pHandler); MFError.ThrowExceptionForHR(hr); int cTypes = 0; hr = pHandler.GetMediaTypeCount(out cTypes); MFError.ThrowExceptionForHR(hr); CaptureFormat[] captureFormats = new CaptureFormat[cTypes]; for (int i = 0; i < cTypes; i++) { hr = pHandler.GetMediaTypeByIndex(i, out pType); MFError.ThrowExceptionForHR(hr); CaptureFormat mediatype = LogMediaType(pType); Trace.WriteLine(mediatype); Trace.WriteLine("Media Type " + i.ToString()); captureFormats[i] = mediatype; //OutputDebugString(L"\n"); Marshal.FinalReleaseComObject(pType); } Marshal.FinalReleaseComObject(pPD); Marshal.FinalReleaseComObject(pSD); Marshal.FinalReleaseComObject(pHandler); Marshal.FinalReleaseComObject(pType); return(captureFormats); }
private void createSession(string sFilePath) { try { MFError throwonhr = null; if (m_pSession == null) { throwonhr = MFExtern.MFCreateMediaSession(null, out m_pSession); } else { Stop(); } // Create the media source. CreateMediaSource(sFilePath); if (m_pSource == null) { return; } IMFPresentationDescriptor lPresentationDescriptor = null; m_pSource.CreatePresentationDescriptor(out lPresentationDescriptor); if (lPresentationDescriptor == null) { return; } lPresentationDescriptor.GetUINT64(MFAttributesClsid.MF_PD_DURATION, out mMediaDuration); IMFTopology pTopology = null; // Create a partial topology. CreateTopologyFromSource(out pTopology); HResult hr = HResult.S_OK; // Set the topology on the media session. hr = m_pSession.SetTopology(MFSessionSetTopologyFlags.Immediate, pTopology); StartPlayback(); } catch (Exception) { } }
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); } }
public HResult Start(IMFPresentationDescriptor pPresentationDescriptor, Guid pguidTimeFormat, ConstPropVariant pvarStartPos) { HResult hr = HResult.S_OK; // Check parameters. // Start position and presentation descriptor cannot be NULL. if (pvarStartPos == null || pPresentationDescriptor == null) { return(HResult.E_INVALIDARG); } // Check the time format. if ((pguidTimeFormat != null) && (pguidTimeFormat != Guid.Empty)) { // Unrecognized time format GUID. return(HResult.MF_E_UNSUPPORTED_TIME_FORMAT); } // Check the data type of the start position. if (pvarStartPos.GetVariantType() != VariantType.None && pvarStartPos.GetVariantType() != VariantType.Int64) { return(HResult.MF_E_UNSUPPORTED_TIME_FORMAT); } if (_eSourceState != SourceState.SourceState_Stopped && _eSourceState != SourceState.SourceState_Started) { hr = HResult.MF_E_INVALIDREQUEST; } if (MFError.Succeeded(hr)) { // Check if the presentation description is valid. hr = ValidatePresentationDescriptor(pPresentationDescriptor); } if (MFError.Succeeded(hr)) { CSourceOperation op = new CSourceOperation { Type = SourceOperationType.Operation_Start, PresentationDescriptor = pPresentationDescriptor, Data = pvarStartPos }; doStart(op); } return(hr); }
protected void CreateTopologyFromSource(out IMFTopology ppTopology) { TRACE("CPlayer::CreateTopologyFromSource"); Debug.Assert(m_pSession != null); Debug.Assert(m_pSource != null); IMFTopology pTopology = null; IMFPresentationDescriptor pSourcePD = null; int cSourceStreams = 0; HResult hr; try { // Create a new topology. hr = MFExtern.MFCreateTopology(out pTopology); MFError.ThrowExceptionForHR(hr); // Create the presentation descriptor for the media source. hr = m_pSource.CreatePresentationDescriptor(out pSourcePD); MFError.ThrowExceptionForHR(hr); // Get the number of streams in the media source. hr = pSourcePD.GetStreamDescriptorCount(out cSourceStreams); MFError.ThrowExceptionForHR(hr); TRACE(string.Format("Stream count: {0}", cSourceStreams)); // For each stream, create the topology nodes and add them to the topology. for (int i = 0; i < cSourceStreams; i++) { AddBranchToPartialTopology(pTopology, m_hwndVideo, m_pSource, pSourcePD, i); } // Return the IMFTopology pointer to the caller. ppTopology = pTopology; } catch { // If we failed, release the topology SafeRelease(pTopology); throw; } finally { SafeRelease(pSourcePD); } }
public HResult CreatePresentationDescriptor(out IMFPresentationDescriptor ppPresentationDescriptor) { ppPresentationDescriptor = null; HResult hr = CheckShutdown(); if (MFError.Succeeded(hr) && (_eSourceState == SourceState.SourceState_Opening || _eSourceState == SourceState.SourceState_Invalid || null == _spPresentationDescriptor)) { hr = HResult.MF_E_NOT_INITIALIZED; } if (MFError.Succeeded(hr)) { hr = _spPresentationDescriptor.Clone(out ppPresentationDescriptor); } return(hr); }
/////////////////////////////////////////////////////////////////////// // 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: CPlayer::QueueNextSegment (Private) // Description: // Queues the next topology on the session. // // Parameter: // pPresentationDescriptor: [in] Presentation descriptor for the next topology // pSegmentId: [out] Receives the corresponding segment identifier for the topology // // Note: The presentation descriptor is received from the MENewPresentation event. // This event tells the session about the next topology in the sequencer. // If NULL is passed, this method queues the first topology on the media session. ///////////////////////////////////////////////////////////////////////////////////////// private void QueueNextSegment( IMFPresentationDescriptor pPresentationDescriptor, out int pSegmentId) { HResult hr; IMFMediaSourceTopologyProvider pMediaSourceTopologyProvider; IMFTopology pTopology; int SegId = 0; // Get the Segment ID. hr = m_pSequencerSource.GetPresentationContext( pPresentationDescriptor, out SegId, out pTopology); MFError.ThrowExceptionForHR(hr); SafeRelease(pTopology); Debug.WriteLine(string.Format("CPlayer::QueueNextSegment: {0}", SegId)); //Get the topology for the presentation descriptor pMediaSourceTopologyProvider = (IMFMediaSourceTopologyProvider)m_pSequencerSource; hr = pMediaSourceTopologyProvider.GetMediaSourceTopology( pPresentationDescriptor, out pTopology); MFError.ThrowExceptionForHR(hr); try { //Set the topology on the media session hr = m_pMediaSession.SetTopology(MFSessionSetTopologyFlags.None, pTopology); MFError.ThrowExceptionForHR(hr); pSegmentId = SegId; } finally { //clean up SafeRelease(pTopology); } }
protected void SetDuration() { if (m_pSource == null) { return; } long duration = 0; IMFPresentationDescriptor pPD = null; int hr = m_pSource.CreatePresentationDescriptor(out pPD); if (hr == 0) { pPD.GetUINT64(MFAttributesClsid.MF_PD_DURATION, out duration); } COMBase.SafeRelease(pPD); Duration = duration; }
private void InitPresentationDescription() { IMFPresentationDescriptor spPresentationDescriptor; IMFStreamDescriptor[] aStreams = new IMFStreamDescriptor[_streams.Count]; for (int i = 0; i < _streams.Count; i++) { ThrowIfError(_streams[i].GetStreamDescriptor(out aStreams[i])); } ThrowIfError(MFExtern.MFCreatePresentationDescriptor(_streams.Count, aStreams, out spPresentationDescriptor)); for (int nStream = 0; nStream < _streams.Count; ++nStream) { ThrowIfError(spPresentationDescriptor.SelectStream(nStream)); } _spPresentationDescriptor = spPresentationDescriptor; }
protected void CreateTopologyFromSource(out IMFTopology ppTopology) { IMFTopology pTopology = null; IMFPresentationDescriptor pSourcePD = null; int cSourceStreams = 0; MFError throwonhr; try { // Create a new topology. throwonhr = MFExtern.MFCreateTopology(out pTopology); // Create the presentation descriptor for the media source. throwonhr = m_pSource.CreatePresentationDescriptor(out pSourcePD); // Get the number of streams in the media source. throwonhr = pSourcePD.GetStreamDescriptorCount(out cSourceStreams); //TRACE(string.Format("Stream count: {0}", cSourceStreams)); // For each stream, create the topology nodes and add them to the topology. for (int i = 0; i < cSourceStreams; i++) { AddBranchToPartialTopology(pTopology, pSourcePD, i); } // Return the IMFTopology pointer to the caller. ppTopology = pTopology; } catch { // If we failed, release the topology //SafeRelease(pTopology); throw; } finally { //SafeRelease(pSourcePD); } }
private void doStart(CSourceOperation pOp) { Debug.Assert(pOp.Type == SourceOperationType.Operation_Start); IMFPresentationDescriptor spPD = pOp.PresentationDescriptor; try { SelectStreams(spPD); _eSourceState = SourceState.SourceState_Starting; _networkStreamAdapter.SendStartRequest(); _eSourceState = SourceState.SourceState_Started; ThrowIfError(_spEventQueue.QueueEventParamVar(MediaEventType.MESourceStarted, Guid.Empty, HResult.S_OK, pOp.Data)); } catch (Exception ex) { _spEventQueue.QueueEventParamVar(MediaEventType.MESourceStarted, Guid.Empty, (HResult)ex.HResult, null); } }
private HResult ValidatePresentationDescriptor(IMFPresentationDescriptor pPD) { HResult hr = HResult.S_OK; bool fSelected = false; int cStreams = 0; if (_streams.Count == 0) { return(HResult.E_UNEXPECTED); } // The caller's PD must have the same number of streams as ours. hr = pPD.GetStreamDescriptorCount(out cStreams); if (MFError.Succeeded(hr)) { if (cStreams != _streams.Count) { hr = HResult.E_INVALIDARG; } } // The caller must select at least one stream. if (MFError.Succeeded(hr)) { for (int i = 0; i < cStreams; i++) { IMFStreamDescriptor spSD; hr = pPD.GetStreamDescriptorByIndex(i, out fSelected, out spSD); if (MFError.Failed(hr)) { break; } } } return(hr); }
//------------------------------------------------------------------- // Name: QueueNewStreamEvent // Description: // Queues an MENewStream or MEUpdatedStream event during Start. // // pPD: The presentation descriptor. // // Precondition: The presentation descriptor is assumed to be valid. // Call ValidatePresentationDescriptor before calling this method. //------------------------------------------------------------------- private void QueueNewStreamEvent(IMFPresentationDescriptor pPD) { int hr; Debug.Assert(pPD != null); m_Log.WriteLine("QueueNewStreamEvent"); IMFStreamDescriptor pSD = null; bool fSelected = false; hr = pPD.GetStreamDescriptorByIndex(0, out fSelected, out pSD); MFError.ThrowExceptionForHR(hr); // The stream must be selected, because we don't allow the app // to de-select the stream. See ValidatePresentationDescriptor. Debug.Assert(fSelected); if (m_pStream != null) { // The stream already exists, and is still selected. // Send the MEUpdatedStream event. QueueEvent(MediaEventType.MEUpdatedStream, Guid.Empty, S_Ok, new PropVariant(m_pStream)); } else { // The stream does not exist, and is now selected. // Create a new stream. CreateWavStream(pSD); // CreateWavStream creates the stream, so m_pStream is no longer null. Debug.Assert(m_pStream != null); // Send the MENewStream event. QueueEvent(MediaEventType.MENewStream, Guid.Empty, S_Ok, new PropVariant(m_pStream)); } //SAFE_RELEASE(pSD); }
//------------------------------------------------------------------- // Name: ValidatePresentationDescriptor // Description: Validates the caller's presentation descriptor. // // This method is called when Start() is called with a non-NULL // presentation descriptor. The caller is supposed to give us back // the same PD that we gave out in CreatePresentationDescriptor(). // This method performs a sanity check on the caller's PD to make // sure it matches ours. // // Note: Because this media source has one stream with single, fixed // media type, there is not much for the caller to decide. In // a more complicated source, the caller might select different // streams, or select from a list of media types. //------------------------------------------------------------------- private void ValidatePresentationDescriptor(IMFPresentationDescriptor pPD) { int hr; m_Log.WriteLine("ValidatePresentationDescriptor"); Debug.Assert(pPD != null); IMFStreamDescriptor pStreamDescriptor = null; IMFMediaTypeHandler pHandler = null; IMFMediaType pMediaType = null; WaveFormatEx pFormat = null; int cStreamDescriptors = 0; bool fSelected = false; // Make sure there is only one stream. hr = pPD.GetStreamDescriptorCount(out cStreamDescriptors); MFError.ThrowExceptionForHR(hr); if (cStreamDescriptors != 1) { throw new COMException("not just 1 stream", MFError.MF_E_UNSUPPORTED_REPRESENTATION); } // Get the stream descriptor. hr = pPD.GetStreamDescriptorByIndex(0, out fSelected, out pStreamDescriptor); MFError.ThrowExceptionForHR(hr); // Make sure it's selected. (This media source has only one stream, so it // is not useful to deselect the only stream.) if (!fSelected) { throw new COMException("not selected", MFError.MF_E_UNSUPPORTED_REPRESENTATION); } // Get the media type handler, so that we can get the media type. hr = pStreamDescriptor.GetMediaTypeHandler(out pHandler); MFError.ThrowExceptionForHR(hr); hr = pHandler.GetCurrentMediaType(out pMediaType); MFError.ThrowExceptionForHR(hr); int iSize; // Deprecated method, but it works //IntPtr ip = pAudioType.GetAudioFormat(); //pFormat = new WaveFormatEx(); //Marshal.PtrToStructure(ip, pFormat); hr = MFExtern.MFCreateWaveFormatExFromMFMediaType( pMediaType, out pFormat, out iSize, MFWaveFormatExConvertFlags.Normal); MFError.ThrowExceptionForHR(hr); if ((pFormat == null) || (this.WaveFormat() == null)) { throw new COMException("bad format or waveformat", MFError.MF_E_INVALIDMEDIATYPE); } if (!pFormat.Equals(WaveFormat())) { throw new COMException("wave formats don't match", MFError.MF_E_INVALIDMEDIATYPE); } //SAFE_RELEASE(pStreamDescriptor); //SAFE_RELEASE(pHandler); //SAFE_RELEASE(pMediaType); //SAFE_RELEASE(pAudioType); }
public static extern int MFRequireProtectedEnvironment(IMFPresentationDescriptor pPresentationDescriptor);
//////////////////////////////////////////////////////////////////////////////////////// // Name: CPlayer::CreateNodesForStream (Private) // Description: // Creates the source and output nodes for a stream and // Adds them to the topology // Connects the source node to the output node // // Parameter: // pPresentationDescriptor: [in] Pointer to the presentation descriptor for the media source // pMediaSource: [in] Pointer to the media source // pTopology: [in] Pointer to the topology // // Notes: For each stream, the app must: // 1. Create a source node associated with the stream. // 2. Create an output node for the renderer. // 3. Connect the two nodes. // The media session will resolve the topology, transform nodes are not required ///////////////////////////////////////////////////////////////////////////////////////// private void CreateNodesForStream( IMFPresentationDescriptor pPresentationDescriptor, IMFMediaSource pMediaSource, IMFTopology pTopology) { if (pPresentationDescriptor == null || pMediaSource == null || pTopology == null) { throw new COMException("null pointer", (int)HResult.E_POINTER); } HResult hr; IMFStreamDescriptor pStreamDescriptor; IMFTopologyNode pSourceNode; IMFTopologyNode pOutputNode; bool fSelected = false; // Get the stream descriptor for the only stream index =0. hr = pPresentationDescriptor.GetStreamDescriptorByIndex(0, out fSelected, out pStreamDescriptor); MFError.ThrowExceptionForHR(hr); try { if (fSelected) { // Create a source node for this stream and add it to the topology. CreateSourceNode(pPresentationDescriptor, pStreamDescriptor, pMediaSource, out pSourceNode); try { hr = pTopology.AddNode(pSourceNode); MFError.ThrowExceptionForHR(hr); // Create the output node for the renderer and add it to the topology. CreateOutputNode(pStreamDescriptor, out pOutputNode); try { 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 { SafeRelease(pOutputNode); } } finally { SafeRelease(pSourceNode); } } } finally { //clean up SafeRelease(pStreamDescriptor); } }
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); }
//////////////////////////////////////////////////////////////////////////////////////// // Name: CPlayer::CreateNodesForStream (Private) // Description: // Creates the source and output nodes for a stream and // Adds them to the topology // Connects the source node to the output node // // Parameter: // pPresentationDescriptor: [in] Pointer to the presentation descriptor for the media source // pMediaSource: [in] Pointer to the media source // pTopology: [in] Pointer to the topology // // Notes: For each stream, the app must: // 1. Create a source node associated with the stream. // 2. Create an output node for the renderer. // 3. Connect the two nodes. // The media session will resolve the topology, transform nodes are not required ///////////////////////////////////////////////////////////////////////////////////////// private void CreateNodesForStream( IMFPresentationDescriptor pPresentationDescriptor, IMFMediaSource pMediaSource, IMFTopology pTopology) { if (pPresentationDescriptor == null || pMediaSource == null || pTopology == null) { throw new COMException("null pointer", E_Pointer); } int hr; IMFStreamDescriptor pStreamDescriptor; IMFTopologyNode pSourceNode; IMFTopologyNode pOutputNode; bool fSelected = false; // Get the stream descriptor for the only stream index =0. hr = pPresentationDescriptor.GetStreamDescriptorByIndex(0, out fSelected, out pStreamDescriptor); MFError.ThrowExceptionForHR(hr); try { if (fSelected) { // Create a source node for this stream and add it to the topology. CreateSourceNode(pPresentationDescriptor, pStreamDescriptor, pMediaSource, out pSourceNode); try { hr = pTopology.AddNode(pSourceNode); MFError.ThrowExceptionForHR(hr); // Create the output node for the renderer and add it to the topology. CreateOutputNode(pStreamDescriptor, out pOutputNode); try { 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 { SafeRelease(pOutputNode); } } finally { SafeRelease(pSourceNode); } } } finally { //clean up SafeRelease(pStreamDescriptor); } }
public void Dispose() { if (m_pRiff != null) { m_pRiff.Dispose(); m_pRiff = null; } if (m_pStream != null) { m_pStream.Dispose(); m_pStream = null; } if (m_pEventQueue != null) { Marshal.ReleaseComObject(m_pEventQueue); m_pEventQueue = null; } if (m_pPresentationDescriptor != null) { Marshal.ReleaseComObject(m_pPresentationDescriptor); m_pPresentationDescriptor = null; } if (m_Log != null) { m_Log.Dispose(); m_Log = null; } GC.SuppressFinalize(this); }
//////////////////////////////////////////////////////////////////////////////////////// // Name: CPlayer::QueueNextSegment (Private) // Description: // Queues the next topology on the session. // // Parameter: // pPresentationDescriptor: [in] Presentation descriptor for the next topology // pSegmentId: [out] Receives the corresponding segment identifier for the topology // // Note: The presentation descriptor is received from the MENewPresentation event. // This event tells the session about the next topology in the sequencer. // If NULL is passed, this method queues the first topology on the media session. ///////////////////////////////////////////////////////////////////////////////////////// private void QueueNextSegment( IMFPresentationDescriptor pPresentationDescriptor, out int pSegmentId) { int hr; IMFMediaSourceTopologyProvider pMediaSourceTopologyProvider; IMFTopology pTopology; int SegId = 0; // Get the Segment ID. hr = m_pSequencerSource.GetPresentationContext( pPresentationDescriptor, out SegId, out pTopology); MFError.ThrowExceptionForHR(hr); SafeRelease(pTopology); Debug.WriteLine(string.Format("CPlayer::QueueNextSegment: {0}", SegId)); //Get the topology for the presentation descriptor pMediaSourceTopologyProvider = (IMFMediaSourceTopologyProvider)m_pSequencerSource; hr = pMediaSourceTopologyProvider.GetMediaSourceTopology( pPresentationDescriptor, out pTopology); MFError.ThrowExceptionForHR(hr); try { //Set the topology on the media session hr = m_pMediaSession.SetTopology(MFSessionSetTopologyFlags.None, pTopology); MFError.ThrowExceptionForHR(hr); pSegmentId = SegId; } finally { //clean up SafeRelease(pTopology); } }
/////////////////////////////////////////////////////////////////////// // 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; int hr; Guid majorType; bool fSelected = false; // Get the stream descriptor for this stream. hr = pSourcePD.GetStreamDescriptorByIndex(iStream, out fSelected, out pSourceSD); MFError.ThrowExceptionForHR(hr); // 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. hr = pTopology.AddNode(pSourceNode); MFError.ThrowExceptionForHR(hr); // 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) { CreateAudioBranch(pTopology, pSourceNode, Guid.Empty); } } finally { // Clean up. SafeRelease(pSourceSD); SafeRelease(pSourceNode); } } }
//------------------------------------------------------------------- // Name: Start // Description: Switches to running state. //------------------------------------------------------------------- public int Start( IMFPresentationDescriptor pPresentationDescriptor, Guid pguidTimeFormat, ConstPropVariant pvarStartPosition ) { // Make sure we *never* leave this entry point with an exception try { int hr; m_Log.WriteLine("-Start"); lock (this) { PropVariant var; long llStartOffset = 0; bool bIsSeek = false; bool bIsRestartFromCurrentPosition = false; // Fail if the source is shut down. CheckShutdown(); // Check parameters. // Start position and presentation descriptor cannot be null. if (pPresentationDescriptor == null) // pvarStartPosition == null || { throw new COMException("null presentation descriptor", E_InvalidArgument); } // Check the time format. Must be "reference time" units. if ((pguidTimeFormat != null) && (pguidTimeFormat != Guid.Empty)) { // Unrecognized time format GUID. throw new COMException("unrecognized time format guid", MFError.MF_E_UNSUPPORTED_TIME_FORMAT); } // Check the start position. if ((pvarStartPosition == null) || (pvarStartPosition.GetMFAttributeType() == MFAttributeType.None)) { // Start position is "current position". // For stopped, that means 0. Otherwise, use the current position. if (m_state == State.Stopped) { llStartOffset = 0; } else { llStartOffset = GetCurrentPosition(); bIsRestartFromCurrentPosition = true; } } else if (pvarStartPosition.GetMFAttributeType() == MFAttributeType.Uint64) { // Start position is given in pvarStartPosition in 100-ns units. llStartOffset = (long)pvarStartPosition; if (m_state != State.Stopped) { // Source is running or paused, so this is a seek. bIsSeek = true; } } else { // We don't support this time format. throw new COMException("We don't support this time format", MFError.MF_E_UNSUPPORTED_TIME_FORMAT); } // Validate the caller's presentation descriptor. ValidatePresentationDescriptor(pPresentationDescriptor); // Sends the MENewStream or MEUpdatedStream event. QueueNewStreamEvent(pPresentationDescriptor); // Notify the stream of the new start time. m_pStream.SetPosition(llStartOffset); // Send Started or Seeked events. We will send them // 1. from the media source // 2. from each stream var = new PropVariant(llStartOffset); // (1) Send the source event. if (bIsSeek) { QueueEvent(MediaEventType.MESourceSeeked, Guid.Empty, S_Ok, var); } else { // For starting, if we are RESTARTING from the current position and our // previous state was running/paused, then we need to add the // MF_EVENT_SOURCE_ACTUAL_START attribute to the event. This requires // creating the event object first. IMFMediaEvent pEvent = null; // Create the event. hr = MFExtern.MFCreateMediaEvent( MediaEventType.MESourceStarted, Guid.Empty, S_Ok, var, out pEvent ); MFError.ThrowExceptionForHR(hr); // For restarts, set the actual start time as an attribute. if (bIsRestartFromCurrentPosition) { hr = pEvent.SetUINT64(MFAttributesClsid.MF_EVENT_SOURCE_ACTUAL_START, llStartOffset); MFError.ThrowExceptionForHR(hr); } // Now queue the event. hr = m_pEventQueue.QueueEvent(pEvent); MFError.ThrowExceptionForHR(hr); //SAFE_RELEASE(pEvent); } // 2. Send the stream event. if (m_pStream != null) { if (bIsSeek) { m_pStream.QueueEvent(MediaEventType.MEStreamSeeked, Guid.Empty, S_Ok, var); } else { m_pStream.QueueEvent(MediaEventType.MEStreamStarted, Guid.Empty, S_Ok, var); } } // Update our state. m_state = State.Started; // NOTE: If this method were implemented as an asynchronous operation // and the operation Failed asynchronously, the media source would need // to send an MESourceStarted event with the failure code. For this // sample, all operations are synchronous (which is allowed), so any // failures are also synchronous. var.Clear(); } return S_Ok; } catch (Exception e) { return Marshal.GetHRForException(e); } }
/////////////////////////////////////////////////////////////////////// // 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 ) { int 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: 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); }
//////////////////////////////////////////////////////////////////////////////////////// // 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: 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); }
protected void AddBranchToPartialTopology( IMFTopology pTopology, IMFPresentationDescriptor pSourcePD, int iStream ) { 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. 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. pTopology.AddNode(pSourceNode); pTopology.AddNode(pOutputNode); // Connect the source node to the output node. pSourceNode.ConnectOutput(0, pOutputNode, 0); } } finally { // Clean up. SafeRelease(pSourceSD); SafeRelease(pSourceNode); SafeRelease(pOutputNode); } }
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; } }
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); }
//------------------------------------------------------------------- // Name: CreatePresentationDescriptor // Description: Returns a copy of the default presentation descriptor. //------------------------------------------------------------------- public int CreatePresentationDescriptor(out IMFPresentationDescriptor ppPresentationDescriptor) { // Make sure we *never* leave this entry point with an exception try { int hr; m_Log.WriteLine("-CreatePresentationDescriptor"); ppPresentationDescriptor = null; lock (this) { CheckShutdown(); if (m_pPresentationDescriptor == null) { CreatePresentationDescriptor(); } // Clone our default presentation descriptor. hr = m_pPresentationDescriptor.Clone(out ppPresentationDescriptor); MFError.ThrowExceptionForHR(hr); } return S_Ok; } catch (Exception e) { ppPresentationDescriptor = null; return Marshal.GetHRForException(e); } }