Esempio n. 1
0
    public HResult OpenURL(string sURL)
    {
        TRACE("CPlayer::OpenURL");
        TRACE("URL = " + sURL);

        // 1. Create a new media session.
        // 2. Create the media source.
        // 3. Create the topology.
        // 4. Queue the topology [asynchronous]
        // 5. Start playback [asynchronous - does not happen in this method.]

        HResult hr = HResult.S_OK;

        try
        {
            IMFTopology pTopology = null;

            // Create the media session.
            CreateSession();

            // Create the media source.
            CreateMediaSource(sURL);

            // Create a partial topology.
            CreateTopologyFromSource(out pTopology);

            // Set the topology on the media session.
            hr = m_pSession.SetTopology(0, pTopology);
            MFError.ThrowExceptionForHR(hr);

            // Set our state to "open pending"
            m_state = PlayerState.OpenPending;
            NotifyState();

            SafeRelease(pTopology);

            // If SetTopology succeeded, the media session will queue an
            // MESessionTopologySet event.
        }
        catch (Exception ce)
        {
            hr = (HResult)Marshal.GetHRForException(ce);
            NotifyError(hr);
            m_state = PlayerState.Ready;
        }

        return(hr);
    }
Esempio n. 2
0
    protected void CreateTopologyFromSource(out IMFTopology ppTopology)
    {
        TRACE("CPlayer::CreateTopologyFromSource");

        Debug.Assert(m_pSession != null);
        Debug.Assert(m_pSource != null);

        HResult     hr;
        IMFTopology pTopology = null;
        IMFPresentationDescriptor pSourcePD = null;
        int cSourceStreams = 0;

        try
        {
            // Create a new topology.
            hr = MFExtern.MFCreateTopology(out pTopology);
            MFError.ThrowExceptionForHR(hr);

            // Create the presentation descriptor for the media source.
            hr = m_pSource.CreatePresentationDescriptor(out pSourcePD);
            MFError.ThrowExceptionForHR(hr);

            // Get the number of streams in the media source.
            hr = pSourcePD.GetStreamDescriptorCount(out cSourceStreams);
            MFError.ThrowExceptionForHR(hr);

            TRACE(string.Format("Stream count: {0}", cSourceStreams));

            // For each stream, create the topology nodes and add them to the topology.
            for (int i = 0; i < cSourceStreams; i++)
            {
                AddBranchToPartialTopology(pTopology, pSourcePD, i);
            }

            // Return the IMFTopology pointer to the caller.
            ppTopology = pTopology;
        }
        catch
        {
            // If we failed, release the topology
            SafeRelease(pTopology);
            throw;
        }
        finally
        {
            SafeRelease(pSourcePD);
        }
    }
Esempio n. 3
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);
        }
    }
Esempio n. 4
0
        ///////////////////////////////////////////////////////////////////////
        //  Name: CreateWavFile
        //  Description:  Creates a .wav file from an input file.
        ///////////////////////////////////////////////////////////////////////

        static void CreateWavFile(string sURL, string sOutputFile)
        {
            IMFByteStream   pStream   = null;
            IMFMediaSinkAlt pSink     = null;
            IMFMediaSource  pSource   = null;
            IMFTopology     pTopology = null;

            WavSinkNS.CWavSink pObj = null;

            HResult hr = MFExtern.MFCreateFile(MFFileAccessMode.Write, MFFileOpenMode.DeleteIfExist, MFFileFlags.None, sOutputFile, out pStream);

            MFError.ThrowExceptionForHR(hr);

            try
            {
                pObj  = new WavSinkNS.CWavSink(pStream);
                pSink = pObj as IMFMediaSinkAlt;

                // Create the media source from the URL.
                CreateMediaSource(sURL, out pSource);

                // Create the topology.
                CreateTopology(pSource, pSink, out pTopology);

                // Run the media session.
                RunMediaSession(pTopology);

                hr = pSource.Shutdown();
                MFError.ThrowExceptionForHR(hr);
            }
            finally
            {
                if (pStream != null)
                {
                    Marshal.ReleaseComObject(pStream);
                }
                if (pSource != null)
                {
                    Marshal.ReleaseComObject(pSource);
                }
                if (pTopology != null)
                {
                    Marshal.ReleaseComObject(pTopology);
                }
                //pObj.Dispose();
            }
        }
Esempio n. 5
0
    protected void CreateTopologyFromSource(out IMFTopology ppTopology)
    {
        TRACE("CPlayer::CreateTopologyFromSource");

        Debug.Assert(m_pSession != null);
        Debug.Assert(m_pSource != null);

        IMFTopology pTopology = null;
        IMFPresentationDescriptor pSourcePD = null;
        int     cSourceStreams = 0;
        MFError throwonhr;

        try
        {
            // Create a new topology.
            throwonhr = MFExtern.MFCreateTopology(out pTopology);

            throwonhr = pTopology.SetUINT32(MFAttributesClsid.MF_TOPOLOGY_DXVA_MODE, (int)MFTOPOLOGY_DXVA_MODE.Full);

            // Create the presentation descriptor for the media source.
            throwonhr = m_pSource.CreatePresentationDescriptor(out pSourcePD);

            // Get the number of streams in the media source.
            throwonhr = pSourcePD.GetStreamDescriptorCount(out cSourceStreams);

            TRACE(string.Format("Stream count: {0}", cSourceStreams));

            // For each stream, create the topology nodes and add them to the topology.
            for (int i = 0; i < cSourceStreams; i++)
            {
                AddBranchToPartialTopology(pTopology, m_hwndVideo, m_pSource, pSourcePD, i);
            }

            // Return the IMFTopology pointer to the caller.
            ppTopology = pTopology;
        }
        catch
        {
            // If we failed, release the topology
            SafeRelease(pTopology);
            throw;
        }
        finally
        {
            SafeRelease(pSourcePD);
        }
    }
Esempio n. 6
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);
                }
            }
        }
