我用directshow做了个视频采集的程序,因为是初学,东凑西凑终于把预览和采集这块做好了,现在就是差个压缩,用ffdshow进行压缩,编码器已下好,我现在用了一个CSDN上的一个网友给我的压缩FILTER,但是感觉添加上去自己没有添加正确,有点糊,导致现在直接运行程序就报错,代码如下。压缩FilterBOOL CCaptureVideo::MakeEncoder()
{
// if(pEncoderFilter)
// return TRUE; HRESULT hr;
ICreateDevEnum *m_pSysDevEnum = NULL;
IEnumMoniker *pEnumCat = NULL; hr = CoCreateInstance(CLSID_SystemDeviceEnum,NULL,CLSCTX_INPROC,IID_ICreateDevEnum,(void**)&m_pSysDevEnum);
if(FAILED(hr))
{
return FALSE;
}
hr = m_pSysDevEnum->CreateClassEnumerator(CLSID_VideoCompressorCategory,&pEnumCat,0);
if(FAILED(hr))
{
return FALSE;
}
IMoniker *pMoniker;
ULONG cFetched;
VARIANT varName = {0};
while(pEnumCat->Next(1,&pMoniker,&cFetched) == S_OK)
{
if(!pMoniker)
{
return FALSE;
}
IPropertyBag *pPropBag;
hr = pMoniker->BindToStorage(0,0,IID_IPropertyBag,(void**)&pPropBag);
if(FAILED(hr))
{
continue;
}
varName.vt = VT_BSTR;
hr = pPropBag->Read(L"FriendlyName",&varName,0);
if(FAILED(hr))
{
continue;
}
CString str(varName.bstrVal);
SysFreeString(varName.bstrVal); if(str == "ffdshow video encoder") //压缩器名称
{
VARIANT varFilterClsid;
varFilterClsid.vt = VT_BSTR;
hr = pMoniker->BindToObject(0,0,IID_IBaseFilter,(void**)&pEncoderFilter);
if(SUCCEEDED(hr))
{
SAFE_RELEASE(pPropBag);
SAFE_RELEASE(pMoniker); hr = m_pGB->AddFilter(pEncoderFilter,L"EncodeFilter");
if(hr == NOERROR)
{
return TRUE;
}
}
break;
}
}
return FALSE;
}然后我在Init方法中添加的RenderStream,如下HRESULT CCaptureVideo::Init(int iDeviceID, HWND hWnd)
{
HRESULT hr;
hr = InitCaptureGraphBuilder();
if (FAILED(hr))
{
AfxMessageBox("Failed to get video interfaces!");
return hr;
}
// Bind Device Filter. We know the device because the id was passed in
if(!BindFilter(iDeviceID, &m_pBF))return S_FALSE;
hr = m_pGB->AddFilter(m_pBF, L"Capture Filter");
// hr = m_pCapture->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,
// m_pBF, NULL, NULL);
// create a sample grabber// hr = m_pGrabber.CoCreateInstance( CLSID_SampleGrabber );
hr = CoCreateInstance( CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, IID_ISampleGrabber, (void**)&m_pGrabber );
if( !m_pGrabber )
{
AfxMessageBox("Fail to create SampleGrabber, maybe qedit.dll is not registered?");
return hr;
} CComQIPtr< IBaseFilter, &IID_IBaseFilter > pGrabBase( m_pGrabber ); //设置视频格式
AM_MEDIA_TYPE mt;
ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
mt.majortype = MEDIATYPE_Video;
mt.subtype = MEDIASUBTYPE_RGB24;
hr = m_pGrabber->SetMediaType(&mt);
if( FAILED( hr ) )
{
AfxMessageBox("Fail to set media type!");
return hr;
}
hr = m_pGB->AddFilter( pGrabBase, L"Grabber" );
if( FAILED( hr ) )
{
AfxMessageBox("Fail to put sample grabber in graph");
return hr;
}
// try to render preview/capture pin
hr = m_pCapture->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,m_pBF,pGrabBase,NULL);
if( FAILED( hr ) )
{
hr = m_pCapture->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,m_pBF,pGrabBase,NULL);
hr = m_pCapture->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,m_pBF,pEncoderFilter,pMux);
}
if( FAILED( hr ) )
{
AfxMessageBox("Can’t build the graph");
return hr;
}
hr = m_pGrabber->GetConnectedMediaType( &mt );
if ( FAILED( hr) )
{
AfxMessageBox("Failt to read the connected media type");
return hr;
}
VIDEOINFOHEADER * vih = (VIDEOINFOHEADER*) mt.pbFormat;
mCB.lWidth = vih->bmiHeader.biWidth;
mCB.lHeight = vih->bmiHeader.biHeight;
FreeMediaType(mt);
hr = m_pGrabber->SetBufferSamples( FALSE );
hr = m_pGrabber->SetOneShot( FALSE );
hr = m_pGrabber->SetCallback( &mCB, 1 );
//设置视频捕捉窗口
m_hWnd = hWnd ;
SetupVideoWindow();
hr = m_pMC->Run();//开始视频捕捉
if(FAILED(hr))
{
AfxMessageBox("Couldn't run the graph!");
return hr;
}
return S_OK;
}我自己原来还有一个枚举设备的EnumDevices,代码如下int CCaptureVideo::EnumDevices(HWND hList)
{
if (!hList)
return -1;
int id = 0;
//枚举视频扑捉设备
ICreateDevEnum *pCreateDevEnum;
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,IID_ICreateDevEnum, (void**)&pCreateDevEnum);
if (hr != NOERROR)return -1;
CComPtr<IEnumMoniker> pEm;
hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEm, 0);
if (hr != NOERROR)return -1;
pEm->Reset();
ULONG cFetched;
IMoniker *pM;
while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK)
{
IPropertyBag *pBag;
hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);
if(SUCCEEDED(hr))
{
VARIANT var;
var.vt = VT_BSTR;
hr = pBag->Read(L"FriendlyName", &var, NULL);
if (hr == NOERROR)
{
TCHAR str[2048];
id++;
WideCharToMultiByte(CP_ACP,0,var.bstrVal, -1, str, 2048, NULL, NULL);
::SendMessage(hList, CB_ADDSTRING, 0,(LPARAM)str);
SysFreeString(var.bstrVal);
}
pBag->Release();
}
pM->Release();
}
return id;
}然后我现在在OnInitDialog方法中添加
m_cap->MakeEncoder();
m_cap->EnumDevices(pHnd);
m_listCtrl.SetCurSel (0);
int id = m_listCtrl.GetCurSel(); //获取当前选中的视频设备
// m_cap.PreviewImages(id , VideoHnd); //开始预览视频
m_cap->Init(id,VideoHnd); //开始预览视频一运行程序就报错,错误定位在
压缩Filter的hr = m_pGB->AddFilter(pEncoderFilter,L"EncodeFilter");这句话上面
请大家帮我看看错在哪了,万分感谢
{
// if(pEncoderFilter)
// return TRUE; HRESULT hr;
ICreateDevEnum *m_pSysDevEnum = NULL;
IEnumMoniker *pEnumCat = NULL; hr = CoCreateInstance(CLSID_SystemDeviceEnum,NULL,CLSCTX_INPROC,IID_ICreateDevEnum,(void**)&m_pSysDevEnum);
if(FAILED(hr))
{
return FALSE;
}
hr = m_pSysDevEnum->CreateClassEnumerator(CLSID_VideoCompressorCategory,&pEnumCat,0);
if(FAILED(hr))
{
return FALSE;
}
IMoniker *pMoniker;
ULONG cFetched;
VARIANT varName = {0};
while(pEnumCat->Next(1,&pMoniker,&cFetched) == S_OK)
{
if(!pMoniker)
{
return FALSE;
}
IPropertyBag *pPropBag;
hr = pMoniker->BindToStorage(0,0,IID_IPropertyBag,(void**)&pPropBag);
if(FAILED(hr))
{
continue;
}
varName.vt = VT_BSTR;
hr = pPropBag->Read(L"FriendlyName",&varName,0);
if(FAILED(hr))
{
continue;
}
CString str(varName.bstrVal);
SysFreeString(varName.bstrVal); if(str == "ffdshow video encoder") //压缩器名称
{
VARIANT varFilterClsid;
varFilterClsid.vt = VT_BSTR;
hr = pMoniker->BindToObject(0,0,IID_IBaseFilter,(void**)&pEncoderFilter);
if(SUCCEEDED(hr))
{
SAFE_RELEASE(pPropBag);
SAFE_RELEASE(pMoniker); hr = m_pGB->AddFilter(pEncoderFilter,L"EncodeFilter");
if(hr == NOERROR)
{
return TRUE;
}
}
break;
}
}
return FALSE;
}然后我在Init方法中添加的RenderStream,如下HRESULT CCaptureVideo::Init(int iDeviceID, HWND hWnd)
{
HRESULT hr;
hr = InitCaptureGraphBuilder();
if (FAILED(hr))
{
AfxMessageBox("Failed to get video interfaces!");
return hr;
}
// Bind Device Filter. We know the device because the id was passed in
if(!BindFilter(iDeviceID, &m_pBF))return S_FALSE;
hr = m_pGB->AddFilter(m_pBF, L"Capture Filter");
// hr = m_pCapture->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,
// m_pBF, NULL, NULL);
// create a sample grabber// hr = m_pGrabber.CoCreateInstance( CLSID_SampleGrabber );
hr = CoCreateInstance( CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, IID_ISampleGrabber, (void**)&m_pGrabber );
if( !m_pGrabber )
{
AfxMessageBox("Fail to create SampleGrabber, maybe qedit.dll is not registered?");
return hr;
} CComQIPtr< IBaseFilter, &IID_IBaseFilter > pGrabBase( m_pGrabber ); //设置视频格式
AM_MEDIA_TYPE mt;
ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
mt.majortype = MEDIATYPE_Video;
mt.subtype = MEDIASUBTYPE_RGB24;
hr = m_pGrabber->SetMediaType(&mt);
if( FAILED( hr ) )
{
AfxMessageBox("Fail to set media type!");
return hr;
}
hr = m_pGB->AddFilter( pGrabBase, L"Grabber" );
if( FAILED( hr ) )
{
AfxMessageBox("Fail to put sample grabber in graph");
return hr;
}
// try to render preview/capture pin
hr = m_pCapture->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,m_pBF,pGrabBase,NULL);
if( FAILED( hr ) )
{
hr = m_pCapture->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,m_pBF,pGrabBase,NULL);
hr = m_pCapture->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,m_pBF,pEncoderFilter,pMux);
}
if( FAILED( hr ) )
{
AfxMessageBox("Can’t build the graph");
return hr;
}
hr = m_pGrabber->GetConnectedMediaType( &mt );
if ( FAILED( hr) )
{
AfxMessageBox("Failt to read the connected media type");
return hr;
}
VIDEOINFOHEADER * vih = (VIDEOINFOHEADER*) mt.pbFormat;
mCB.lWidth = vih->bmiHeader.biWidth;
mCB.lHeight = vih->bmiHeader.biHeight;
FreeMediaType(mt);
hr = m_pGrabber->SetBufferSamples( FALSE );
hr = m_pGrabber->SetOneShot( FALSE );
hr = m_pGrabber->SetCallback( &mCB, 1 );
//设置视频捕捉窗口
m_hWnd = hWnd ;
SetupVideoWindow();
hr = m_pMC->Run();//开始视频捕捉
if(FAILED(hr))
{
AfxMessageBox("Couldn't run the graph!");
return hr;
}
return S_OK;
}我自己原来还有一个枚举设备的EnumDevices,代码如下int CCaptureVideo::EnumDevices(HWND hList)
{
if (!hList)
return -1;
int id = 0;
//枚举视频扑捉设备
ICreateDevEnum *pCreateDevEnum;
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,IID_ICreateDevEnum, (void**)&pCreateDevEnum);
if (hr != NOERROR)return -1;
CComPtr<IEnumMoniker> pEm;
hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEm, 0);
if (hr != NOERROR)return -1;
pEm->Reset();
ULONG cFetched;
IMoniker *pM;
while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK)
{
IPropertyBag *pBag;
hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);
if(SUCCEEDED(hr))
{
VARIANT var;
var.vt = VT_BSTR;
hr = pBag->Read(L"FriendlyName", &var, NULL);
if (hr == NOERROR)
{
TCHAR str[2048];
id++;
WideCharToMultiByte(CP_ACP,0,var.bstrVal, -1, str, 2048, NULL, NULL);
::SendMessage(hList, CB_ADDSTRING, 0,(LPARAM)str);
SysFreeString(var.bstrVal);
}
pBag->Release();
}
pM->Release();
}
return id;
}然后我现在在OnInitDialog方法中添加
m_cap->MakeEncoder();
m_cap->EnumDevices(pHnd);
m_listCtrl.SetCurSel (0);
int id = m_listCtrl.GetCurSel(); //获取当前选中的视频设备
// m_cap.PreviewImages(id , VideoHnd); //开始预览视频
m_cap->Init(id,VideoHnd); //开始预览视频一运行程序就报错,错误定位在
压缩Filter的hr = m_pGB->AddFilter(pEncoderFilter,L"EncodeFilter");这句话上面
请大家帮我看看错在哪了,万分感谢
解决方案 »
- 问个基础问题:vc2010无法保存历史打开工程记录
- 关于360度环绕图片处理的问题,高人速来!在线等解决
- SetWindowsHookEx 的问题
- 跪求RichEdit中显示gif的方法
- 根据发展的需要,本人申请基础版版主,敬请各位支持。鞠躬
- ###求filemon源代码###
- 哪种网络协议最快(稳定是次要的),如何在该网络协议下快速传递数据。
- 高分请教:如何配置windows2000的autoexec.nt和config.nt??
- 快,如何判断一个文件夹是否存在?
- 请问在VC中CDC有什么函数可以用来在OnDraw中清屏,即将CView类窗口恢复纯白。
- VC6下如何读写超过4G的文件
- 怎么将doc转换成纯txt??
IBaseFilter* pEncoderFilter;
IBaseFilter *pMux;//捕获视频为AVI文件
HWND m_hWnd;
IGraphBuilder *m_pGB;
ICaptureGraphBuilder2* m_pCapture;
IBaseFilter* m_pBF;
IMediaControl* m_pMC;
IVideoWindow* m_pVW;
ISampleGrabber* m_pGrabber;
int m_IMonikerNum;
IMoniker *rgpmVideo[10];
CTHIRD::OnInitDialog() line 76
AfxDlgProc(HWND__ * 0x00130736, unsigned int 272, unsigned int 1115950, unsigned int 1115950) line 35 + 14 bytes
USER32! 77d18734()
USER32! 77d2413c()
USER32! 77d23b30()
USER32! 77d3e599()
USER32! 77d18734()
USER32! 77d18816()
USER32! 77d2a013()
USER32! 77d2a998()
CWnd::DefWindowProcA(unsigned int 272, unsigned int 1115950, long 0) line 1011 + 32 bytes
CWnd::Default() line 258
CDialog::HandleInitDialog(unsigned int 1115950, unsigned int 1115950) line 624 + 8 bytes
CWnd::OnWndMsg(unsigned int 272, unsigned int 1115950, long 0, long * 0x0012ea80) line 1826 + 17 bytes
CWnd::WindowProc(unsigned int 272, unsigned int 1115950, long 0) line 1596 + 30 bytes
AfxCallWndProc(CWnd * 0x0012fa8c {CTHIRD hWnd=???}, HWND__ * 0x00130736, unsigned int 272, unsigned int 1115950, long 0) line 215 + 26 bytes
AfxWndProc(HWND__ * 0x00130736, unsigned int 272, unsigned int 1115950, long 0) line 379
USER32! 77d18734()
USER32! 77d18816()
USER32! 77d2a013()
USER32! 77d2a998()
SKINPPWTL! 1004140a()
SKINPPWTL! 1004143d()
USER32! 77d18734()
USER32! 77d18816()
USER32! 77d28ea0()
USER32! 77d28eec()
NTDLL! 7c92e473()
USER32! 77d2651a()
USER32! 77d2683e()
USER32! 77d39b43()
CWnd::CreateDlgIndirect(const DLGTEMPLATE * 0x00185828, CWnd * 0x0012fa30 {CVCCaptureDlg hWnd=???}, HINSTANCE__ * 0x00400000) line 327 + 36 bytes
CDialog::CreateIndirect(const DLGTEMPLATE * 0x0062f510, CWnd * 0x0012fa30 {CVCCaptureDlg hWnd=???}, void * 0x00000000, HINSTANCE__ * 0x00400000) line 223
CDialog::CreateIndirect(void * 0x0062f510, CWnd * 0x00000000 {CWnd hWnd=???}, HINSTANCE__ * 0x00400000) line 200 + 22 bytes
CDialog::Create(const char * 0x00000083, CWnd * 0x00000000 {CWnd hWnd=???}) line 182 + 20 bytes
CDialog::Create(unsigned int 131, CWnd * 0x00000000 {CWnd hWnd=???}) line 543 + 29 bytes
CVCCaptureDlg::OnInitDialog() line 131
AfxDlgProc(HWND__ * 0x000803d4, unsigned int 272, unsigned int 656320, unsigned int 656320) line 35 + 14 bytes
USER32! 77d18734()
USER32! 77d2413c()
USER32! 77d23b30()
USER32! 77d3e599()
USER32! 77d18734()
USER32! 77d18816()
USER32! 77d2a013()
USER32! 77d2a998()
CWnd::DefWindowProcA(unsigned int 272, unsigned int 656320, long 0) line 1011 + 32 bytes
CWnd::Default() line 258
CDialog::HandleInitDialog(unsigned int 656320, unsigned int 656320) line 624 + 8 bytes
CWnd::OnWndMsg(unsigned int 272, unsigned int 656320, long 0, long * 0x0012f440) line 1826 + 17 bytes
CWnd::WindowProc(unsigned int 272, unsigned int 656320, long 0) line 1596 + 30 bytes
AfxCallWndProc(CWnd * 0x0012fa30 {CVCCaptureDlg hWnd=???}, HWND__ * 0x000803d4, unsigned int 272, unsigned int 656320, long 0) line 215 + 26 bytes
AfxWndProc(HWND__ * 0x000803d4, unsigned int 272, unsigned int 656320, long 0) line 379
USER32! 77d18734()
USER32! 77d18816()
USER32! 77d2a013()
USER32! 77d2a998()
SKINPPWTL! 1004140a()
SKINPPWTL! 1004143d()
USER32! 77d18734()
USER32! 77d18816()
USER32! 77d28ea0()
USER32! 77d28eec()
NTDLL! 7c92e473()
USER32! 77d2651a()
USER32! 77d2683e()
USER32! 77d39b43()
CWnd::CreateDlgIndirect(const DLGTEMPLATE * 0x0062ee28, CWnd * 0x00000000 {CWnd hWnd=???}, HINSTANCE__ * 0x00400000) line 327 + 36 bytes
CDialog::DoModal() line 531 + 32 bytes
CVCCaptureApp::InitInstance() line 78 + 11 bytes
AfxWinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x00141f1c, int 1) line 39 + 11 bytes
WinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x00141f1c, int 1) line 30
WinMainCRTStartup() line 198 + 54 bytes
KERNEL32! 7c817077()
指向的地方就是 hr = m_pGB->AddFilter(pEncoderFilter,L"EncodeFilter");
在压缩Filter中BOOL CCaptureVideo::MakeEncoder()
{
// if(pEncoderFilter)
// return TRUE; HRESULT hr;
ICreateDevEnum *m_pSysDevEnum = NULL;
IEnumMoniker *pEnumCat = NULL; hr = CoCreateInstance(CLSID_SystemDeviceEnum,NULL,CLSCTX_INPROC,IID_ICreateDevEnum,(void**)&m_pSysDevEnum); if(FAILED(hr))
{
return FALSE;
}
hr = m_pSysDevEnum->CreateClassEnumerator(CLSID_VideoCompressorCategory,&pEnumCat,0);
if(FAILED(hr))
{
return FALSE;
}
IMoniker *pMoniker;
ULONG cFetched;
VARIANT varName = {0};
while(pEnumCat->Next(1,&pMoniker,&cFetched) == S_OK)
{
if(!pMoniker)
{
return FALSE;
}
IPropertyBag *pPropBag;
hr = pMoniker->BindToStorage(0,0,IID_IPropertyBag,(void**)&pPropBag);
if(FAILED(hr))
{
continue;
}
varName.vt = VT_BSTR;
hr = pPropBag->Read(L"FriendlyName",&varName,0);
if(FAILED(hr))
{
continue;
}
CString str(varName.bstrVal);
SysFreeString(varName.bstrVal); if(str == "ffdshow video encoder") //压缩器名称
{
VARIANT varFilterClsid;
varFilterClsid.vt = VT_BSTR;
hr = pMoniker->BindToObject(0,0,IID_IBaseFilter,(void**)&pEncoderFilter);
if(SUCCEEDED(hr))
{
SAFE_RELEASE(pPropBag);
SAFE_RELEASE(pMoniker);
// hr = m_pGB->AddFilter(pEncoderFilter,L"EncodeFilter");
// if(hr == NOERROR)
// {
return TRUE;
// }
}
break;
}
}
return FALSE;
}把这个添加过滤器的话注释掉了
然后在Init方法中加上HRESULT CCaptureVideo::Init(int iDeviceID, HWND hWnd)
{
HRESULT hr;
hr = InitCaptureGraphBuilder();
if (FAILED(hr))
{
AfxMessageBox("Failed to get video interfaces!");
return hr;
}
if(MakeEncoder())
{
hr = m_pGB->AddFilter(pEncoderFilter, L"EncodeFilter");
}
// Bind Device Filter. We know the device because the id was passed in
if(!BindFilter(iDeviceID, &m_pBF))return S_FALSE;
hr = m_pGB->AddFilter(m_pBF, L"Capture Filter");
// hr = m_pCapture->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,
// m_pBF, NULL, NULL);
// create a sample grabber// hr = m_pGrabber.CoCreateInstance( CLSID_SampleGrabber );
hr = CoCreateInstance( CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, IID_ISampleGrabber, (void**)&m_pGrabber );
if( !m_pGrabber )
{
AfxMessageBox("Fail to create SampleGrabber, maybe qedit.dll is not registered?");
return hr;
} CComQIPtr< IBaseFilter, &IID_IBaseFilter > pGrabBase( m_pGrabber ); //设置视频格式
AM_MEDIA_TYPE mt;
ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
mt.majortype = MEDIATYPE_Video;
mt.subtype = MEDIASUBTYPE_RGB24;
hr = m_pGrabber->SetMediaType(&mt);
if( FAILED( hr ) )
{
AfxMessageBox("Fail to set media type!");
return hr;
}
hr = m_pGB->AddFilter( pGrabBase, L"Grabber" );
if( FAILED( hr ) )
{
AfxMessageBox("Fail to put sample grabber in graph");
return hr;
}
// try to render preview/capture pin
hr = m_pCapture->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,m_pBF,pGrabBase,NULL);
if( FAILED( hr ) )
{
hr = m_pCapture->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,m_pBF,pGrabBase,NULL);
// hr = m_pCapture->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,m_pBF,pEncoderFilter,pMux);
}
if( FAILED( hr ) )
{
AfxMessageBox("Can’t build the graph");
return hr;
}
hr = m_pGrabber->GetConnectedMediaType( &mt );
if ( FAILED( hr) )
{
AfxMessageBox("Failt to read the connected media type");
return hr;
}
VIDEOINFOHEADER * vih = (VIDEOINFOHEADER*) mt.pbFormat;
mCB.lWidth = vih->bmiHeader.biWidth;
mCB.lHeight = vih->bmiHeader.biHeight;
FreeMediaType(mt);
hr = m_pGrabber->SetBufferSamples( FALSE );
hr = m_pGrabber->SetOneShot( FALSE );
hr = m_pGrabber->SetCallback( &mCB, 1 );
//设置视频捕捉窗口
m_hWnd = hWnd ;
SetupVideoWindow();
hr = m_pMC->Run();//开始视频捕捉
if(FAILED(hr))
{
AfxMessageBox("Couldn't run the graph!");
return hr;
}
return S_OK;
}
在这里做个判断然后加上,我在调试的时候会成功的进入if里面。
然后在压缩方法那里我是这样写的HRESULT CCaptureVideo::CaptureImagesToAVI(CString inFileName)
{
HRESULT hr=0;
m_pMC->Stop();
//先停止视频//设置文件名,注意第二个参数的类型
hr = m_pCapture->SetOutputFileName( &MEDIASUBTYPE_Avi,inFileName.AllocSysString(), &pMux, NULL );
//渲染媒体,链接所有滤波器
// hr = m_pCapture->RenderStream( &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pBF, NULL, pMux );
hr = m_pCapture->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,m_pBF,pEncoderFilter,pMux);
pMux->Release();
m_pMC->Run();//回复视频
return hr;
}我把AddFilter方法写在这里,就不会报错了,可是好像只压缩一帧就不压缩了,诚心的请求各位大大帮帮我,都快急死了呢,谢谢了
if(FAILED(hr))
{
return FALSE;
}
hr = m_pSysDevEnum->CreateClassEnumerator(CLSID_VideoCompressorCategory,&pEnumCat,0);
if(FAILED(hr))
{
return FALSE;
}
IMoniker *pMoniker;
ULONG cFetched;
VARIANT varName = {0};
while(pEnumCat->Next(1,&pMoniker,&cFetched) == S_OK)这样的遍历代码,但是我原来的EnumDevice方法里面也有这样类似的int CCaptureVideo::EnumDevices(HWND hList)
{
if (!hList)
return -1;
int id = 0;
//枚举视频扑捉设备
ICreateDevEnum *pCreateDevEnum;
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,IID_ICreateDevEnum, (void**)&pCreateDevEnum);
if (hr != NOERROR)return -1;
CComPtr<IEnumMoniker> pEm;
hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEm, 0);
if (hr != NOERROR)return -1;
pEm->Reset();
ULONG cFetched;
IMoniker *pM;
while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK)
{我就不知道该怎么加上这个filter了,我把它这个MakeEncoder()写成了一个方法,然后在Init这个方法里添加AddFilter,
这样HRESULT CCaptureVideo::Init(int iDeviceID, HWND hWnd)
{
HRESULT hr;
hr = InitCaptureGraphBuilder();
if (FAILED(hr))
{
AfxMessageBox("Failed to get video interfaces!");
return hr;
}
if(MakeEncoder())
{
hr = m_pGB->AddFilter(pEncoderFilter, L"EncodeFilter");
}然后在开始采集的时候,就是点击录制按钮的地方用的是这样的代码HRESULT CCaptureVideo::CaptureImagesToAVI(CString inFileName)
{
HRESULT hr=0;
m_pMC->Stop();
//先停止视频//设置文件名,注意第二个参数的类型
hr = m_pCapture->SetOutputFileName( &MEDIASUBTYPE_Avi,inFileName.AllocSysString(), &pMux, NULL );
//渲染媒体,链接所有滤波器
// hr = m_pCapture->RenderStream( &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pBF, NULL, pMux );
hr = m_pCapture->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,m_pBF,pEncoderFilter,pMux);
pMux->Release();
m_pMC->Run();//回复视频
return hr;
}红色的就是后来添加的,蓝色的就是没有添加压缩的,但是这样添加上去以后,可以预览,然后点击录制,马上影像就卡在那不动,我看存放录制文件的文件夹也生生成了AVI,但是都是64KB,而且不能播放
m_pMC->Stop();
//先停止视频//设置文件名,注意第二个参数的类型
hr = m_pCapture->SetOutputFileName( &MEDIASUBTYPE_Avi,inFileName.AllocSysString(), &pMux, NULL );
//渲染媒体,链接所有滤波器
// hr = m_pCapture->RenderStream( &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pBF, NULL, pMux );
hr = m_pCapture->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,m_pBF,pEncoderFilter,pMux);
pMux->Release();
m_pMC->Run();//回复视频
return hr;点击录制后,它先调用m_pMC->Stop();,然后视频就不动了,本来应该在开始采集的时候会继续调用m_pMC->Run();//回复视频的,但是应该是在hr = m_pCapture->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,m_pBF,pEncoderFilter,pMux);这个地方出了问题,导致没有继续往下走,真的快糊掉了,希望高手能帮帮我
ICreateDevEnum *pSysDevEnum = NULL;
hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum, (void **)&pSysDevEnum);
// Obtain a class enumerator for the video compressor category.
IEnumMoniker *pEnumCat = NULL;
hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoCompressorCategory, &pEnumCat, 0);
if (hr == S_OK)
{
// Enumerate the monikers.
IMoniker *pMoniker;
ULONG cFetched;
while(pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK)
{
IPropertyBag *pPropBag;
pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pPropBag);
// To retrieve the friendly name of the filter, do the following:
VARIANT varName;
VariantInit(&varName);
hr = pPropBag->Read(L"FriendlyName", &varName, 0);
if (SUCCEEDED(hr))
{
CString str(varName.bstrVal);
SysFreeString(varName.bstrVal);
if(str == "Microsoft MPEG-4 Video Codec V2")
{
hr = pMoniker->BindToObject(0,0,IID_IBaseFilter,(void**)&pEncoderFilter);
if(hr == S_OK)
{
hr = m_pGB->AddFilter(pEncoderFilter,L"EncodeFilter");
}
}
}
VariantClear(&varName);
// To create an instance of the filter, do the following:
IBaseFilter *pFilter;
pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter, (void**)&pFilter);
// Now add the filter to the graph. Remember to release pFilter later.
// Clean up.
pPropBag->Release();
pMoniker->Release();
}
pEnumCat->Release();
}
pSysDevEnum->Release();
但是每次运行到hr = m_pGB->AddFilter(pEncoderFilter,L"EncodeFilter");这句话的时候就会出错,弹出的错误是
‘0x004060614f’指令引用的‘0x00000000’内存,该内存不能为'read'.