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

大概测试了一下,如果直接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;
            }
        }


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值