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