📄 dxmanager.cpp
字号:
}
success = true;
release_and_return:
pProcessThis.Release();
pHandVuIn.Release();
pHandVuOut.Release();
pSmartTee.Release();
pAppRenderer.Release();
pSmartTPreviewOut.Release();
return success;
}
// Destroy DirectShow Filter Graph
void DXManager::DestroyFilterGraph()
{
if (m_FilterGraph) {
CComPtr<IEnumFilters> pEnumFilters = 0;
m_FilterGraph->EnumFilters( &pEnumFilters );
if( pEnumFilters ) {
CComPtr<IBaseFilter> pFilter = 0;
ULONG cFetched = 0;
while( pEnumFilters->Next( 1, &pFilter, &cFetched ) == S_OK && pFilter != 0 ) {
m_FilterGraph->RemoveFilter( pFilter );
pFilter.Release();
cFetched = 0;
}
pEnumFilters.Release();
}
}
#ifdef DEBUG
RemoveFromROT(m_ROTregister);
#endif
m_GraphBuilder.Release();
m_MediaControl.Release();
m_MediaEventEx.Release();
m_FilterGraph.Release();
m_HandVuFilter.Release();
m_HandVuFilterProp.Release();
m_SourceFilter.Release();
m_CameraControl.Release();
m_VideoWindow.Release();
m_SourceVideoWindow.Release();
NullComPtrs();
}
bool DXManager::CreateHandVuFilter()
{
HRESULT hr = CoCreateInstance( CLSID_HandVuFilter, NULL, CLSCTX_INPROC_SERVER,
IID_IBaseFilter, (void**)&m_HandVuFilter );
if (SUCCEEDED(hr)) {
m_HandVuFilter->QueryInterface(IID_IHandVuFilter, (void**)&m_HandVuFilterProp);
}
if (m_HandVuFilterProp) {
hr = m_HandVuFilterProp->AddListener(this);
ASSERT(SUCCEEDED(hr));
if (m_pIAMTCReader) {
hr = m_HandVuFilterProp->SetTimecodeReader(m_pIAMTCReader);
ASSERT(SUCCEEDED(hr));
}
hr = m_HandVuFilterProp->SetVerbosity(g_verbose, m_handvu_logfilename);
ASSERT(SUCCEEDED(hr));
}
return m_HandVuFilterProp != 0;
}
bool DXManager::InitHandVuFilter()
{
ASSERT(m_SourceFilter);
CComPtr<IPin> pPin = GetVideoPin(m_SourceFilter, PINDIR_OUTPUT);
AM_MEDIA_TYPE media_type;
pPin->ConnectionMediaType(&media_type);
BITMAPINFOHEADER* pHdr=NULL;
if (media_type.formattype==FORMAT_VideoInfo) {
pHdr = &((VIDEOINFOHEADER*) media_type.pbFormat)->bmiHeader;
} else if (media_type.formattype==FORMAT_VideoInfo2) {
pHdr = &((VIDEOINFOHEADER2*) media_type.pbFormat)->bmiHeader;
} else {
return false;
}
ASSERT(pHdr);
int width = pHdr->biWidth;
int height = pHdr->biHeight;
int iPixelSize = pHdr->biBitCount / 8;
HRESULT hr = m_HandVuFilterProp->Initialize(width, height, iPixelSize, this);
ASSERT(SUCCEEDED(hr));
return SUCCEEDED(hr);
}
bool DXManager::CreateCamera( int idx )
{
CComPtr<ICreateDevEnum> pCreateDevEnum = 0;
CComPtr<IEnumMoniker> pEnumMon = 0;
ULONG cFetched = 0;
m_SourceFilter.Release();
CoCreateInstance( CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum, (void**)&pCreateDevEnum );
/* Create capture device */
if( pCreateDevEnum ) {
CComPtr<IMoniker> pMon = 0;
pCreateDevEnum->CreateClassEnumerator( CLSID_VideoInputDeviceCategory, &pEnumMon, 0);
if( pEnumMon && idx > 0 ) {
pEnumMon->Skip( idx );
ASSERT(0); // need to give user a choice
}
if( pEnumMon && SUCCEEDED( pEnumMon->Next(1, &pMon, &cFetched)) && cFetched == 1 ) {
pMon->BindToObject(0, 0, IID_IBaseFilter, (void **)&m_SourceFilter );
pMon.Release();
}
pEnumMon.Release();
pCreateDevEnum.Release();
}
if (!m_SourceFilter) {
// try file input
CFileDialog open_dlg(true, 0, 0, OFN_FILEMUSTEXIST,
"All Media Files (*.avi;*.mpg;*.mpeg;*.mov;*.wm;*.wmv;*.wma)|*.avi; *.mpg; *.mpeg; *.mov; *.wm; *.wmv; *.wma|"
"Movie Files (*.avi;*.mpg;*.mpeg;*.mov)|*.avi; *.mpg; *.mpeg; *.mov|"
"Windows Media Files (*.wm;*.wmv;*.wma)|*.wm;*.wmv;*.wma|"
"All Files (*.*)|*.*||");
if (open_dlg.DoModal()==IDOK) {
CString str = open_dlg.GetPathName();
if (str.GetLength()>0) {
WCHAR wname[1000] = L"";
MultiByteToWideChar( CP_ACP, 0, str, -1, wname, sizeof(wname)/2 );
HRESULT hr = m_GraphBuilder->AddSourceFilter(wname, L"Mmh da sauze filter", &m_SourceFilter);
if (!SUCCEEDED(hr) || m_SourceFilter==NULL) {
VERBOSE0(3, "DXManager: could not add source filter");
return false;
}
}
}
}
if (m_SourceFilter) {
HRESULT hr = m_SourceFilter->QueryInterface(IID_IAMCameraControl, (void **)&m_CameraControl);
if (SUCCEEDED(hr) && m_CameraControl) {
VERBOSE0(5, "IAMCameraControl is implemented");
// make sure it works
try {
double exposure = GetCurrentExposure();
double new_exposure = SetExposure(exposure);
} catch (HVException& hve) {
VERBOSE1(2, "IAMCameraControl operation test failed: %s",
hve.GetMessage().c_str());
m_CameraControl.Release();
m_CameraControl = NULL;
}
if (m_CameraControl) {
VERBOSE0(5, "IAMCameraControl functional - got CameraController");
}
} else {
VERBOSE0(2, "IAMCameraControl not implemented");
}
hr = m_SourceFilter->QueryInterface(IID_IAMTimecodeReader, (void **) &m_pIAMTCReader);
if (!SUCCEEDED(hr)) {
VERBOSE0(3, "DXManager: no DV TimecodeReader available");
m_pIAMTCReader = NULL;
}
}
return m_SourceFilter != 0;
}
#ifdef DEBUG
/////////////////////////////////////////////////////////////////////////////
// this allows GraphEdit to connect to the filter graph
// (File ... connect)
HRESULT DXManager::AddToROT(IUnknown *pUnkGraph, DWORD *pdwRegister)
{
IMoniker * pMoniker;
IRunningObjectTable *pROT;
if (FAILED(GetRunningObjectTable(0, &pROT))) {
return E_FAIL;
}
int const sz = 256;
WCHAR wsz[sz];
size_t cbDest = sz * sizeof(WCHAR);
// StringCbPrintfW(wsz, cbDest, L"FilterGraph %08p pid %08x", (DWORD *) pUnkGraph, GetCurrentProcessId());
wsprintfW(wsz, L"FilterGraph %08p pid %08x", (DWORD *) pUnkGraph, GetCurrentProcessId());
HRESULT hr = CreateItemMoniker(L"!", wsz, &pMoniker);
//HRESULT hr = CreateItemMoniker(L"!", L"HandVuDXApp", &pMoniker);
if (SUCCEEDED(hr)) {
hr = pROT->Register(0, pUnkGraph, pMoniker, pdwRegister);
pMoniker->Release();
}
pROT->Release();
return hr;
}
/////////////////////////////////////////////////////////////////////////////
// remove filter graph from Running Object Table
void DXManager::RemoveFromROT(DWORD pdwRegister)
{
IRunningObjectTable *pROT;
if (SUCCEEDED(GetRunningObjectTable(0, &pROT))) {
pROT->Revoke(pdwRegister);
pROT->Release();
}
}
#endif // DEBUG
void DXManager::GetVideoSourceSize(int* pWidth, int* pHeight)
{
*pWidth = -1;
*pHeight = -1;
if (m_SourceFilter!=0) {
CComPtr<IPin> pPin = GetVideoPin(m_SourceFilter, PINDIR_OUTPUT);
AM_MEDIA_TYPE media_type;
pPin->ConnectionMediaType(&media_type);
BITMAPINFOHEADER* pHdr=NULL;
if (media_type.formattype==FORMAT_VideoInfo) {
pHdr = &((VIDEOINFOHEADER*) media_type.pbFormat)->bmiHeader;
} else if (media_type.formattype==FORMAT_VideoInfo2) {
pHdr = &((VIDEOINFOHEADER2*) media_type.pbFormat)->bmiHeader;
}
if (pHdr!=NULL) {
*pWidth = pHdr->biWidth;
*pHeight = abs(pHdr->biHeight);
VERBOSE2(4, "DXManager: got real size %d %d", *pWidth, *pHeight);
}
}
if (*pWidth==-1 || *pHeight==-1) {
*pWidth = 640;
*pHeight = 480;
VERBOSE2(4, "DXManager: got fake size %d %d", *pWidth, *pHeight);
}
}
void DXManager::SetVideoWindowPosition(int left, int top, int width, int height)
{
if (m_VideoWindow) {
VERBOSE4(4, "DXManager: setting left %d, top %d, width %d, height %d",
left, top, width, height);
m_VideoWindow->SetWindowPosition( left, top, width, height );
}
}
void DXManager::SetSourceVideoWindowPosition(int left, int top, int width, int height)
{
if (m_SourceVideoWindow) {
m_SourceVideoWindow->SetWindowPosition( left, top, width, height );
}
}
HRESULT DXManager::AddFilter(IBaseFilter* filter, LPCWSTR name) {
HRESULT hr = m_FilterGraph->AddFilter(filter, name);
#ifdef DEBUG
if (!SUCCEEDED(hr)) {
char buf[MAX_ERROR_TEXT_LEN];
AMGetErrorText(hr, buf, MAX_ERROR_TEXT_LEN);
ASSERT(0);
}
#endif // DEBUG
return hr;
}
HRESULT DXManager::ConnectPins(IPin* from, IPin* to) {
HRESULT hr = m_GraphBuilder->Connect(from, to);
#ifdef DEBUG
if (!SUCCEEDED(hr)) {
char buf[MAX_ERROR_TEXT_LEN];
AMGetErrorText(hr, buf, MAX_ERROR_TEXT_LEN);
ASSERT(0);
}
#endif // DEBUG
return hr;
}
void DXManager::GetVersion(string& version) const
{
string dxm_version = "DXManager: $Id: DXManager.cpp,v 1.14 2005/10/30 23:00:43 matz Exp $";
string filter_version = "no HandVuFilter loaded";
if (m_HandVuFilterProp) {
HRESULT hr = m_HandVuFilterProp->GetVersion(filter_version);
ASSERT(SUCCEEDED(hr));
}
version = dxm_version + "\n" + filter_version;
}
BOOL PinMatchesCategory(CComPtr<IPin> pPin, const GUID& Category)
{
if (pPin == NULL) {
return false;
}
BOOL bFound = FALSE;
IKsPropertySet *pKs;
HRESULT hr = pPin->QueryInterface(IID_IKsPropertySet, (void **)&pKs);
if (SUCCEEDED(hr))
{
GUID PinCategory;
DWORD cbReturned;
hr = pKs->Get(AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY, NULL, 0,
&PinCategory, sizeof(GUID), &cbReturned);
if (SUCCEEDED(hr))
{
bFound = (PinCategory == Category);
}
pKs->Release();
}
return bFound;
}
static CComPtr<IPin> GetPin(CComPtr<IBaseFilter> pFilter, PIN_DIRECTION PinDir, int skip/*=0*/, const GUID* pCategory /*= NULL*/)
{
CComPtr<IEnumPins> pEnum;
CComPtr<IPin> pPin;
HRESULT hr = pFilter->EnumPins(&pEnum);
if (FAILED(hr)) {
return NULL;
}
while((hr=pEnum->Next(1, &pPin.p, 0)) == S_OK) {
PIN_DIRECTION PinDirThis;
pPin->QueryDirection(&PinDirThis);
if (PinDir==PinDirThis) {
if (pCategory==NULL || PinMatchesCategory(pPin, *pCategory)) {
if (skip) {
skip--;
} else {
break;
}
}
}
pPin.Release();
}
pEnum.Release();
return pPin;
}
// get a video output pin
static CComPtr<IPin> GetVideoPin(CComPtr<IBaseFilter> pFilter, PIN_DIRECTION PinDir) //, int skip/*=0*/, const GUID* pCategory /*= NULL*/)
{
CComPtr<IPin> pPin;
bool got_one = false;
int skip = 0;
BITMAPINFOHEADER* pHdr=NULL;
do {
pPin = GetPin(pFilter, PINDIR_OUTPUT, skip);
if (pPin==NULL) {
return NULL;
}
CComPtr<IEnumMediaTypes> pEnum;
HRESULT hr = pPin->EnumMediaTypes(&pEnum);
if (!SUCCEEDED(hr) || !pEnum) return NULL;
AM_MEDIA_TYPE* pMediaType = NULL;
hr = pEnum->Next(1, &pMediaType, NULL);
while (hr==S_OK) {
if (pMediaType->formattype==FORMAT_VideoInfo ||
pMediaType->majortype==MEDIATYPE_Video ||
pMediaType->majortype==MEDIATYPE_Interleaved ||
pMediaType->majortype==MEDIATYPE_Stream ||
pMediaType->majortype==MEDIATYPE_AnalogVideo)
{
DeleteMediaType(pMediaType);
pMediaType = NULL;
got_one = true;
break;
}
DeleteMediaType(pMediaType);
pMediaType = NULL;
hr = pEnum->Next(1, &pMediaType, NULL);
}
skip++;
if (!got_one) {
pPin.Release();
}
} while (!got_one);
return pPin;
}
IMPLEMENT_DYNCREATE(CSourceView, CScrollView)
BEGIN_MESSAGE_MAP(CSourceView, CScrollView)
ON_WM_SIZE()
END_MESSAGE_MAP()
CSourceView::CSourceView()
{
}
CSourceView::~CSourceView()
{
}
BOOL CSourceView::PreCreateWindow(CREATESTRUCT& cs)
{
return CView::PreCreateWindow(cs);
}
void CSourceView::OnInitialUpdate()
{
CScrollView::OnInitialUpdate();
SetVideoWindowSize(0, 0);
}
void CSourceView::OnSize(UINT nType, int cx, int cy)
{
CScrollView::OnSize(nType, cx, cy);
SetVideoWindowSize(cx, cy);
Invalidate(true);
}
void CSourceView::SetVideoWindowSize(int width, int height)
{
int source_width, source_height;
m_pDXManager->GetVideoSourceSize(&source_width, &source_height);
if (source_height<0) {
source_height = -source_height;
}
CRect rc;
GetClientRect( &rc );
if (width==0 && height==0) {
width = source_width;
height = source_height;
// MoveWindow(&rc);
} else {
width = max(width, source_width);
height = max(height, source_height);
double ratio = (double)source_width/(double)source_height;
width = min(width, (int)((double)height*ratio));
height = min(height, (int)((double)width/ratio));
}
m_pDXManager->SetSourceVideoWindowPosition( rc.left, rc.top, width, height );
SetScrollSizes(MM_TEXT, CSize(source_width, source_height));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -