Пример #1
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);
        }
        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;
            }
        }
Пример #3
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);
        }
Пример #4
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);
        }
Пример #5
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);
        }
Пример #6
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);
    }
Пример #7
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);
            }
        }
    }
Пример #8
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);
            }
        }
Пример #9
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);
        }
Пример #10
0
        private void Initialize(StspStreamDescription pStreamDescription, IBufferPacket attributesBuffer)
        {
            //Create the media event queue.
            ThrowIfError(MFExtern.MFCreateEventQueue(out _spEventQueue));

            IMFMediaType        mediaType;
            IMFStreamDescriptor spSD;
            IMFMediaTypeHandler spMediaTypeHandler;

            _isVideo = (pStreamDescription.guiMajorType == MFMediaType.Video);

            //Create a media type object.
            ThrowIfError(MFExtern.MFCreateMediaType(out mediaType));

            if (attributesBuffer.GetLength() < pStreamDescription.cbAttributesSize || pStreamDescription.cbAttributesSize == 0)
            {
                //Invalid stream description
                Throw(HResult.MF_E_UNSUPPORTED_FORMAT);
            }

            //Prepare buffer where we will copy attributes to, then initialize media type's attributes
            var pAttributes = Marshal.AllocHGlobal(pStreamDescription.cbAttributesSize);

            try
            {
                Marshal.Copy(attributesBuffer.TakeBuffer(pStreamDescription.cbAttributesSize), 0, pAttributes, pStreamDescription.cbAttributesSize);
                ThrowIfError(MFExtern.MFInitAttributesFromBlob(mediaType, pAttributes, pStreamDescription.cbAttributesSize));
            }
            finally
            {
                Marshal.FreeHGlobal(pAttributes);
            }

            Validation.ValidateInputMediaType(pStreamDescription.guiMajorType, pStreamDescription.guiSubType, mediaType);
            ThrowIfError(mediaType.SetGUID(MF_MT_MAJOR_TYPE, pStreamDescription.guiMajorType));
            ThrowIfError(mediaType.SetGUID(MF_MT_SUBTYPE, pStreamDescription.guiSubType));

            //Now we can create MF stream descriptor.
            ThrowIfError(MFExtern.MFCreateStreamDescriptor(pStreamDescription.dwStreamId, 1, new IMFMediaType[] { mediaType }, out spSD));
            ThrowIfError(spSD.GetMediaTypeHandler(out spMediaTypeHandler));

            //Set current media type
            ThrowIfError(spMediaTypeHandler.SetCurrentMediaType(mediaType));

            _spStreamDescriptor = spSD;
            _id = pStreamDescription.dwStreamId;
            //State of the stream is started.
            _eSourceState = SourceState.SourceState_Stopped;
        }
Пример #11
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);
        }
    }
Пример #12
0
        private void initVideoDesctriptor(StspStreamDescription pStreamDescription, IBufferPacket attributesBuffer)
        {
            IMFMediaType        mediaType;
            IMFStreamDescriptor spSD;
            IMFMediaTypeHandler spMediaTypeHandler;

            //Create a media type object.
            ThrowIfError(MFExtern.MFCreateMediaType(out mediaType));

            if (attributesBuffer.GetLength() < pStreamDescription.cbAttributesSize || pStreamDescription.cbAttributesSize == 0)
            {
                //Invalid stream description
                Throw(HResult.MF_E_UNSUPPORTED_FORMAT);
            }

            //Prepare buffer where we will copy attributes to, then initialize media type's attributes
            var pAttributes = Marshal.AllocHGlobal(pStreamDescription.cbAttributesSize);

            try
            {
                Marshal.Copy(attributesBuffer.TakeBuffer(pStreamDescription.cbAttributesSize), 0, pAttributes, pStreamDescription.cbAttributesSize);
                ThrowIfError(MFExtern.MFInitAttributesFromBlob(mediaType, pAttributes, pStreamDescription.cbAttributesSize));
            }
            finally
            {
                Marshal.FreeHGlobal(pAttributes);
            }

            ThrowIfError(mediaType.SetGUID(MF_MT_MAJOR_TYPE, pStreamDescription.guiMajorType));
            ThrowIfError(mediaType.SetGUID(MF_MT_SUBTYPE, pStreamDescription.guiSubType));

            //Now we can create MF stream descriptor.
            ThrowIfError(MFExtern.MFCreateStreamDescriptor(pStreamDescription.dwStreamId, 1, new IMFMediaType[] { mediaType }, out spSD));
            ThrowIfError(spSD.GetMediaTypeHandler(out spMediaTypeHandler));

            //Set current media type
            ThrowIfError(spMediaTypeHandler.SetCurrentMediaType(mediaType));

            _videoMediaType        = mediaType;
            _videoStreamDescriptor = spSD;
            _videoStreamId         = pStreamDescription.dwStreamId;

            ThrowIfError(MFExtern.MFGetAttributeSize(mediaType, MFAttributesClsid.MF_MT_FRAME_SIZE, out _videoWitdh, out _videoHeight));
            ThrowIfError(MFExtern.MFGetAttributeRatio(mediaType, MFAttributesClsid.MF_MT_PIXEL_ASPECT_RATIO, out _videoRatioN, out _videoRatioD));

            _drawDevice.InitializeSetVideoSize(_videoWitdh, _videoHeight, new MFRatio(_videoRatioN, _videoRatioD));
        }
Пример #13
0
        ////////////////////////////////////////////////////////////////////////////////////////
        //  Name: CPlayer::CreateOutputNode (Private)
        //  Description:
        //      Creates an output node for a stream
        //      Sets the IActivate pointer on the node
        //  Parameter:
        //      pStreamDescriptor: [in] Stream descriptor for the stream
        //      ppSourceNode: [out] Receives a pointer to the new node
        ////////////////////////////////////////////////////////////////////////////////////////

        private void CreateOutputNode(
            IMFStreamDescriptor pStreamDescriptor,
            out IMFTopologyNode ppOutputNode)
        {
            if (pStreamDescriptor == null)
            {
                throw new COMException("null pointer", (int)HResult.E_POINTER);
            }

            IMFMediaTypeHandler pHandler;

            Guid guidMajorType = Guid.Empty;

            // Create a downstream node.
            HResult hr = MFExtern.MFCreateTopologyNode(MFTopologyType.OutputNode, out ppOutputNode);

            MFError.ThrowExceptionForHR(hr);

            // Get the media type handler for the stream.
            hr = pStreamDescriptor.GetMediaTypeHandler(out pHandler);
            MFError.ThrowExceptionForHR(hr);

            try
            {
                // Get the major media type.
                pHandler.GetMajorType(out guidMajorType);

                // Set the IActivate object on the output node.
                if (MFMediaType.Audio == guidMajorType)
                {
                    hr = ppOutputNode.SetObject(m_pAudioRendererActivate);
                    MFError.ThrowExceptionForHR(hr);
                    Debug.WriteLine(("Audio stream"));
                }
                //Only audio is implemented, if guidMajorType is any other type, return E_NOTIMPL
                else
                {
                    Debug.WriteLine(("Unsupported stream"));
                    throw new COMException("Unsupported stream", (int)HResult.E_NOTIMPL);
                }
            }
            finally
            {
                // Clean up.
                SafeRelease(pHandler);
            }
        }
Пример #14
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);
                }
            }
        }
Пример #15
0
        public HResult GetStreamDescriptor(out IMFStreamDescriptor ppStreamDescriptor)
        {
            HResult hr = HResult.S_OK;

            ppStreamDescriptor = null;

            lock (_spSource)
            {
                hr = CheckShutdown();

                if (MFError.Succeeded(hr))
                {
                    ppStreamDescriptor = _spStreamDescriptor;
                }

                return(hr);
            }
        }
Пример #16
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;
        }
