www.pudn.com > VirtualVCR-src-v2.6.9.zip > CCodec.cpp


/* 
	Virtual VCR 
    Copyright (C) 2002  Shaun Faulds 
 
    This program is free software; you can redistribute it and/or modify 
    it under the terms of the GNU General Public License as published by 
    the Free Software Foundation; either version 2 of the License, or 
    (at your option) any later version. 
 
    This program is distributed in the hope that it will be useful, 
    but WITHOUT ANY WARRANTY; without even the implied warranty of 
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
    GNU General Public License for more details. 
 
    You should have received a copy of the GNU General Public License 
    along with this program; if not, write to the Free Software 
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
 
	Acknowledgments: 
	This application and associated filters are based on the examples 
	from the Microsoft DirectX DirectShow SDK. 
*/ 
 
#include  
#include "CCodec.h" 
#include  
using namespace std; 
 
CCodec::CCodec(GUID type)  
{ 
	memset(codecList, 0, (sizeof(codecList[0]) * 1024)); 
	codecType = type; 
	pVComp = NULL; 
	codecID = -1; 
	getCodecNames(); 
} 
 
CCodec::~CCodec() 
{ 
	if(pVComp) 
		pVComp->Release(); 
} 
 
CCodec::getCodecNames() 
{ 
	ICreateDevEnum *pSysDevEnum; 
	IEnumMoniker *pEnumCat; 
 
	CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC, IID_ICreateDevEnum,(void **)&pSysDevEnum); 
 
	ULONG cFetched; 
	IMoniker *pMoniker = NULL; 
	codec_counter = 0; 
	pSysDevEnum->CreateClassEnumerator(codecType, &pEnumCat, 0); 
 
	while(pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK) 
		codecList[codec_counter++] = pMoniker; 
 
	pEnumCat->Release(); 
	pSysDevEnum->Release(); 
} 
 
string CCodec::getCodecName(int index) 
{ 
	char name[200]; 
	if(index < codec_counter) 
	{ 
		IPropertyBag *pPropBag = NULL; 
		codecList[index]->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pPropBag); 
		VARIANT varName; 
		varName.vt = VT_BSTR; 
		pPropBag->Read(L"FriendlyName", &varName, 0); 
 
		WideCharToMultiByte(CP_ACP, 0, varName.bstrVal, -1, name, 128, NULL, NULL); 
 
		pPropBag->Release(); 
		return name; 
	} 
	else 
	{ 
		string none = "end"; 
		return none; 
	} 
} 
 
CCodec::showProperties(HWND hwnd) 
{ 
	if(pVComp) 
	{ 
		 
		IAMVfwCompressDialogs *setupd; 
		pVComp->QueryInterface(IID_IAMVfwCompressDialogs, (void **)&setupd); 
		if(setupd) 
		{ 
			setupd->ShowDialog(1, NULL); 
			setupd->Release(); 
		} 
		else 
		{ 
			ISpecifyPropertyPages *pProp; 
			HRESULT hr = pVComp->QueryInterface(IID_ISpecifyPropertyPages, (void **)&pProp); 
			if (SUCCEEDED(hr))  
			{ 
				// Get the filter's name and IUnknown pointer. 
				IUnknown *pFilterUnk = NULL; 
				pVComp->QueryInterface(IID_IUnknown, (void **)&pFilterUnk); 
				 
				// Show the page.  
				CAUUID caGUID; 
				pProp->GetPages(&caGUID); 
				pProp->Release(); 
				 
				OleCreatePropertyFrame( 
					hwnd,                   // Parent window 
					0, 0,                   // (Reserved) 
					L"Codec ",				// Caption for the dialog box 
					1,                      // Number of objects (just the filter) 
					&pFilterUnk,            // Array of object pointers.  
					caGUID.cElems,          // Number of property pages 
					caGUID.pElems,          // Array of property page CLSIDs 
					0,                      // Locale identifier 
					0, NULL                 // Reserved 
					); 
				 
				// Clean up. 
				pFilterUnk->Release(); 
				CoTaskMemFree(caGUID.pElems); 
			} 
		} 
	} 
} 
/* 
void CCodec::getFilter(char *codecName) 
{ 
	char name[128];	 
	for(int x=0; x < (sizeof(codecList)/sizeof(IMoniker)); x++) 
	{ 
		if(!codecList[x]) break; 
 
		IPropertyBag *pPropBag; 
		codecList[x]->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pPropBag); 
 
		VARIANT varName; 
		varName.vt = VT_BSTR; 
		pPropBag->Read(L"FriendlyName", &varName, 0); 
		WideCharToMultiByte(CP_ACP, 0, varName.bstrVal, -1, name, 128, NULL, NULL);	 
 
		if (strcmp(name, codecName) == 0) 
		{ 
			getFilterByINDEX(x); 
		} 
 
		pPropBag->Release(); 
	} 
} 
*/ 
void CCodec::getFilterByID(string ID) 
{ 
	TCHAR *tach = NULL; 
	WCHAR *szDisplayName = NULL; 
	for(int x=0; x < (sizeof(codecList)/sizeof(IMoniker)); x++) 
	{ 
		if(!codecList[x]) break; 
 
		szDisplayName = 0; 
 
		if(SUCCEEDED(codecList[x]->GetDisplayName(0, 0, &szDisplayName))) 
		{    
			if(szDisplayName) 
			{ 
				tach = new TCHAR [wcslen(szDisplayName)+1]; 
				wsprintf(tach, TEXT("%S"), szDisplayName); 
				CoTaskMemFree(szDisplayName); 
 
				if(strcmp(tach, ID.c_str()) == 0) 
				{ 
					delete(tach); 
					tach = NULL; 
					getFilterByINDEX(x); 
					break; 
				} 
 
				delete(tach); 
				tach = NULL; 
			} 
		} 
 
	} 
} 
 
void CCodec::getFilterByINDEX(int ID) 
{ 
	codecID = ID; 
 
	if(pVComp) 
		pVComp->Release(); 
 
	if(codecList[ID]) 
	{ 
		codecList[ID]->BindToObject(0, 0, IID_IBaseFilter, (void**)&pVComp); 
	} 
} 
 
int CCodec::currentCodecINDEX() 
{ 
	return codecID; 
} 
 
IBaseFilter* CCodec::getCurrentCodec() 
{ 
	return pVComp; 
} 
 
string CCodec::getCodecIDstring(int index) 
{ 
	if(index > -1 && index < codec_counter) 
	{ 
		TCHAR *tach = NULL; 
		WCHAR *szDisplayName = NULL; 
		szDisplayName = 0; 
 
		if(codecList[index]) 
		{ 
			if(SUCCEEDED(codecList[index]->GetDisplayName(0, 0, &szDisplayName))) 
			{    
				if(szDisplayName) 
				{ 
					tach = new TCHAR [wcslen(szDisplayName)+1]; 
					wsprintf(tach, TEXT("%S"), szDisplayName); 
					CoTaskMemFree(szDisplayName); 
				} 
			} 
		} 
 
		return tach; 
	} 
	else 
	{ 
		string none = "end"; 
		return none; 
	} 
}