Esempio n. 7
0
        /// <summary>
        /// Configures the DirectShow graph to play the selected video capture
        /// device with the selected parameters
        /// </summary>
        private void SetupGraph()
        {
            /* Clean up any messes left behind */
            FreeResources();
            Trace.WriteLine("setting up graph 1");
            try
            {
                Trace.WriteLine("setting up graph 2");
                // Create the media session.
                CreateSession();
                Trace.WriteLine("setting up graph 3");

                CreateVideoCaptureSource();

                // Create a partial topology.
                IMFTopology pTopology = CreateTopologyFromSource();

                Trace.WriteLine("setting up graph 4");
                // Set the topology on the media session.
                int hr = m_pSession.SetTopology(0, pTopology);
                MFError.ThrowExceptionForHR(hr);

                //m_pSession.GetClock(out pClock);
                Trace.WriteLine("setting up graph 5");
                COMBase.SafeRelease(pTopology);


                //Marshal.ReleaseComObject();
            }
            catch (Exception ex)
            {
                Marshal.GetHRForException(ex);

                Trace.WriteLine("SetupGraph Exception " + ex.ToString());
                FreeResources();
                InvokeMediaFailed(new MediaFailedEventArgs(ex.Message, ex));
            }

            /* Success */
            InvokeMediaOpened();
        }
Esempio n. 8
0
        private void createSession(string sFilePath)
        {
            try
            {
                MFError throwonhr = MFExtern.MFCreateMediaSession(null, out m_pSession);

                // Create the media source.

                CreateMediaSource(sFilePath);

                if (m_pSource == null)
                {
                    return;
                }

                IMFPresentationDescriptor lPresentationDescriptor = null;

                m_pSource.CreatePresentationDescriptor(out lPresentationDescriptor);

                if (lPresentationDescriptor == null)
                {
                    return;
                }

                lPresentationDescriptor.GetUINT64(MFAttributesClsid.MF_PD_DURATION, out mMediaDuration);

                IMFTopology pTopology = null;

                // Create a partial topology.
                CreateTopologyFromSource(out pTopology);

                HResult hr = HResult.S_OK;
                // Set the topology on the media session.
                hr = m_pSession.SetTopology(0, pTopology);

                StartPlayback();
            }
            catch (Exception)
            {
            }
        }
Esempio n. 9
0
    ///////////////////////////////////////////////////////////////////////
    //  Name: BeginEnableContent
    //  Description:  Called by the PMP session to start the enable action.
    /////////////////////////////////////////////////////////////////////////

    public HResult BeginEnableContent(
        IMFActivate pEnablerActivate,
        IMFTopology pTopo,
        IMFAsyncCallback pCallback,
        object punkState
        )
    {
        // Make sure we *never* leave this entry point with an exception
        try
        {
            Debug.WriteLine("ContentProtectionManager::BeginEnableContent");

            if (m_pEnabler != null)
            {
                throw new COMException("A previous call is still pending", (int)HResult.E_FAIL);
            }

            HResult hr;

            // Save so we can create an async result later
            m_pCallback = pCallback;
            m_punkState = punkState;

            // Create the enabler from the IMFActivate pointer.
            object o;
            hr = pEnablerActivate.ActivateObject(typeof(IMFContentEnabler).GUID, out o);
            MFError.ThrowExceptionForHR(hr);
            m_pEnabler = o as IMFContentEnabler;

            // Notify the application. The application will call DoEnable from the app thread.
            m_state = Enabler.Ready; // Reset the state.
            PostMessage(m_hwnd, WM_APP_CONTENT_ENABLER, IntPtr.Zero, IntPtr.Zero);

            return(HResult.S_OK);
        }
        catch (Exception e)
        {
            return((HResult)Marshal.GetHRForException(e));
        }
    }
Esempio n. 10
0
    ///////////////////////////////////////////////////////////////////////
    //  Name: CreateVideoBranch
    //  Description:
    //  Adds and connects the nodes downstream from a video source node.
    //
    //  pTopology:      Pointer to the topology.
    //  pSourceNode:    Pointer to the source node.
    //  hVideoWindow:   Handle to the video window.
    //  clsidTransform: CLSID of an effect transform.
    /////////////////////////////////////////////////////////////////////////

    void CreateVideoBranch(
        IMFTopology pTopology,
        IMFTopologyNode pSourceNode,
        IntPtr hVideoWindow,
        Guid clsidTransform   // GUID_NULL = No effect transform.
        )
    {
        TRACE("CreateVideoBranch");

        IMFTopologyNode pOutputNode       = null;
        IMFActivate     pRendererActivate = null;

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

        MFError.ThrowExceptionForHR(hr);

        try
        {
            // Create an IMFActivate object for the video renderer.
            hr = MFExtern.MFCreateVideoRendererActivate(hVideoWindow, out pRendererActivate);
            MFError.ThrowExceptionForHR(hr);

            // Set the IActivate object on the output node.
            hr = pOutputNode.SetObject(pRendererActivate);
            MFError.ThrowExceptionForHR(hr);

            // Add the output node to the topology.
            hr = pTopology.AddNode(pOutputNode);
            MFError.ThrowExceptionForHR(hr);

            // Connect the source to the output.
            ConnectSourceToOutput(pTopology, pSourceNode, pOutputNode, clsidTransform);
        }
        finally
        {
            SafeRelease(pOutputNode);
            SafeRelease(pRendererActivate);
        }
    }