Пример #17
0
        public HResult Shutdown()
        {
            lock (_spSource)
            {
                HResult hr = CheckShutdown();

                if (MFError.Succeeded(hr))
                {
                    Flush();
                    if (null != _spEventQueue)
                    {
                        _spEventQueue.Shutdown();
                    }

                    _spStreamDescriptor = null;
                    _eSourceState       = SourceState.SourceState_Shutdown;
                }

                return(hr);
            }
        }
Пример #18
0
        ///////////////////////////////////////////////////////////////////////
        //  Name: GetStreamMajorType
        //  Description:  Returns the major media type for a stream.
        ///////////////////////////////////////////////////////////////////////

        static void GetStreamMajorType(IMFStreamDescriptor pSD, out Guid pMajorType)
        {
            HResult             hr;
            IMFMediaTypeHandler pHandler;

            hr = pSD.GetMediaTypeHandler(out pHandler);
            MFError.ThrowExceptionForHR(hr);

            try
            {
                hr = pHandler.GetMajorType(out pMajorType);
                MFError.ThrowExceptionForHR(hr);
            }
            finally
            {
                if (pHandler != null)
                {
                    Marshal.ReleaseComObject(pHandler);
                }
            }
        }
Пример #19
0
    ///////////////////////////////////////////////////////////////////////
    //  Name: GetStreamType
    //  Description:
    //  Returns the major media type from a stream descriptor.
    //
    //  pTopology:      Pointer to the topology.
    //  pSourceNode:    Pointer to the source node.
    //  pOutputNode:    Pointer to the output node.
    //  clsidTrnasform: CLSID of an effect transform.
    /////////////////////////////////////////////////////////////////////////

    void GetStreamType(IMFStreamDescriptor pSourceSD, out Guid pMajorType)
    {
        MFError throwonhr;

        Debug.Assert(pSourceSD != null);
        //Debug.Assert(pMajorType != null);

        IMFMediaTypeHandler pHandler;

        // Get the media type handler for the stream.
        throwonhr = pSourceSD.GetMediaTypeHandler(out pHandler);

        try
        {
            // Get the major media type.
            throwonhr = pHandler.GetMajorType(out pMajorType);
        }
        finally
        {
            SafeRelease(pHandler);
        }
    }
Пример #20
0
        protected IMFTopologyNode CreateOutputNode(IMFStreamDescriptor pSourceSD)
        {
            IMFTopologyNode     pNode             = null;
            IMFMediaTypeHandler pHandler          = null;
            IMFActivate         pRendererActivate = null;

            Guid guidMajorType = Guid.Empty;
            int  hr            = 0;

            // Get the stream ID.
            int streamID = 0;

            try
            {
                try
                {
                    hr = pSourceSD.GetStreamIdentifier(out streamID); // Just for debugging, ignore any failures.
                    MFError.ThrowExceptionForHR(hr);
                }
                catch
                {
                    //TRACE("IMFStreamDescriptor::GetStreamIdentifier" + hr.ToString());
                }

                // Get the media type handler for the stream.
                hr = pSourceSD.GetMediaTypeHandler(out pHandler);
                MFError.ThrowExceptionForHR(hr);

                // Get the major media type.
                hr = pHandler.GetMajorType(out guidMajorType);
                MFError.ThrowExceptionForHR(hr);

                // Create a downstream node.
                hr = MFExtern.MFCreateTopologyNode(MFTopologyType.OutputNode, out pNode);
                MFError.ThrowExceptionForHR(hr);

                // Create an IMFActivate object for the renderer, based on the media type.
                if (MFMediaType.Audio == guidMajorType)
                {
                    // Create the audio renderer.
                    hr = MFExtern.MFCreateAudioRendererActivate(out pRendererActivate);
                    MFError.ThrowExceptionForHR(hr);
                    object sar;
                    pRendererActivate.ActivateObject(typeof(IMFMediaSink).GUID, out sar);
                    StreamingAudioRenderer = sar as IMFMediaSink;
                }
                else if (MFMediaType.Video == guidMajorType)
                {
                    // Create the video renderer.
                    pRendererActivate = CreateVideoRenderer();
                }
                else
                {
                    //TRACE(string.Format("Stream {0}: Unknown format", streamID));
                    throw new COMException("Unknown format");
                }

                // Set the IActivate object on the output node.
                hr = pNode.SetObject(pRendererActivate);
                MFError.ThrowExceptionForHR(hr);
            }
            catch (Exception ex)
            {
                // If we failed, release the pNode
                COMBase.SafeRelease(pNode);
                throw;
            }
            finally
            {
                // Clean up.
                COMBase.SafeRelease(pHandler);
                COMBase.SafeRelease(pRendererActivate);
            }
            return(pNode);
        }
Пример #21
0
 public static extern void MFCreateStreamDescriptor(
     int dwStreamIdentifier,
     int cMediaTypes,
     [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] IMFMediaType[] apMediaTypes,
     out IMFStreamDescriptor ppDescriptor
     );
Пример #22
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);
        }
Пример #23
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);
                }
            }
        }
Пример #24
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);
    }
Пример #25
0
        ////////////////////////////////////////////////////////////////////////////////////////
        //  Name: CPlayer::CreateOutputNode (Private)
        //  Description:
        //      Creates an output node for a stream
        //      Sets the IActivate pointer on the node
        //  Parameter:
        //      pStreamDescriptor: [in] Stream descriptor for the stream
        //      ppSourceNode: [out] Receives a pointer to the new node
        ////////////////////////////////////////////////////////////////////////////////////////
        private void CreateOutputNode(
                            IMFStreamDescriptor pStreamDescriptor,
                            out IMFTopologyNode ppOutputNode)
        {
            if (pStreamDescriptor == null)
            {
                throw new COMException("null pointer", E_Pointer);
            }

            IMFMediaTypeHandler pHandler;

            Guid guidMajorType = Guid.Empty;

            // Create a downstream node.
            int hr = MFExtern.MFCreateTopologyNode(MFTopologyType.OutputNode, out ppOutputNode);
            MFError.ThrowExceptionForHR(hr);

            // Get the media type handler for the stream.
            hr = pStreamDescriptor.GetMediaTypeHandler(out pHandler);
            MFError.ThrowExceptionForHR(hr);

            try
            {
                // Get the major media type.
                pHandler.GetMajorType(out guidMajorType);

                // Set the IActivate object on the output node.
                if (MFMediaType.Audio == guidMajorType)
                {
                    hr = ppOutputNode.SetObject(m_pAudioRendererActivate);
                    MFError.ThrowExceptionForHR(hr);
                    Debug.WriteLine(("Audio stream"));
                }
                //Only audio is implemented, if guidMajorType is any other type, return E_NOTIMPL
                else
                {
                    Debug.WriteLine(("Unsupported stream"));
                    throw new COMException("Unsupported stream", E_NotImplemented);
                }
            }
            finally
            {
                // Clean up.
                SafeRelease(pHandler);
            }
        }
Пример #26
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;
            }
        }
