现在的位置: 首页 > 综合 > 正文

多个同类型编码视频切换时,只改变SourceFilter,不改变Filter Graph中其他Filter的C#实现

2017年08月29日 ⁄ 综合 ⁄ 共 1548字 ⁄ 字号 评论关闭

大概测试了一下,如果直接RenderFile播放的话,视频之间从上一个视频Stop到下一个视频Run之间 所需的时间为下面方法的至少3倍时间,

对于采用同一种视频编码的多个视频,可以采用只改变SourceFilter,而其他Filter不用改变的方式来切换视频。
实现方式如下,注意需要
DirectShowLibNET

DirectShowLibNET - A library to allow .NET applications to use DirectShow functions

 

public void ChangeFileSource(string newfilename)
        {
            // 先加入 新加入的文件名代表的SourceFilter
            IPin nextOutPin = null;
            int hr = 0;
            IBaseFilter sourceFilter = null;
            hr = m_FilterGraph.AddSourceFilter(newfilename, newfilename, out sourceFilter);
            DsError.ThrowExceptionForHR(hr);

            hr = sourceFilter.FindPin("Output", out nextOutPin);
            DsError.ThrowExceptionForHR(hr);
            
            //然后停止 当前FilterGraph的播放,
            hr = m_mediaCtrl.Stop();
            DsError.ThrowExceptionForHR(hr);

            //然后枚举所有Filter
            IEnumFilters enumFilters = null;
            hr = m_FilterGraph.EnumFilters(out enumFilters);

            int iFiltCount = 0;

            while (0 == enumFilters.Skip(1))
            {
                iFiltCount++;
            }
            enumFilters.Reset();

            int iPos = 0;
            IBaseFilter[] filters = new IBaseFilter[iFiltCount];
            while (iPos < iFiltCount)
            {
                int numFiltersToGet = 1;
                IBaseFilter[] filter = new IBaseFilter[numFiltersToGet];
                IntPtr fetched = IntPtr.Zero;
                hr = enumFilters.Next(1, filter, fetched);
                DsError.ThrowExceptionForHR(hr);
                filters[iPos] = filter[0];
                iPos++;
            }

            //此循环将新加入的SourceFilter加入到FilterGraph中,并将原SourceFilter移除并释放掉
            for (iPos = 0; iPos < iFiltCount; iPos++)
            {
                m_FilterGraph.RemoveFilter(filters[iPos]);
                if (filters[iPos] != m_currentSource)
                {
                    m_FilterGraph.AddFilter(filters[iPos], null);
                }
                else
                {
                    Marshal.ReleaseComObject(filters[iPos]);
                }
            }

            hr = m_FilterGraph.Render(nextOutPin);
            DsError.ThrowExceptionForHR(hr);
            m_currentSource = sourceFilter;
            sourceFilter = null;

            m_mediaCtrl.Run();

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

 

抱歉!评论已关闭.