Esempio n. 11
0
    ///////////////////////////////////////////////////////////////////////
    //  Name: BeginEnableContent
    //  Description:  Called by the PMP session to start the enable action.
    /////////////////////////////////////////////////////////////////////////
    public int BeginEnableContent(
        IMFActivate pEnablerActivate,
        IMFTopology pTopo,
        IMFAsyncCallback pCallback,
        object punkState
        )
    {
        // Make sure we *never* leave this entry point with an exception
        try
        {
            Debug.WriteLine("ContentProtectionManager::BeginEnableContent");

            if (m_pEnabler != null)
            {
                throw new COMException("A previous call is still pending", E_Fail);
            }

            int hr;

            // Save so we can create an async result later
            m_pCallback = pCallback;
            m_punkState = punkState;

            // Create the enabler from the IMFActivate pointer.
            object o;
            hr = pEnablerActivate.ActivateObject(typeof(IMFContentEnabler).GUID, out o);
            MFError.ThrowExceptionForHR(hr);
            m_pEnabler = o as IMFContentEnabler;

            // Notify the application. The application will call DoEnable from the app thread.
            m_state = Enabler.Ready; // Reset the state.
            PostMessage(m_hwnd, WM_APP_CONTENT_ENABLER, IntPtr.Zero, IntPtr.Zero);

            return S_Ok;
        }
        catch (Exception e)
        {
            return Marshal.GetHRForException(e);
        }
    }
Esempio n. 12
0
        ////////////////////////////////////////////////////////////////////////////////////////
        //  Name: CPlayer::AddTopologyToSequencer (Private)
        //  Description:
        //      Adds the topology to the sequencer
        //  Parameter:
        //      sURL: [in] File URL
        //      pMediaSource: [in] Pointer to the media source
        //      pTopology: [in] Pointer to the topology
        //      pSegmentId: [out] Receives the segment id returned by the sequencer source
        /////////////////////////////////////////////////////////////////////////////////////////

        private void AddTopologyToSequencer(
            string sURL,
            IMFMediaSource pMediaSource,
            IMFTopology pTopology,
            out int pSegmentId)
        {
            Debug.WriteLine("CPlayer::AddTopologyToSequencer");

            if (sURL == null || pMediaSource == null || pTopology == null)
            {
                throw new COMException("null pointer", (int)HResult.E_POINTER);
            }

            long    hnsSegmentDuration = 0;
            long    TopologyID         = 0;
            HResult hr;

            IMFPresentationDescriptor pPresentationDescriptor;

            hr = m_pSequencerSource.AppendTopology(pTopology, 0, out pSegmentId);
            MFError.ThrowExceptionForHR(hr);

            hr = pTopology.GetTopologyID(out TopologyID);
            MFError.ThrowExceptionForHR(hr);

            //create a presentation descriptor
            hr = pMediaSource.CreatePresentationDescriptor(out pPresentationDescriptor);
            MFError.ThrowExceptionForHR(hr);

            //get the segment duration
            hr = pPresentationDescriptor.GetUINT64(MFAttributesClsid.MF_PD_DURATION, out hnsSegmentDuration);
            MFError.ThrowExceptionForHR(hr);

            Debug.Assert(hnsSegmentDuration > 0);

            //store the segment info: SegmentId, SegmentDuration, TopoID in the linked list.
            m_Segments.AddNewSegmentEntry(pSegmentId, hnsSegmentDuration, TopologyID, sURL);
        }
Esempio n. 13
0
        ////////////////////////////////////////////////////////////////////////////////////////
        //  Name: CPlayer::CreateTopology (Private)
        //  Description:
        //      Creates a topology for the media source
        //  Parameter:
        //      pMediaSource: [in] Pointer to the media source
        //      pTopology: [in] Receives the partial topology
        /////////////////////////////////////////////////////////////////////////////////////////
        private void CreateTopology(
                            IMFMediaSource pMediaSource,
                            IMFTopology pTopology)
        {
            Debug.WriteLine("CPlayer::CreateTopology");

            //The caller needs to pass a valid media source
            //We need the media source because to set the source node attribute, media source is needed

            if (pMediaSource == null || pTopology == null)
            {
                throw new COMException("null pointer", E_Pointer);
            }

            IMFPresentationDescriptor pPresentationDescriptor;

            //Create Presentation Descriptor for the media source
            int hr = pMediaSource.CreatePresentationDescriptor(out pPresentationDescriptor);
            MFError.ThrowExceptionForHR(hr);

            try
            {
                CreateNodesForStream(pPresentationDescriptor, pMediaSource, pTopology);
            }
            finally
            {
                SafeRelease(pPresentationDescriptor);
            }
        }
Esempio n. 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
            )
        {
            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);
                }
            }
        }
Esempio n. 15
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)
        {
            int 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");
            }
        }
Esempio n. 16
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");
            }
        }