Пример #27
0
        protected void CreateOutputNode(
            IMFStreamDescriptor pSourceSD,
            out IMFTopologyNode ppNode
            )
        {
            IMFTopologyNode pNode = null;
            IMFMediaTypeHandler pHandler = null;
            IMFActivate pRendererActivate = null;

            Guid guidMajorType = Guid.Empty;
            int hr = S_Ok;

            // Get the stream ID.
            int streamID = 0;

            try
            {
                try
                {
                    pSourceSD.GetStreamIdentifier(out streamID); // Just for debugging, ignore any failures.
                }
                catch
                {
                    TRACE("IMFStreamDescriptor::GetStreamIdentifier" + hr.ToString());
                }

                // Get the media type handler for the stream.
                pSourceSD.GetMediaTypeHandler(out pHandler);

                // Get the major media type.
                pHandler.GetMajorType(out guidMajorType);

                // Create a downstream node.
                MFExtern.MFCreateTopologyNode(MFTopologyType.OutputNode, out pNode);

                // Create an IMFActivate object for the renderer, based on the media type.
                if (MFMediaType.Audio == guidMajorType)
                {
                    // Create the audio renderer.
                    TRACE(string.Format("Stream {0}: audio stream", streamID));
                    MFExtern.MFCreateAudioRendererActivate(out pRendererActivate);
                }
                else if (MFMediaType.Video == guidMajorType)
                {
                    // Create the video renderer.
                    TRACE(string.Format("Stream {0}: video stream", streamID));
                    MFExtern.MFCreateVideoRendererActivate(m_hwndVideo, out pRendererActivate);

                    object ppv;
                    pRendererActivate.ActivateObject(typeof(IMFVideoRenderer).GUID, out ppv);

                    var renderer = ppv as IMFVideoRenderer;
                    m_customPresenter = EvrPresenter.CreateNew();
                    m_customPresenter.NewAllocatorFrame += m_customPresenter_NewAllocatorFrame;
                    m_customPresenter.NewAllocatorSurface += m_customPresenter_NewAllocatorSurface;
                    var presenter = m_customPresenter.VideoPresenter as IMFVideoDisplayControl;
                    hr = presenter.SetVideoWindow(m_hwndVideo);
                    hr = renderer.InitializeRenderer(null, m_customPresenter.VideoPresenter);
                    var settings = presenter as IEVRPresenterSettings;
                    settings.SetBufferCount(5);
                }
                else
                {
                    TRACE(string.Format("Stream {0}: Unknown format", streamID));
                    throw new COMException("Unknown format", E_Fail);
                }

                // Set the IActivate object on the output node.
                pNode.SetObject(pRendererActivate);

                // Return the IMFTopologyNode pointer to the caller.
                ppNode = pNode;
            }
            catch
            {
                // If we failed, release the pNode
                SafeRelease(pNode);
                throw;
            }
            finally
            {
                // Clean up.
                SafeRelease(pHandler);
                SafeRelease(pRendererActivate);
            }
        }
Пример #28
0
        /// <summary>
        /// Create media ouput node
        /// </summary>
        /// <param name="pSourceSD"></param>
        /// <param name="ppNode"></param>
        protected void CreateOutputNode(
            IMFStreamDescriptor pSourceSD,
            out IMFTopologyNode ppNode)
        {
            IMFTopologyNode pNode = null;
            IMFMediaTypeHandler pHandler = null;
            IMFActivate pRendererActivate = null;

            Guid guidMajorType = Guid.Empty;
            int hr = S_Ok;

            // Get the stream ID.
            int streamID = 0;
            try
            {
                try
                {
                    pSourceSD.GetStreamIdentifier(out streamID); // Just for debugging, ignore any failures.
                }
                catch
                {
                    TRACE("IMFStreamDescriptor::GetStreamIdentifier" + hr.ToString());
                }

                // Get the media type handler for the stream.
                pSourceSD.GetMediaTypeHandler(out pHandler);

                // Get the major media type.
                pHandler.GetMajorType(out guidMajorType);

                // Create a downstream node.
                MFExtern.MFCreateTopologyNode(MFTopologyType.OutputNode, out pNode);

                // Create an IMFActivate object for the renderer, based on the media type.
                if (MFMediaType.Audio == guidMajorType)
                {
                    // Create the audio renderer.
                    TRACE(string.Format("Stream {0}: Audio Stream", streamID));
                    MFExtern.MFCreateAudioRendererActivate(out pRendererActivate);
                }
                else if (MFMediaType.Video == guidMajorType)
                {
                    // Create the video renderer.
                    TRACE(string.Format("Stream {0}: Video Stream", streamID));
                    MFExtern.MFCreateVideoRendererActivate(m_hwndVideo, out pRendererActivate);
                }
                else
                {
                    TRACE(string.Format("Stream {0}: Unknown Format", streamID));
                    throw new COMException("Unknown Format", E_Fail);
                }

                // Set the IActivate object on the output node.
                pNode.SetObject(pRendererActivate);

                // Return the IMFTopologyNode pointer to the caller.
                ppNode = pNode;
            }
            catch
            {
                // If we failed, release the pNode
                SafeRelease(pNode);
                throw;
            }
            finally
            {
                // Clean up.
                SafeRelease(pHandler);
                SafeRelease(pRendererActivate);
            }
        }
Пример #29
0
        public void Dispose()
        {
            if (m_Riff != null)
            {
                m_Riff.Dispose();
                m_Riff = null;
            }

            if (m_pEventQueue != null)
            {
                Marshal.ReleaseComObject(m_pEventQueue);
                m_pEventQueue = null;
            }

            if (m_pSource != null)
            {
                //m_pSource.Dispose(); Children don't dispose their parents...
                m_pSource = null;
            }

            if (m_pStreamDescriptor != null)
            {
                Marshal.ReleaseComObject(m_pStreamDescriptor);
                m_pStreamDescriptor = null;
            }
            if (m_Log != null)
            {
                m_Log.Dispose();
                m_Log = null;
            }
            GC.SuppressFinalize(this);
        }
Пример #30
0
    ///////////////////////////////////////////////////////////////////////
    //  Name: GetStreamType
    //  Description:
    //  Returns the major media type from a stream descriptor.
    //
    //  pTopology:      Pointer to the topology.
    //  pSourceNode:    Pointer to the source node.
    //  pOutputNode:    Pointer to the output node.
    //  clsidTrnasform: CLSID of an effect transform.
    /////////////////////////////////////////////////////////////////////////
    void GetStreamType(IMFStreamDescriptor pSourceSD, out Guid pMajorType)
    {
        int hr;
        Debug.Assert(pSourceSD != null);
        //Debug.Assert(pMajorType != null);

        IMFMediaTypeHandler pHandler;

        // Get the media type handler for the stream.
        hr = pSourceSD.GetMediaTypeHandler(out pHandler);
        MFError.ThrowExceptionForHR(hr);

        try
        {
            // Get the major media type.
            hr = pHandler.GetMajorType(out pMajorType);
            MFError.ThrowExceptionForHR(hr);
        }
        finally
        {
            SafeRelease(pHandler);
        }
    }
Пример #31
0
        private void CreatePresentationDescriptor()
        {
            int hr;
            m_Log.WriteLine("CreatePresentationDescriptor");

            IMFMediaType pMediaType = null;
            IMFStreamDescriptor pStreamDescriptor = null;
            IMFMediaTypeHandler pHandler = null;

            Debug.Assert(WaveFormat() != null);

            // Create an empty media type.
            hr = MFExtern.MFCreateMediaType(out pMediaType);
            MFError.ThrowExceptionForHR(hr);

            // Initialize the media type from the WAVEFORMATEX structure.
            hr = MFExtern.MFInitMediaTypeFromWaveFormatEx(pMediaType, WaveFormat(), WaveFormatSize());
            MFError.ThrowExceptionForHR(hr);

            IMFMediaType[] mt = new IMFMediaType[1];
            mt[0] = pMediaType;

            // Create the stream descriptor.
            hr = MFExtern.MFCreateStreamDescriptor(
                0,          // stream identifier
                mt.Length,          // Number of media types.
                mt, // Array of media types
                out pStreamDescriptor
                );
            MFError.ThrowExceptionForHR(hr);

            // Set the default media type on the media type handler.
            hr = pStreamDescriptor.GetMediaTypeHandler(out pHandler);
            MFError.ThrowExceptionForHR(hr);

            hr = pHandler.SetCurrentMediaType(pMediaType);
            MFError.ThrowExceptionForHR(hr);

            IMFStreamDescriptor[] ms = new IMFStreamDescriptor[1];
            ms[0] = pStreamDescriptor;

            // Create the presentation descriptor.
            hr = MFExtern.MFCreatePresentationDescriptor(
                ms.Length,      // Number of stream descriptors
                ms, // Array of stream descriptors
                out m_pPresentationDescriptor
                );
            MFError.ThrowExceptionForHR(hr);

            // Select the first stream
            hr = m_pPresentationDescriptor.SelectStream(0);
            MFError.ThrowExceptionForHR(hr);

            // Set the file duration as an attribute on the presentation descriptor.
            long duration = m_pRiff.FileDuration();
            hr = m_pPresentationDescriptor.SetUINT64(MFAttributesClsid.MF_PD_DURATION, (long)duration);
            MFError.ThrowExceptionForHR(hr);

            //SAFE_RELEASE(pMediaType);
            //SAFE_RELEASE(pStreamDescriptor);
            //SAFE_RELEASE(pHandler);
        }
