课本剧放下你的鞭子:使用VideoWave采集不同格式的视音频文件 (3)

来源:百度文库 编辑:九乡新闻网 时间:2024/04/29 20:26:19

Extend your system with Video
主页
关于我们
产品 / 方案
技术支持
最新事件
如何购买
联系我们
网上购买
使用VideoWave采集不同格式的视音频文件 (3)
采集MPG,AVI和ASF的程序代码
上一篇:从MPEG文件中解析出视频流和音频流
采集MPG, AVI或ASF文件
下面的程序代码示范了如何用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如下图:

下载可执行文件
下载源代码
Copyright © 2006 TechThink All rights reserved.
网上购买

关于我们 |产品 |最新事件 |技术支持 |如何购买 |联系我们