Esempio n. 17
0
        ///////////////////////////////////////////////////////////////////////
        //  Name: RunMediaSession
        //  Description:
        //  Queues the specified topology on the media session and runs the
        //  media session until the MESessionEnded event is received.
        ///////////////////////////////////////////////////////////////////////
        static void RunMediaSession(IMFTopology pTopology)
        {
            int hr;
            IMFMediaSession pSession;

            bool bGetAnotherEvent = true;
            PropVariant varStartPosition = new PropVariant();

            hr = MFExtern.MFCreateMediaSession(null, out pSession);
            MFError.ThrowExceptionForHR(hr);

            try
            {
                hr = pSession.SetTopology(0, pTopology);
                MFError.ThrowExceptionForHR(hr);

                while (bGetAnotherEvent)
                {
                    int hrStatus = 0;
                    IMFMediaEvent pEvent;
                    MediaEventType meType = MediaEventType.MEUnknown;

                    int TopoStatus = (int)MFTopoStatus.Invalid; // Used with MESessionTopologyStatus event.

                    hr = pSession.GetEvent(MFEventFlag.None, out pEvent);
                    MFError.ThrowExceptionForHR(hr);

                    try
                    {
                        hr = pEvent.GetStatus(out hrStatus);
                        MFError.ThrowExceptionForHR(hr);

                        hr = pEvent.GetType(out meType);
                        MFError.ThrowExceptionForHR(hr);

                        if (hrStatus >= 0)
                        {
                            switch (meType)
                            {
                                case MediaEventType.MESessionTopologySet:
                                    Debug.WriteLine("MESessionTopologySet");
                                    break;

                                case MediaEventType.MESessionTopologyStatus:
                                    // Get the status code.
                                    hr = pEvent.GetUINT32(MFAttributesClsid.MF_EVENT_TOPOLOGY_STATUS, out TopoStatus);
                                    MFError.ThrowExceptionForHR(hr);
                                    switch ((MFTopoStatus)TopoStatus)
                                    {
                                        case MFTopoStatus.Ready:
                                            Debug.WriteLine("MESessionTopologyStatus: MF_TOPOSTATUS_READY");
                                            pSession.Start(Guid.Empty, varStartPosition);
                                            break;

                                        case MFTopoStatus.Ended:
                                            Debug.WriteLine("MESessionTopologyStatus: MF_TOPOSTATUS_ENDED");
                                            break;
                                    }
                                    break;

                                case MediaEventType.MESessionStarted:
                                    Debug.WriteLine("MESessionStarted");
                                    break;

                                case MediaEventType.MESessionEnded:
                                    Debug.WriteLine("MESessionEnded");
                                    hr = pSession.Stop();
                                    break;

                                case MediaEventType.MESessionStopped:
                                    Debug.WriteLine("MESessionStopped");
                                    Console.WriteLine("Attempting to close the media session.");
                                    hr = pSession.Close();
                                    MFError.ThrowExceptionForHR(hr);
                                    break;

                                case MediaEventType.MESessionClosed:
                                    Debug.WriteLine("MESessionClosed");
                                    bGetAnotherEvent = false;
                                    break;

                                default:
                                    Debug.WriteLine(string.Format("Media session event: {0}", meType));
                                    break;
                            }
                        }
                        else
                        {
                            Debug.WriteLine(string.Format("HRStatus: {0}", hrStatus));
                            bGetAnotherEvent = false;
                        }
                    }
                    finally
                    {
                        if (pEvent != null)
                        {
                            Marshal.ReleaseComObject(pEvent);
                        }
                    }
                }

                Debug.WriteLine("Shutting down the media session.");
                hr = pSession.Shutdown();
                MFError.ThrowExceptionForHR(hr);
            }
            finally
            {
                if (pSession != null)
                {
                    Marshal.ReleaseComObject(pSession);
                }
            }
        }
Esempio n. 18
0
 private static extern int ExternMFCreateTranscodeTopology(
     [In, MarshalAs(UnmanagedType.Interface)] IMFMediaSource pSrc,
     [In, MarshalAs(UnmanagedType.LPWStr)] string pwszOutputFilePath,
     [In, MarshalAs(UnmanagedType.Interface)] IMFTranscodeProfile pProfile,
     [Out, MarshalAs(UnmanagedType.Interface)] out IMFTopology ppTranscodeTopo);
Esempio n. 19
0
        ///////////////////////////////////////////////////////////////////////
        //  Name: RunMediaSession
        //  Description:
        //  Queues the specified topology on the media session and runs the
        //  media session until the MESessionEnded event is received.
        ///////////////////////////////////////////////////////////////////////

        static void RunMediaSession(IMFTopology pTopology)
        {
            HResult         hr;
            IMFMediaSession pSession;

            bool        bGetAnotherEvent = true;
            PropVariant varStartPosition = new PropVariant();

            hr = MFExtern.MFCreateMediaSession(null, out pSession);
            MFError.ThrowExceptionForHR(hr);

            try
            {
                hr = pSession.SetTopology(0, pTopology);
                MFError.ThrowExceptionForHR(hr);

                while (bGetAnotherEvent)
                {
                    HResult        hrStatus = 0;
                    IMFMediaEvent  pEvent;
                    MediaEventType meType = MediaEventType.MEUnknown;

                    int TopoStatus = (int)MFTopoStatus.Invalid; // Used with MESessionTopologyStatus event.

                    hr = pSession.GetEvent(MFEventFlag.None, out pEvent);
                    MFError.ThrowExceptionForHR(hr);

                    try
                    {
                        hr = pEvent.GetStatus(out hrStatus);
                        MFError.ThrowExceptionForHR(hr);

                        hr = pEvent.GetType(out meType);
                        MFError.ThrowExceptionForHR(hr);

                        if (hrStatus >= 0)
                        {
                            switch (meType)
                            {
                            case MediaEventType.MESessionTopologySet:
                                Debug.WriteLine("MESessionTopologySet");
                                break;

                            case MediaEventType.MESessionTopologyStatus:
                                // Get the status code.
                                hr = pEvent.GetUINT32(MFAttributesClsid.MF_EVENT_TOPOLOGY_STATUS, out TopoStatus);
                                MFError.ThrowExceptionForHR(hr);
                                switch ((MFTopoStatus)TopoStatus)
                                {
                                case MFTopoStatus.Ready:
                                    Debug.WriteLine("MESessionTopologyStatus: MF_TOPOSTATUS_READY");
                                    pSession.Start(Guid.Empty, varStartPosition);
                                    break;

                                case MFTopoStatus.Ended:
                                    Debug.WriteLine("MESessionTopologyStatus: MF_TOPOSTATUS_ENDED");
                                    break;
                                }
                                break;

                            case MediaEventType.MESessionStarted:
                                Debug.WriteLine("MESessionStarted");
                                break;

                            case MediaEventType.MESessionEnded:
                                Debug.WriteLine("MESessionEnded");
                                hr = pSession.Stop();
                                break;

                            case MediaEventType.MESessionStopped:
                                Debug.WriteLine("MESessionStopped");
                                Console.WriteLine("Attempting to close the media session.");
                                hr = pSession.Close();
                                MFError.ThrowExceptionForHR(hr);
                                break;

                            case MediaEventType.MESessionClosed:
                                Debug.WriteLine("MESessionClosed");
                                bGetAnotherEvent = false;
                                break;

                            default:
                                Debug.WriteLine(string.Format("Media session event: {0}", meType));
                                break;
                            }
                        }
                        else
                        {
                            Debug.WriteLine(string.Format("HRStatus: {0}", hrStatus));
                            bGetAnotherEvent = false;
                        }
                    }
                    finally
                    {
                        if (pEvent != null)
                        {
                            Marshal.ReleaseComObject(pEvent);
                        }
                    }
                }

                Debug.WriteLine("Shutting down the media session.");
                hr = pSession.Shutdown();
                MFError.ThrowExceptionForHR(hr);
            }
            finally
            {
                if (pSession != null)
                {
                    Marshal.ReleaseComObject(pSession);
                }
            }
        }