Пример #32
0
        protected void CreateOutputNode(
            IMFStreamDescriptor pSourceSD,
            out IMFTopologyNode ppNode
            )
        {
            IMFTopologyNode     pNode             = null;
            IMFMediaTypeHandler pHandler          = null;
            IMFActivate         pRendererActivate = null;

            Guid guidMajorType = Guid.Empty;
            int  hr            = S_Ok;

            // Get the stream ID.
            int streamID = 0;

            try
            {
                try
                {
                    pSourceSD.GetStreamIdentifier(out streamID); // Just for debugging, ignore any failures.
                }
                catch
                {
                    TRACE("IMFStreamDescriptor::GetStreamIdentifier" + hr.ToString());
                }

                // Get the media type handler for the stream.
                pSourceSD.GetMediaTypeHandler(out pHandler);

                // Get the major media type.
                pHandler.GetMajorType(out guidMajorType);

                // Create a downstream node.
                MFExtern.MFCreateTopologyNode(MFTopologyType.OutputNode, out pNode);

                // Create an IMFActivate object for the renderer, based on the media type.
                if (MFMediaType.Audio == guidMajorType)
                {
                    // Create the audio renderer.
                    TRACE(string.Format("Stream {0}: audio stream", streamID));
                    MFExtern.MFCreateAudioRendererActivate(out pRendererActivate);
                }
                else if (MFMediaType.Video == guidMajorType)
                {
                    // Create the video renderer.
                    TRACE(string.Format("Stream {0}: video stream", streamID));
                    MFExtern.MFCreateVideoRendererActivate(m_hwndVideo, out pRendererActivate);

                    object ppv;
                    pRendererActivate.ActivateObject(typeof(IMFVideoRenderer).GUID, out ppv);

                    var renderer = ppv as IMFVideoRenderer;
                    m_customPresenter = EvrPresenter.CreateNew();
                    m_customPresenter.NewAllocatorFrame   += m_customPresenter_NewAllocatorFrame;
                    m_customPresenter.NewAllocatorSurface += m_customPresenter_NewAllocatorSurface;
                    var presenter = m_customPresenter.VideoPresenter as IMFVideoDisplayControl;
                    hr = presenter.SetVideoWindow(m_hwndVideo);
                    hr = renderer.InitializeRenderer(null, m_customPresenter.VideoPresenter);
                    var settings = presenter as IEVRPresenterSettings;
                    settings.SetBufferCount(5);
                }
                else
                {
                    TRACE(string.Format("Stream {0}: Unknown format", streamID));
                    throw new COMException("Unknown format", E_Fail);
                }

                // Set the IActivate object on the output node.
                pNode.SetObject(pRendererActivate);

                // Return the IMFTopologyNode pointer to the caller.
                ppNode = pNode;
            }
            catch
            {
                // If we failed, release the pNode
                SafeRelease(pNode);
                throw;
            }
            finally
            {
                // Clean up.
                SafeRelease(pHandler);
                SafeRelease(pRendererActivate);
            }
        }
Пример #33
0
        private void CreateWavStream(IMFStreamDescriptor pSD)
        {
            m_Log.WriteLine("CreateWavStream");

            m_pStream = new WavStream(this, m_pRiff, pSD);
        }
Пример #34
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;
            }
        }
Пример #35
0
        ///////////////////////////////////////////////////////////////////////
        //  Name: GetStreamMajorType
        //  Description:  Returns the major media type for a stream.
        ///////////////////////////////////////////////////////////////////////
        static void GetStreamMajorType(IMFStreamDescriptor pSD, out Guid pMajorType)
        {
            int hr;
            IMFMediaTypeHandler pHandler;

            hr = pSD.GetMediaTypeHandler(out pHandler);
            MFError.ThrowExceptionForHR(hr);

            try
            {
                hr = pHandler.GetMajorType(out pMajorType);
                MFError.ThrowExceptionForHR(hr);
            }
            finally
            {
                if (pHandler != null)
                {
                    Marshal.ReleaseComObject(pHandler);
                }
            }
        }
Пример #36
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);
        }
Пример #37
0
        ///////////////////////////////////////////////////////////////////////
        //  Name: CreateTopology
        //  Description:  Creates the topology.
        //
        //  Note: The first audio stream is conntected to the media sink.
        //        Other streams are deselected.
        ///////////////////////////////////////////////////////////////////////

        static void CreateTopology(IMFMediaSource pSource, IMFMediaSinkAlt pSink, out IMFTopology ppTopology)
        {
            HResult hr;
            IMFPresentationDescriptor pPD = null;
            IMFStreamDescriptor       pSD = null;

            int  cStreams   = 0;
            bool fConnected = false;

            hr = MFExtern.MFCreateTopology(out ppTopology);
            MFError.ThrowExceptionForHR(hr);

            hr = pSource.CreatePresentationDescriptor(out pPD);
            MFError.ThrowExceptionForHR(hr);

            try
            {
                hr = pPD.GetStreamDescriptorCount(out cStreams);
                MFError.ThrowExceptionForHR(hr);

                Guid majorType;
                bool fSelected = false;

                for (int iStream = 0; iStream < cStreams; iStream++)
                {
                    hr = pPD.GetStreamDescriptorByIndex(iStream, out fSelected, out pSD);
                    MFError.ThrowExceptionForHR(hr);

                    try
                    {
                        // If the stream is not selected by default, ignore it.
                        if (!fSelected)
                        {
                            continue;
                        }

                        // Get the major media type.
                        GetStreamMajorType(pSD, out majorType);

                        // If it's not audio, deselect it and continue.
                        if (majorType != MFMediaType.Audio)
                        {
                            // Deselect this stream
                            hr = pPD.DeselectStream(iStream);
                            MFError.ThrowExceptionForHR(hr);

                            continue;
                        }

                        // It's an audio stream, so try to create the topology branch.
                        CreateTopologyBranch(ppTopology, pSource, pPD, pSD, pSink);
                    }
                    finally
                    {
                        if (pSD != null)
                        {
                            Marshal.ReleaseComObject(pSD);
                        }
                    }

                    // Set our status flag.
                    fConnected = true;

                    // At this point we have reached the first audio stream in the
                    // source, so we can stop looking (whether we succeeded or failed).
                    break;
                }
            }
            finally
            {
                if (pPD != null)
                {
                    Marshal.ReleaseComObject(pPD);
                }
            }

            // Even if we succeeded, if we didn't connect any streams, it's a failure.
            // (For example, it might be a video-only source.
            if (!fConnected)
            {
                throw new Exception("No audio streams");
            }
        }
        protected void CreateOutputNode(
            IMFStreamDescriptor pSourceSD,
            out IMFTopologyNode ppNode
            )
        {
            IMFTopologyNode     pNode             = null;
            IMFMediaTypeHandler pHandler          = null;
            IMFActivate         pRendererActivate = null;

            Guid    guidMajorType = Guid.Empty;
            MFError throwonhr;

            // Get the stream ID.
            int streamID = 0;

            try
            {
                HResult hr;

                hr = pSourceSD.GetStreamIdentifier(out streamID); // Just for debugging, ignore any failures.
                if (MFError.Failed(hr))
                {
                    //TRACE("IMFStreamDescriptor::GetStreamIdentifier" + hr.ToString());
                }

                // Get the media type handler for the stream.
                throwonhr = pSourceSD.GetMediaTypeHandler(out pHandler);

                // Get the major media type.
                throwonhr = pHandler.GetMajorType(out guidMajorType);

                // Create a downstream node.
                throwonhr = MFExtern.MFCreateTopologyNode(MFTopologyType.OutputNode, out pNode);

                // Create an IMFActivate object for the renderer, based on the media type.
                if (MFMediaType.Audio == guidMajorType)
                {
                    // Create the audio renderer.
                    //TRACE(string.Format("Stream {0}: audio stream", streamID));
                    throwonhr = MFExtern.MFCreateAudioRendererActivate(out pRendererActivate);

                    // Set the IActivate object on the output node.
                    throwonhr = pNode.SetObject(pRendererActivate);
                }
                else if (MFMediaType.Video == guidMajorType)
                {
                    // Create the video renderer.
                    //TRACE(string.Format("Stream {0}: video stream", streamID));
                    //throwonhr = MFExtern.MFCreateVideoRendererActivate(m_hwndVideo, out pRendererActivate);

                    mIMFTopologyNode.GetObject(out pRendererActivate);

                    throwonhr = pNode.SetObject(pRendererActivate);
                }
                else
                {
                    //TRACE(string.Format("Stream {0}: Unknown format", streamID));
                    //throw new COMException("Unknown format", (int)HResult.E_FAIL);
                }


                // Return the IMFTopologyNode pointer to the caller.
                ppNode = pNode;
            }
            catch
            {
                // If we failed, release the pNode
                //SafeRelease(pNode);
                throw;
            }
            finally
            {
                // Clean up.
                //SafeRelease(pHandler);
                //SafeRelease(pRendererActivate);
            }
        }
