This source file includes following definitions.
- bstr2string
- EnumMediaTypesOnPin
- EnumPinsOnFilter
- GetFilterGraphFromFilter
- WChar2Char
- FindTunerRadioSupport
- GetInstalledAudioDevices
- RenderStream
- DeleteList
- DeleteList
- DeleteList
#ifndef HELPFUNC_H_
#define HELPFUNC_H_
#include <list>
#include <math.h>
#include <string>
#include <DShow.h>
#include <mtype.h>
#include <qedit.h>
#include <winnls.h>
#ifndef __STREAMS__
# include <streams.h>
#endif
#define VIDEO_SAMPLEGRABBER_FILTER_NAME L"SampleGrabber Video"
#define AUDIO_SAMPLEGRABBER_FILTER_NAME L"SampleGrabber Audio"
#define CAP_VIDEO_CAPTURE 0x00000001
#define CAP_VIDEO_OUTPUT 0x00000002
#define CAP_VIDEO_OVERLAY 0x00000004
#define CAP_VBI_CAPTURE 0x00000010
#define CAP_TUNERDEVICE 0x00010000
#define CAP_TUNER 0x00020000
#define CAP_AUDIO_CAPTURE 0x00040000
#define CAP_RADIO 0x00080000
static inline void DeleteList(std::list<IPin*> &PinList);
static inline void DeleteList(std::list<IBaseFilter*> &AudioCaptureFilterList);
static inline void DeleteList(std::list<AM_MEDIA_TYPE*> &MediaTypeList);
static inline void EnumMediaTypesOnPin(IPin *Pin,
std::list<AM_MEDIA_TYPE*> &MediaTypeList);
static inline void EnumPinsOnFilter(IBaseFilter *Filter,
std::list<IPin*> &PinList);
static inline bool GetFilterGraphFromFilter(IBaseFilter *Filter,
IGraphBuilder **FilterGraph,
ICaptureGraphBuilder2 **CaptureGraphBuilder=NULL);
static inline char* WChar2Char(const wchar_t* szWChar);
static inline bool FindTunerRadioSupport(IBaseFilter *CaptureFilter,
int *Capabilities);
static inline bool RenderStream(IUnknown *FilterOrPinToRender,
bool RenderVideo, bool RenderAudio);
static inline bool GetInstalledDeviceIDs(
std::list<std::string> &UniqueDeviceIDList);
static inline std::string bstr2string(BSTR bstr);
static inline std::string bstr2string(BSTR bstr)
{
int length = ((DWORD*) bstr)[0];
wchar_t* wchar_data = (wchar_t*) (((DWORD*) bstr) );
int converted_length = WideCharToMultiByte(CP_ACP, 0, wchar_data, -1, 0, 0,
0, 0);
char* char_data = new char[converted_length];
WideCharToMultiByte(CP_ACP, 0, wchar_data, -1, char_data, converted_length,
0, 0);
std::string res = char_data;
delete[] char_data;
return res;
}
static inline void EnumMediaTypesOnPin(IPin *Pin,
std::list<AM_MEDIA_TYPE*> &MediaTypeList)
{
QzCComPtr<IEnumMediaTypes> EnumMediaTypes;
if (Pin->EnumMediaTypes(&EnumMediaTypes)==S_OK) {
AM_MEDIA_TYPE *MediaType=NULL;
while (EnumMediaTypes->Next(1, &MediaType, NULL) == S_OK) {
MediaTypeList.push_back(MediaType);
}
}
}
static inline void EnumPinsOnFilter(IBaseFilter *Filter,
std::list<IPin*> &PinList)
{
QzCComPtr<IEnumPins> EnumPins;
IPin *Pin=NULL;
if (Filter->EnumPins(&EnumPins)==S_OK) {
while (EnumPins->Next(1, &Pin, 0) == S_OK) {
PinList.push_back(Pin);
}
}
}
static inline bool GetFilterGraphFromFilter(IBaseFilter *Filter,
IGraphBuilder **FilterGraph,
ICaptureGraphBuilder2 **CaptureGraphBuilder)
{
if (Filter==NULL) {
return false;
}
FILTER_INFO FilterInfo;
if (FAILED(Filter->QueryFilterInfo(&FilterInfo))) {
return false;
}
if (FilterInfo.pGraph==NULL) {
return false;
}
if (FAILED(FilterInfo.pGraph->QueryInterface(IID_IGraphBuilder,
(void**) &*FilterGraph))) {
return false;
}
if (CaptureGraphBuilder!=NULL) {
if (FAILED(CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL,
CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2,
(void**)&*CaptureGraphBuilder))) {
return false;
}
if (FAILED((*CaptureGraphBuilder)->SetFiltergraph(*FilterGraph))) {
return false;
}
}
return true;
}
static inline char* WChar2Char(const wchar_t* szWChar)
{
if (szWChar == NULL) {
return NULL;
}
char* szChar = NULL;
size_t size = 0;
if ((size = wcstombs(0, szWChar, 0)) == -1) {
return NULL;
}
szChar = new char[size + 1];
szChar[size] = 0;
wcstombs(szChar, szWChar, size);
return szChar;
}
static inline bool FindTunerRadioSupport(IBaseFilter *CaptureFilter,
int *Capabilities)
{
if (CaptureFilter==NULL) {
return false;
}
QzCComPtr<ICaptureGraphBuilder2> CaptureGraphBuilder;
QzCComPtr<IGraphBuilder> FilterGraph;
if (!GetFilterGraphFromFilter(CaptureFilter, &FilterGraph,
&CaptureGraphBuilder)) {
return false;
}
QzCComPtr<IAMTVTuner> Tuner;
if (SUCCEEDED(CaptureGraphBuilder->FindInterface(&LOOK_UPSTREAM_ONLY, NULL,
CaptureFilter, IID_IAMTVTuner, (void**)&Tuner))) {
long lModes = 0;
HRESULT hr = Tuner->GetAvailableModes(&lModes);
if (SUCCEEDED(hr) && (lModes & AMTUNER_MODE_FM_RADIO)) {
*Capabilities |= CAP_RADIO;
}
if (SUCCEEDED(hr) && (lModes & AMTUNER_MODE_TV)) {
*Capabilities |= CAP_TUNER;
}
}
return true;
}
static inline void GetInstalledAudioDevices(
std::list<IBaseFilter*> &AudioCaptureFilterList)
{
std::list<CLSID> EnumCategoriesList;
EnumCategoriesList.push_back(CLSID_AudioInputDeviceCategory);
for (std::list<CLSID>::iterator EnumCategoriesListIter=
EnumCategoriesList.begin(); EnumCategoriesListIter
!=EnumCategoriesList.end(); EnumCategoriesListIter++) {
HRESULT hr;
ICreateDevEnum *SysDevEnum = NULL;
if (FAILED(CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void **)&SysDevEnum))) {
return;
}
IEnumMoniker *EnumCat = NULL;
hr = SysDevEnum->CreateClassEnumerator(*EnumCategoriesListIter,
&EnumCat, 0);
if (hr == S_OK) {
IMoniker *Moniker = NULL;
ULONG Fetched;
while (EnumCat->Next(1, &Moniker, &Fetched) == S_OK) {
IBaseFilter *AudioCaptureFilter=NULL;
if (SUCCEEDED(Moniker->BindToObject(0, 0, IID_IBaseFilter,
(void**)&AudioCaptureFilter))) {
AudioCaptureFilterList.push_back(AudioCaptureFilter);
}
else {
if (AudioCaptureFilter!=NULL) {
AudioCaptureFilter->Release();
}
}
Moniker->Release();
}
EnumCat->Release();
}
SysDevEnum->Release();
}
}
static inline bool RenderStream(IUnknown *FilterOrPinToRender,
bool RenderVideo, bool RenderAudio)
{
QzCComPtr<IGraphBuilder> FilterGraph;
QzCComPtr<ICaptureGraphBuilder2> CaptureGraphBuilder;
QzCComPtr<IPin> Pin;
bool IsPin=false;
if (SUCCEEDED(FilterOrPinToRender->QueryInterface(IID_IPin, (void**)&Pin)))
{
PIN_INFO PinInfo;
Pin->QueryPinInfo(&PinInfo);
IsPin=true;
if (!GetFilterGraphFromFilter(PinInfo.pFilter, &FilterGraph,
&CaptureGraphBuilder)) {
return false;
}
}
else
{
if (!GetFilterGraphFromFilter((IBaseFilter*)FilterOrPinToRender,
&FilterGraph, &CaptureGraphBuilder)) {
return false;
}
}
if (RenderVideo) {
QzCComPtr<IBaseFilter> RendererVideo;
if (FAILED(CoCreateInstance(CLSID_NullRenderer, 0,
CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&RendererVideo))) {
return false;
}
if (FAILED(FilterGraph->AddFilter(RendererVideo,L"Video Null Renderer" ))) {return false;}
QzCComPtr<IBaseFilter> SampleGrabberVideo;
if(FAILED(CoCreateInstance(CLSID_SampleGrabber, 0, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&SampleGrabberVideo))) {return false;}
if(FAILED(FilterGraph->AddFilter(SampleGrabberVideo, VIDEO_SAMPLEGRABBER_FILTER_NAME))) {return false;}
QzCComPtr<ISampleGrabber> SampleGrabber;
if(FAILED(SampleGrabberVideo->QueryInterface(IID_ISampleGrabber, (void**)&SampleGrabber))) {return false;}
AM_MEDIA_TYPE mt;
mt.majortype=MEDIATYPE_Video;
mt.subtype=GUID_NULL;
mt.pUnk=NULL;
mt.cbFormat=0;
if(FAILED(SampleGrabber->SetMediaType(&mt))) {return false;}
if(FAILED(CaptureGraphBuilder->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, FilterOrPinToRender, SampleGrabberVideo, RendererVideo))) {return false;}
}
if(RenderAudio)
{
QzCComPtr<IBaseFilter> RendererAudio;
CoCreateInstance(CLSID_NullRenderer, 0, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&RendererAudio);
FilterGraph->AddFilter(RendererAudio, L"Audio Null Renderer");
QzCComPtr<IBaseFilter> SampleGrabberAudio;
CoCreateInstance(CLSID_SampleGrabber, 0, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&SampleGrabberAudio);
FilterGraph->AddFilter(SampleGrabberAudio, AUDIO_SAMPLEGRABBER_FILTER_NAME);
QzCComPtr<ISampleGrabber> SampleGrabber;
SampleGrabberAudio->QueryInterface(IID_ISampleGrabber, (void**)&SampleGrabber);
AM_MEDIA_TYPE mt;
mt.majortype=MEDIATYPE_Audio;
mt.subtype=GUID_NULL;
mt.pUnk=NULL;
mt.cbFormat=0;
SampleGrabber->SetMediaType(&mt);
if(IsPin)
{
HRESULT hr=CaptureGraphBuilder->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Audio, FilterOrPinToRender, SampleGrabberAudio, RendererAudio);
if(hr!=S_OK) {return false;}
}
else if(FAILED(CaptureGraphBuilder->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Audio, FilterOrPinToRender, SampleGrabberAudio, RendererAudio)))
{
std::list<IBaseFilter*> AudioCaptureFilterList;
GetInstalledAudioDevices(AudioCaptureFilterList);
for(std::list<IBaseFilter*>::iterator Iter=AudioCaptureFilterList.begin(); Iter!=AudioCaptureFilterList.end(); Iter++)
{
FilterGraph->AddFilter((*Iter), L"AudioCaptureFilter");
if(SUCCEEDED(CaptureGraphBuilder->RenderStream(NULL, &MEDIATYPE_Audio, (*Iter), SampleGrabberAudio, RendererAudio)))
{
break;
}
FilterGraph->RemoveFilter((*Iter));
}
DeleteList(AudioCaptureFilterList);
}
}
return true;
}
static inline void DeleteList(std::list<IPin*> &PinList)
{
for (std::list<IPin*>::iterator Iter=PinList.begin(); Iter!=PinList.end(); Iter++) {
if ((*Iter)!=NULL) {
(*Iter)->Release();
}
}
PinList.clear();
}
static inline void DeleteList(std::list<IBaseFilter*> &AudioCaptureFilterList)
{
for (std::list<IBaseFilter*>::iterator Iter=AudioCaptureFilterList.begin(); Iter
!=AudioCaptureFilterList.end(); Iter++) {
if ((*Iter)!=NULL) {
(*Iter)->Release();
}
}
AudioCaptureFilterList.clear();
}
static inline void DeleteList(std::list<AM_MEDIA_TYPE*> &MediaTypeList)
{
for (std::list<AM_MEDIA_TYPE*>::iterator Iter=MediaTypeList.begin(); Iter
!=MediaTypeList.end(); Iter++) {
DeleteMediaType(*Iter);
}
MediaTypeList.clear();
}
#endif