掌握 dump filter 的用法:采集MPG,AVI和ASF的程序代码
2010-07-19 14:30
447 查看
http://www.360doc.com/content/08/0705/23/29694_1401883.shtml 此网址有源码
下面的程序代码示范了如何用VW卡采集MPG,AVI或ASF文件。 本程序是基于DirectShow通过VW卡的DirectShow Source Filter及相关Filter实现文件采集。 由于在这里AVI,ASF格式文件均为MPEG-4视频,所以,为简单起见,MPG文件也为MPEG-4视频,即前面文章所提高的MPEG-4 Embedded MPEG-2。
在程序运行后,首先创建一个Filter Graph,其中仅含有VW Source Filter并进行相应的设置,在本实例中设置的参数为: PAL复合视频输入,MPEG-4 Program编码,视频位速率为1M bps, 分辨率为720 x 576 , 音频位速率192K bps, 44.1K采样频率,MPEG-1 L2 音频编码(AVI文件的音频编码为PCM)。然后,根据选择不同的输出文件 格式,完成相应的Filte Graph。
1. 创建基本的Filter Graph
// We create a Filter graph including Source Filter only. // For every usage, we add other usaful filter into the graph // and remove useless filters. HRESULT CCap4Dlg::CraeteBaseCaptureGraph () { HRESULT hr; IBaseFilter *pSrc = NULL; if (m_pGraph) { SAFE_RELEASE (m_pGraph); } __try { // 创建Filter Graph CHECK_HR( hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, / IID_IGraphBuilder, (void **)&m_pGraph)); // 创建Source Filter实例并加入到Filter Graph中. CHECK_HR( hr = CoCreateInstance(CLSID_VWSource, NULL,CLSCTX_INPROC,IID_IBaseFilter,(void**)&pSrc)); CHECK_HR( hr = m_pGraph->AddFilter(pSrc, L"Source Filter")); ISrcControl * p_ISrc; CHECK_HR( hr = pSrc->QueryInterface (IID_ISrcControl, (void **)&p_ISrc)); // 获取接口指针 p_ISrc->SetAudioEncodeFormat (1); // MPEG-1 L2 p_ISrc->SetDeviceNumber (0); // 指定操作0号卡 p_ISrc->SetStreamType (3); // 指定MPEG-4 Program p_ISrc->SetVideoSource (VW_COMPOSITE); // 复合输入 p_ISrc->SetVideoStandard (VW_SRC_PAL); // PAL p_ISrc->SetVideoResolution (VW_VIDEO_RESOLUTION_FULL_720); // 720 x 576 p_ISrc->SetVideoBitrate (1000000); // 1M bps视频位速率 p_ISrc->SetAudioFrequency(VW_AUDIO_FREQ_44100); // 44.1KHz音频采样 p_ISrc->SetAudioBitrate(VW_AUDIO_BITRATE_192); // 192K 音频位速率 p_ISrc->SetParameterActive (); SAFE_RELEASE (p_ISrc); }__finally { SAFE_RELEASE(pSrc); if (FAILED(hr)){ SAFE_RELEASE(m_pGraph); } } #ifdef _DEBUG if (SUCCEEDED(hr)) AddGraphToRot(m_pGraph, &m_dwGraphRegister); #endif return hr; }
2. 创建MPG文件采集的Filter Graph
创建用于采集MPG文件的Filter Graph 比较简单,只需要加入Dump Filter,把它连接到Source Filter就行了。
// Remove all filters except source filter, then add Dump filter
HRESULT CCap4Dlg::UpdateCaptureGraphForMpg (const char * filename) { HRESULT hr = E_FAIL; IBaseFilter * pSrc = NULL; IBaseFilter * pDump = NULL; IFileSinkFilter *pSink = NULL; WCHAR wFile[512]; IPin * pSrcPin; IPin * pDstPin; #ifdef _DEBUG if (m_dwGraphRegister) { RemoveGraphFromRot(m_dwGraphRegister); m_dwGraphRegister = 0; } #endif __try { CHECK_HR (hr = m_pGraph->FindFilterByName (L"Source Filter", &pSrc)); TearDownGraph (pSrc); // Create and add Dump Filter CHECK_HR( hr = CoCreateInstance(CLSID_Dump,NULL,CLSCTX_INPROC,IID_IBaseFilter,(void**)&pDump)); CHECK_HR( hr = m_pGraph->AddFilter(pDump, L"Dump")); CHECK_HR( hr = pDump->QueryInterface (IID_IFileSinkFilter, (void **)&pSink)); MultiByteToWideChar(CP_ACP, 0, filename, -1, wFile, NUMELMS(wFile)); pSink->SetFileName (wFile, NULL); // Connect Source to Dump pSrcPin = GetOutPin (pSrc, 0); pDstPin = GetInPin (pDump, 0); CHECK_HR( hr = m_pGraph->Connect (pSrcPin, pDstPin)); }__finally { SAFE_RELEASE(pSink); SAFE_RELEASE(pDump); SAFE_RELEASE(pSrc); } #ifdef _DEBUG if (SUCCEEDED(hr)) AddGraphToRot(m_pGraph, &m_dwGraphRegister); #endif return hr; }
用于采集mpg文件的Filter Graph如下图
3. 创建AVI文件采集的Filter Graph
创建AVI文件采集的Filter Graph要稍微复杂一些,我们直接利用VW Source Video的Video和Audio输出Pin,把他们连接到AVI Mux filter,由于是采用PCM音频编码,我们要连接一个MPEG Audio Decoder Filter在VW Source Filter Pin2到AVI Mux。VW Source Filter的Pin0,即输出MPEG Multiplexing Stream 的Pin上实现的主线程,我们不能让他空在这儿,所以就用一个NullRenderer Filter连接到这个Pin上。最后把AVI Mux连接到File Witer filter。
// Remove all filters except source filter, then add AVI Mux filter HRESULT CCap4Dlg::UpdateCaptureGraphForAvi (const char * filename) { HRESULT hr = E_FAIL; IBaseFilter * pSrc = NULL; IBaseFilter * pFileWriter = NULL; IBaseFilter * pMux = NULL; IBaseFilter * pAudDec = NULL; IBaseFilter * pNullRnd = NULL; IFileSinkFilter *pSink = NULL; WCHAR wFile[512]; IPin * pSrcPin; IPin * pDstPin; #ifdef _DEBUG if (m_dwGraphRegister) { RemoveGraphFromRot(m_dwGraphRegister); m_dwGraphRegister = 0; } #endif __try { CHECK_HR (hr = m_pGraph->FindFilterByName (L"Source Filter", &pSrc)); TearDownGraph (pSrc); CHECK_HR( hr = CoCreateInstance(CLSID_NullRenderer, NULL,CLSCTX_INPROC,IID_IBaseFilter,(void**)&pNullRnd)); CHECK_HR( hr = m_pGraph->AddFilter(pNullRnd, L"Null Render")); pSrcPin = GetOutPin (pSrc, 0); pDstPin = GetInPin (pNullRnd, 0); CHECK_HR( hr = m_pGraph->Connect (pSrcPin, pDstPin)); CHECK_HR( hr = CoCreateInstance(CLSID_AviDest, NULL,CLSCTX_INPROC,IID_IBaseFilter,(void**)&pMux)); CHECK_HR( hr = m_pGraph->AddFilter(pMux, L"AVI Mux")); CHECK_HR( hr = CoCreateInstance(CLSID_CMpegAudioCodec,NULL,CLSCTX_INPROC,IID_IBaseFilter,(void**)&pAudDec)); CHECK_HR( hr = m_pGraph->AddFilter(pAudDec, L"Audio Decoder")); CHECK_HR( hr = CoCreateInstance(CLSID_FileWriter, NULL,CLSCTX_INPROC,IID_IBaseFilter,(void**)&pFileWriter)); CHECK_HR( hr = m_pGraph->AddFilter(pFileWriter, L"File Writer")); CHECK_HR( hr = pFileWriter->QueryInterface (IID_IFileSinkFilter, (void **)&pSink)); MultiByteToWideChar(CP_ACP, 0,filename, -1, wFile, NUMELMS(wFile)); pSink->SetFileName (wFile, NULL); pSrcPin = GetOutPin (pSrc, 1); pDstPin = GetInPin (pMux, 0); CHECK_HR( hr = m_pGraph->Connect (pSrcPin, pDstPin)); pSrcPin = GetOutPin (pSrc, 2); pDstPin = GetInPin (pAudDec, 0); CHECK_HR( hr = m_pGraph->Connect (pSrcPin, pDstPin)); pSrcPin = GetOutPin (pAudDec, 0); pDstPin = GetInPin (pMux, 1); CHECK_HR( hr = m_pGraph->Connect (pSrcPin, pDstPin)); pSrcPin = GetOutPin (pMux, 0); pDstPin = GetInPin (pFileWriter, 0); CHECK_HR( hr = m_pGraph->Connect (pSrcPin, pDstPin)); }__finally { SAFE_RELEASE(pMux); SAFE_RELEASE(pNullRnd); SAFE_RELEASE(pFileWriter); SAFE_RELEASE(pSink); SAFE_RELEASE(pAudDec); SAFE_RELEASE(pSrc); } #ifdef _DEBUG if (SUCCEEDED(hr)) AddGraphToRot(m_pGraph, &m_dwGraphRegister); #endif return hr; }
创建后的Filter Graph如下图:
4. 创建ASF文件采集的Filter Graph.
创建ASF文件采的Filter Graph和前面的AVI文件采集Filter Graph差不多,但ASF Writer中包含了文件存储,所以不需要 File Writer或Dump这样的文件输出Filter了.
// Remove all filters except source filter, then add ASF Mux filter HRESULT CCap4Dlg::UpdateCaptureGraphForAsf (const char * filename) { HRESULT hr = E_FAIL; IBaseFilter * pSrc = NULL; IBaseFilter * pMux = NULL; IBaseFilter * pNullRnd = NULL; IFileSinkFilter *pSink = NULL; WCHAR wFile[512]; IPin * pSrcPin; IPin * pDstPin; #ifdef _DEBUG if (m_dwGraphRegister) { RemoveGraphFromRot(m_dwGraphRegister); m_dwGraphRegister = 0; } #endif __try { CHECK_HR (hr = m_pGraph->FindFilterByName (L"Source Filter", &pSrc)); TearDownGraph (pSrc); CHECK_HR( hr = CoCreateInstance(CLSID_NullRenderer, NULL,CLSCTX_INPROC,IID_IBaseFilter, (void**)&pNullRnd)); CHECK_HR( hr = m_pGraph->AddFilter(pNullRnd, L"Null Render")); pSrcPin = GetOutPin (pSrc, 0); pDstPin = GetInPin (pNullRnd, 0); CHECK_HR( hr = m_pGraph->Connect (pSrcPin, pDstPin)); CHECK_HR( hr = CoCreateInstance(CLSID_ASFWRITER, NULL,CLSCTX_INPROC,IID_IBaseFilter,(void**)&pMux)); CHECK_HR( hr = m_pGraph->AddFilter(pMux, L"ASF Mux")); CHECK_HR( hr = pMux->QueryInterface (IID_IFileSinkFilter, (void **)&pSink)); MultiByteToWideChar(CP_ACP, 0,filename, -1, wFile, NUMELMS(wFile)); pSink->SetFileName (wFile, NULL); pSrcPin = GetOutPin (pSrc, 1); pDstPin = GetInPin (pMux, 0); CHECK_HR( hr = m_pGraph->Connect (pSrcPin, pDstPin)); pSrcPin = GetOutPin (pSrc, 2); pDstPin = GetInPin (pMux, 1); CHECK_HR( hr = m_pGraph->Connect (pSrcPin, pDstPin)); }__finally { SAFE_RELEASE(pMux); SAFE_RELEASE(pNullRnd); SAFE_RELEASE(pSink); SAFE_RELEASE(pSrc); } #ifdef _DEBUG if (SUCCEEDED(hr)) AddGraphToRot(m_pGraph, &m_dwGraphRegister); #endif return hr; }
创建后的Filter Graph如下图:
相关文章推荐
- asp 网页视频播放器程序代码(通用代码),支持avi,wmv,asf,mov,rm,ra,ram等
- SAP程序代码中RANGE表的用法禁忌
- try catch finally 的用法,你知道多少?最详细、最到位的讲解,配合代码实例讲解,让你轻松掌握和理解
- mpg,avi,wmv格式网页播放代码
- share一段采集论坛程序的代码
- php 论坛采集程序 模拟登陆,抓取页面 实现代码
- 让程序在崩溃时体面的退出之终极解决方案(SEH+Dump+Unhandled Exception Filter)
- Android深入浅出系列之实例应用—开机就运行自定义的程序BroadcastReceiver和intent-filter的用法
- 在线播放器代码大全(avi/mpg/rm/wmv/)
- socket select用法:100行代码实现网络数据转发程序
- 调试release版本程序dump时出现的代码定位不准确问题
- 让程序在崩溃时体面的退出之终极解决方案(SEH+Dump+Unhandled Exception Filter)
- 截取视频文件第一桢的图片和转换视频格式文件为flv(支持文件格式:asf,avi,mpg,flv,3gp,mov,wmv)
- 一段采集程序代码
- ASP下实现自动采集程序及入库的代码
- Android开发之recycleView详解代码,看完包你熟练掌握recycleView的用法。转自网络经典文章
- html制作简单框架网页二 实现自己的影音驿站 操作步骤及源文件下载 (可播放mp4、avi、mpg、asx、swf各种文件的视频播放代码)
- xcode反汇编调试iOS模拟器程序(八)反汇编自己的代码来掌握规则
- [C#]ADO.NET #3 (GridView + SqlDataSource)完全手写、后置程序代码,兼论 SqlDataSource与UpdateParameter/DeleteParameter的用法
- dump文件定位程序崩溃代码行