Пример #39
0
        public int GetStreamDescriptor(out IMFStreamDescriptor ppStreamDescriptor)
        {
            // Make sure we *never* leave this entry point with an exception
            try
            {
                m_Log.WriteLine("-GetStreamDescriptor");
                ppStreamDescriptor = null;

                lock (this)
                {
                    if (m_pStreamDescriptor == null)
                    {
                        throw new COMException("null stream descriptor", E_Unexpected);
                    }

                    CheckShutdown();
                    ppStreamDescriptor = m_pStreamDescriptor;
                }
                return S_Ok;
            }
            catch (Exception e)
            {
                ppStreamDescriptor = null;
                return Marshal.GetHRForException(e);
            }
        }
Пример #40
0
 public override void StartStream()
 {
     Task.Run(() =>
     {
         // check our source filename is correct and usable
         StreamReaderHandler = new StreamHandler(ProcessFrame, MFBPressed);
         HResult hr;
         IMFSourceResolver pSourceResolver = null;
         IMFPresentationDescriptor sourcePresentationDescriptor = null;
         IMFStreamDescriptor videoStreamDescriptor = null;
         try
         {
             // reset everything
             CloseAllMediaDevices();
             // Create the media session.
             hr = MFExtern.MFCreateMediaSession(null, out mediaSession);
             if (hr != HResult.S_OK)
             {
                 throw new Exception("PrepareSessionAndTopology call to MFExtern.MFCreateMediaSession failed. Err=" + hr.ToString());
             }
             // set up our media session call back handler.
             mediaSessionAsyncCallbackHandler = new AsyncCallbackHandler();
             mediaSessionAsyncCallbackHandler.Initialize();
             mediaSessionAsyncCallbackHandler.MediaSession = mediaSession;
             mediaSessionAsyncCallbackHandler.MediaSessionAsyncCallBackError = HandleMediaSessionAsyncCallBackErrors;
             mediaSessionAsyncCallbackHandler.MediaSessionAsyncCallBackEvent = HandleMediaSessionAsyncCallBackEvent;
             // Register the callback handler with the session and tell it that events can
             // start. This does not actually trigger an event it just lets the media session
             // know that it can now send them if it wishes to do so.
             hr = mediaSession.BeginGetEvent(mediaSessionAsyncCallbackHandler, null);
             if (hr != HResult.S_OK)
             {
                 throw new Exception("PrepareSessionAndTopology call to mediaSession.BeginGetEvent failed. Err=" + hr.ToString());
             }
             StreamReader = WMFUtils.CreateSourceReaderAsyncFromDevice(UnderlyingDevice, StreamReaderHandler);
             try
             {
                 SetCurrentMediaType(StreamReader, IMFStreamIndex, 0);
             }
             catch
             {
             }
             try
             {
                 SetCurrentMediaType(StreamReader, IMFSnapIndex, 1);
             }
             catch
             {
             }
             StreamReaderHandler.StreamReader = StreamReader;
             StreamReader.GetCurrentMediaType(1, out IMFMediaType ppMediaType);
             StreamReader.GetNativeMediaType(1, 0, out IMFMediaType PPMediaType);
             StreamReader.GetCurrentMediaType(0, out IMFMediaType ppMediaType1);
             StreamReader.GetNativeMediaType(0, 0, out IMFMediaType PPMediaType1);
             ppMediaType.GetMajorType(out Guid ppMediaTypeMGUID);
             PPMediaType.GetMajorType(out Guid PPMediaTypeMGUID);
             ppMediaType.GetGUID(MFAttributesClsid.MF_MT_SUBTYPE, out Guid ppMediaTypeSGUID);
             PPMediaType.GetGUID(MFAttributesClsid.MF_MT_SUBTYPE, out Guid PPMediaTypeSGUID);
             Console.WriteLine(WMFUtils.ConvertGuidToName(ppMediaTypeMGUID));
             Console.WriteLine(WMFUtils.ConvertGuidToName(PPMediaTypeMGUID));
             Console.WriteLine(WMFUtils.ConvertGuidToName(ppMediaTypeSGUID));
             Console.WriteLine(WMFUtils.ConvertGuidToName(PPMediaTypeSGUID));
             ppMediaType1.GetMajorType(out Guid ppMediaTypeMGUID1);
             PPMediaType1.GetMajorType(out Guid PPMediaTypeMGUID1);
             ppMediaType1.GetGUID(MFAttributesClsid.MF_MT_SUBTYPE, out Guid ppMediaTypeSGUID1);
             PPMediaType1.GetGUID(MFAttributesClsid.MF_MT_SUBTYPE, out Guid PPMediaTypeSGUID1);
             Console.WriteLine(WMFUtils.ConvertGuidToName(ppMediaTypeMGUID1));
             Console.WriteLine(WMFUtils.ConvertGuidToName(PPMediaTypeMGUID1));
             Console.WriteLine(WMFUtils.ConvertGuidToName(ppMediaTypeSGUID1));
             Console.WriteLine(WMFUtils.ConvertGuidToName(PPMediaTypeSGUID1));
             Paused = false;
             StreamReader.SetStreamSelection(0, true);
             StreamReader.SetStreamSelection(1, true);
             hr = StreamReader.ReadSample(
                 0,
                 MediaFoundation.ReadWrite.MF_SOURCE_READER_CONTROL_FLAG.None,
                 IntPtr.Zero,
                 IntPtr.Zero,
                 IntPtr.Zero,
                 IntPtr.Zero
                 );
             hr = StreamReader.ReadSample(1,
                                          MediaFoundation.ReadWrite.MF_SOURCE_READER_CONTROL_FLAG.None,
                                          IntPtr.Zero,
                                          IntPtr.Zero,
                                          IntPtr.Zero,
                                          IntPtr.Zero
                                          );
             if (hr != HResult.S_OK)
             {
                 // we failed
                 throw new Exception("Failed on calling the first ReadSample on the reader, retVal=" + hr.ToString());
             }
         }
         catch (Exception ex)
         {
             Console.WriteLine("PrepareSessionAndTopology Error: " + ex.Message);
         }
         finally
         {
             // Clean up
             if (pSourceResolver != null)
             {
                 Marshal.ReleaseComObject(pSourceResolver);
             }
             if (sourcePresentationDescriptor != null)
             {
                 Marshal.ReleaseComObject(sourcePresentationDescriptor);
             }
             if (videoStreamDescriptor != null)
             {
                 Marshal.ReleaseComObject(videoStreamDescriptor);
             }
         }
     });
 }
