00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef HELPFUNC_H_
00026 #define HELPFUNC_H_
00027
00028 #include <list>
00029 #include <math.h>
00030 #include <string>
00031
00032 #include <DShow.h>
00033 #include <mtype.h>
00034 #include <qedit.h>
00035 #include <winnls.h>
00036
00037 #ifndef __STREAMS__
00038 # include <streams.h>
00039 #endif
00040
00041
00042 #define VIDEO_SAMPLEGRABBER_FILTER_NAME L"SampleGrabber Video"
00043 #define AUDIO_SAMPLEGRABBER_FILTER_NAME L"SampleGrabber Audio"
00044
00045 #define CAP_VIDEO_CAPTURE 0x00000001
00046 #define CAP_VIDEO_OUTPUT 0x00000002
00047 #define CAP_VIDEO_OVERLAY 0x00000004
00048 #define CAP_VBI_CAPTURE 0x00000010
00049
00050 #define CAP_TUNERDEVICE 0x00010000
00051 #define CAP_TUNER 0x00020000
00052 #define CAP_AUDIO_CAPTURE 0x00040000
00053 #define CAP_RADIO 0x00080000
00054
00055
00056 static inline void DeleteList(std::list<IPin*> &PinList);
00057
00058 static inline void DeleteList(std::list<IBaseFilter*> &AudioCaptureFilterList);
00059
00060 static inline void DeleteList(std::list<AM_MEDIA_TYPE*> &MediaTypeList);
00061
00062 static inline void EnumMediaTypesOnPin(IPin *Pin,
00063 std::list<AM_MEDIA_TYPE*> &MediaTypeList);
00064
00065 static inline void EnumPinsOnFilter(IBaseFilter *Filter,
00066 std::list<IPin*> &PinList);
00067
00068 static inline bool GetFilterGraphFromFilter(IBaseFilter *Filter,
00069 IGraphBuilder **FilterGraph,
00070 ICaptureGraphBuilder2 **CaptureGraphBuilder=NULL);
00071
00072 static inline char* WChar2Char(const wchar_t* szWChar);
00073
00074 static inline bool FindTunerRadioSupport(IBaseFilter *CaptureFilter,
00075 int *Capabilities);
00076
00077 static inline bool RenderStream(IUnknown *FilterOrPinToRender,
00078 bool RenderVideo, bool RenderAudio);
00079
00080 static inline bool GetInstalledDeviceIDs(
00081 std::list<std::string> &UniqueDeviceIDList);
00082
00083 static inline std::string bstr2string(BSTR bstr);
00084
00085 static inline std::string bstr2string(BSTR bstr)
00086 {
00087
00088 int length = ((DWORD*) bstr)[0];
00089 wchar_t* wchar_data = (wchar_t*) (((DWORD*) bstr) );
00090
00091 int converted_length = WideCharToMultiByte(CP_ACP, 0, wchar_data, -1, 0, 0,
00092 0, 0);
00093 char* char_data = new char[converted_length];
00094 WideCharToMultiByte(CP_ACP, 0, wchar_data, -1, char_data, converted_length,
00095 0, 0);
00096 std::string res = char_data;
00097 delete[] char_data;
00098 return res;
00099 }
00100
00101
00102
00103 static inline void EnumMediaTypesOnPin(IPin *Pin,
00104 std::list<AM_MEDIA_TYPE*> &MediaTypeList)
00105 {
00106 QzCComPtr<IEnumMediaTypes> EnumMediaTypes;
00107 if (Pin->EnumMediaTypes(&EnumMediaTypes)==S_OK) {
00108 AM_MEDIA_TYPE *MediaType=NULL;
00109 while (EnumMediaTypes->Next(1, &MediaType, NULL) == S_OK) {
00110 MediaTypeList.push_back(MediaType);
00111 }
00112 }
00113 }
00114
00115 static inline void EnumPinsOnFilter(IBaseFilter *Filter,
00116 std::list<IPin*> &PinList)
00117 {
00118 QzCComPtr<IEnumPins> EnumPins;
00119 IPin *Pin=NULL;
00120 if (Filter->EnumPins(&EnumPins)==S_OK) {
00121 while (EnumPins->Next(1, &Pin, 0) == S_OK) {
00122 PinList.push_back(Pin);
00123 }
00124 }
00125 }
00126
00127 static inline bool GetFilterGraphFromFilter(IBaseFilter *Filter,
00128 IGraphBuilder **FilterGraph,
00129 ICaptureGraphBuilder2 **CaptureGraphBuilder)
00130 {
00131 if (Filter==NULL) {
00132 return false;
00133 }
00134
00135 FILTER_INFO FilterInfo;
00136 if (FAILED(Filter->QueryFilterInfo(&FilterInfo))) {
00137 return false;
00138 }
00139 if (FilterInfo.pGraph==NULL) {
00140 return false;
00141 }
00142 if (FAILED(FilterInfo.pGraph->QueryInterface(IID_IGraphBuilder,
00143 (void**) &*FilterGraph))) {
00144 return false;
00145 }
00146
00147
00148 if (CaptureGraphBuilder!=NULL) {
00149 if (FAILED(CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL,
00150 CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2,
00151 (void**)&*CaptureGraphBuilder))) {
00152 return false;
00153 }
00154 if (FAILED((*CaptureGraphBuilder)->SetFiltergraph(*FilterGraph))) {
00155 return false;
00156 }
00157 }
00158
00159 return true;
00160 }
00161
00162 static inline char* WChar2Char(const wchar_t* szWChar)
00163 {
00164 if (szWChar == NULL) {
00165 return NULL;
00166 }
00167 char* szChar = NULL;
00168 size_t size = 0;
00169 if ((size = wcstombs(0, szWChar, 0)) == -1) {
00170 return NULL;
00171 }
00172 szChar = new char[size + 1];
00173 szChar[size] = 0;
00174 wcstombs(szChar, szWChar, size);
00175 return szChar;
00176 }
00177
00178 static inline bool FindTunerRadioSupport(IBaseFilter *CaptureFilter,
00179 int *Capabilities)
00180 {
00181 if (CaptureFilter==NULL) {
00182 return false;
00183 }
00184
00185
00186 QzCComPtr<ICaptureGraphBuilder2> CaptureGraphBuilder;
00187 QzCComPtr<IGraphBuilder> FilterGraph;
00188 if (!GetFilterGraphFromFilter(CaptureFilter, &FilterGraph,
00189 &CaptureGraphBuilder)) {
00190 return false;
00191 }
00192
00193
00194 QzCComPtr<IAMTVTuner> Tuner;
00195 if (SUCCEEDED(CaptureGraphBuilder->FindInterface(&LOOK_UPSTREAM_ONLY, NULL,
00196 CaptureFilter, IID_IAMTVTuner, (void**)&Tuner))) {
00197 long lModes = 0;
00198 HRESULT hr = Tuner->GetAvailableModes(&lModes);
00199 if (SUCCEEDED(hr) && (lModes & AMTUNER_MODE_FM_RADIO)) {
00200 *Capabilities |= CAP_RADIO;
00201 }
00202 if (SUCCEEDED(hr) && (lModes & AMTUNER_MODE_TV)) {
00203 *Capabilities |= CAP_TUNER;
00204 }
00205 }
00206
00207 return true;
00208 }
00209
00210 static inline void GetInstalledAudioDevices(
00211 std::list<IBaseFilter*> &AudioCaptureFilterList)
00212 {
00213
00214 std::list<CLSID> EnumCategoriesList;
00215 EnumCategoriesList.push_back(CLSID_AudioInputDeviceCategory);
00216
00217 for (std::list<CLSID>::iterator EnumCategoriesListIter=
00218 EnumCategoriesList.begin(); EnumCategoriesListIter
00219 !=EnumCategoriesList.end(); EnumCategoriesListIter++) {
00220
00221 HRESULT hr;
00222 ICreateDevEnum *SysDevEnum = NULL;
00223 if (FAILED(CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
00224 CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void **)&SysDevEnum))) {
00225 return;
00226 }
00227
00228
00229 IEnumMoniker *EnumCat = NULL;
00230 hr = SysDevEnum->CreateClassEnumerator(*EnumCategoriesListIter,
00231 &EnumCat, 0);
00232
00233 if (hr == S_OK) {
00234
00235 IMoniker *Moniker = NULL;
00236 ULONG Fetched;
00237 while (EnumCat->Next(1, &Moniker, &Fetched) == S_OK) {
00238 IBaseFilter *AudioCaptureFilter=NULL;
00239 if (SUCCEEDED(Moniker->BindToObject(0, 0, IID_IBaseFilter,
00240 (void**)&AudioCaptureFilter))) {
00241 AudioCaptureFilterList.push_back(AudioCaptureFilter);
00242 }
00243 else {
00244 if (AudioCaptureFilter!=NULL) {
00245 AudioCaptureFilter->Release();
00246 }
00247 }
00248 Moniker->Release();
00249 }
00250 EnumCat->Release();
00251 }
00252 SysDevEnum->Release();
00253 }
00254 }
00255
00256 static inline bool RenderStream(IUnknown *FilterOrPinToRender,
00257 bool RenderVideo, bool RenderAudio)
00258 {
00259 QzCComPtr<IGraphBuilder> FilterGraph;
00260 QzCComPtr<ICaptureGraphBuilder2> CaptureGraphBuilder;
00261
00262
00263 QzCComPtr<IPin> Pin;
00264 bool IsPin=false;
00265 if (SUCCEEDED(FilterOrPinToRender->QueryInterface(IID_IPin, (void**)&Pin)))
00266 {
00267 PIN_INFO PinInfo;
00268 Pin->QueryPinInfo(&PinInfo);
00269 IsPin=true;
00270
00271 if (!GetFilterGraphFromFilter(PinInfo.pFilter, &FilterGraph,
00272 &CaptureGraphBuilder)) {
00273 return false;
00274 }
00275 }
00276 else
00277 {
00278 if (!GetFilterGraphFromFilter((IBaseFilter*)FilterOrPinToRender,
00279 &FilterGraph, &CaptureGraphBuilder)) {
00280 return false;
00281 }
00282 }
00283
00284
00285
00286
00287 if (RenderVideo) {
00288
00289
00290 QzCComPtr<IBaseFilter> RendererVideo;
00291 if (FAILED(CoCreateInstance(CLSID_NullRenderer, 0,
00292 CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&RendererVideo))) {
00293 return false;
00294 }
00295 if (FAILED(FilterGraph->AddFilter(RendererVideo,L"Video Null Renderer" ))) {return false;}
00296 QzCComPtr<IBaseFilter> SampleGrabberVideo;
00297 if(FAILED(CoCreateInstance(CLSID_SampleGrabber, 0, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&SampleGrabberVideo))) {return false;}
00298 if(FAILED(FilterGraph->AddFilter(SampleGrabberVideo, VIDEO_SAMPLEGRABBER_FILTER_NAME))) {return false;}
00299
00300 QzCComPtr<ISampleGrabber> SampleGrabber;
00301 if(FAILED(SampleGrabberVideo->QueryInterface(IID_ISampleGrabber, (void**)&SampleGrabber))) {return false;}
00302 AM_MEDIA_TYPE mt;
00303 mt.majortype=MEDIATYPE_Video;
00304 mt.subtype=GUID_NULL;
00305 mt.pUnk=NULL;
00306 mt.cbFormat=0;
00307 if(FAILED(SampleGrabber->SetMediaType(&mt))) {return false;}
00308
00309 if(FAILED(CaptureGraphBuilder->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, FilterOrPinToRender, SampleGrabberVideo, RendererVideo))) {return false;}
00310 }
00311
00312 if(RenderAudio)
00313 {
00314
00315
00316 QzCComPtr<IBaseFilter> RendererAudio;
00317 CoCreateInstance(CLSID_NullRenderer, 0, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&RendererAudio);
00318 FilterGraph->AddFilter(RendererAudio, L"Audio Null Renderer");
00319 QzCComPtr<IBaseFilter> SampleGrabberAudio;
00320 CoCreateInstance(CLSID_SampleGrabber, 0, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&SampleGrabberAudio);
00321 FilterGraph->AddFilter(SampleGrabberAudio, AUDIO_SAMPLEGRABBER_FILTER_NAME);
00322
00323 QzCComPtr<ISampleGrabber> SampleGrabber;
00324 SampleGrabberAudio->QueryInterface(IID_ISampleGrabber, (void**)&SampleGrabber);
00325 AM_MEDIA_TYPE mt;
00326 mt.majortype=MEDIATYPE_Audio;
00327 mt.subtype=GUID_NULL;
00328 mt.pUnk=NULL;
00329 mt.cbFormat=0;
00330 SampleGrabber->SetMediaType(&mt);
00331
00332
00333 if(IsPin)
00334 {
00335 HRESULT hr=CaptureGraphBuilder->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Audio, FilterOrPinToRender, SampleGrabberAudio, RendererAudio);
00336 if(hr!=S_OK) {return false;}
00337 }
00338
00339
00340 else if(FAILED(CaptureGraphBuilder->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Audio, FilterOrPinToRender, SampleGrabberAudio, RendererAudio)))
00341 {
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362 std::list<IBaseFilter*> AudioCaptureFilterList;
00363 GetInstalledAudioDevices(AudioCaptureFilterList);
00364 for(std::list<IBaseFilter*>::iterator Iter=AudioCaptureFilterList.begin(); Iter!=AudioCaptureFilterList.end(); Iter++)
00365 {
00366 FilterGraph->AddFilter((*Iter), L"AudioCaptureFilter");
00367 if(SUCCEEDED(CaptureGraphBuilder->RenderStream(NULL, &MEDIATYPE_Audio, (*Iter), SampleGrabberAudio, RendererAudio)))
00368 {
00369 break;
00370 }
00371 FilterGraph->RemoveFilter((*Iter));
00372 }
00373 DeleteList(AudioCaptureFilterList);
00374 }
00375 }
00376
00377 return true;
00378 }
00379
00380 static inline void DeleteList(std::list<IPin*> &PinList)
00381 {
00382 for (std::list<IPin*>::iterator Iter=PinList.begin(); Iter!=PinList.end(); Iter++) {
00383 if ((*Iter)!=NULL) {
00384 (*Iter)->Release();
00385 }
00386 }
00387 PinList.clear();
00388 }
00389
00390 static inline void DeleteList(std::list<IBaseFilter*> &AudioCaptureFilterList)
00391 {
00392 for (std::list<IBaseFilter*>::iterator Iter=AudioCaptureFilterList.begin(); Iter
00393 !=AudioCaptureFilterList.end(); Iter++) {
00394 if ((*Iter)!=NULL) {
00395 (*Iter)->Release();
00396 }
00397 }
00398 AudioCaptureFilterList.clear();
00399 }
00400
00401 static inline void DeleteList(std::list<AM_MEDIA_TYPE*> &MediaTypeList)
00402 {
00403 for (std::list<AM_MEDIA_TYPE*>::iterator Iter=MediaTypeList.begin(); Iter
00404 !=MediaTypeList.end(); Iter++) {
00405 DeleteMediaType(*Iter);
00406 }
00407 MediaTypeList.clear();
00408 }
00409
00410 #endif