| 11 | cycrow | 1 | #include "Movies.h"
 | 
        
           |  |  | 2 | #include <dshow.h>
 | 
        
           |  |  | 3 | #include <windows.h>
 | 
        
           |  |  | 4 | #include <mmsystem.h>
 | 
        
           |  |  | 5 | #include <atlbase.h>
 | 
        
           |  |  | 6 |   | 
        
           |  |  | 7 | //#define NO_AUDIO_RENDERER
 | 
        
           |  |  | 8 |   | 
        
           |  |  | 9 | LPDIRECT3DTEXTURE9 m_pTexture = NULL; // our texture
 | 
        
           |  |  | 10 |   | 
        
           |  |  | 11 | CComPtr<IGraphBuilder>  g_pGB;          // GraphBuilder
 | 
        
           |  |  | 12 | CComPtr<IMediaControl>  g_pMC;          // Media Control
 | 
        
           |  |  | 13 | CComPtr<IMediaPosition> g_pMP;          // Media Position
 | 
        
           |  |  | 14 | CComPtr<IMediaEvent>    g_pME;          // Media Event
 | 
        
           |  |  | 15 | CComPtr<IBaseFilter>    g_pRenderer;    // our custom renderer
 | 
        
           |  |  | 16 |   | 
        
           |  |  | 17 | D3DFORMAT               g_TextureFormat; // Texture format
 | 
        
           |  |  | 18 |   | 
        
           |  |  | 19 |   | 
        
           |  |  | 20 | LPDIRECT3DDEVICE9 gD3dDevice2;
 | 
        
           |  |  | 21 |   | 
        
           |  |  | 22 | //////////
 | 
        
           |  |  | 23 | // Construction/Destruction
 | 
        
           |  |  | 24 | //
 | 
        
           |  |  | 25 |   | 
        
           |  |  | 26 | CMovies::CMovies()
 | 
        
           |  |  | 27 | {
 | 
        
           |  |  | 28 | 	Clean();
 | 
        
           |  |  | 29 | }
 | 
        
           |  |  | 30 |   | 
        
           |  |  | 31 | LPDIRECT3DTEXTURE9 CMovies::GetTexture () { return m_pTexture; }
 | 
        
           |  |  | 32 |   | 
        
           |  |  | 33 | CMovies::~CMovies()
 | 
        
           |  |  | 34 | {
 | 
        
           |  |  | 35 | 	CoUninitialize();
 | 
        
           |  |  | 36 | }
 | 
        
           |  |  | 37 |   | 
        
           |  |  | 38 | bool CMovies::Initialise( LPDIRECT3DDEVICE9 device, const char *szVideoFilename, LPDIRECT3DTEXTURE9 texture )
 | 
        
           |  |  | 39 | {
 | 
        
           |  |  | 40 | 	if ( m_cVideoFilename == szVideoFilename )
 | 
        
           |  |  | 41 | 	{
 | 
        
           |  |  | 42 | 		Stop();
 | 
        
           |  |  | 43 | 		return true;
 | 
        
           |  |  | 44 | 	}
 | 
        
           |  |  | 45 |   | 
        
           |  |  | 46 | 	Clean();
 | 
        
           |  |  | 47 |   | 
        
           |  |  | 48 | 	m_cVideoFilename = (char*)szVideoFilename; 
 | 
        
           |  |  | 49 |   | 
        
           |  |  | 50 | 	gD3dDevice2 = device;
 | 
        
           |  |  | 51 |   | 
        
           |  |  | 52 | 	//CoInitialize(NULL);
 | 
        
           |  |  | 53 |   | 
        
           |  |  | 54 | 	HRESULT hr = S_OK;
 | 
        
           |  |  | 55 | 	CComPtr<IBaseFilter>    pFSrc;			// Source Filter
 | 
        
           |  |  | 56 | 	CComPtr<IPin>           pFSrcPinOut;	// Source Filter Output Pin   
 | 
        
           |  |  | 57 | 	CTextureRenderer        *pCTR = 0;		// DirectShow Texture renderer
 | 
        
           |  |  | 58 |   | 
        
           |  |  | 59 | //	Create the filter graph
 | 
        
           |  |  | 60 | 	if ( FAILED( g_pGB.CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC) ) )
 | 
        
           |  |  | 61 | 		return false;
 | 
        
           |  |  | 62 |   | 
        
           |  |  | 63 | //	Create the Texture Renderer object
 | 
        
           |  |  | 64 | 	pCTR = new CTextureRenderer(NULL, &hr);
 | 
        
           |  |  | 65 |   | 
        
           |  |  | 66 |     if ( FAILED(hr) || !pCTR )
 | 
        
           |  |  | 67 | 		return false;
 | 
        
           |  |  | 68 |   | 
        
           |  |  | 69 | 	g_pRenderer = pCTR;
 | 
        
           |  |  | 70 | //	pFTR = pCTR;
 | 
        
           |  |  | 71 |   | 
        
           |  |  | 72 | 	if ( FAILED( g_pGB->AddFilter(g_pRenderer, L"TEXTURERENDERER") ) )
 | 
        
           |  |  | 73 | 		return false;
 | 
        
           |  |  | 74 |   | 
        
           |  |  | 75 | 	TCHAR strFileName[MAX_PATH];
 | 
        
           |  |  | 76 | 	WCHAR wFileName[MAX_PATH];
 | 
        
           |  |  | 77 |   | 
        
           |  |  | 78 | 	lstrcpyn( strFileName, szVideoFilename, MAX_PATH - 1 );
 | 
        
           |  |  | 79 |   | 
        
           |  |  | 80 |     strFileName[MAX_PATH-1] = 0;
 | 
        
           |  |  | 81 |     wFileName[MAX_PATH-1] = 0;
 | 
        
           |  |  | 82 |   | 
        
           |  |  | 83 | 	USES_CONVERSION;
 | 
        
           |  |  | 84 | 	wcsncpy(wFileName, T2W(strFileName), NUMELMS(wFileName));
 | 
        
           |  |  | 85 |   | 
        
           |  |  | 86 | 	hr = g_pGB->AddSourceFilter (wFileName, L"SOURCE", &pFSrc);
 | 
        
           |  |  | 87 |   | 
        
           |  |  | 88 | //	If the media file was not found, inform the user.
 | 
        
           |  |  | 89 | 	if ( hr == VFW_E_NOT_FOUND )
 | 
        
           |  |  | 90 | 	{
 | 
        
           |  |  | 91 | //		Msg(TEXT("Could not add source filter to graph!  (hr==VFW_E_NOT_FOUND)\r\n\r\n")
 | 
        
           |  |  | 92 | //			TEXT("This sample reads a media file from the DirectX SDK's media path.\r\n")
 | 
        
           |  |  | 93 | //			TEXT("Please install the DirectX 9 SDK on this machine."));
 | 
        
           |  |  | 94 | 		return false;
 | 
        
           |  |  | 95 | 	}
 | 
        
           |  |  | 96 | 	else if ( FAILED( hr ) )
 | 
        
           |  |  | 97 | 	{
 | 
        
           |  |  | 98 | //		Msg(TEXT("Could not add source filter to graph!  hr=0x%x"), hr);
 | 
        
           |  |  | 99 | 		return false;
 | 
        
           |  |  | 100 | 	}
 | 
        
           |  |  | 101 |   | 
        
           |  |  | 102 | 	if ( FAILED( pFSrc->FindPin(L"Output", &pFSrcPinOut) ) )
 | 
        
           |  |  | 103 | 	{
 | 
        
           |  |  | 104 | //		Msg(TEXT("Could not find output pin!  hr=0x%x"), hr);
 | 
        
           |  |  | 105 | 		return false;
 | 
        
           |  |  | 106 | 	}
 | 
        
           |  |  | 107 |   | 
        
           |  |  | 108 | #ifdef NO_AUDIO_RENDERER
 | 
        
           |  |  | 109 |   | 
        
           |  |  | 110 | 	CComPtr<IPin> pFTRPinIn;      // Texture Renderer Input Pin
 | 
        
           |  |  | 111 |   | 
        
           |  |  | 112 | //	Find the source's output pin and the renderer's input pin
 | 
        
           |  |  | 113 | 	if ( FAILED( g_pRenderer->FindPin(L"In", &pFTRPinIn) ) )
 | 
        
           |  |  | 114 | 	{
 | 
        
           |  |  | 115 | //		Msg(TEXT("Could not find input pin!  hr=0x%x"), hr);
 | 
        
           |  |  | 116 | 		return false;
 | 
        
           |  |  | 117 | 	}
 | 
        
           |  |  | 118 |   | 
        
           |  |  | 119 | //	Connect these two filters
 | 
        
           |  |  | 120 | 	if ( FAILED( g_pGB->Connect(pFSrcPinOut, pFTRPinIn) ) )
 | 
        
           |  |  | 121 | 	{
 | 
        
           |  |  | 122 | //		Msg(TEXT("Could not connect pins!  hr=0x%x"), hr);
 | 
        
           |  |  | 123 | 		return false;
 | 
        
           |  |  | 124 | 	}
 | 
        
           |  |  | 125 |   | 
        
           |  |  | 126 | #else
 | 
        
           |  |  | 127 |   | 
        
           |  |  | 128 | 	// Render the source filter's output pin.  The Filter Graph Manager
 | 
        
           |  |  | 129 | 	// will connect the video stream to the loaded CTextureRenderer
 | 
        
           |  |  | 130 | 	// and will load and connect an audio renderer (if needed).
 | 
        
           |  |  | 131 |   | 
        
           |  |  | 132 | 	if ( FAILED( g_pGB->Render(pFSrcPinOut) ) )
 | 
        
           |  |  | 133 | 	{
 | 
        
           |  |  | 134 | //		Msg(TEXT("Could not render source output pin!  hr=0x%x"), hr);
 | 
        
           |  |  | 135 | 		return false;
 | 
        
           |  |  | 136 | 	}
 | 
        
           |  |  | 137 |   | 
        
           |  |  | 138 | #endif
 | 
        
           |  |  | 139 |   | 
        
           |  |  | 140 | //	Get the graph's media control, event & position interfaces
 | 
        
           |  |  | 141 | 	g_pGB.QueryInterface(&g_pMC);
 | 
        
           |  |  | 142 | 	g_pGB.QueryInterface(&g_pMP);
 | 
        
           |  |  | 143 | 	g_pGB.QueryInterface(&g_pME);
 | 
        
           |  |  | 144 |   | 
        
           |  |  | 145 | 	m_iVideoWidth = pCTR->m_lVidWidth;
 | 
        
           |  |  | 146 | 	m_iVideoHeight = pCTR->m_lVidHeight;
 | 
        
           |  |  | 147 | 	m_fRotation = 0.0f;
 | 
        
           |  |  | 148 |   | 
        
           |  |  | 149 | 	return true;
 | 
        
           |  |  | 150 | }
 | 
        
           |  |  | 151 |   | 
        
           |  |  | 152 | void CMovies::Clean()
 | 
        
           |  |  | 153 | {
 | 
        
           |  |  | 154 | 	g_pGB = NULL;
 | 
        
           |  |  | 155 | 	g_pMP = NULL;
 | 
        
           |  |  | 156 | 	g_pMC = NULL;
 | 
        
           |  |  | 157 | 	g_pME = NULL;
 | 
        
           |  |  | 158 | 	g_pRenderer = NULL;
 | 
        
           |  |  | 159 |   | 
        
           |  |  | 160 | 	m_cVideoFilename = NULL;
 | 
        
           |  |  | 161 | 	m_bPlaying = false;
 | 
        
           |  |  | 162 | 	m_bPaused = true;
 | 
        
           |  |  | 163 | }
 | 
        
           |  |  | 164 |   | 
        
           |  |  | 165 | bool CMovies::Play()
 | 
        
           |  |  | 166 | {
 | 
        
           |  |  | 167 | 	if ( FAILED( g_pMC->Run() ) )
 | 
        
           |  |  | 168 | 		return false;
 | 
        
           |  |  | 169 |   | 
        
           |  |  | 170 | 	m_bPlaying = true;
 | 
        
           |  |  | 171 | 	m_bPaused = false;
 | 
        
           |  |  | 172 |   | 
        
           |  |  | 173 | 	return true;
 | 
        
           |  |  | 174 | }
 | 
        
           |  |  | 175 |   | 
        
           |  |  | 176 | bool CMovies::Stop()
 | 
        
           |  |  | 177 | {
 | 
        
           |  |  | 178 | 	if ( FAILED ( g_pMC->Stop() ) )
 | 
        
           |  |  | 179 | 		return false;
 | 
        
           |  |  | 180 |   | 
        
           |  |  | 181 | 	double temp;
 | 
        
           |  |  | 182 |   | 
        
           |  |  | 183 | 	g_pMP->get_CurrentPosition( &temp );
 | 
        
           |  |  | 184 |   | 
        
           |  |  | 185 | 	if ( FAILED ( g_pMP->put_CurrentPosition( 0 ) ) )
 | 
        
           |  |  | 186 | 		return false;
 | 
        
           |  |  | 187 |   | 
        
           |  |  | 188 | //	temp += 0;
 | 
        
           |  |  | 189 |   | 
        
           |  |  | 190 | 	m_bPlaying = false;
 | 
        
           |  |  | 191 | 	m_bPaused = true;
 | 
        
           |  |  | 192 |   | 
        
           |  |  | 193 | 	return true;
 | 
        
           |  |  | 194 | }
 | 
        
           |  |  | 195 |   | 
        
           |  |  | 196 | bool CMovies::Pause()
 | 
        
           |  |  | 197 | {
 | 
        
           |  |  | 198 | 	if ( FAILED ( g_pMC->Pause() ) )
 | 
        
           |  |  | 199 | 		return false;
 | 
        
           |  |  | 200 |   | 
        
           |  |  | 201 | 	m_bPaused = true;
 | 
        
           |  |  | 202 |   | 
        
           |  |  | 203 | 	return true;
 | 
        
           |  |  | 204 | }
 | 
        
           |  |  | 205 |   | 
        
           |  |  | 206 | bool CMovies::JumpTo( double PositionInSeconds )
 | 
        
           |  |  | 207 | {
 | 
        
           |  |  | 208 | 	if ( FAILED ( g_pMP->put_CurrentPosition( PositionInSeconds ) ) )
 | 
        
           |  |  | 209 | 		return false;
 | 
        
           |  |  | 210 |   | 
        
           |  |  | 211 | 	return true;
 | 
        
           |  |  | 212 | }
 | 
        
           |  |  | 213 |   | 
        
           |  |  | 214 | bool CMovies::HasMovieEnded()
 | 
        
           |  |  | 215 | {
 | 
        
           |  |  | 216 | 	long lEventCode, lParam1, lParam2;
 | 
        
           |  |  | 217 |   | 
        
           |  |  | 218 | //	Check for completion events
 | 
        
           |  |  | 219 | 	HRESULT hr = g_pME->GetEvent(&lEventCode, (LONG_PTR *) &lParam1, (LONG_PTR *) &lParam2, 0);
 | 
        
           |  |  | 220 |   | 
        
           |  |  | 221 | 	if (SUCCEEDED(hr))
 | 
        
           |  |  | 222 | 	{
 | 
        
           |  |  | 223 | 		if ( EC_COMPLETE == lEventCode ) 
 | 
        
           |  |  | 224 | 			return true;
 | 
        
           |  |  | 225 |   | 
        
           |  |  | 226 | //		Free any memory associated with this event
 | 
        
           |  |  | 227 | 		hr = g_pME->FreeEventParams(lEventCode, lParam1, lParam2);
 | 
        
           |  |  | 228 | 	}
 | 
        
           |  |  | 229 |   | 
        
           |  |  | 230 | 	return false;
 | 
        
           |  |  | 231 | }
 | 
        
           |  |  | 232 |   | 
        
           |  |  | 233 | long CMovies::MovieLength()
 | 
        
           |  |  | 234 | {
 | 
        
           |  |  | 235 | 	double length;
 | 
        
           |  |  | 236 |   | 
        
           |  |  | 237 | 	g_pMP->get_Duration( &length );
 | 
        
           |  |  | 238 |   | 
        
           |  |  | 239 | 	return (long)length * 1000;
 | 
        
           |  |  | 240 | }
 | 
        
           |  |  | 241 |   | 
        
           |  |  | 242 | //////////
 | 
        
           |  |  | 243 | //	Construction / Deconstruction
 | 
        
           |  |  | 244 | //
 | 
        
           |  |  | 245 | CTextureRenderer::CTextureRenderer( LPUNKNOWN pUnk, HRESULT *phr )
 | 
        
           |  |  | 246 |                                   : CBaseVideoRenderer(__uuidof(CLSID_TextureRenderer), 
 | 
        
           |  |  | 247 |                                     NAME("Texture Renderer"), pUnk, phr),
 | 
        
           |  |  | 248 |                                     m_bUseDynamicTextures(FALSE)
 | 
        
           |  |  | 249 | {
 | 
        
           |  |  | 250 | //	Store and AddRef the texture for our use.
 | 
        
           |  |  | 251 | 	if (phr)
 | 
        
           |  |  | 252 | 		*phr = S_OK;
 | 
        
           |  |  | 253 | }
 | 
        
           |  |  | 254 |   | 
        
           |  |  | 255 |   | 
        
           |  |  | 256 | CTextureRenderer::~CTextureRenderer()
 | 
        
           |  |  | 257 | {
 | 
        
           |  |  | 258 |   | 
        
           |  |  | 259 | }
 | 
        
           |  |  | 260 |   | 
        
           |  |  | 261 | HRESULT CTextureRenderer::CheckMediaType(const CMediaType *pmt)
 | 
        
           |  |  | 262 | {
 | 
        
           |  |  | 263 |   | 
        
           |  |  | 264 |     HRESULT   hr = E_FAIL;
 | 
        
           |  |  | 265 |     VIDEOINFO *pvi=0;
 | 
        
           |  |  | 266 |   | 
        
           |  |  | 267 |     CheckPointer(pmt,E_POINTER);
 | 
        
           |  |  | 268 |   | 
        
           |  |  | 269 |     // Reject the connection if this is not a video type
 | 
        
           |  |  | 270 |     if( *pmt->FormatType() != FORMAT_VideoInfo ) {
 | 
        
           |  |  | 271 |         return E_INVALIDARG;
 | 
        
           |  |  | 272 |     }
 | 
        
           |  |  | 273 |   | 
        
           |  |  | 274 | // Only accept RGB24 video
 | 
        
           |  |  | 275 |     pvi = (VIDEOINFO *)pmt->Format();
 | 
        
           |  |  | 276 |   | 
        
           |  |  | 277 |     if ( IsEqualGUID( *pmt->Type(),    MEDIATYPE_Video )  &&
 | 
        
           |  |  | 278 | 		 IsEqualGUID( *pmt->Subtype(), MEDIASUBTYPE_RGB24 ) )
 | 
        
           |  |  | 279 | 		hr = S_OK;
 | 
        
           |  |  | 280 |     return hr;
 | 
        
           |  |  | 281 |   }
 | 
        
           |  |  | 282 |   | 
        
           |  |  | 283 | HRESULT CTextureRenderer::SetMediaType(const CMediaType *pmt)
 | 
        
           |  |  | 284 | {
 | 
        
           |  |  | 285 |     HRESULT hr;
 | 
        
           |  |  | 286 |   | 
        
           |  |  | 287 |     UINT uintWidth = 2;
 | 
        
           |  |  | 288 |     UINT uintHeight = 2;
 | 
        
           |  |  | 289 |   | 
        
           |  |  | 290 |     // Retrive the size of this media type
 | 
        
           |  |  | 291 |     D3DCAPS9 caps;
 | 
        
           |  |  | 292 |     VIDEOINFO *pviBmp;                      // Bitmap info header
 | 
        
           |  |  | 293 |     pviBmp = (VIDEOINFO *)pmt->Format();
 | 
        
           |  |  | 294 |   | 
        
           |  |  | 295 |     m_lVidWidth  = pviBmp->bmiHeader.biWidth;
 | 
        
           |  |  | 296 |     m_lVidHeight = abs(pviBmp->bmiHeader.biHeight);
 | 
        
           |  |  | 297 |     m_lVidPitch  = (m_lVidWidth * 3 + 3) & ~(3); // We are forcing RGB24
 | 
        
           |  |  | 298 |   | 
        
           |  |  | 299 |     // here let's check if we can use dynamic textures
 | 
        
           |  |  | 300 |     ZeroMemory( &caps, sizeof(D3DCAPS9));
 | 
        
           |  |  | 301 |   | 
        
           |  |  | 302 |     hr = gD3dDevice2->GetDeviceCaps( &caps );
 | 
        
           |  |  | 303 | /*
 | 
        
           |  |  | 304 |     if ( caps.Caps2 & D3DCAPS2_DYNAMICTEXTURES )
 | 
        
           |  |  | 305 |     {
 | 
        
           |  |  | 306 |         m_bUseDynamicTextures = true;
 | 
        
           |  |  | 307 |     }*/
 | 
        
           |  |  | 308 |   | 
        
           |  |  | 309 |     if( caps.TextureCaps & D3DPTEXTURECAPS_POW2 )
 | 
        
           |  |  | 310 |     {
 | 
        
           |  |  | 311 |         while( (LONG)uintWidth < m_lVidWidth )
 | 
        
           |  |  | 312 |             uintWidth = uintWidth << 1;
 | 
        
           |  |  | 313 |   | 
        
           |  |  | 314 | 		while( (LONG)uintHeight < m_lVidHeight )
 | 
        
           |  |  | 315 |             uintHeight = uintHeight << 1;
 | 
        
           |  |  | 316 |     }
 | 
        
           |  |  | 317 |     else
 | 
        
           |  |  | 318 |     {
 | 
        
           |  |  | 319 |         uintWidth = m_lVidWidth;
 | 
        
           |  |  | 320 |         uintHeight = m_lVidHeight;
 | 
        
           |  |  | 321 |     }
 | 
        
           |  |  | 322 |   | 
        
           |  |  | 323 |   | 
        
           |  |  | 324 | //	Create the texture that maps to this media type
 | 
        
           |  |  | 325 |     hr = E_UNEXPECTED;
 | 
        
           |  |  | 326 |   | 
        
           |  |  | 327 |     if( m_bUseDynamicTextures )
 | 
        
           |  |  | 328 |     {
 | 
        
           |  |  | 329 |         hr = gD3dDevice2->CreateTexture( uintWidth, uintHeight, 1, D3DUSAGE_DYNAMIC, D3DFMT_X8R8G8B8,D3DPOOL_DEFAULT,
 | 
        
           |  |  | 330 | 										&m_pTexture, NULL );
 | 
        
           |  |  | 331 |         if( FAILED(hr))
 | 
        
           |  |  | 332 |             m_bUseDynamicTextures = FALSE;
 | 
        
           |  |  | 333 |     }
 | 
        
           |  |  | 334 |   | 
        
           |  |  | 335 |     if( FALSE == m_bUseDynamicTextures )
 | 
        
           |  |  | 336 |         hr = gD3dDevice2->CreateTexture(uintWidth, uintHeight, 1, 0, 
 | 
        
           |  |  | 337 |                                          D3DFMT_X8R8G8B8,D3DPOOL_MANAGED,
 | 
        
           |  |  | 338 |                                          &m_pTexture, NULL);
 | 
        
           |  |  | 339 |   | 
        
           |  |  | 340 | 	if ( FAILED(hr) )
 | 
        
           |  |  | 341 | 		return false;
 | 
        
           |  |  | 342 |   | 
        
           |  |  | 343 |     // CreateTexture can silently change the parameters on us
 | 
        
           |  |  | 344 |     D3DSURFACE_DESC ddsd;
 | 
        
           |  |  | 345 |     ZeroMemory(&ddsd, sizeof(ddsd));
 | 
        
           |  |  | 346 |   | 
        
           |  |  | 347 |     if ( FAILED( m_pTexture->GetLevelDesc( 0, &ddsd ) ) ) 
 | 
        
           |  |  | 348 |         return false;
 | 
        
           |  |  | 349 |   | 
        
           |  |  | 350 |     CComPtr<IDirect3DSurface9> pSurf; 
 | 
        
           |  |  | 351 |   | 
        
           |  |  | 352 |     if ( SUCCEEDED( hr = m_pTexture->GetSurfaceLevel(0, &pSurf) ) )
 | 
        
           |  |  | 353 |         pSurf->GetDesc(&ddsd);
 | 
        
           |  |  | 354 |   | 
        
           |  |  | 355 |     // Save format info
 | 
        
           |  |  | 356 |     g_TextureFormat = ddsd.Format;
 | 
        
           |  |  | 357 |   | 
        
           |  |  | 358 |     if ( (g_TextureFormat != D3DFMT_X8R8G8B8) && (g_TextureFormat != D3DFMT_A1R5G5B5) )
 | 
        
           |  |  | 359 |         return VFW_E_TYPE_NOT_ACCEPTED;
 | 
        
           |  |  | 360 |   | 
        
           |  |  | 361 |     return S_OK;
 | 
        
           |  |  | 362 | }
 | 
        
           |  |  | 363 |   | 
        
           |  |  | 364 | HRESULT CTextureRenderer::DoRenderSample( IMediaSample * pSample )
 | 
        
           |  |  | 365 | {
 | 
        
           |  |  | 366 |   | 
        
           |  |  | 367 |     BYTE  *pBmpBuffer, *pTxtBuffer; // Bitmap buffer, texture buffer
 | 
        
           |  |  | 368 |     LONG  lTxtPitch;                // Pitch of bitmap, texture
 | 
        
           |  |  | 369 |   | 
        
           |  |  | 370 |     BYTE  * pbS = NULL;
 | 
        
           |  |  | 371 |     DWORD * pdwS = NULL;
 | 
        
           |  |  | 372 |     DWORD * pdwD = NULL;
 | 
        
           |  |  | 373 |     UINT row, col, dwordWidth, backwards;
 | 
        
           |  |  | 374 |   | 
        
           |  |  | 375 |     CheckPointer( pSample,E_POINTER );
 | 
        
           |  |  | 376 |     CheckPointer( m_pTexture,E_UNEXPECTED );
 | 
        
           |  |  | 377 |   | 
        
           |  |  | 378 |     // Get the video bitmap buffer
 | 
        
           |  |  | 379 |     pSample->GetPointer( &pBmpBuffer );
 | 
        
           |  |  | 380 |   | 
        
           |  |  | 381 |     // Lock the Texture
 | 
        
           |  |  | 382 |     D3DLOCKED_RECT d3dlr;
 | 
        
           |  |  | 383 |     if( m_bUseDynamicTextures )
 | 
        
           |  |  | 384 |     {
 | 
        
           |  |  | 385 |         if( FAILED(m_pTexture->LockRect(0, &d3dlr, 0, D3DLOCK_DISCARD)))
 | 
        
           |  |  | 386 |             return E_FAIL;
 | 
        
           |  |  | 387 |     }
 | 
        
           |  |  | 388 |     else
 | 
        
           |  |  | 389 |     {
 | 
        
           |  |  | 390 |         if (FAILED(m_pTexture->LockRect(0, &d3dlr, 0, 0)))
 | 
        
           |  |  | 391 |             return E_FAIL;
 | 
        
           |  |  | 392 |     }
 | 
        
           |  |  | 393 |     // Get the texture buffer & pitch
 | 
        
           |  |  | 394 |     pTxtBuffer = static_cast<byte *>(d3dlr.pBits);
 | 
        
           |  |  | 395 |     lTxtPitch = d3dlr.Pitch;
 | 
        
           |  |  | 396 |   | 
        
           |  |  | 397 | //	Copy the bits    
 | 
        
           |  |  | 398 |     if ( g_TextureFormat == D3DFMT_X8R8G8B8 )
 | 
        
           |  |  | 399 |     {
 | 
        
           |  |  | 400 |         // Instead of copying data bytewise, we use DWORD alignment here.
 | 
        
           |  |  | 401 |         // We also unroll loop by copying 4 pixels at once.
 | 
        
           |  |  | 402 |         //
 | 
        
           |  |  | 403 |         // original BYTE array is [b0][g0][r0][b1][g1][r1][b2][g2][r2][b3][g3][r3]
 | 
        
           |  |  | 404 |         //
 | 
        
           |  |  | 405 |         // aligned DWORD array is     [b1 r0 g0 b0][g2 b2 r1 g1][r3 g3 b3 r2]
 | 
        
           |  |  | 406 |         //
 | 
        
           |  |  | 407 |         // We want to transform it to [ff r0 g0 b0][ff r1 g1 b1][ff r2 g2 b2][ff r3 b3 g3]
 | 
        
           |  |  | 408 |         // below, bitwise operations do exactly this.
 | 
        
           |  |  | 409 |   | 
        
           |  |  | 410 |         dwordWidth = m_lVidWidth / 4; // aligned width of the row, in DWORDS
 | 
        
           |  |  | 411 |                                       // (pixel by 3 bytes over sizeof(DWORD))
 | 
        
           |  |  | 412 |   | 
        
           |  |  | 413 | 		backwards = m_lVidWidth * m_lVidHeight * 4;
 | 
        
           |  |  | 414 |   | 
        
           |  |  | 415 |         for( row = 0; row< (UINT)m_lVidHeight; row++)
 | 
        
           |  |  | 416 |         {
 | 
        
           |  |  | 417 |             pdwS = ( DWORD* )pBmpBuffer;
 | 
        
           |  |  | 418 |             pdwD = ( DWORD* )pTxtBuffer;
 | 
        
           |  |  | 419 |   | 
        
           |  |  | 420 | 			for( col = 0; col < dwordWidth; col ++ )
 | 
        
           |  |  | 421 | 			{
 | 
        
           |  |  | 422 | 				pdwD[0] =  pdwS[0] | 0xFF000000;
 | 
        
           |  |  | 423 | 				pdwD[1] = ( ( pdwS[1] << 8)  | 0xFF000000) | ( pdwS[0] >> 24 );
 | 
        
           |  |  | 424 | 				pdwD[2] = ( ( pdwS[2] << 16) | 0xFF000000) | ( pdwS[1] >> 16 );
 | 
        
           |  |  | 425 | 				pdwD[3] = 0xFF000000 | ( pdwS[2] >> 8 );
 | 
        
           |  |  | 426 | 				pdwD += 4; 
 | 
        
           |  |  | 427 | 				pdwS += 3;
 | 
        
           |  |  | 428 | 			}
 | 
        
           |  |  | 429 |   | 
        
           |  |  | 430 |   | 
        
           |  |  | 431 | //			We might have remaining (misaligned) bytes here
 | 
        
           |  |  | 432 |             pbS = (BYTE*) pdwS;
 | 
        
           |  |  | 433 |             for( col = 0; col < (UINT)m_lVidWidth % 4; col++)
 | 
        
           |  |  | 434 |             {
 | 
        
           |  |  | 435 |                 *pdwD = 0xFF000000     |
 | 
        
           |  |  | 436 |                         (pbS[2] << 16) |
 | 
        
           |  |  | 437 |                         (pbS[1] <<  8) |
 | 
        
           |  |  | 438 |                         (pbS[0]);
 | 
        
           |  |  | 439 |                 pdwD++;
 | 
        
           |  |  | 440 |                 pbS += 3;           
 | 
        
           |  |  | 441 |             }
 | 
        
           |  |  | 442 |   | 
        
           |  |  | 443 |             pBmpBuffer  += m_lVidPitch;
 | 
        
           |  |  | 444 |             pTxtBuffer += lTxtPitch;
 | 
        
           |  |  | 445 |         }// for rows
 | 
        
           |  |  | 446 |     }
 | 
        
           |  |  | 447 |   | 
        
           |  |  | 448 |     if (g_TextureFormat == D3DFMT_A1R5G5B5) 
 | 
        
           |  |  | 449 |     {
 | 
        
           |  |  | 450 |         for(int y = 0; y < m_lVidHeight; y++ ) 
 | 
        
           |  |  | 451 |         {
 | 
        
           |  |  | 452 |             BYTE *pBmpBufferOld = pBmpBuffer;
 | 
        
           |  |  | 453 |             BYTE *pTxtBufferOld = pTxtBuffer;   
 | 
        
           |  |  | 454 |   | 
        
           |  |  | 455 |             for (int x = 0; x < m_lVidWidth; x++) 
 | 
        
           |  |  | 456 |             {
 | 
        
           |  |  | 457 |                 *(WORD *)pTxtBuffer = (WORD)
 | 
        
           |  |  | 458 |                     (0x8000 +
 | 
        
           |  |  | 459 |                     ((pBmpBuffer[2] & 0xF8) << 7) +
 | 
        
           |  |  | 460 |                     ((pBmpBuffer[1] & 0xF8) << 2) +
 | 
        
           |  |  | 461 |                     (pBmpBuffer[0] >> 3));
 | 
        
           |  |  | 462 |   | 
        
           |  |  | 463 |                 pTxtBuffer += 2;
 | 
        
           |  |  | 464 |                 pBmpBuffer += 3;
 | 
        
           |  |  | 465 |             }
 | 
        
           |  |  | 466 |   | 
        
           |  |  | 467 |             pBmpBuffer = pBmpBufferOld + m_lVidPitch;
 | 
        
           |  |  | 468 |             pTxtBuffer = pTxtBufferOld + lTxtPitch;
 | 
        
           |  |  | 469 |         }
 | 
        
           |  |  | 470 |     }
 | 
        
           |  |  | 471 |   | 
        
           |  |  | 472 |     // Unlock the Texture
 | 
        
           |  |  | 473 |     if ( FAILED( m_pTexture->UnlockRect(0) ) )
 | 
        
           |  |  | 474 |         return E_FAIL;
 | 
        
           |  |  | 475 |   | 
        
           |  |  | 476 |     return S_OK;
 | 
        
           |  |  | 477 | }
 | 
        
           |  |  | 478 |   | 
        
           |  |  | 479 |   | 
        
           |  |  | 480 |   |