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

来源:互联网 发布:网络作品版权出售 编辑:程序博客网 时间:2024/06/07 02:43

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


 

阅读全文
0 0
原创粉丝点击