16,473
社区成员
发帖
与我相关
我的任务
分享
//枚举压缩器
////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT hr;
ICreateDevEnum *pSysDevEnum = NULL; //创建枚举器指针
pCompress = 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 == "ffdshow video encoder")
{
hr = pMoniker->BindToObject(0,0,IID_IBaseFilter,(void**)&pCompress);
pMoniker->Release();
break;
}
}
VariantClear(&varName);
}
pEnumCat->Release();
pMoniker->Release();
m_pGB->AddFilter(pCompress,L"Compressor"); //添加过滤器
HRESULT ret =NULL;
IPin * pSourceOut = NULL;
IPin* pCompressIn,* pCompressOut=NULL;
IAMVideoCompression * pAMCompress = NULL; //压缩参数设置
pCompressIn = FindPin(pCompress,PINDIR_INPUT) ; //查找输入引脚
pCompressOut = FindPin(pCompress,PINDIR_OUTPUT); //查找输出引脚
pCompressOut->QueryInterface(IID_IAMVideoCompression,(void**)&pAMCompress);
}
pSysDevEnum->Release();
HRESULT hr=0;
if(m_pMC)
{
m_pMC->Stop(); ////////////////////此处出现问题 }
hr = m_pCapture->SetOutputFileName( &MEDIASUBTYPE_Avi,inFileName.AllocSysString(), &pMux, NULL );
//渲染媒体,链接所有滤波器
m_pCapture->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,m_pBF,pCompress,pMux);
HRESULT ret = pMux->QueryInterface(IID_IMediaSeeking, (void**)&pSeek);
pMux->Release();
m_pMC->Run();//回复视频
return hr;
//Remove Filter From Graph
Stop();
if(m_pGraph != NULL)
{
IEnumFilters * pEnum = NULL;
HRESULT hr = m_pGraph->EnumFilters(&pEnum);
if (SUCCEEDED(hr))
{
IBaseFilter *pFilter = NULL;
while (S_OK == pEnum->Next(1, &pFilter, NULL))
{
m_pGraph->RemoveFilter(pFilter);
pEnum->Reset();
SafeRelease(pFilter);
}
}
SafeRelease(pEnum);
}
public:
IBaseFilter *pMux ,*pWriter,*pCompress; //过滤器
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];
IMoniker *pMoniker; //监视器
IMediaSeeking *pSeek;
IMediaEventEx *pEvent;
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;
mt.bTemporalCompression = TRUE;
hr = m_pGrabber->SetMediaType(&mt);
if( FAILED( hr ) )
{
AfxMessageBox("Fail to set media type!");
return hr;
}
hr = m_pGB->AddFilter( pGrabBase, L"Grabber" );
// hr = m_pGB->AddFilter(pEncoderFilter,L"EncodeFilter");
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;
}
m_pVW->put_MessageDrain((OAHWND)m_hWnd);
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;
}
HRESULT CCaptureVideo::InitCaptureGraphBuilder()
{
m_pGB = NULL;
HRESULT hr;
// 创建IGraphBuilder接口
hr=CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&m_pGB);
// 创建ICaptureGraphBuilder2接口
hr = CoCreateInstance (CLSID_CaptureGraphBuilder2,NULL, CLSCTX_INPROC,
IID_ICaptureGraphBuilder2, (void **) &m_pCapture);
if (FAILED(hr))
return hr;
m_pCapture->SetFiltergraph(m_pGB);
hr = m_pGB->QueryInterface(IID_IMediaControl, (void **)&m_pMC);
if (FAILED(hr))return hr;
hr = m_pGB->QueryInterface(IID_IVideoWindow, (LPVOID *) &m_pVW);
if (FAILED(hr))return hr;
return hr;
}
void CCaptureVideo::MakeEncoder()
{
//枚举压缩器
////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT hr;
ICreateDevEnum *pSysDevEnum = NULL; //创建枚举器指针
pCompress = 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 == "ffdshow video encoder")
{
hr = pMoniker->BindToObject(0,0,IID_IBaseFilter,(void**)&pCompress);
pMoniker->Release();
break;
}
}
VariantClear(&varName);
}
pEnumCat->Release();
pMoniker->Release();
m_pGB->AddFilter(pCompress,L"Compressor"); //添加过滤器
HRESULT ret =NULL;
IPin * pSourceOut = NULL;
IPin* pCompressIn,* pCompressOut=NULL;
IAMVideoCompression * pAMCompress = NULL; //压缩参数设置
pCompressIn = FindPin(pCompress,PINDIR_INPUT) ; //查找输入引脚
pCompressOut = FindPin(pCompress,PINDIR_OUTPUT); //查找输出引脚
pCompressOut->QueryInterface(IID_IAMVideoCompression,(void**)&pAMCompress);
}
pSysDevEnum->Release();
}
HRESULT CCaptureVideo::CaptureImagesToAVI(CString inFileName)
{
HRESULT hr=0;
if(m_pMC)
{
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);
m_pCapture->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,m_pBF,pCompress,pMux);
HRESULT ret = pMux->QueryInterface(IID_IMediaSeeking, (void**)&pSeek);
pMux->Release();
m_pMC->Run();//回复视频
return hr;
}