Esempio n. 20
0
    ///////////////////////////////////////////////////////////////////////
    //  Name:  AddBranchToPartialTopology
    //  Description:  Adds a topology branch for one stream.
    //
    //  pTopology: Pointer to the topology object.
    //  hVideoWindow: Handle to the video window (for video streams).
    //  pSource: Media source.
    //  pSourcePD: The source's presentation descriptor.
    //  iStream: Index of the stream to render.
    //
    //  Pre-conditions: The topology must be created already.
    //
    //  Notes: For each stream, we must do the following:
    //    1. Create a source node associated with the stream.
    //    2. Create an output node for the renderer.
    //    3. Connect the two nodes.
    //
    //  Optionally we can also add an effect transform between the source
    //  and output nodes.
    //
    //  The media session will resolve the topology, so we do not have
    //  to worry about decoders or color converters.
    /////////////////////////////////////////////////////////////////////////
    void AddBranchToPartialTopology(
        IMFTopology pTopology,
        IntPtr hVideoWindow,
        IMFMediaSource pSource,
        IMFPresentationDescriptor pSourcePD,
        int iStream)
    {
        TRACE("Player::RenderStream");

        IMFStreamDescriptor pSourceSD = null;
        IMFTopologyNode pSourceNode = null;

        int hr;
        Guid majorType;
        bool fSelected = false;

        // Get the stream descriptor for this stream.
        hr = pSourcePD.GetStreamDescriptorByIndex(iStream, out fSelected, out pSourceSD);
        MFError.ThrowExceptionForHR(hr);

        // First check if the stream is selected by default. If not, ignore it.
        // More sophisticated applications can change the default selections.
        if (fSelected)
        {
            try
            {
                // Create a source node for this stream.
                CreateSourceStreamNode(pSource, pSourcePD, pSourceSD, out pSourceNode);

                // Add the source node to the topology.
                hr = pTopology.AddNode(pSourceNode);
                MFError.ThrowExceptionForHR(hr);

                // Get the major media type for the stream.
                GetStreamType(pSourceSD, out majorType);

                if (majorType == MFMediaType.Video)
                {
                    // For video, use the grayscale transform.
                    CreateVideoBranch(pTopology, pSourceNode, hVideoWindow, m_VideoEffect);
                }
                else if (majorType == MFMediaType.Audio)
                {
                    CreateAudioBranch(pTopology, pSourceNode, Guid.Empty);
                }
            }
            finally
            {
                // Clean up.
                SafeRelease(pSourceSD);
                SafeRelease(pSourceNode);
            }
        }
    }
Esempio n. 21
0
    protected void CreateTopologyFromSource(out IMFTopology ppTopology)
    {
        TRACE("CPlayer::CreateTopologyFromSource");

        Debug.Assert(m_pSession != null);
        Debug.Assert(m_pSource != null);

        IMFTopology pTopology = null;
        IMFPresentationDescriptor pSourcePD = null;
        int     cSourceStreams = 0;
        HResult hr;

        try
        {
            // Create a new topology.
            hr = MFExtern.MFCreateTopology(out pTopology);
            MFError.ThrowExceptionForHR(hr);

            // Create the presentation descriptor for the media source.
            hr = m_pSource.CreatePresentationDescriptor(out pSourcePD);
            MFError.ThrowExceptionForHR(hr);

            {
                // See if there is metadata.  If anything fails,
                // just leave m_pMetadata as null.
                object o;
                hr = MFExtern.MFGetService(
                    m_pSource,
                    MFServices.MF_METADATA_PROVIDER_SERVICE,
                    typeof(IMFMetadataProvider).GUID,
                    out o
                    );

                if (Succeeded(hr))
                {
                    IMFMetadataProvider pMetaProvider = o as IMFMetadataProvider;
                    hr = pMetaProvider.GetMFMetadata(
                        pSourcePD,
                        0,      // Stream id 0 == presentation-level metadata.
                        0,      // Reserved
                        out m_pMetadata);
                }
            }

            // Get the number of streams in the media source.
            hr = pSourcePD.GetStreamDescriptorCount(out cSourceStreams);
            MFError.ThrowExceptionForHR(hr);

            TRACE(string.Format("Stream count: {0}", cSourceStreams));

            // For each stream, create the topology nodes and add them to the topology.
            for (int i = 0; i < cSourceStreams; i++)
            {
                AddBranchToPartialTopology(pTopology, m_hwndVideo, m_pSource, pSourcePD, i);
            }

            // Return the IMFTopology pointer to the caller.
            ppTopology = pTopology;
        }
        catch
        {
            // If we failed, release the topology
            SafeRelease(pTopology);
            throw;
        }
        finally
        {
            SafeRelease(pSourcePD);
        }
    }
Esempio n. 22
0
 public static void MFCreateTranscodeTopology(
     IMFMediaSource mediaSource,
     string outputFilePath,
     IMFTranscodeProfile transcodeProfile,
     out IMFTopology transcodeTopology)
 {
     int result = ExternMFCreateTranscodeTopology(mediaSource, outputFilePath, transcodeProfile, out transcodeTopology);
     if (result < 0)
     {
         throw new COMException("Exception from HRESULT: 0x" + result.ToString("X", System.Globalization.NumberFormatInfo.InvariantInfo) + " (MFCreateTranscodeTopology failed)", result);
     }
 }
