00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "StdAfx.h"
00012 #include <tchar.h>
00013 #include <strsafe.h>
00014 #include <cstdlib>
00015 #include "CameraSource.h"
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 TDSSampler::TDSSampler( IUnknown* unk, HRESULT *hr ):
00029 CBaseVideoRenderer(__uuidof(CLSID_Sampler), NAME("RGB Sampler"), unk, hr)
00030 {
00031 this->AddRef();
00032
00033 m_data1 = NULL;
00034 m_data2 = NULL;
00035 };
00036
00037
00038
00039
00040
00041 TDSSampler::~TDSSampler()
00042 {
00043 delete [] m_data1;
00044 delete [] m_data2;
00045 }
00046
00047
00048
00049
00050
00051 HRESULT TDSSampler::CheckMediaType( const CMediaType* media )
00052 {
00053 if ( NULL == media )
00054 {
00055 return E_FAIL;
00056 }
00057
00058
00059
00060 if ( FORMAT_VideoInfo == ( *media->FormatType() ) )
00061 {
00062 VIDEOINFOHEADER* vi;
00063
00064 if (
00065 ! IsEqualGUID( *( media->Subtype() ), MEDIASUBTYPE_RGB24) ||
00066 ! ( vi = (VIDEOINFOHEADER *)media->Format() )
00067 )
00068 {
00069
00070 return E_FAIL;
00071 }
00072 else
00073 {
00074
00075 m_info = vi->bmiHeader;
00076 }
00077 }
00078 else
00079 {
00080
00081 if ( FORMAT_VideoInfo2 == ( *media->FormatType() ) )
00082 {
00083 VIDEOINFOHEADER2* vi;
00084
00085 if (
00086 ! IsEqualGUID( *( media->Subtype() ), MEDIASUBTYPE_RGB24) ||
00087 ! ( vi = (VIDEOINFOHEADER2 *)media->Format() )
00088 )
00089 {
00090
00091 return E_FAIL;
00092 }
00093 else
00094 {
00095
00096 m_info = vi->bmiHeader;
00097 }
00098 }
00099 else
00100 {
00101
00102 return E_FAIL;
00103 }
00104 }
00105
00106
00107
00108 m_rgb_width = m_info.biWidth;
00109 m_rgb_height = abs(m_info.biHeight);
00110 m_rgb_size = m_rgb_width * m_rgb_height * 3;
00111
00112 m_rowsFliped = m_info.biHeight >= 0;
00113
00114
00115 int tmp_width = m_rgb_width * 3;
00116 if ( (tmp_width % 4) > 0 )
00117 {
00118 m_img_align = 4 - ( tmp_width % 4 );
00119 }
00120 else
00121 {
00122 m_img_align = 0;
00123 }
00124 m_img_stride = tmp_width + m_img_align;
00125
00126
00127 delete [] m_data1;
00128 m_data1 = NULL;
00129 delete [] m_data2;
00130 m_data2 = NULL;
00131
00132 m_data1 = new BYTE[m_rgb_size];
00133 m_data2 = new BYTE[m_rgb_size];
00134
00135 return S_OK;
00136 }
00137
00138
00139
00140
00141
00142
00143
00144 HRESULT TDSSampler::DoRenderSample(IMediaSample *sample)
00145 {
00146
00147 BYTE * src = NULL;
00148 sample->GetPointer( &src );
00149
00150
00151
00152 DWORD offsetSrc = 0;
00153 DWORD offsetDst = 0;
00154 if ( m_rowsFliped )
00155 {
00156
00157 for ( int r = (m_rgb_height - 1) ; r >= 0 ; r-- )
00158 {
00159 offsetDst = r * m_rgb_width * 3;
00160
00161 for ( int c = 0 ; c < m_rgb_width ; c++ )
00162 {
00163 m_data2[offsetDst++] = src[offsetSrc++];
00164 m_data2[offsetDst++] = src[offsetSrc++];
00165 m_data2[offsetDst++] = src[offsetSrc++];
00166 }
00167 offsetSrc += m_img_align;
00168 }
00169 }
00170 else
00171 {
00172
00173 for ( int r = 0 ; r < m_rgb_height ; r++ )
00174 {
00175 for ( int c = 0 ; c < m_rgb_width ; c++ )
00176 {
00177 m_data2[offsetDst++] = src[offsetSrc++];
00178 m_data2[offsetDst++] = src[offsetSrc++];
00179 m_data2[offsetDst++] = src[offsetSrc++];
00180 }
00181 offsetSrc += m_img_align;
00182 }
00183 }
00184
00185
00186 m_cs.Lock();
00187 BYTE * tmp = m_data1;
00188 m_data1 = m_data2;
00189 m_data2 = tmp;
00190 m_cs.Unlock();
00191
00192 return S_OK;
00193 }
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 HRESULT TDSSampler::ShouldDrawSampleNow(
00204 IMediaSample *sample,
00205 REFERENCE_TIME *start,
00206 REFERENCE_TIME *stop
00207 )
00208 {
00209
00210
00211 return S_FALSE;
00212 }
00213
00214
00215
00216
00217
00218 void TDSSampler::GetData( void * data )
00219 {
00220
00221 m_cs.Lock();
00222
00223
00224 memcpy( data, m_data1, m_rgb_size );
00225
00226 m_cs.Unlock();
00227 }
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240 TVideoDSFile::TVideoDSFile(void)
00241 {
00242 m_graph = NULL;
00243 m_ctrl = NULL;
00244 m_sampler = NULL;
00245 }
00246
00247
00248
00249
00250
00251 TVideoDSFile::~TVideoDSFile(void)
00252 {
00253 this->Destroy();
00254 }
00255
00256
00257
00258
00259
00260
00261
00262
00263 bool TVideoDSFile::EnumCamera( IBaseFilter ** camera, IPin ** cameraOut )
00264 {
00265 HRESULT hr;
00266
00267 ICreateDevEnum* enums = NULL;
00268 hr = CoCreateInstance ( CLSID_SystemDeviceEnum, 0, CLSCTX_INPROC, IID_ICreateDevEnum, (void **) &enums );
00269 if ( FAILED ( hr ) )
00270 {
00271 return false;
00272 }
00273
00274 IEnumMoniker* enumsMon = NULL;
00275 hr = enums->CreateClassEnumerator ( CLSID_VideoInputDeviceCategory, &enumsMon, 0 );
00276 if ( FAILED ( hr ) )
00277 {
00278 enums->Release();
00279 return false;
00280 }
00281
00282 IMoniker* moniker = NULL;
00283 hr = enumsMon->Next (1, &moniker, 0 );
00284 if ( FAILED( hr ) )
00285 {
00286 enumsMon->Release();
00287 enums->Release();
00288 return false;
00289 }
00290
00291 IBaseFilter* lcamera = NULL;
00292 hr = moniker->BindToObject( 0, 0, IID_IBaseFilter, (void**) &lcamera );
00293 if ( FAILED ( hr ) )
00294 {
00295 moniker->Release();
00296 enumsMon->Release();
00297 enums->Release();
00298 return false;
00299 }
00300
00301 IEnumPins* enumsPins = NULL;
00302 hr = lcamera->EnumPins( &enumsPins );
00303 if ( FAILED( hr ) )
00304 {
00305 lcamera->Release();
00306 moniker->Release();
00307 enumsMon->Release();
00308 enums->Release();
00309 return false;
00310 }
00311
00312 IPin* lcameraOut = 0;
00313 hr = enumsPins->Next( 1, &lcameraOut, 0);
00314 if ( FAILED( hr ) )
00315 {
00316 enumsPins->Release();
00317 lcamera->Release();
00318 moniker->Release();
00319 enumsMon->Release();
00320 enums->Release();
00321 return false;
00322 }
00323
00324 *camera = lcamera;
00325 *cameraOut = lcameraOut;
00326
00327 return true;
00328 }
00329
00330
00331
00332
00333
00334
00335 bool TVideoDSFile::Initialize( void )
00336 {
00337 if ( ! m_graph )
00338 {
00339
00340
00341
00342 if ( FAILED( CoInitialize( 0 ) ) )
00343 {
00344 return false;
00345 }
00346
00347
00348 HRESULT hr =
00349 CoCreateInstance( CLSID_FilterGraph, 0, CLSCTX_INPROC, IID_IGraphBuilder, (void **) &m_graph );
00350 if ( FAILED( hr ) )
00351 {
00352 m_graph = NULL;
00353 CoUninitialize();
00354 return false;
00355 }
00356
00357 hr = m_graph->QueryInterface( IID_IMediaControl, (void **) &m_ctrl );
00358 if ( FAILED( hr ) )
00359 {
00360 m_ctrl = NULL;
00361 m_graph->Release(); m_graph = NULL;
00362 CoUninitialize();
00363 return false;
00364 }
00365
00366
00367 ICaptureGraphBuilder2 * builder = NULL;
00368 hr = CoCreateInstance( CLSID_CaptureGraphBuilder2, 0, CLSCTX_INPROC, IID_ICaptureGraphBuilder2, (void **) &builder );
00369 if ( FAILED( hr ) )
00370 {
00371 m_ctrl->Release(); m_ctrl = NULL;
00372 m_graph->Release(); m_graph = NULL;
00373 CoUninitialize();
00374 return false;
00375 }
00376
00377 hr = builder->SetFiltergraph( m_graph );
00378 if ( FAILED( hr ) )
00379 {
00380 builder->Release(); builder = NULL;
00381 m_ctrl->Release(); m_ctrl = NULL;
00382 m_graph->Release(); m_graph = NULL;
00383 CoUninitialize();
00384 return false;
00385 }
00386
00387
00388 m_sampler = new TDSSampler( 0, &hr );
00389
00390
00391
00392 IBaseFilter* video = NULL;
00393 IPin* videoOut = NULL;
00394
00395 if ( ! this->EnumCamera( &video, &videoOut ) )
00396 {
00397 m_sampler->Release(); m_sampler = NULL;
00398 builder->Release(); builder = NULL;
00399 m_ctrl->Release(); m_ctrl = NULL;
00400 m_graph->Release(); m_graph = NULL;
00401 CoUninitialize();
00402 return false;
00403 }
00404
00405 videoOut->Release();
00406 videoOut = NULL;
00407
00408
00409 hr = m_graph->AddFilter( video, L"DirectShow camera" );
00410 if ( FAILED ( hr ) )
00411 {
00412 video->Release(); video = NULL;
00413 m_sampler->Release(); m_sampler = NULL;
00414 builder->Release(); builder = NULL;
00415 m_ctrl->Release(); m_ctrl = NULL;
00416 m_graph->Release(); m_graph = NULL;
00417 CoUninitialize();
00418 return false;
00419 }
00420
00421
00422 hr = m_graph->AddFilter( (IBaseFilter*)m_sampler, L"Sampler" );
00423 if ( FAILED( hr ) )
00424 {
00425 video->Release(); video = NULL;
00426 m_sampler->Release(); m_sampler = NULL;
00427 builder->Release(); builder = NULL;
00428 m_ctrl->Release(); m_ctrl = NULL;
00429 m_graph->Release(); m_graph = NULL;
00430 CoUninitialize();
00431 return false;
00432 }
00433
00434 hr = builder->RenderStream( &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, video, NULL, m_sampler );
00435 if ( FAILED( hr ) )
00436 {
00437 video->Release(); video = NULL;
00438 m_sampler->Release(); m_sampler = NULL;
00439 builder->Release(); builder = NULL;
00440 m_ctrl->Release(); m_ctrl = NULL;
00441 m_graph->Release(); m_graph = NULL;
00442 CoUninitialize();
00443 return false;
00444 }
00445
00446
00447 builder->Release();
00448 builder = NULL;
00449
00450
00451 video->Release();
00452 video = NULL;
00453
00454
00455 {
00456 m_width = m_sampler->GetWidth();
00457 m_height = m_sampler->GetHeight();
00458 }
00459
00460
00461 hr = m_ctrl->Run();
00462 if ( FAILED( hr ) )
00463 {
00464 m_sampler->Release(); m_sampler = NULL;
00465 m_ctrl->Release(); m_ctrl = NULL;
00466 m_graph->Release(); m_graph = NULL;
00467 CoUninitialize();
00468 return false;
00469 }
00470
00471 return true;
00472 }
00473 else
00474 {
00475
00476 return true;
00477 }
00478 }
00479
00480
00481
00482 bool TVideoDSFile::Destroy(void)
00483 {
00484 if ( m_graph )
00485 {
00486
00487 m_ctrl->Stop();
00488
00489
00490 if ( m_sampler )
00491 {
00492 m_sampler->Release();
00493 m_sampler = NULL;
00494 }
00495
00496 if ( m_ctrl )
00497 {
00498 m_ctrl->Release();
00499 m_ctrl = NULL;
00500 }
00501
00502 m_graph->Release();
00503 m_graph = NULL;
00504
00505 CoUninitialize();
00506 }
00507
00508 return true;
00509 }
00510
00511
00512
00513
00514
00515
00516
00517
00518 void TVideoDSFile::GetDataRGB( void * data )
00519 {
00520 m_sampler->GetData( data );
00521 }
00522
00523
00524
00525
00526