📄 capture.cpp
字号:
}
OAFilterState ofs;
m_pMC->GetState(1000, &ofs);
if(ofs == State_Running)
{
CVideoChanged vc;
if(vc.DoModal() == IDOK)
{
CWnd wd;
wd.Attach(m_hWndOwner);
((CGVCaptureDlg*)wd.GetParent())->OnNotifyStop();
DisassembleGraph();
((CGVCaptureDlg*)wd.GetParent())->OnNotifyPlay();
wd.Detach();
}
}
else
{
if(m_bGraphBuiled)
{
DisassembleGraph();
if(FAILED(BuildGraph()))
{
DisassembleGraph();
return E_FAIL;
}
}
}
return S_OK;
}
STDMETHODIMP CCaptureGraph::ConfigAudioEncoderByName(HWND hParent)
{
if (NULL == m_pAudioEncoder)
{
return E_FAIL;
}
if (NULL == m_hWndOwner)
{
AfxMessageBox("m_hWndOwner不能为空");
}
CWnd wnd;
wnd.Attach(m_hWndOwner);
CAudioCompressSelectorDlg afs(this, &wnd);
if(afs.DoModal()== IDOK)
{
OAFilterState ofs;
m_pMC->GetState(1000, &ofs);
if(ofs == State_Running)
{
CAudioChangedDlg vc;
if(vc.DoModal() == IDOK)
{
AfxMessageBox("不可能执行的代码");
((CGVCaptureDlg*)wnd.GetParent())->OnNotifyStop();
DisassembleGraph();
((CGVCaptureDlg*)wnd.GetParent())->OnNotifyPlay();
}
}
else
{
if(m_bGraphBuiled)
{
DisassembleGraph();
if(FAILED(BuildGraph()))
{
wnd.Detach();
DisassembleGraph();
return E_FAIL;
}
}
}
}
wnd.Detach();
return S_OK;
}
//系统设置框
STDMETHODIMP CCaptureGraph::ConfigSysCfg(HWND hParent)
{
CSysConfig afs;
afs.DoModal();
return S_OK;
}
// some filter creations must be implemented by enumulator
// implemented with FindFilterByName auxily function
HRESULT CCaptureGraph::CreateVideoCapDeviceFilterByName(LPTSTR strName)
{
// here we disassamble the graph
if (m_bGraphBuiled)
{
DisassembleGraph();
}
RemoveFilter(m_pVideoCapture);
SAFE_RELEASE(m_pVideoCapture);
FindFilterByName(strName, &m_pVideoCapture, VIDEO_CAP);
if(m_pVideoCapture == NULL)
{
TRACE0("no this filte in system");
return S_FALSE;
}
return NOERROR;
}
// some filter creations must be implemented by enumulator
// implemented with FindFilterByName auxily function
HRESULT CCaptureGraph::CreateAudioCapDeviceFilterByName(LPTSTR strName)
{
// here we disassamble the graph
if (m_bGraphBuiled)
{
DisassembleGraph();
}
RemoveFilter(m_pAudioCapture);
SAFE_RELEASE(m_pAudioCapture);
FindFilterByName(strName, &m_pAudioCapture, AUDIO_CAP);
if(m_pAudioCapture == NULL)
{
TRACE0("no this filte in system");
return S_FALSE;
}
return NOERROR;
}
BOOL CCaptureGraph::IsDMOFilter()
{
HRESULT hr;
IDMOWrapperFilter *pDmoWrapper;
hr = m_pVideoEncoder->QueryInterface(IID_IDMOWrapperFilter, (void**)&pDmoWrapper);
if (SUCCEEDED(hr))
{
return TRUE;
}
return FALSE;
}
STDMETHODIMP CCaptureGraph::BuildVideoDMOEncoder()
{
AM_MEDIA_TYPE mtIn, mtOut;
mtIn.majortype = MEDIATYPE_Video; //set this for the call to "Connect Filters"
mtIn.cbFormat = 0;
GetInputMediaType(m_pVideoCapture, mtIn); //S_FALSE is ok here
// now connect these filters and render them
if (NULL == m_pVideoOverlay)
{
if(FAILED(ConnectPins(m_pVideoCapture, NULL, m_pVideoEncoder, NULL, &mtIn)))
{
AfxMessageBox("不能进行播放,请重新选择视频编码器。");
return E_FAIL;
}
}
else
{
if(FAILED(ConnectPins(m_pVideoOverlay, NULL, m_pVideoEncoder, NULL, &mtIn)))
{
AfxMessageBox("不能进行播放,请重新选择视频编码器。");
return E_FAIL;
}
}
CComQIPtr<IMediaObject, &IID_IMediaObject> pDMO(m_pVideoEncoder);
ConfigureDMO(pDMO, &mtIn, &mtOut);
// Get Wrapper's output pin
IPin* pOutPin = FindPinOnFilter( m_pVideoEncoder, NULL, PINDIR_OUTPUT );
if(pOutPin == NULL)
{
TRACE("Failed to get wrapper's output pin!");
return E_FAIL;
}
// Set the output media type
CComQIPtr<IAMStreamConfig, &IID_IAMStreamConfig> pIAMStreamConfig( pOutPin );
ON_QI_FAIL("Failed to QI for IAMStreamConfig!", pIAMStreamConfig)
// Set the media type
HRESULT hr = pIAMStreamConfig->SetFormat( &mtOut );
ON_FAIL("Failed to set wrapper's output type!", hr)
FreeMediaType(mtIn);
FreeMediaType(mtOut);
return S_OK;
}
HRESULT CCaptureGraph::CreateV9EncoderFilter()
{
// here we disassamble the graph
// DisassembleGraph();
HRESULT hr = CoCreateInstance(CLSID_DMOWrapperFilter, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&m_pVideoEncoder);
if (SUCCEEDED(hr))
{
// Query for IDMOWrapperFilter.
IDMOWrapperFilter *pDmoWrapper;
hr = m_pVideoEncoder->QueryInterface(IID_IDMOWrapperFilter, (void**)&pDmoWrapper);
if (SUCCEEDED(hr))
{
// Initialize the filter.
hr = pDmoWrapper->Init(CLSID_CWMVEncMediaObject2, CLSID_VideoCompressorCategory);
pDmoWrapper->Release();
if (SUCCEEDED(hr))
{
// Add the filter to the graph.
hr = m_pGB->AddFilter(m_pVideoEncoder, L"My DMO");
}
}
}
return hr;
}
HRESULT CCaptureGraph::CreateVideoEncoderFilterByName(LPTSTR strName)
{
// here we disassamble the graph
if (NULL == strName)
{
AfxMessageBox("Filter名称为空");
return E_FAIL;
}
if (m_bGraphBuiled)
{
DisassembleGraph();
}
RemoveFilter(m_pVideoEncoder);
SAFE_RELEASE(m_pVideoEncoder);
if (0 == strcmp(strName, "MicroSoft Media 9 DMO"))
{
CreateV9EncoderFilter();
}
else
{
FindFilterByName(strName, &m_pVideoEncoder, VIDEO_COMPRESS);
}
if(m_pVideoEncoder == NULL)
{
TRACE0("no this filte in system");
return S_FALSE;
}
m_strCurVideoEncoder = strName;
return NOERROR;
}
HRESULT CCaptureGraph::CreateAudioEncoderFilterByName(LPTSTR strName)
{
// here we disassamble the graph
if (NULL == strName)
{
AfxMessageBox("Filter名称为空");
return E_FAIL;
}
if (m_bGraphBuiled)
{
DisassembleGraph();
}
RemoveFilter(m_pAudioEncoder);
SAFE_RELEASE(m_pAudioEncoder);
FindFilterByName(strName, &m_pAudioEncoder, AUDIO_COMPRESS);
if (m_pAudioEncoder == NULL)
{
TRACE0("no this filte in system");
return S_FALSE;
}
if(m_pCurAudioAMT)
{
HeapFree(GetProcessHeap(), 0, m_pCurAudioAMT);
m_pCurAudioAMT = NULL;
}
return NOERROR;
}
//xiezhouwei 05-08-17 添加
/*
// 设置是否需要字幕的
void CCaptureGraph::SetNeedOverlay(bool abNeedOverlay)
{
m_bNeedOverlay = abNeedOverlay;
}
*/
//初始化字幕Filter
HRESULT CCaptureGraph::CreateUideoOverlay()
{
HRESULT hr;
hr = CoCreateInstance(CLSID_FVideoOverlay,
NULL,
CLSCTX_INPROC,
IID_IBaseFilter,
(void **)&m_pVideoOverlay);
if(FAILED(hr))
{
TRACE("Could not instantiate VideoOverlay filter");
}
return hr;
}
//配置字幕property。
HRESULT CCaptureGraph::ConfigVideoOverlay(HWND hParent)
{
ASSERT(m_pVideoOverlay);
HRESULT hr;
ISpecifyPropertyPages *pSpec;
hr = m_pVideoOverlay->QueryInterface(IID_ISpecifyPropertyPages, (void**)(&pSpec));
if(FAILED(hr))
{
return E_FAIL;
}
// Popup page
CAUUID cauuid;
pSpec->GetPages(&cauuid);
if(cauuid.cElems >= 1)
{
hr = OleCreatePropertyFrame(NULL, 30, 30, /*wstrCaption*/NULL, 1,
(IUnknown **)&pSpec, cauuid.cElems,
(GUID *)cauuid.pElems, 0, 0, NULL);
if(FAILED(hr))
{
CoTaskMemFree(cauuid.pElems);
pSpec->Release();
return hr;
}
}
// Destructor
CoTaskMemFree(cauuid.pElems);
pSpec->Release();
return hr;
}
//释放掉字幕filter
void CCaptureGraph::ReleaseUideoOverlay()
{
//DisassembleGraph();
if (TRUE == m_bGraphBuiled)
{
DisassembleGraph();
}
RemoveFilter(m_pVideoOverlay);
SAFE_RELEASE(m_pVideoOverlay);
}
// preview
VOID CCaptureGraph::SetPreview(BOOL bIsPreview)
{
if(m_bGraphBuiled)
{
if(bIsPreview)
{
m_pVW->put_Owner((OAHWND)m_hWndOwner);
m_pVW->put_WindowStyle(WS_CHILD|WS_CLIPSIBLINGS|WS_CLIPCHILDREN);
CRect rc;
GetClientRect(m_hWndOwner, &rc);
m_pVW->put_Top(0);
m_pVW->put_Left(0);
m_pVW->put_Width(rc.Width());
m_pVW->put_Height(rc.Height());
m_pVW->put_Visible(-1);
m_pVW->put_AutoShow(-1);
}
else
{
m_pVW->put_Visible(0);
m_pVW->put_AutoShow(0);
m_pVW->put_Owner(NULL);
}
}
m_bIsPreview = bIsPreview;
}
void CCaptureGraph::SetOnlyAudio( BOOL bIsOnlyAudio )
{
OAFilterState ofs;
m_pMC->GetState(1000, &ofs);
m_bIsOnlyAudio = bIsOnlyAudio;
if(ofs == State_Running)
{
//将对wd的操作解除。因为在DisassembleGraph中会会做的,
//如果不解除,因为attach操作不允许同时做两遍,会导致断言。
CWnd wd;
wd.Attach(m_hWndOwner);
((CGVCaptureDlg*)wd.GetParent())->OnNotifyStop();
DisassembleGraph();
((CGVCaptureDlg*)wd.GetParent())->OnNotifyPlay();
wd.Detach();
}
else
{
if(m_bGraphBuiled)
{
DisassembleGraph();
if(FAILED(BuildGraph()))
DisassembleGraph();
}
}
}
STDMETHODIMP CCaptureGraph::AddFilter(CLSID clsidFilter,
IBaseFilter** ppIFilter,
LPCTSTR pstrFilterName)
{
HRESULT hr;
ASSERT(m_pGB);
ASSERT(ppIFilter);
(*ppIFilter) = NULL;
// try to instantiate the filter
hr = CoCreateInstance(clsidFilter,
NULL,
CLSCTX_INPROC,
IID_IBaseFilter,
(LPVOID*)(ppIFilter));
if(FAILED(hr))
{
TRACE("Could not instantiate filter");
return hr;
}
// Check for unicode or not
#ifndef _UNICODE
if(pstrFilterName)
{
// not unicode, we need to unicodify the string
WCHAR wstrFilterName[256];
MultiByteToWideChar(CP_ACP,
MB_PRECOMPOSED | MB_USEGLYPHCHARS,
pstrFilterName,
-1,
wstrFilterName,
sizeof(wstrFilterName) / sizeof(WCHAR));
// try to add it to the filter graph
hr = m_pGB->AddFilter(*ppIFilter, wstrFilterName);
}
else
{
// No filter name specified, cannot convert
// try to add it to the filter graph
hr = m_pGB->AddFilter(*ppIFilter, NULL);
}
#else
// already unicode, no need to change anything
// try to add it to the filter graph
hr = m_pGB->AddFilter(*ppIFilter, pstrFilterName);
#endif
// check the result of the operation
if(FAILED(hr))
{
TRACE("Could not add filter to filter graph\n");
// free the filter definitely
(*ppIFilter)->Release();
(*ppIFilter) = NULL;
return hr;
}
// that's it
return hr;
}
STDMETHODIMP CCaptureGraph::RemoveFilter(IBaseFilter* pIFilter)
{
HRESULT hr;
// Parameters...
if(!pIFilter)
// DON'T return an error, this is expected
return NOERROR;
ASSERT(m_pGB);
// Just remove it from the graph
hr = m_pGB->RemoveFilter(pIFilter);
// Check the result
if(FAILED(hr))
TRACE("Could not remove filter from filter graph\n");
return hr;
}
STDMETHODIMP CCaptureGraph::ConnectPins(IBaseFilter* pIFilterOutput,
LPCTSTR pstrPinNameOutput,
IBaseFilter* pIFilterInput,
LPCTSTR pstrPinNameInput,
AM_MEDIA_TYPE* pmt)
{
HRESULT hr;
ASSERT(m_pGB);
// Parameters...
if((!pIFilterOutput) || (!pIFilterInput))
{
ASSERT(pIFilterOutput && pIFilterInput);
TRACE("ConnectPins called with NULL parameter\n");
return E_INVALIDARG;
}
// Find the first pin
IPin* pIPinOutput = FindPinOnFilter(pIFilterOutput,
pstrPinNameOutput,
PINDIR_OUTPUT);
if(!pIPinOutput)
{
ASSERT(pIPinOutput);
return E_FAIL;
}
// Find the second pin
IPin* pIPinInput = FindPinOnFilter(pIFilterInput,
pstrPinNameInput,
PINDIR_INPUT);
if(!pIPinInput)
{
ASSERT(pIPinInput);
// release the other pin
pIPinOutput->Release();
return E_FAIL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -