1 #include "DShowVideo.hh"
2 #include <BIAS_DeclSpec.hh>
3 #include <Base/Debug/Exception.hh>
4 #include "SampleGrabberCallback.hh"
5 #include <Base/Debug/Debug.hh>
10 #ifdef BIAS_HAVE_DSHOW
16 # define __IDxtCompositor_INTERFACE_DEFINED__
17 # define __IDxtAlphaSetter_INTERFACE_DEFINED__
18 # define __IDxtJpeg_INTERFACE_DEFINED__
19 # define __IDxtKey_INTERFACE_DEFINED__
30 #ifdef BIAS_HAVE_DSHOW
31 CComPtr< IMediaControl > pMediaControl_;
32 CComPtr< IMediaEventEx > pMediaEvent_;
33 CComPtr< IMediaSeeking > pMediaSeeking_;
34 CComPtr< ISampleGrabber > pSampleGrabber_;
35 CComPtr< IVideoFrameStep> pVideoFrameStep_;
36 CComPtr< IMediaFilter> pMediaFilter_;
37 CComPtr< IBaseFilter > pNullRenderer_;
38 CComPtr< IGraphBuilder > pGraphBuilder_;
39 CComPtr< IBaseFilter > pSrcFilter_ ;
40 CComPtr< IPin > pSrcOutPin_;
41 CComPtr< IPin > pSampleGrabberOutPin_;
42 CComPtr< IPin > pSampleGrabberInPin_;
43 CComPtr< IPin > pNullRendererInPin_;
53 cout << "exception: " << arg << endl; \
54 throw BaseException(arg);\
56 #define CHECK_HR(hr,msg) { if (hr!=S_OK) { RAISE(msg); } }
62 DShowStuff_ =
new DShowStuff;
69 Width_ = Height_ = ChannelCount_ = 0;
78 #ifdef BIAS_HAVE_DSHOW
87 #ifdef BIAS_HAVE_DSHOW
101 hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
103 (
void **) &DShowStuff_->pGraphBuilder_);
104 CHECK_HR(hr,
"CoCreateInstance GraphBuilder failed");
107 hr = DShowStuff_->pGraphBuilder_->QueryInterface(IID_IMediaControl,
108 (LPVOID *) &DShowStuff_->pMediaControl_);
109 CHECK_HR(hr,
"QueryInterface MediaControl failed");
112 hr = DShowStuff_->pGraphBuilder_->QueryInterface(IID_IMediaFilter,
113 (LPVOID *) &DShowStuff_->pMediaFilter_);
114 CHECK_HR(hr,
"QueryInterface IMediaFilter failed");
119 hr = DShowStuff_->pGraphBuilder_->QueryInterface(IID_IMediaSeeking,
120 (LPVOID *) &DShowStuff_->pMediaSeeking_);
121 CHECK_HR(hr,
"QueryInterface MediaSeeking failed");
123 hr = DShowStuff_->pGraphBuilder_->QueryInterface(IID_IMediaEvent,
124 (LPVOID *) &DShowStuff_->pMediaEvent_);
125 CHECK_HR(hr,
"QueryInterface MediaEvent failed");
128 hr = DShowStuff_->pNullRenderer_.CoCreateInstance(CLSID_NullRenderer);
129 CHECK_HR(hr,
"CoCreateInstance NullRenderer failed");
130 hr = DShowStuff_->pGraphBuilder_->AddFilter(DShowStuff_->pNullRenderer_,
132 CHECK_HR(hr,
"AddFilter(NullRenderer) failed");
135 hr = DShowStuff_->pSampleGrabber_.CoCreateInstance(CLSID_SampleGrabber);
136 CHECK_HR(hr,
"CoCreateInstance SampleGrabber failed");
138 CComQIPtr< IBaseFilter, &IID_IBaseFilter >
139 pGrabberBase( DShowStuff_->pSampleGrabber_ );
140 hr = DShowStuff_->pGraphBuilder_->AddFilter(pGrabberBase,L
"SampleGrabber");
141 CHECK_HR(hr,
"AddFilter(NullRenderer) failed");
142 pGrabberBase.Release();
145 hr = DShowStuff_->pSampleGrabber_->SetBufferSamples(
false);
146 CHECK_HR(hr,
"SetBufferSample failed");
147 hr = DShowStuff_->pSampleGrabber_->SetOneShot(
false);
148 CHECK_HR(hr,
"SetOneShot failed");
150 DShowStuff_->pSampleGrabber_->SetCallback(SGCB_,0);
158 ZeroMemory(&mt,
sizeof(AM_MEDIA_TYPE));
159 mt.majortype = MEDIATYPE_Video;
160 mt.subtype = MEDIASUBTYPE_RGB24;
161 mt.formattype = FORMAT_VideoInfo;
162 hr = DShowStuff_->pSampleGrabber_->SetMediaType(&mt);
163 CHECK_HR(hr,
"SetMediaType failed");
178 cout<<
"opening avi "<<filename<<endl;
181 #ifdef BIAS_HAVE_DSHOW
184 int length = MultiByteToWideChar(CP_ACP,0,filename.c_str() ,
185 filename.size()+1,NULL,0);
186 LPWSTR wc_filename =
new WCHAR[length];
187 MultiByteToWideChar(CP_ACP,0,filename.c_str() ,filename.size()+1,
191 hr = DShowStuff_->pGraphBuilder_->AddSourceFilter(wc_filename,L
"SourceFilter",
192 &DShowStuff_->pSrcFilter_);
193 CHECK_HR(hr,
"AddSourceFilter failed");
196 CComQIPtr< IBaseFilter, &IID_IBaseFilter > pGrabberBase( DShowStuff_->pSampleGrabber_ );
197 hr = pGrabberBase->FindPin(L
"In",&DShowStuff_->pSampleGrabberInPin_);
198 CHECK_HR(hr,
"Failed to find in-pin of SampleGrabber");
200 IEnumPins *pEnum = NULL;
202 hr = DShowStuff_->pSrcFilter_->EnumPins(&pEnum);
203 CHECK_HR(hr,
"EnumPins failed on SrcFilter");
204 while(pEnum->Next(1, &pPin, 0) == S_OK) {
205 PIN_DIRECTION PinDirThis;
206 hr = pPin->QueryDirection(&PinDirThis);
210 pGrabberBase.Release();
214 pPin->QueryId(&pinName);
215 if (PINDIR_OUTPUT == PinDirThis) {
216 DShowStuff_->pSrcOutPin_ = pPin;
225 hr = DShowStuff_->pGraphBuilder_->Connect(DShowStuff_->pSrcOutPin_,
226 DShowStuff_->pSampleGrabberInPin_);
227 CHECK_HR(hr,
"Failed to connect SrcFilter with SampleGrabber");
231 hr = pGrabberBase->FindPin(L
"Out",&DShowStuff_->pSampleGrabberOutPin_);
232 CHECK_HR(hr,
"Failed to find out-pin of SampleGrabber");
234 hr = DShowStuff_->pNullRenderer_->FindPin(L
"In",
235 &DShowStuff_->pNullRendererInPin_);
236 CHECK_HR(hr,
"Failed to find out-pin of SampleGrabber");
238 hr = DShowStuff_->pGraphBuilder_->Connect(DShowStuff_->pSampleGrabberOutPin_,
239 DShowStuff_->pNullRendererInPin_);
240 CHECK_HR(hr,
"Failed to connect SampleGrabber with NullRenderer");
243 AM_MEDIA_TYPE MediaType;
244 ZeroMemory(&MediaType,
sizeof(MediaType));
245 hr = DShowStuff_->pSampleGrabber_->GetConnectedMediaType(&MediaType);
246 CHECK_HR(hr,
"GetConnectedMediaType failed");
249 VIDEOINFOHEADER *pVideoHeader = (VIDEOINFOHEADER*)MediaType.pbFormat;
250 if (pVideoHeader == NULL) {
251 pGrabberBase.Release();
257 BITMAPINFO BitmapInfo;
258 ZeroMemory(&BitmapInfo,
sizeof(BitmapInfo));
259 CopyMemory(&BitmapInfo.bmiHeader, &(pVideoHeader->bmiHeader),
260 sizeof(BITMAPINFOHEADER));
262 Width_ = BitmapInfo.bmiHeader.biWidth;
263 Height_ = BitmapInfo.bmiHeader.biHeight;
264 ChannelCount_ = BitmapInfo.bmiHeader.biBitCount/8;
266 DShowStuff_->pMediaSeeking_->SetTimeFormat(&TIME_FORMAT_FRAME);
267 DShowStuff_->pMediaSeeking_->SetRate(128);
268 DShowStuff_->pSrcFilter_->SetSyncSource(NULL);
269 pGrabberBase->SetSyncSource(NULL);
270 pGrabberBase.Release();
271 DShowStuff_->pNullRenderer_->SetSyncSource(NULL);
273 DShowStuff_->pMediaFilter_->SetSyncSource(NULL);
275 long long currentPos,stopPos;
278 DShowStuff_->pMediaSeeking_->SetPositions(¤tPos,
279 AM_SEEKING_AbsolutePositioning,
281 AM_SEEKING_AbsolutePositioning );
283 DShowStuff_->pMediaControl_->Pause();
298 #ifdef BIAS_HAVE_DSHOW
299 long long currentPos,stopPos;
300 currentPos=FrameNum_;
301 stopPos = currentPos;
302 DShowStuff_->pMediaSeeking_->SetPositions(¤tPos,AM_SEEKING_AbsolutePositioning,
303 &stopPos,AM_SEEKING_AbsolutePositioning );
305 SGCB_->SampleTriggerArm();
306 DShowStuff_->pMediaControl_->Run();
311 if (SGCB_->HasCallbackFunction()){
316 unsigned timeoutcount=0;
317 unsigned paniclevel =0;
318 while (!SGCB_->SampleTriggered())
334 cout<<
"avi read panic!"<<endl;
340 DShowStuff_->pMediaSeeking_->
341 SetPositions(¤tPos,AM_SEEKING_AbsolutePositioning,
342 &stopPos,AM_SEEKING_AbsolutePositioning );
343 DShowStuff_->pMediaControl_->Run();
357 #ifdef BIAS_HAVE_DSHOW
361 hr = DShowStuff_->pMediaControl_->Run();
363 if (hr != S_OK) Sleep(10);
364 else IsRunning_ =
true;
365 }
while (hr != S_OK && tries <10);
367 CHECK_HR(hr,
"DirectShow Run failed");
377 #ifdef BIAS_HAVE_DSHOW
381 hr = DShowStuff_->pMediaControl_->Stop();
383 if (hr != S_OK) Sleep(1);
384 else IsRunning_ =
true;
385 }
while (hr != S_OK && tries <10);
386 CHECK_HR(hr,
"Stop failed");
389 hr = DShowStuff_->pMediaEvent_->WaitForCompletion(INFINITE, &evCode);
390 CHECK_HR(hr,
"WaitForCompletion failed");
398 #ifdef BIAS_HAVE_DSHOW
420 if (Open_ && DShowStuff_) {
421 #ifdef BIAS_HAVE_DSHOW
423 cout <<
"ReadAvi::Close()\n";
425 if (DShowStuff_->pMediaControl_) {
426 DShowStuff_->pMediaControl_->Stop();
428 if (DShowStuff_->pGraphBuilder_){
430 if (DShowStuff_->pSrcFilter_){
431 hr = DShowStuff_->pGraphBuilder_->
432 RemoveFilter(DShowStuff_->pSrcFilter_);
433 CHECK_HR(hr,
"RemoveFilter failed");
435 if (DShowStuff_->pNullRenderer_){
436 hr = DShowStuff_->pGraphBuilder_->
437 RemoveFilter(DShowStuff_->pNullRenderer_);
438 CHECK_HR(hr,
"RemoveFilter failed");
440 if (DShowStuff_->pSampleGrabber_){
441 CComQIPtr< IBaseFilter, &IID_IBaseFilter >
442 pGrabberBase( DShowStuff_->pSampleGrabber_ );
443 hr = DShowStuff_->pGraphBuilder_->RemoveFilter(pGrabberBase);
444 CHECK_HR(hr,
"RemoveFilter failed");
445 pGrabberBase.Release();
449 if (DShowStuff_->pMediaControl_){
450 DShowStuff_->pMediaControl_.Release();
452 if (DShowStuff_->pMediaEvent_){
453 DShowStuff_->pMediaEvent_.Release();
455 if (DShowStuff_->pMediaSeeking_){
456 DShowStuff_->pMediaSeeking_.Release();
458 if (DShowStuff_->pSrcOutPin_){
459 DShowStuff_->pSrcOutPin_.Release();
461 if (DShowStuff_->pSampleGrabberInPin_){
462 DShowStuff_->pSampleGrabberInPin_.Release();
464 if (DShowStuff_->pSampleGrabberOutPin_){
465 DShowStuff_->pSampleGrabberOutPin_.Release();
467 if (DShowStuff_->pNullRendererInPin_){
468 DShowStuff_->pNullRendererInPin_.Release();
470 if (DShowStuff_->pSrcFilter_){
471 DShowStuff_->pSrcFilter_.Release();
473 if (DShowStuff_->pSampleGrabber_){
474 DShowStuff_->pSampleGrabber_.Release();
476 if (DShowStuff_->pNullRenderer_){
477 DShowStuff_->pNullRenderer_.Release();
479 if (DShowStuff_->pMediaFilter_){
480 DShowStuff_->pMediaFilter_.Release();
482 if (DShowStuff_->pGraphBuilder_){
483 DShowStuff_->pGraphBuilder_.Release();
488 Width_ = Height_ = ChannelCount_ = 0;
494 unsigned &channel_count)
496 if (Width_==0 || Height_==0 || ChannelCount_==0) {
return false; }
499 channel_count = ChannelCount_;
void GotoFrame(unsigned long long frameNo)
bool Open(const std::string &filename)
open file, if not possible throw exception
DShowVideo(SampleGrabberCallback *sgcb)
bool GetImageSize(unsigned &width, unsigned &height, unsigned &channel_count)
returns the image size contained in the stream, only meaningfull results after call to Open() functio...
sample grabber callback class for grabbing single frames only