Пример #41
0
        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Displays the video formats for the currently selected video device. This
        /// is more complicated than it looks. We have to open the video source, convert
        /// that to a Media Source and then interrogate the that source to find a list
        /// of video formats.
        ///
        /// NOTE: this function will throw exceptions - caller must trap them
        /// </summary>
        /// <history>
        ///    01 Nov 18  Cynic - Started
        /// </history>
        private void DisplayVideoFormatsForCurrentCaptureDevice()
        {
            IMFPresentationDescriptor sourcePresentationDescriptor = null;
            int  sourceStreamCount = 0;
            bool streamIsSelected  = false;
            IMFStreamDescriptor videoStreamDescriptor = null;
            IMFMediaTypeHandler typeHandler           = null;
            int mediaTypeCount = 0;

            List <TantaMFVideoFormatContainer> formatList = new List <TantaMFVideoFormatContainer>();
            HResult        hr;
            IMFMediaSource mediaSource = null;

            try
            {
                // clear what we have now
                listViewSupportedFormats.Clear();
                // reset this
                listViewSupportedFormats.ListViewItemSorter = null;

                // get the currently selected device
                TantaMFDevice currentDevice = (TantaMFDevice)comboBoxCaptureDevices.SelectedItem;
                if (currentDevice == null)
                {
                    throw new Exception("DisplayVideoFormatsForCurrentCaptureDevice currentDevice == null");
                }

                // use the device symbolic name to create the media source for the video device. Media sources are objects that generate media data.
                // For example, the data might come from a video file, a network stream, or a hardware device, such as a camera. Each
                // media source contains one or more streams, and each stream delivers data of one type, such as audio or video.
                mediaSource = TantaWMFUtils.GetMediaSourceFromTantaDevice(currentDevice);
                if (mediaSource == null)
                {
                    throw new Exception("DisplayVideoFormatsForCurrentCaptureDevice call to mediaSource == null");
                }

                // A presentation is a set of related media streams that share a common presentation time.
                // we don't need that functionality in this app but we do need to presentation descriptor
                // to find out the stream descriptors, these will give us the media types on offer
                hr = mediaSource.CreatePresentationDescriptor(out sourcePresentationDescriptor);
                if (hr != HResult.S_OK)
                {
                    throw new Exception("DisplayVideoFormatsForCurrentCaptureDevice call to mediaSource.CreatePresentationDescriptor failed. Err=" + hr.ToString());
                }
                if (sourcePresentationDescriptor == null)
                {
                    throw new Exception("DisplayVideoFormatsForCurrentCaptureDevice call to mediaSource.CreatePresentationDescriptor failed. sourcePresentationDescriptor == null");
                }

                // Now we get the number of stream descriptors in the presentation.
                // A presentation descriptor contains a list of one or more
                // stream descriptors.
                hr = sourcePresentationDescriptor.GetStreamDescriptorCount(out sourceStreamCount);
                if (hr != HResult.S_OK)
                {
                    throw new Exception("DisplayVideoFormatsForCurrentCaptureDevice call to sourcePresentationDescriptor.GetStreamDescriptorCount failed. Err=" + hr.ToString());
                }
                if (sourceStreamCount == 0)
                {
                    throw new Exception("DisplayVideoFormatsForCurrentCaptureDevice call to sourcePresentationDescriptor.GetStreamDescriptorCount failed. sourceStreamCount == 0");
                }

                // look for the video stream
                for (int i = 0; i < sourceStreamCount; i++)
                {
                    // we require the major type to be video
                    Guid guidMajorType = TantaWMFUtils.GetMajorMediaTypeFromPresentationDescriptor(sourcePresentationDescriptor, i);
                    if (guidMajorType != MFMediaType.Video)
                    {
                        continue;
                    }

                    // we also require the stream to be enabled
                    hr = sourcePresentationDescriptor.GetStreamDescriptorByIndex(i, out streamIsSelected, out videoStreamDescriptor);
                    if (hr != HResult.S_OK)
                    {
                        throw new Exception("DisplayVideoFormatsForCurrentCaptureDevice call to sourcePresentationDescriptor.GetStreamDescriptorByIndex(v) failed. Err=" + hr.ToString());
                    }
                    if (videoStreamDescriptor == null)
                    {
                        throw new Exception("DisplayVideoFormatsForCurrentCaptureDevice call to sourcePresentationDescriptor.GetStreamDescriptorByIndex(v) failed. videoStreamDescriptor == null");
                    }
                    // if the stream is not selected (enabled) look for the next
                    if (streamIsSelected == false)
                    {
                        Marshal.ReleaseComObject(videoStreamDescriptor);
                        videoStreamDescriptor = null;
                        continue;
                    }

                    // Get the media type handler for the stream. IMFMediaTypeHandler
                    // interface is a standard way of looking at the media types on an stream
                    hr = videoStreamDescriptor.GetMediaTypeHandler(out typeHandler);
                    if (hr != HResult.S_OK)
                    {
                        throw new Exception("call to videoStreamDescriptor.GetMediaTypeHandler failed. Err=" + hr.ToString());
                    }
                    if (typeHandler == null)
                    {
                        throw new Exception("call to videoStreamDescriptor.GetMediaTypeHandler failed. typeHandler == null");
                    }
                    // Now we get the number of media types in the stream descriptor.
                    hr = typeHandler.GetMediaTypeCount(out mediaTypeCount);
                    if (hr != HResult.S_OK)
                    {
                        throw new Exception("DisplayVideoFormatsForCurrentCaptureDevice call to typeHandler.GetMediaTypeCount failed. Err=" + hr.ToString());
                    }
                    if (mediaTypeCount == 0)
                    {
                        throw new Exception("DisplayVideoFormatsForCurrentCaptureDevice call to typeHandler.GetMediaTypeCount failed. mediaTypeCount == 0");
                    }

                    // now loop through each media type
                    for (int mediaTypeId = 0; mediaTypeId < mediaTypeCount; mediaTypeId++)
                    {
                        // Now we have the handler, get the media type.
                        IMFMediaType workingMediaType = null;
                        hr = typeHandler.GetMediaTypeByIndex(mediaTypeId, out workingMediaType);
                        if (hr != HResult.S_OK)
                        {
                            throw new Exception("GetMediaTypeFromStreamDescriptorById call to typeHandler.GetMediaTypeByIndex failed. Err=" + hr.ToString());
                        }
                        if (workingMediaType == null)
                        {
                            throw new Exception("GetMediaTypeFromStreamDescriptorById call to typeHandler.GetMediaTypeByIndex failed. workingMediaType == null");
                        }
                        TantaMFVideoFormatContainer tmpContainer = TantaMediaTypeInfo.GetVideoFormatContainerFromMediaTypeObject(workingMediaType, currentDevice);
                        if (tmpContainer == null)
                        {
                            // we failed
                            throw new Exception("GetSupportedVideoFormatsFromSourceReaderInFormatContainers failed on call to GetVideoFormatContainerFromMediaTypeObject");
                        }
                        // now add it
                        formatList.Add(tmpContainer);
                        Marshal.ReleaseComObject(workingMediaType);
                        workingMediaType = null;
                    }

                    // NOTE: we only do the first enabled video stream we find.
                    // it is possible to have more but our control
                    // cannot cope with that
                    break;
                }

                // now display the formats
                foreach (TantaMFVideoFormatContainer videoFormat in formatList)
                {
                    ListViewItem lvi = new ListViewItem(new[] { videoFormat.SubTypeAsString, videoFormat.FrameSizeAsString, videoFormat.FrameRateAsString, videoFormat.FrameRateMaxAsString, videoFormat.AllAttributes });
                    lvi.Tag = videoFormat;
                    listViewSupportedFormats.Items.Add(lvi);
                }

                listViewSupportedFormats.Columns.Add("Type", 70);
                listViewSupportedFormats.Columns.Add("FrameSize WxH", 100);
                listViewSupportedFormats.Columns.Add("FrameRate f/s", 100);
                listViewSupportedFormats.Columns.Add("FrameRateMax f/s", 100);
                listViewSupportedFormats.Columns.Add("All Attributes", 2500);
            }
            finally
            {
                // close and release
                if (mediaSource != null)
                {
                    Marshal.ReleaseComObject(mediaSource);
                    mediaSource = null;
                }
                if (sourcePresentationDescriptor != null)
                {
                    Marshal.ReleaseComObject(sourcePresentationDescriptor);
                    sourcePresentationDescriptor = null;
                }
                if (videoStreamDescriptor != null)
                {
                    Marshal.ReleaseComObject(videoStreamDescriptor);
                    videoStreamDescriptor = null;
                }
                if (typeHandler != null)
                {
                    Marshal.ReleaseComObject(typeHandler);
                    typeHandler = null;
                }
            }
        }