Esempio n. 23
0
        ////////////////////////////////////////////////////////////////////////////////////////
        //  Name: CPlayer::CreateNodesForStream (Private)
        //  Description:
        //      Creates the source and output nodes for a stream and
        //      Adds them to the topology
        //      Connects the source node to the output node
        //
        //  Parameter:
        //      pPresentationDescriptor: [in] Pointer to the presentation descriptor for the media source
        //      pMediaSource: [in] Pointer to the media source
        //      pTopology: [in] Pointer to the topology
        //
        //  Notes: For each stream, the app must:
        //      1. Create a source node associated with the stream.
        //      2. Create an output node for the renderer.
        //      3. Connect the two nodes.
        //      The media session will resolve the topology, transform nodes are not required
        /////////////////////////////////////////////////////////////////////////////////////////

        private void CreateNodesForStream(
            IMFPresentationDescriptor pPresentationDescriptor,
            IMFMediaSource pMediaSource,
            IMFTopology pTopology)
        {
            if (pPresentationDescriptor == null || pMediaSource == null || pTopology == null)
            {
                throw new COMException("null pointer", (int)HResult.E_POINTER);
            }

            HResult             hr;
            IMFStreamDescriptor pStreamDescriptor;
            IMFTopologyNode     pSourceNode;
            IMFTopologyNode     pOutputNode;

            bool fSelected = false;

            // Get the stream descriptor for the only stream index =0.
            hr = pPresentationDescriptor.GetStreamDescriptorByIndex(0, out fSelected, out pStreamDescriptor);
            MFError.ThrowExceptionForHR(hr);

            try
            {
                if (fSelected)
                {
                    // Create a source node for this stream and add it to the topology.
                    CreateSourceNode(pPresentationDescriptor, pStreamDescriptor, pMediaSource, out pSourceNode);

                    try
                    {
                        hr = pTopology.AddNode(pSourceNode);
                        MFError.ThrowExceptionForHR(hr);

                        // Create the output node for the renderer and add it to the topology.
                        CreateOutputNode(pStreamDescriptor, out pOutputNode);

                        try
                        {
                            hr = pTopology.AddNode(pOutputNode);
                            MFError.ThrowExceptionForHR(hr);

                            // Connect the source node to the output node.
                            hr = pSourceNode.ConnectOutput(0, pOutputNode, 0);
                            MFError.ThrowExceptionForHR(hr);
                        }
                        finally
                        {
                            SafeRelease(pOutputNode);
                        }
                    }
                    finally
                    {
                        SafeRelease(pSourceNode);
                    }
                }
            }
            finally
            {
                //clean up
                SafeRelease(pStreamDescriptor);
            }
        }
Esempio n. 24
0
    ///////////////////////////////////////////////////////////////////////
    //  Name: ConnectSourceToOutput
    //  Description:
    //  Connects the source node to the output node.
    //
    //  pTopology:      Pointer to the topology.
    //  pSourceNode:    Pointer to the source node.
    //  pOutputNode:    Pointer to the output node.
    //  clsidTransform: CLSID of an effect transform.
    /////////////////////////////////////////////////////////////////////////
    void ConnectSourceToOutput(
        IMFTopology pTopology,
        IMFTopologyNode pSourceNode,
        IMFTopologyNode pOutputNode,
        Guid clsidTransform
        )
    {
        int hr;

        if (clsidTransform == Guid.Empty)
        {
            // There is no effect specified, so connect the source node
            // directly to the output node.
            hr = pSourceNode.ConnectOutput(0, pOutputNode, 0);
            MFError.ThrowExceptionForHR(hr);
        }
        else
        {
            IMFTopologyNode pTransformNode = null;
            object pTransformUnk = null;

            // Create a transform node.
            hr = MFExtern.MFCreateTopologyNode(MFTopologyType.TransformNode, out pTransformNode);
            MFError.ThrowExceptionForHR(hr);

            try
            {
                Type type = Type.GetTypeFromCLSID(clsidTransform);

                pTransformUnk = Activator.CreateInstance(type);
                hr = pTransformNode.SetObject(pTransformUnk);
                MFError.ThrowExceptionForHR(hr);

                //// Set the CLSID of the transform.
                //if (SUCCEEDED(hr))
                //{
                //    hr = pTransformNode->SetGUID(MF_TOPONODE_TRANSFORM_OBJECTID, clsidTransform);
                //}

                // Add the transform node to the topology.
                hr = pTopology.AddNode(pTransformNode);
                MFError.ThrowExceptionForHR(hr);

                // Connect the source node to the transform node.
                hr = pSourceNode.ConnectOutput(0, pTransformNode, 0);
                MFError.ThrowExceptionForHR(hr);

                // Connect the transform node to the output node.
                hr = pTransformNode.ConnectOutput(0, pOutputNode, 0);
                MFError.ThrowExceptionForHR(hr);
            }
            finally
            {
                SafeRelease(pTransformNode);
                //SafeRelease(pTransformUnk);
            }
        }
    }
Esempio n. 25
0
        ////////////////////////////////////////////////////////////////////////////////////////
        //  Name: CPlayer::AddTopologyToSequencer (Private)
        //  Description:
        //      Adds the topology to the sequencer
        //  Parameter:
        //      sURL: [in] File URL
        //      pMediaSource: [in] Pointer to the media source
        //      pTopology: [in] Pointer to the topology
        //      pSegmentId: [out] Receives the segment id returned by the sequencer source
        /////////////////////////////////////////////////////////////////////////////////////////
        private void AddTopologyToSequencer(
                            string sURL,
                            IMFMediaSource pMediaSource,
                            IMFTopology pTopology,
                            out int pSegmentId)
        {
            Debug.WriteLine("CPlayer::AddTopologyToSequencer");

            if (sURL == null || pMediaSource == null || pTopology == null)
            {
                throw new COMException("null pointer", E_Pointer);
            }

            long hnsSegmentDuration = 0;
            long TopologyID = 0;
            int hr;

            IMFPresentationDescriptor pPresentationDescriptor;

            hr = m_pSequencerSource.AppendTopology(pTopology, 0, out pSegmentId);
            MFError.ThrowExceptionForHR(hr);

            hr = pTopology.GetTopologyID(out TopologyID);
            MFError.ThrowExceptionForHR(hr);

            //create a presentation descriptor
            hr = pMediaSource.CreatePresentationDescriptor(out pPresentationDescriptor);
            MFError.ThrowExceptionForHR(hr);

            //get the segment duration
            hr = pPresentationDescriptor.GetUINT64(MFAttributesClsid.MF_PD_DURATION, out hnsSegmentDuration);
            MFError.ThrowExceptionForHR(hr);

            Debug.Assert(hnsSegmentDuration > 0);

            //store the segment info: SegmentId, SegmentDuration, TopoID in the linked list.
            m_Segments.AddNewSegmentEntry(pSegmentId, hnsSegmentDuration, TopologyID, sURL);
        }
