IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

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

    mao0514发表于 2017-06-02 10:39:35
    love 0

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

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

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

     

    [cpp] view plain copy
    1. public void ChangeFileSource(string newfilename)  
    2.         {  
    3.             // 先加入 新加入的文件名代表的SourceFilter  
    4.             IPin nextOutPin = null;  
    5.             int hr = 0;  
    6.             IBaseFilter sourceFilter = null;  
    7.             hr = m_FilterGraph.AddSourceFilter(newfilename, newfilename, out sourceFilter);  
    8.             DsError.ThrowExceptionForHR(hr);  
    9.   
    10.             hr = sourceFilter.FindPin("Output", out nextOutPin);  
    11.             DsError.ThrowExceptionForHR(hr);  
    12.               
    13.             //然后停止 当前FilterGraph的播放,  
    14.             hr = m_mediaCtrl.Stop();  
    15.             DsError.ThrowExceptionForHR(hr);  
    16.   
    17.             //然后枚举所有Filter  
    18.             IEnumFilters enumFilters = null;  
    19.             hr = m_FilterGraph.EnumFilters(out enumFilters);  
    20.   
    21.             int iFiltCount = 0;  
    22.   
    23.             while (0 == enumFilters.Skip(1))  
    24.             {  
    25.                 iFiltCount++;  
    26.             }  
    27.             enumFilters.Reset();  
    28.   
    29.             int iPos = 0;  
    30.             IBaseFilter[] filters = new IBaseFilter[iFiltCount];  
    31.             while (iPos < iFiltCount)  
    32.             {  
    33.                 int numFiltersToGet = 1;  
    34.                 IBaseFilter[] filter = new IBaseFilter[numFiltersToGet];  
    35.                 IntPtr fetched = IntPtr.Zero;  
    36.                 hr = enumFilters.Next(1, filter, fetched);  
    37.                 DsError.ThrowExceptionForHR(hr);  
    38.                 filters[iPos] = filter[0];  
    39.                 iPos++;  
    40.             }  
    41.   
    42.             //此循环将新加入的SourceFilter加入到FilterGraph中,并将原SourceFilter移除并释放掉  
    43.             for (iPos = 0; iPos < iFiltCount; iPos++)  
    44.             {  
    45.                 m_FilterGraph.RemoveFilter(filters[iPos]);  
    46.                 if (filters[iPos] != m_currentSource)  
    47.                 {  
    48.                     m_FilterGraph.AddFilter(filters[iPos], null);  
    49.                 }  
    50.                 else  
    51.                 {  
    52.                     Marshal.ReleaseComObject(filters[iPos]);  
    53.                 }  
    54.             }  
    55.   
    56.             hr = m_FilterGraph.Render(nextOutPin);  
    57.             DsError.ThrowExceptionForHR(hr);  
    58.             m_currentSource = sourceFilter;  
    59.             sourceFilter = null;  
    60.   
    61.             m_mediaCtrl.Run();  
    62.   
    63.             if (enumFilters != null)  
    64.             {  
    65.                 Marshal.ReleaseComObject(enumFilters);  
    66.                 enumFilters = null;  
    67.             }  
    68.         }  


     



沪ICP备19023445号-2号
友情链接