Пример #42
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);
        }
Пример #43
0
        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Opens prepares the media session and topology and opens the media source
        /// and media sink.
        ///
        /// Once the session and topology are setup, a MESessionTopologySet event
        /// will be triggered in the callback handler. After that the events there
        /// trigger other events and everything rolls along automatically.
        /// </summary>
        /// <param name="sourceFileName">the source file name</param>
        /// <param name="outputFileName">the name of the output file</param>
        /// <history>
        ///    01 Nov 18  Cynic - Originally Written
        /// </history>
        public void PrepareSessionAndTopology(string sourceFileName, string outputFileName)
        {
            HResult                   hr;
            IMFSourceResolver         pSourceResolver = null;
            IMFTopology               pTopology       = null;
            IMFPresentationDescriptor sourcePresentationDescriptor = null;
            int sourceStreamCount = 0;
            IMFStreamDescriptor audioStreamDescriptor = null;
            bool            streamIsSelected          = false;
            IMFTopologyNode sourceAudioNode           = null;
            IMFTopologyNode outputSinkNode            = null;
            IMFMediaType    currentAudioMediaType     = null;
            int             audioStreamIndex          = -1;

            LogMessage("PrepareSessionAndTopology ");

            // we sanity check the filenames - the existence of the path and if the file already exists
            // should have been checked before this call
            if ((sourceFileName == null) || (sourceFileName.Length == 0))
            {
                throw new Exception("PrepareSessionAndTopology: source file name is invalid. Cannot continue.");
            }

            if ((outputFileName == null) || (outputFileName.Length == 0))
            {
                throw new Exception("PrepareSessionAndTopology: output file name is invalid. Cannot continue.");
            }

            try
            {
                // reset everything
                CloseAllMediaDevices();

                // Create the media session.
                hr = MFExtern.MFCreateMediaSession(null, out mediaSession);
                if (hr != HResult.S_OK)
                {
                    throw new Exception("PrepareSessionAndTopology call to MFExtern.MFCreateMediaSession failed. Err=" + hr.ToString());
                }
                if (mediaSession == null)
                {
                    throw new Exception("PrepareSessionAndTopology call to MFExtern.MFCreateMediaSession failed. mediaSession == null");
                }

                // set up our media session call back handler.
                mediaSessionAsyncCallbackHandler = new TantaAsyncCallbackHandler();
                mediaSessionAsyncCallbackHandler.Initialize();
                mediaSessionAsyncCallbackHandler.MediaSession = mediaSession;
                mediaSessionAsyncCallbackHandler.MediaSessionAsyncCallBackError = HandleMediaSessionAsyncCallBackErrors;
                mediaSessionAsyncCallbackHandler.MediaSessionAsyncCallBackEvent = HandleMediaSessionAsyncCallBackEvent;

                // Register the callback handler with the session and tell it that events can
                // start. This does not actually trigger an event it just lets the media session
                // know that it can now send them if it wishes to do so.
                hr = mediaSession.BeginGetEvent(mediaSessionAsyncCallbackHandler, null);
                if (hr != HResult.S_OK)
                {
                    throw new Exception("PrepareSessionAndTopology call to mediaSession.BeginGetEvent failed. Err=" + hr.ToString());
                }

                // Create a new topology.  A topology describes a collection of media sources, sinks, and transforms that are
                // connected in a certain order. These objects are represented within the topology by topology nodes,
                // which expose the IMFTopologyNode interface. A topology describes the path of multimedia data through these nodes.
                hr = MFExtern.MFCreateTopology(out pTopology);
                if (hr != HResult.S_OK)
                {
                    throw new Exception("PrepareSessionAndTopology call to MFExtern.MFCreateTopology failed. Err=" + hr.ToString());
                }
                if (pTopology == null)
                {
                    throw new Exception("PrepareSessionAndTopology call to MFExtern.MFCreateTopology failed. pTopology == null");
                }

                // ####
                // #### we now create the media source, this is an audio file
                // ####

                // use the file name to create the media source for the audio device. Media sources are objects that generate media data.
                // For example, the data might come from a video file, a network stream, or a hardware device, such as a camera. Each
                // media source contains one or more streams, and each stream delivers data of one type, such as audio or video.
                mediaSource = TantaWMFUtils.GetMediaSourceFromFile(sourceFileName);
                if (mediaSource == null)
                {
                    throw new Exception("PrepareSessionAndTopology call to mediaSource == null");
                }

                // A presentation is a set of related media streams that share a common presentation time.  We now get a copy of the media
                // source's presentation descriptor. Applications can use the presentation descriptor to select streams
                // and to get information about the source content.
                hr = mediaSource.CreatePresentationDescriptor(out sourcePresentationDescriptor);
                if (hr != HResult.S_OK)
                {
                    throw new Exception("PrepareSessionAndTopology call to mediaSource.CreatePresentationDescriptor failed. Err=" + hr.ToString());
                }
                if (sourcePresentationDescriptor == null)
                {
                    throw new Exception("PrepareSessionAndTopology call to mediaSource.CreatePresentationDescriptor failed. sourcePresentationDescriptor == null");
                }

                // Now we get the number of stream descriptors in the presentation. A presentation descriptor contains a list of one or more
                // stream descriptors. These describe the streams in the presentation. Streams can be either selected or deselected. Only the
                // selected streams produce data. Deselected streams are not active and do not produce any data.
                hr = sourcePresentationDescriptor.GetStreamDescriptorCount(out sourceStreamCount);
                if (hr != HResult.S_OK)
                {
                    throw new Exception("PrepareSessionAndTopology call to sourcePresentationDescriptor.GetStreamDescriptorCount failed. Err=" + hr.ToString());
                }
                if (sourceStreamCount == 0)
                {
                    throw new Exception("PrepareSessionAndTopology call to sourcePresentationDescriptor.GetStreamDescriptorCount failed. sourceStreamCount == 0");
                }

                // Look at each stream, there can be more than one stream here
                // Usually only one is enabled. This app uses the first "selected"
                // stream we come to which has the appropriate media type
                for (int i = 0; i < sourceStreamCount; i++)
                {
                    // we require the major type to be audio
                    Guid guidMajorType = TantaWMFUtils.GetMajorMediaTypeFromPresentationDescriptor(sourcePresentationDescriptor, i);
                    if (guidMajorType != MFMediaType.Audio)
                    {
                        continue;
                    }

                    // we also require the stream to be enabled
                    hr = sourcePresentationDescriptor.GetStreamDescriptorByIndex(i, out streamIsSelected, out audioStreamDescriptor);
                    if (hr != HResult.S_OK)
                    {
                        throw new Exception("PrepareSessionAndTopology call to sourcePresentationDescriptor.GetStreamDescriptorByIndex failed. Err=" + hr.ToString());
                    }
                    if (audioStreamDescriptor == null)
                    {
                        throw new Exception("PrepareSessionAndTopology call to sourcePresentationDescriptor.GetStreamDescriptorByIndex failed. audioStreamDescriptor == null");
                    }
                    // if the stream is selected, leave now we will release the audioStream descriptor later
                    if (streamIsSelected == true)
                    {
                        audioStreamIndex = i;  // record this
                        break;
                    }

                    // release the one we are not using
                    if (audioStreamDescriptor != null)
                    {
                        Marshal.ReleaseComObject(audioStreamDescriptor);
                        audioStreamDescriptor = null;
                    }
                    audioStreamIndex = -1;
                }

                // by the time we get here we should have a audioStreamDescriptor if
                // we do not, then we cannot proceed
                if (audioStreamDescriptor == null)
                {
                    throw new Exception("PrepareSessionAndTopology call to sourcePresentationDescriptor.GetStreamDescriptorByIndex failed. audioStreamDescriptor == null");
                }
                if (audioStreamIndex < 0)
                {
                    throw new Exception("PrepareSessionAndTopology call to sourcePresentationDescriptor.GetStreamDescriptorByIndex failed. audioStreamIndex < 0");
                }

                // ####
                // #### we now create the media sink, we need the type from the stream to do
                // #### this which is why we wait until now to set it up
                // ####

                currentAudioMediaType = TantaWMFUtils.GetCurrentMediaTypeFromStreamDescriptor(audioStreamDescriptor);
                if (currentAudioMediaType == null)
                {
                    throw new Exception("PrepareSessionAndTopology call to currentAudioMediaType == null");
                }

                mediaSink = OpenMediaFileSink(outputFileName);
                if (mediaSink == null)
                {
                    throw new Exception("PrepareSessionAndTopology call to mediaSink == null");
                }

                // ####
                // #### we now make up a topology branch for the audio stream
                // ####

                // Create a source node for this stream.
                sourceAudioNode = TantaWMFUtils.CreateSourceNodeForStream(mediaSource, sourcePresentationDescriptor, audioStreamDescriptor);
                if (sourceAudioNode == null)
                {
                    throw new Exception("PrepareSessionAndTopology call to CreateSourceNodeForStream failed. pSourceNode == null");
                }

                // Create the output node - this is a file sink in this case.
                outputSinkNode = TantaWMFUtils.CreateSinkNodeForStream(mediaSink);
                if (outputSinkNode == null)
                {
                    throw new Exception("PrepareSessionAndTopology call to CreateOutputNodeForStream failed. outputSinkNode == null");
                }

                // Add the nodes to the topology. First the source
                hr = pTopology.AddNode(sourceAudioNode);
                if (hr != HResult.S_OK)
                {
                    throw new Exception("PrepareSessionAndTopology call to pTopology.AddNode(sourceAudioNode) failed. Err=" + hr.ToString());
                }

                // then add the output
                hr = pTopology.AddNode(outputSinkNode);
                if (hr != HResult.S_OK)
                {
                    throw new Exception("PrepareSessionAndTopology call to pTopology.AddNode(outputSinkNode) failed. Err=" + hr.ToString());
                }

                // Connect the output stream from the source node to the input stream of the output node. The parameters are:
                //    dwOutputIndex  -  Zero-based index of the output stream on this node.
                //    *pDownstreamNode  -  Pointer to the IMFTopologyNode interface of the node to connect to.
                //    dwInputIndexOnDownstreamNode  -  Zero-based index of the input stream on the other node.
                hr = sourceAudioNode.ConnectOutput(0, outputSinkNode, 0);
                if (hr != HResult.S_OK)
                {
                    throw new Exception("PrepareSessionAndTopology call to  pSourceNode.ConnectOutput failed. Err=" + hr.ToString());
                }

                // Set the topology on the media session.
                // If SetTopology succeeds, the media session will queue an
                // MESessionTopologySet event.
                hr = mediaSession.SetTopology(0, pTopology);
                MFError.ThrowExceptionForHR(hr);

                // Release the topology
                if (pTopology != null)
                {
                    Marshal.ReleaseComObject(pTopology);
                }
            }
            catch (Exception ex)
            {
                LogMessage("Error: " + ex.Message);
                OISMessageBox(ex.Message);
            }
            finally
            {
                // Clean up
                if (pSourceResolver != null)
                {
                    Marshal.ReleaseComObject(pSourceResolver);
                }
                if (sourcePresentationDescriptor != null)
                {
                    Marshal.ReleaseComObject(sourcePresentationDescriptor);
                }
                if (audioStreamDescriptor != null)
                {
                    Marshal.ReleaseComObject(audioStreamDescriptor);
                }
                if (sourceAudioNode != null)
                {
                    Marshal.ReleaseComObject(sourceAudioNode);
                }
                if (outputSinkNode != null)
                {
                    Marshal.ReleaseComObject(outputSinkNode);
                }
                if (currentAudioMediaType != null)
                {
                    Marshal.ReleaseComObject(currentAudioMediaType);
                }
            }
        }