Esempio n. 26
0
    ///////////////////////////////////////////////////////////////////////
    //  Name: CreateVideoBranch
    //  Description:
    //  Adds and connects the nodes downstream from a video source node.
    //
    //  pTopology:      Pointer to the topology.
    //  pSourceNode:    Pointer to the source node.
    //  hVideoWindow:   Handle to the video window.
    //  clsidTransform: CLSID of an effect transform.
    /////////////////////////////////////////////////////////////////////////
    void CreateVideoBranch(
        IMFTopology pTopology,
        IMFTopologyNode pSourceNode,
        IntPtr hVideoWindow,
        Guid clsidTransform   // GUID_NULL = No effect transform.
        )
    {
        TRACE("CreateVideoBranch");

        IMFTopologyNode pOutputNode = null;
        IMFActivate pRendererActivate = null;

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

        try
        {
            // Create an IMFActivate object for the video renderer.
            hr = MFExtern.MFCreateVideoRendererActivate(hVideoWindow, out pRendererActivate);
            MFError.ThrowExceptionForHR(hr);

            // Set the IActivate object on the output node.
            hr = pOutputNode.SetObject(pRendererActivate);
            MFError.ThrowExceptionForHR(hr);

            // Add the output node to the topology.
            hr = pTopology.AddNode(pOutputNode);
            MFError.ThrowExceptionForHR(hr);

            // Connect the source to the output.
            ConnectSourceToOutput(pTopology, pSourceNode, pOutputNode, clsidTransform);
        }
        finally
        {
            SafeRelease(pOutputNode);
            SafeRelease(pRendererActivate);
        }
    }
Esempio n. 27
0
        ////////////////////////////////////////////////////////////////////////////////////////
        //  Name: CPlayer::CreateNodesForStream (Private)
        //  Description:
        //      Creates the source and output nodes for a stream and
        //      Adds them to the topology
        //      Connects the source node to the output node
        //
        //  Parameter:
        //      pPresentationDescriptor: [in] Pointer to the presentation descriptor for the media source
        //      pMediaSource: [in] Pointer to the media source
        //      pTopology: [in] Pointer to the topology
        //
        //  Notes: For each stream, the app must:
        //      1. Create a source node associated with the stream.
        //      2. Create an output node for the renderer.
        //      3. Connect the two nodes.
        //      The media session will resolve the topology, transform nodes are not required
        /////////////////////////////////////////////////////////////////////////////////////////
        private void CreateNodesForStream(
                            IMFPresentationDescriptor pPresentationDescriptor,
                            IMFMediaSource pMediaSource,
                            IMFTopology pTopology)
        {
            if (pPresentationDescriptor == null || pMediaSource == null || pTopology == null)
            {
                throw new COMException("null pointer", E_Pointer);
            }

            int hr;
            IMFStreamDescriptor pStreamDescriptor;
            IMFTopologyNode pSourceNode;
            IMFTopologyNode pOutputNode;

            bool fSelected = false;

            // Get the stream descriptor for the only stream index =0.
            hr = pPresentationDescriptor.GetStreamDescriptorByIndex(0, out fSelected, out pStreamDescriptor);
            MFError.ThrowExceptionForHR(hr);

            try
            {
                if (fSelected)
                {
                    // Create a source node for this stream and add it to the topology.
                    CreateSourceNode(pPresentationDescriptor, pStreamDescriptor, pMediaSource, out pSourceNode);

                    try
                    {
                        hr = pTopology.AddNode(pSourceNode);
                        MFError.ThrowExceptionForHR(hr);

                        // Create the output node for the renderer and add it to the topology.
                        CreateOutputNode(pStreamDescriptor, out pOutputNode);

                        try
                        {
                            hr = pTopology.AddNode(pOutputNode);
                            MFError.ThrowExceptionForHR(hr);

                            // Connect the source node to the output node.
                            hr = pSourceNode.ConnectOutput(0, pOutputNode, 0);
                            MFError.ThrowExceptionForHR(hr);
                        }
                        finally
                        {
                            SafeRelease(pOutputNode);
                        }
                    }
                    finally
                    {
                        SafeRelease(pSourceNode);
                    }
                }
            }
            finally
            {
                //clean up
                SafeRelease(pStreamDescriptor);
            }
        }
        /// <summary>
        ///     Starts the asychronous encode operation
        /// </summary>
        /// <param name="inputURL">Source filename</param>
        /// <param name="outputURL">Targe filename</param>
        /// <param name="audioOutput">Audio format that will be used for audio streams</param>
        /// <param name="videoOutput">Video format that will be used for video streams</param>
        /// <param name="startPosition">Starting position of the contet</param>
        /// <param name="endPosition">Position where the new content will end</param>
        public void Encode(string inputURL, string outputURL, AudioFormat audioOutput, VideoFormat videoOutput, ulong startPosition, ulong endPosition)
        {
            // If busy with other operation ignore and return
            if (this.IsBusy())
            {
                return;
            }

            try
            {
                this.presentationClock = null;
                this.startPosition     = startPosition;
                this.endPosition       = endPosition;

                object objectSource = null;

                // Create the media source using source resolver and the input URL
                uint objectType = default(uint);
                this.mediaSource = null;

                // Init source resolver
                IMFSourceResolver sourceResolver = null;
                MFHelper.MFCreateSourceResolver(out sourceResolver);

                sourceResolver.CreateObjectFromURL(inputURL, Consts.MF_RESOLUTION_MEDIASOURCE, null, out objectType, out objectSource);

                this.mediaSource = (IMFMediaSource)objectSource;

                // Create the media session using a global start time so MF_TOPOLOGY_PROJECTSTOP can be used to stop the session
                this.mediaSession = null;
                IMFAttributes mediaSessionAttributes = null;

                MFHelper.MFCreateAttributes(out mediaSessionAttributes, 1);
                mediaSessionAttributes.SetUINT32(new Guid(Consts.MF_SESSION_GLOBAL_TIME), 1);

                MFHelper.MFCreateMediaSession(mediaSessionAttributes, out this.mediaSession);

                // Create the event handler
                AsyncEventHandler mediaEventHandler = new AsyncEventHandler(this.mediaSession);
                mediaEventHandler.MediaEvent += this.MediaEvent;

                // Get the stream descriptor
                IMFPresentationDescriptor presentationDescriptor = null;
                mediaSource.CreatePresentationDescriptor(out presentationDescriptor);

                // Get the duration
                presentationDescriptor.GetUINT64(new Guid(Consts.MF_PD_DURATION), out this.duration);
                IMFTranscodeProfile transcodeProfile = null;

                Guid containerType = new Guid(Consts.MFTranscodeContainerType_MPEG4);
                if (outputURL.EndsWith(".wmv", StringComparison.OrdinalIgnoreCase) || outputURL.EndsWith(".wma", StringComparison.OrdinalIgnoreCase))
                {
                    containerType = new Guid(Consts.MFTranscodeContainerType_ASF);
                }

                // Generate the transcoding profile
                transcodeProfile = SimpleFastEncode.CreateProfile(audioOutput, videoOutput, containerType);

                // Create the MF topology using the profile
                IMFTopology topology = null;
                MFHelper.MFCreateTranscodeTopology(this.mediaSource, outputURL, transcodeProfile, out topology);

                // Set the end position
                topology.SetUINT64(new Guid(Consts.MF_TOPOLOGY_PROJECTSTART), 0);
                topology.SetUINT64(new Guid(Consts.MF_TOPOLOGY_PROJECTSTOP), (endPosition == 0) ? this.duration : endPosition);

                // Set the session topology
                this.mediaSession.SetTopology((uint)Enums.MFSESSION_SETTOPOLOGY_FLAGS.None, topology);
            }
            catch (Exception ex)
            {
                this.mediaSession = null;

                // Fire the EncodeError event
                if (this.EncodeError != null)
                {
                    this.EncodeError(new Exception(ex.Message, ex));
                }
            }
        }
