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 "VideoDS.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 VIDEOINFO* vi;
00054
00055 if (
00056 ! IsEqualGUID( *media->Subtype(), MEDIASUBTYPE_RGB24) ||
00057 ! ( vi = (VIDEOINFO *)media->Format() )
00058 )
00059 {
00060
00061 return E_FAIL;
00062 }
00063
00064
00065 m_info = vi->bmiHeader;
00066
00067 m_rgb_width = m_info.biWidth;
00068 m_rgb_height = abs(m_info.biHeight);
00069 m_rgb_size = m_rgb_width * m_rgb_height * 3;
00070
00071 m_rowsFliped = m_info.biHeight >= 0;
00072
00073
00074 int tmp_width = m_rgb_width * 3;
00075 if ( (tmp_width % 4) > 0 )
00076 {
00077 m_img_align = 4 - ( tmp_width % 4 );
00078 }
00079 else
00080 {
00081 m_img_align = 0;
00082 }
00083 m_img_stride = tmp_width + m_img_align;
00084
00085
00086 delete [] m_data1;
00087 m_data1 = NULL;
00088 delete [] m_data2;
00089 m_data2 = NULL;
00090
00091 m_data1 = new BYTE[m_rgb_size];
00092 m_data2 = new BYTE[m_rgb_size];
00093
00094 return S_OK;
00095 }
00096
00097
00098
00099
00100
00101
00102
00103 HRESULT TDSSampler::DoRenderSample(IMediaSample *sample)
00104 {
00105
00106 BYTE * src = NULL;
00107 sample->GetPointer( &src );
00108
00109
00110
00111 DWORD offsetSrc = 0;
00112 DWORD offsetDst = 0;
00113 if ( m_rowsFliped )
00114 {
00115
00116 for ( int r = (m_rgb_height - 1) ; r >= 0 ; r-- )
00117 {
00118 offsetDst = r * m_rgb_width * 3;
00119
00120 for ( int c = 0 ; c < m_rgb_width ; c++ )
00121 {
00122 m_data2[offsetDst++] = src[offsetSrc++];
00123 m_data2[offsetDst++] = src[offsetSrc++];
00124 m_data2[offsetDst++] = src[offsetSrc++];
00125 }
00126 offsetSrc += m_img_align;
00127 }
00128 }
00129 else
00130 {
00131
00132 for ( int r = 0 ; r < m_rgb_height ; r++ )
00133 {
00134 for ( int c = 0 ; c < m_rgb_width ; c++ )
00135 {
00136 m_data2[offsetDst++] = src[offsetSrc++];
00137 m_data2[offsetDst++] = src[offsetSrc++];
00138 m_data2[offsetDst++] = src[offsetSrc++];
00139 }
00140 offsetSrc += m_img_align;
00141 }
00142 }
00143
00144
00145 m_cs.Lock();
00146 BYTE * tmp = m_data1;
00147 m_data1 = m_data2;
00148 m_data2 = tmp;
00149 m_cs.Unlock();
00150
00151 return S_OK;
00152 }
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162 HRESULT TDSSampler::ShouldDrawSampleNow(
00163 IMediaSample *sample,
00164 REFERENCE_TIME *start,
00165 REFERENCE_TIME *stop
00166 )
00167 {
00168
00169 return S_FALSE;
00170 }
00171
00172
00173
00174
00175
00176 void TDSSampler::GetData( void * data )
00177 {
00178
00179 m_cs.Lock();
00180
00181
00182 memcpy( data, m_data1, m_rgb_size );
00183
00184 m_cs.Unlock();
00185 }
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 TVideoDSFile::TVideoDSFile(void)
00199 {
00200 m_graph = NULL;
00201 m_ctrl = NULL;
00202 m_sampler = NULL;
00203 m_seek = NULL;
00204 }
00205
00206
00207
00208
00209
00210 TVideoDSFile::~TVideoDSFile(void)
00211 {
00212 this->Destroy();
00213 }
00214
00215
00216
00217
00218
00219
00220
00221 bool TVideoDSFile::Initialize( const char * filename )
00222 {
00223 if ( ! m_graph )
00224 {
00225
00226
00227
00228 if ( FAILED( CoInitialize( 0 ) ) )
00229 {
00230 return false;
00231 }
00232
00233
00234 HRESULT hr =
00235 CoCreateInstance( CLSID_FilterGraph, 0, CLSCTX_INPROC, IID_IGraphBuilder, (void **) &m_graph );
00236 if ( FAILED( hr ) )
00237 {
00238 m_graph = NULL;
00239 CoUninitialize();
00240 return false;
00241 }
00242
00243
00244 hr = m_graph->QueryInterface( IID_IMediaControl, (void **) &m_ctrl );
00245 if ( FAILED( hr ) )
00246 {
00247 m_ctrl = NULL;
00248 m_graph->Release(); m_graph = NULL;
00249 CoUninitialize();
00250 return false;
00251 }
00252
00253
00254 m_sampler = new TDSSampler( 0, &hr );
00255
00256
00257 size_t len = mbstowcs( NULL, filename, strlen( filename ) + 1 );
00258 wchar_t * tmp_filename = new wchar_t[len + 1];
00259 mbstowcs( tmp_filename, filename, strlen( filename ) + 1 );
00260
00261 IBaseFilter* video = NULL;
00262 hr = m_graph->AddSourceFilter ( tmp_filename, L"File Source", &video );
00263 delete [] tmp_filename;
00264 if ( FAILED( hr ) )
00265 {
00266 m_sampler->Release(); m_sampler = NULL;
00267 m_ctrl->Release(); m_ctrl = NULL;
00268 m_graph->Release(); m_graph = NULL;
00269 CoUninitialize();
00270 return false;
00271 }
00272
00273
00274 IPin* videoOut = NULL;
00275
00276 hr = video->FindPin( L"Output", &videoOut );
00277 if ( FAILED( hr ) )
00278 {
00279
00280 hr = video->FindPin( L"Raw Video 1", &videoOut );
00281 if ( FAILED( hr ) )
00282 {
00283 video->Release();
00284 m_sampler->Release(); m_sampler = NULL;
00285 m_ctrl->Release(); m_ctrl = NULL;
00286 m_graph->Release(); m_graph = NULL;
00287 CoUninitialize();
00288 return false;
00289 }
00290 }
00291 video->Release();
00292
00293
00294 IPin* samplerInput = NULL;
00295 hr = m_sampler->FindPin( L"In", &samplerInput );
00296 if ( FAILED ( hr ) )
00297 {
00298 videoOut->Release();
00299 m_sampler->Release(); m_sampler = NULL;
00300 m_ctrl->Release(); m_ctrl = NULL;
00301 m_graph->Release(); m_graph = NULL;
00302 CoUninitialize();
00303 return false;
00304 }
00305
00306
00307 hr = m_graph->AddFilter( (IBaseFilter*)m_sampler, L"Sampler" );
00308 if ( FAILED( hr ) )
00309 {
00310 samplerInput->Release();
00311 videoOut->Release();
00312 m_sampler->Release(); m_sampler = NULL;
00313 m_ctrl->Release(); m_ctrl = NULL;
00314 m_graph->Release(); m_graph = NULL;
00315 CoUninitialize();
00316 return false;
00317 }
00318
00319 hr = m_graph->Connect( videoOut, samplerInput );
00320 if ( FAILED( hr ) )
00321 {
00322 samplerInput->Release();
00323 videoOut->Release();
00324 m_sampler->Release(); m_sampler = NULL;
00325 m_ctrl->Release(); m_ctrl = NULL;
00326 m_graph->Release(); m_graph = NULL;
00327 CoUninitialize();
00328 return false;
00329 }
00330
00331 hr = m_graph->Render( videoOut );
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346 videoOut->Release();
00347 samplerInput->Release();
00348
00349
00350 {
00351 m_width = m_sampler->GetWidth();
00352 m_height = m_sampler->GetHeight();
00353 }
00354
00355
00356 hr = m_graph->QueryInterface ( IID_IMediaSeeking, (void **) &m_seek );
00357 if ( FAILED ( hr ) )
00358 {
00359 m_sampler->Release(); m_sampler = NULL;
00360 m_ctrl->Release(); m_ctrl = NULL;
00361 m_graph->Release(); m_graph = NULL;
00362 CoUninitialize();
00363 return false;
00364 }
00365
00366
00367 m_length = 0;
00368 m_seek->GetDuration( &m_length );
00369
00370
00371 hr = m_ctrl->Run();
00372 if ( FAILED( hr ) )
00373 {
00374 m_seek->Release();
00375 m_sampler->Release(); m_sampler = NULL;
00376 m_ctrl->Release(); m_ctrl = NULL;
00377 m_graph->Release(); m_graph = NULL;
00378 CoUninitialize();
00379 return false;
00380 }
00381
00382 return true;
00383 }
00384 else
00385 {
00386
00387 return true;
00388 }
00389 }
00390
00391
00392
00393 bool TVideoDSFile::Destroy(void)
00394 {
00395 if ( m_graph )
00396 {
00397
00398 m_ctrl->Stop();
00399
00400 if ( m_seek )
00401 {
00402 m_seek->Release();
00403 m_seek = NULL;
00404 }
00405
00406
00407 if ( m_sampler )
00408 {
00409 m_sampler->Release();
00410 m_sampler = NULL;
00411 }
00412
00413 if ( m_ctrl )
00414 {
00415 m_ctrl->Release();
00416 m_ctrl = NULL;
00417 }
00418
00419 m_graph->Release();
00420 m_graph = NULL;
00421
00422 CoUninitialize();
00423 }
00424
00425 return true;
00426 }
00427
00428
00429
00430
00431
00432
00433
00434
00435 void TVideoDSFile::GetDataRGB( void * data )
00436 {
00437 m_sampler->GetData( data );
00438
00439
00440 LONGLONG pos;
00441 m_seek->GetCurrentPosition( &pos );
00442 if ( pos == m_length )
00443 {
00444 pos = 0;
00445 m_seek->SetPositions( &pos, AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning );
00446 }
00447 }
00448
00449
00450
00451
00452