Пример #44
0
        private static HResult CreateOutputNode(IMFStreamDescriptor streamDescriptor, out IMFMediaSinkAlt mediaSink, out IMFTopologyNode node)
        {
            HResult hr = S_OK;

            mediaSink = null;
            node      = null;
            IMFMediaTypeHandler mediaTypeHandler = null;
            IMFActivate         activate         = null;
            IMFStreamSinkAlt    streamSink       = null;
            Guid majorType       = Guid.Empty;
            int  streamSinkCount = 0;

            hr = streamDescriptor.GetMediaTypeHandler(out mediaTypeHandler);
            if (Failed(hr))
            {
                return(hr);
            }

            hr = mediaTypeHandler.GetMajorType(out majorType);
            if (Failed(hr))
            {
                SafeRelease(mediaTypeHandler);
                return(hr);
            }

            hr = MF.CreateTopologyNode(MFTopologyType.OutputNode, out node);
            if (Failed(hr))
            {
                SafeRelease(mediaTypeHandler);
                return(hr);
            }

            if (majorType == MFMediaType.Video)
            {
                ExternalMediaSink extMediaSink = new ExternalMediaSink();


                mediaSink = (IMFMediaSinkAlt)extMediaSink;

                hr = mediaSink.GetStreamSinkCount(out streamSinkCount);
                if (Failed(hr))
                {
                    mediaSink = null;
                    return(hr);
                }

                hr = mediaSink.GetStreamSinkByIndex(0, out streamSink);
                if (Failed(hr))
                {
                    mediaSink = null;
                    return(hr);
                }

                hr = node.SetObject(streamSink);
                if (Failed(hr))
                {
                    mediaSink = null;
                    return(hr);
                }
            }
            else if (majorType == MFMediaType.Audio)
            {
                hr = MF.CreateAudioRendererActivate(out activate);
                if (Failed(hr))
                {
                    return(hr);
                }

                hr = node.SetObject(activate);
                if (Failed(hr))
                {
                    return(hr);
                }
            }

            mediaTypeHandler = null;
            activate         = null;
            streamSink       = null;

            return(hr);
        }
Пример #45
0
        long m_rtCurrentPosition; // Current position in the stream, in 100-ns units

        #endregion Fields

        #region Constructors

        public WavStream(WavSource pSource, CWavRiffParser pRiff, IMFStreamDescriptor pSD)
        {
            int hr;
            m_pEventQueue = null;
            m_Log = new xLog("WavStream");
            #if false
            m_nRefCount(0),
            m_IsShutdown(false),
            m_rtCurrentPosition(0),
            m_discontinuity(false),
            m_EOS(false)
            #endif

            m_pSource = pSource;

            m_pStreamDescriptor = pSD;

            m_Riff = pRiff;

            // Create the media event queue.
            hr = MFExternAlt.MFCreateEventQueue(out m_pEventQueue);
            MFError.ThrowExceptionForHR(hr);
        }