Esempio n. 29
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);
                }
            }
        }
Esempio n. 30
0
        protected void AddBranchToPartialTopology(
            IMFTopology pTopology,
            IMFPresentationDescriptor pSourcePD,
            int iStream
            )
        {
            TRACE("CPlayer::AddBranchToPartialTopology");

            Debug.Assert(pTopology != null);

            IMFStreamDescriptor pSourceSD = null;
            IMFTopologyNode pSourceNode = null;
            IMFTopologyNode pOutputNode = null;
            bool fSelected = false;

            try
            {
                // Get the stream descriptor for this stream.
                pSourcePD.GetStreamDescriptorByIndex(iStream, out fSelected, out pSourceSD);

                // Create the topology branch only if the stream is selected.
                // Otherwise, do nothing.
                if (fSelected)
                {
                    // Create a source node for this stream.
                    CreateSourceStreamNode(pSourcePD, pSourceSD, out pSourceNode);

                    // Create the output node for the renderer.
                    CreateOutputNode(pSourceSD, out pOutputNode);

                    // Add both nodes to the topology.
                    pTopology.AddNode(pSourceNode);
                    pTopology.AddNode(pOutputNode);

                    // Connect the source node to the output node.
                    pSourceNode.ConnectOutput(0, pOutputNode, 0);
                }
            }
            finally
            {
                // Clean up.
                SafeRelease(pSourceSD);
                SafeRelease(pSourceNode);
                SafeRelease(pOutputNode);
            }
        }
Esempio n. 31
0
 public static extern void MFCreateTopology(out IMFTopology ppTopo);
Esempio n. 32
0
        protected void CreateTopologyFromSource(out IMFTopology ppTopology)
        {
            TRACE("CPlayer::CreateTopologyFromSource");

            Debug.Assert(m_pSession != null);
            Debug.Assert(m_pSource != null);

            IMFTopology pTopology = null;
            IMFPresentationDescriptor pSourcePD = null;
            int cSourceStreams = 0;

            try
            {
                // Create a new topology.
                MFExtern.MFCreateTopology(out pTopology);

                // Create the presentation descriptor for the media source.
                m_pSource.CreatePresentationDescriptor(out pSourcePD);

                // Get the number of streams in the media source.
                pSourcePD.GetStreamDescriptorCount(out cSourceStreams);

                TRACE(string.Format("Stream count: {0}", cSourceStreams));

                // For each stream, create the topology nodes and add them to the topology.
                for (int i = 0; i < cSourceStreams; i++)
                {
                    AddBranchToPartialTopology(pTopology, pSourcePD, i);
                }

                // Return the IMFTopology pointer to the caller.
                ppTopology = pTopology;
            }
            catch
            {
                // If we failed, release the topology
                SafeRelease(pTopology);
                throw;
            }
            finally
            {
                SafeRelease(pSourcePD);
            }
        }
Esempio n. 33
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);
        }
Esempio n. 34
0
 public static extern HResult MFCreateTopology(
     out IMFTopology ppTopo
     );