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;
            }
        }
示例#2
0
    ///////////////////////////////////////////////////////////////////////
    //  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);
    }
示例#3
0
        //////////////////////////////////////////////////////////////////////
        //  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);
        }
示例#4
0
        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());
                }
            }
        }
示例#5
0
        ////////////////////////////////////////////////////////////////////////////////////////
        //  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);
        }
示例#6
0
        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);
        }
示例#7
0
        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);
        }
示例#9
0
        /// <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));
        }
示例#10
0
    public HResult GetMFMetadata(
        IMFPresentationDescriptor pPresentationDescriptor,
        int dwStreamIdentifier,
        int dwFlags,
        out IMFMetadata ppMFMetadata)
    {
        ppMFMetadata = this;

        return(HResult.S_OK);
    }
示例#11
0
    ///////////////////////////////////////////////////////////////////////
    //  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);
            }
        }
    }
示例#12
0
        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);
            }
        }
示例#13
0
        /// <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));
            }
        }
示例#14
0
        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)
            {
            }
        }
示例#16
0
    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);
        }
    }
示例#17
0
        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);
        }
示例#18
0
    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);
        }
    }
示例#19
0
        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);
        }
示例#20
0
        ///////////////////////////////////////////////////////////////////////
        //  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);
                }
            }
        }
示例#21
0
        ////////////////////////////////////////////////////////////////////////////////////////
        //  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;
        }
示例#23
0
        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);
            }
        }
示例#25
0
        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);
            }
        }
示例#26
0
        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);
        }
示例#27
0
        //-------------------------------------------------------------------
        // 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);
        }
示例#28
0
        //-------------------------------------------------------------------
        // 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);
        }
示例#29
0
 public static extern int MFRequireProtectedEnvironment(IMFPresentationDescriptor pPresentationDescriptor);
示例#30
0
        ////////////////////////////////////////////////////////////////////////////////////////
        //  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);
            }
        }
示例#31
0
        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);
        }
示例#32
0
        ////////////////////////////////////////////////////////////////////////////////////////
        //  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);
            }
        }
示例#33
0
        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);
        }
示例#34
0
        ////////////////////////////////////////////////////////////////////////////////////////
        //  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);
            }
        }
示例#35
0
    ///////////////////////////////////////////////////////////////////////
    //  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);
            }
        }
    }
示例#36
0
        //-------------------------------------------------------------------
        // 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);
            }
        }
示例#37
0
        ///////////////////////////////////////////////////////////////////////
        //  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);
                }
            }
        }
示例#38
0
        //////////////////////////////////////////////////////////////////////
        //  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);
        }
示例#39
0
        ////////////////////////////////////////////////////////////////////////////////////////
        //  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);
        }
示例#40
0
    ///////////////////////////////////////////////////////////////////////
    //  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);
    }
示例#41
0
        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);
            }
        }
示例#42
0
        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;
            }
        }
示例#43
0
        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);
        }
示例#44
0
        //-------------------------------------------------------------------
        // 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);
            }
        }