00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "stdafx.h"
00023 #include "mplayerc.h"
00024 #include <atlbase.h>
00025 #include <atlcoll.h>
00026 #include "..\..\DSUtil\DSUtil.h"
00027
00028 #include <initguid.h>
00029 #include "DX7AllocatorPresenter.h"
00030 #include <ddraw.h>
00031 #include <d3d.h>
00032 #include "..\..\SubPic\DX7SubPic.h"
00033 #include "..\..\..\include\RealMedia\pntypes.h"
00034 #include "..\..\..\include\RealMedia\pnwintyp.h"
00035 #include "..\..\..\include\RealMedia\pncom.h"
00036 #include "..\..\..\include\RealMedia\rmavsurf.h"
00037 #include "IQTVideoSurface.h"
00038
00039 #include "IPinHook.h"
00040
00041 bool IsVMR7InGraph(IFilterGraph* pFG)
00042 {
00043 BeginEnumFilters(pFG, pEF, pBF)
00044 if(CComQIPtr<IVMRWindowlessControl>(pBF)) return(true);
00045 EndEnumFilters
00046 return(false);
00047 }
00048
00049 namespace DSObjects
00050 {
00051
00052 class CDX7AllocatorPresenter
00053 : public ISubPicAllocatorPresenterImpl
00054 {
00055 protected:
00056 CSize m_ScreenSize;
00057
00058 CComPtr<IDirectDraw7> m_pDD;
00059 CComQIPtr<IDirect3D7, &IID_IDirect3D7> m_pD3D;
00060 CComPtr<IDirect3DDevice7> m_pD3DDev;
00061
00062 CComPtr<IDirectDrawSurface7> m_pPrimary, m_pBackBuffer;
00063 CComPtr<IDirectDrawSurface7> m_pVideoTexture, m_pVideoSurface;
00064
00065 virtual HRESULT CreateDevice();
00066 virtual HRESULT AllocSurfaces();
00067 virtual void DeleteSurfaces();
00068
00069 public:
00070 CDX7AllocatorPresenter(HWND hWnd, HRESULT& hr);
00071
00072
00073 STDMETHODIMP CreateRenderer(IUnknown** ppRenderer);
00074 STDMETHODIMP_(bool) Paint(bool fAll);
00075 STDMETHODIMP GetDIB(BYTE* lpDib, DWORD* size);
00076 };
00077
00078 class CVMR7AllocatorPresenter
00079 : public CDX7AllocatorPresenter
00080 , public IVMRSurfaceAllocator
00081 , public IVMRImagePresenter
00082 , public IVMRWindowlessControl
00083 {
00084 CComPtr<IVMRSurfaceAllocatorNotify> m_pIVMRSurfAllocNotify;
00085 CComPtr<IVMRSurfaceAllocator> m_pSA;
00086
00087 HRESULT CreateDevice();
00088 void DeleteSurfaces();
00089
00090 bool m_fUseInternalTimer;
00091
00092 public:
00093 CVMR7AllocatorPresenter(HWND hWnd, HRESULT& hr);
00094
00095 DECLARE_IUNKNOWN
00096 STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
00097
00098
00099 STDMETHODIMP CreateRenderer(IUnknown** ppRenderer);
00100 STDMETHODIMP_(void) SetTime(REFERENCE_TIME rtNow);
00101
00102
00103 STDMETHODIMP AllocateSurface(DWORD_PTR dwUserID, VMRALLOCATIONINFO* lpAllocInfo, DWORD* lpdwBuffer, LPDIRECTDRAWSURFACE7* lplpSurface);
00104 STDMETHODIMP FreeSurface(DWORD_PTR dwUserID);
00105 STDMETHODIMP PrepareSurface(DWORD_PTR dwUserID, IDirectDrawSurface7* lpSurface, DWORD dwSurfaceFlags);
00106 STDMETHODIMP AdviseNotify(IVMRSurfaceAllocatorNotify* lpIVMRSurfAllocNotify);
00107
00108
00109 STDMETHODIMP StartPresenting(DWORD_PTR dwUserID);
00110 STDMETHODIMP StopPresenting(DWORD_PTR dwUserID);
00111 STDMETHODIMP PresentImage(DWORD_PTR dwUserID, VMRPRESENTATIONINFO* lpPresInfo);
00112
00113
00114 STDMETHODIMP GetNativeVideoSize(LONG* lpWidth, LONG* lpHeight, LONG* lpARWidth, LONG* lpARHeight);
00115 STDMETHODIMP GetMinIdealVideoSize(LONG* lpWidth, LONG* lpHeight);
00116 STDMETHODIMP GetMaxIdealVideoSize(LONG* lpWidth, LONG* lpHeight);
00117 STDMETHODIMP SetVideoPosition(const LPRECT lpSRCRect, const LPRECT lpDSTRect);
00118 STDMETHODIMP GetVideoPosition(LPRECT lpSRCRect, LPRECT lpDSTRect);
00119 STDMETHODIMP GetAspectRatioMode(DWORD* lpAspectRatioMode);
00120 STDMETHODIMP SetAspectRatioMode(DWORD AspectRatioMode);
00121 STDMETHODIMP SetVideoClippingWindow(HWND hwnd);
00122 STDMETHODIMP RepaintVideo(HWND hwnd, HDC hdc);
00123 STDMETHODIMP DisplayModeChanged();
00124 STDMETHODIMP GetCurrentImage(BYTE** lpDib);
00125 STDMETHODIMP SetBorderColor(COLORREF Clr);
00126 STDMETHODIMP GetBorderColor(COLORREF* lpClr);
00127 STDMETHODIMP SetColorKey(COLORREF Clr);
00128 STDMETHODIMP GetColorKey(COLORREF* lpClr);
00129 };
00130
00131 class CRM7AllocatorPresenter
00132 : public CDX7AllocatorPresenter
00133 , public IRMAVideoSurface
00134 {
00135 CComPtr<IDirectDrawSurface7> m_pVideoSurfaceOff;
00136 CComPtr<IDirectDrawSurface7> m_pVideoSurfaceYUY2;
00137
00138 RMABitmapInfoHeader m_bitmapInfo;
00139 RMABitmapInfoHeader m_lastBitmapInfo;
00140
00141 protected:
00142 HRESULT AllocSurfaces();
00143 void DeleteSurfaces();
00144
00145 public:
00146 CRM7AllocatorPresenter(HWND hWnd, HRESULT& hr);
00147
00148 DECLARE_IUNKNOWN
00149 STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
00150
00151
00152 STDMETHODIMP Blt(UCHAR* pImageData, RMABitmapInfoHeader* pBitmapInfo, REF(PNxRect) inDestRect, REF(PNxRect) inSrcRect);
00153 STDMETHODIMP BeginOptimizedBlt(RMABitmapInfoHeader* pBitmapInfo);
00154 STDMETHODIMP OptimizedBlt(UCHAR* pImageBits, REF(PNxRect) rDestRect, REF(PNxRect) rSrcRect);
00155 STDMETHODIMP EndOptimizedBlt();
00156 STDMETHODIMP GetOptimizedFormat(REF(RMA_COMPRESSION_TYPE) ulType);
00157 STDMETHODIMP GetPreferredFormat(REF(RMA_COMPRESSION_TYPE) ulType);
00158 };
00159
00160 class CQT7AllocatorPresenter
00161 : public CDX7AllocatorPresenter
00162 , public IQTVideoSurface
00163 {
00164 CComPtr<IDirectDrawSurface7> m_pVideoSurfaceOff;
00165
00166 protected:
00167 HRESULT AllocSurfaces();
00168 void DeleteSurfaces();
00169
00170 public:
00171 CQT7AllocatorPresenter(HWND hWnd, HRESULT& hr);
00172
00173 DECLARE_IUNKNOWN
00174 STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
00175
00176
00177 STDMETHODIMP BeginBlt(const BITMAP& bm);
00178 STDMETHODIMP DoBlt(const BITMAP& bm);
00179 };
00180
00181 }
00182 using namespace DSObjects;
00183
00184
00185
00186 HRESULT CreateAP7(const CLSID& clsid, HWND hWnd, ISubPicAllocatorPresenter** ppAP)
00187 {
00188 CheckPointer(ppAP, E_POINTER);
00189
00190 *ppAP = NULL;
00191
00192 HRESULT hr;
00193 if(clsid == CLSID_VMR7AllocatorPresenter && !(*ppAP = new CVMR7AllocatorPresenter(hWnd, hr))
00194 || clsid == CLSID_RM7AllocatorPresenter && !(*ppAP = new CRM7AllocatorPresenter(hWnd, hr))
00195 || clsid == CLSID_QT7AllocatorPresenter && !(*ppAP = new CQT7AllocatorPresenter(hWnd, hr)))
00196 return E_OUTOFMEMORY;
00197
00198 if(*ppAP == NULL)
00199 return E_FAIL;
00200
00201 (*ppAP)->AddRef();
00202
00203 if(FAILED(hr))
00204 {
00205 (*ppAP)->Release();
00206 *ppAP = NULL;
00207 }
00208
00209 return hr;
00210 }
00211
00212
00213
00214 static HRESULT TextureBlt(CComPtr<IDirect3DDevice7> pD3DDev, CComPtr<IDirectDrawSurface7> pTexture, Vector dst[4], CRect src)
00215 {
00216 if(!pTexture)
00217 return E_POINTER;
00218
00219 HRESULT hr;
00220
00221 do
00222 {
00223 DDSURFACEDESC2 ddsd;
00224 INITDDSTRUCT(ddsd);
00225 if(FAILED(hr = pTexture->GetSurfaceDesc(&ddsd)))
00226 break;
00227
00228 float w = (float)ddsd.dwWidth;
00229 float h = (float)ddsd.dwHeight;
00230
00231 struct
00232 {
00233 float x, y, z, rhw;
00234 float tu, tv;
00235 }
00236 pVertices[] =
00237 {
00238 {(float)dst[0].x, (float)dst[0].y, (float)dst[0].z, 1.0f/(float)dst[0].z, (float)src.left / w, (float)src.top / h},
00239 {(float)dst[1].x, (float)dst[1].y, (float)dst[1].z, 1.0f/(float)dst[1].z, (float)src.right / w, (float)src.top / h},
00240 {(float)dst[2].x, (float)dst[2].y, (float)dst[2].z, 1.0f/(float)dst[2].z, (float)src.left / w, (float)src.bottom / h},
00241 {(float)dst[3].x, (float)dst[3].y, (float)dst[3].z, 1.0f/(float)dst[3].z, (float)src.right / w, (float)src.bottom / h},
00242 };
00243
00244 for(int i = 0; i < countof(pVertices); i++)
00245 {
00246 pVertices[i].x -= 0.5;
00247 pVertices[i].y -= 0.5;
00248 }
00249
00250 hr = pD3DDev->SetTexture(0, pTexture);
00251
00252 pD3DDev->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE);
00253 pD3DDev->SetRenderState(D3DRENDERSTATE_LIGHTING, FALSE);
00254 pD3DDev->SetRenderState(D3DRENDERSTATE_BLENDENABLE, FALSE);
00255 pD3DDev->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE, FALSE);
00256
00257 pD3DDev->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTFG_LINEAR);
00258 pD3DDev->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTFN_LINEAR);
00259 pD3DDev->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTFP_LINEAR);
00260
00261 pD3DDev->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP);
00262
00263
00264
00265 if(FAILED(hr = pD3DDev->BeginScene()))
00266 break;
00267
00268 hr = pD3DDev->DrawPrimitive(D3DPT_TRIANGLESTRIP,
00269 D3DFVF_XYZRHW | D3DFVF_TEX1,
00270 pVertices, 4, D3DDP_WAIT);
00271 pD3DDev->EndScene();
00272
00273
00274
00275 pD3DDev->SetTexture(0, NULL);
00276
00277 return S_OK;
00278 }
00279 while(0);
00280
00281 return E_FAIL;
00282 }
00283
00284
00285
00286
00287
00288 CDX7AllocatorPresenter::CDX7AllocatorPresenter(HWND hWnd, HRESULT& hr)
00289 : ISubPicAllocatorPresenterImpl(hWnd)
00290 , m_ScreenSize(0, 0)
00291 {
00292 if(!IsWindow(m_hWnd))
00293 {
00294 hr = E_INVALIDARG;
00295 return;
00296 }
00297
00298 if(FAILED(hr = DirectDrawCreateEx(NULL, (VOID**)&m_pDD, IID_IDirectDraw7, NULL))
00299 || FAILED(hr = m_pDD->SetCooperativeLevel(AfxGetMainWnd()->GetSafeHwnd(), DDSCL_NORMAL)))
00300 return;
00301
00302 if(!(m_pD3D = m_pDD))
00303 {
00304 hr = E_NOINTERFACE;
00305 return;
00306 }
00307
00308 GetWindowRect(m_hWnd, &m_WindowRect);
00309
00310 hr = CreateDevice();
00311 }
00312
00313 HRESULT CDX7AllocatorPresenter::CreateDevice()
00314 {
00315 m_pD3DDev = NULL;
00316
00317 m_pPrimary = NULL;
00318 m_pBackBuffer = NULL;
00319
00320 DDSURFACEDESC2 ddsd;
00321 INITDDSTRUCT(ddsd);
00322 if(FAILED(m_pDD->GetDisplayMode(&ddsd))
00323 || ddsd.ddpfPixelFormat.dwRGBBitCount <= 8)
00324 return DDERR_INVALIDMODE;
00325
00326 m_ScreenSize.SetSize(ddsd.dwWidth, ddsd.dwHeight);
00327
00328 HRESULT hr;
00329
00330
00331
00332 INITDDSTRUCT(ddsd);
00333 ddsd.dwFlags = DDSD_CAPS;
00334 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
00335 if(FAILED(hr = m_pDD->CreateSurface(&ddsd, &m_pPrimary, NULL)))
00336 return hr;
00337
00338 CComPtr<IDirectDrawClipper> pcClipper;
00339 if(FAILED(hr = m_pDD->CreateClipper(0, &pcClipper, NULL)))
00340 return hr;
00341 pcClipper->SetHWnd(0, m_hWnd);
00342 m_pPrimary->SetClipper(pcClipper);
00343
00344
00345
00346 INITDDSTRUCT(ddsd);
00347 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
00348 ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_3DDEVICE;
00349 ddsd.dwWidth = m_ScreenSize.cx;
00350 ddsd.dwHeight = m_ScreenSize.cy;
00351 if(FAILED(hr = m_pDD->CreateSurface(&ddsd, &m_pBackBuffer, NULL)))
00352 return hr;
00353
00354 pcClipper = NULL;
00355 if(FAILED(hr = m_pDD->CreateClipper(0, &pcClipper, NULL)))
00356 return hr;
00357 BYTE rgnDataBuffer[1024];
00358 HRGN hrgn = CreateRectRgn(0, 0, ddsd.dwWidth, ddsd.dwHeight);
00359 GetRegionData(hrgn, sizeof(rgnDataBuffer), (RGNDATA*)rgnDataBuffer);
00360 DeleteObject(hrgn);
00361 pcClipper->SetClipList((RGNDATA*)rgnDataBuffer, 0);
00362 m_pBackBuffer->SetClipper(pcClipper);
00363
00364
00365
00366 if(FAILED(hr = m_pD3D->CreateDevice(IID_IDirect3DHALDevice, m_pBackBuffer, &m_pD3DDev)))
00367 return hr;
00368
00369
00370
00371 CComPtr<ISubPicProvider> pSubPicProvider;
00372 if(m_pSubPicQueue) m_pSubPicQueue->GetSubPicProvider(&pSubPicProvider);
00373
00374 CSize size;
00375 switch(AfxGetAppSettings().nSPCMaxRes)
00376 {
00377 case 0: default: size = m_ScreenSize; break;
00378 case 1: size.SetSize(1024, 768); break;
00379 case 2: size.SetSize(800, 600); break;
00380 case 3: size.SetSize(640, 480); break;
00381 case 4: size.SetSize(512, 384); break;
00382 case 5: size.SetSize(384, 288); break;
00383 }
00384
00385 if(m_pAllocator)
00386 {
00387 m_pAllocator->ChangeDevice(m_pD3DDev);
00388 }
00389 else
00390 {
00391 m_pAllocator = new CDX7SubPicAllocator(m_pD3DDev, size, AfxGetAppSettings().fSPCPow2Tex);
00392 if(!m_pAllocator || FAILED(hr))
00393 return E_FAIL;
00394 }
00395
00396 hr = S_OK;
00397 m_pSubPicQueue = AfxGetAppSettings().nSPCSize > 0
00398 ? (ISubPicQueue*)new CSubPicQueue(AfxGetAppSettings().nSPCSize, m_pAllocator, &hr)
00399 : (ISubPicQueue*)new CSubPicQueueNoThread(m_pAllocator, &hr);
00400 if(!m_pSubPicQueue || FAILED(hr))
00401 return E_FAIL;
00402
00403 if(pSubPicProvider) m_pSubPicQueue->SetSubPicProvider(pSubPicProvider);
00404
00405 return S_OK;
00406 }
00407
00408 HRESULT CDX7AllocatorPresenter::AllocSurfaces()
00409 {
00410 CAutoLock cAutoLock(this);
00411
00412 AppSettings& s = AfxGetAppSettings();
00413
00414 m_pVideoTexture = NULL;
00415 m_pVideoSurface = NULL;
00416
00417 DDSURFACEDESC2 ddsd;
00418 INITDDSTRUCT(ddsd);
00419 ddsd.dwFlags = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT;
00420 ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY;
00421 ddsd.dwWidth = m_NativeVideoSize.cx;
00422 ddsd.dwHeight = m_NativeVideoSize.cy;
00423 ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
00424 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
00425 ddsd.ddpfPixelFormat.dwRGBBitCount = 32;
00426 ddsd.ddpfPixelFormat.dwRBitMask = 0x00FF0000;
00427 ddsd.ddpfPixelFormat.dwGBitMask = 0x0000FF00;
00428 ddsd.ddpfPixelFormat.dwBBitMask = 0x000000FF;
00429
00430 if(s.iAPSurfaceUsage == VIDRNDT_AP_TEXTURE2D || s.iAPSurfaceUsage == VIDRNDT_AP_TEXTURE3D)
00431 {
00432 ddsd.ddsCaps.dwCaps |= DDSCAPS_TEXTURE;
00433
00434
00435 }
00436
00437 HRESULT hr = m_pDD->CreateSurface(&ddsd, &m_pVideoSurface, NULL);
00438 if(FAILED(hr))
00439 {
00440
00441 DDSURFACEDESC2 ddsd2;
00442 INITDDSTRUCT(ddsd2);
00443 if(!(s.iAPSurfaceUsage == VIDRNDT_AP_TEXTURE2D || s.iAPSurfaceUsage == VIDRNDT_AP_TEXTURE3D)
00444 && SUCCEEDED(m_pDD->GetDisplayMode(&ddsd2))
00445 && ddsd2.ddpfPixelFormat.dwRGBBitCount == 16)
00446 {
00447 ddsd.ddpfPixelFormat.dwRGBBitCount = 16;
00448 ddsd.ddpfPixelFormat.dwRBitMask = 0x0000F800;
00449 ddsd.ddpfPixelFormat.dwGBitMask = 0x000007E0;
00450 ddsd.ddpfPixelFormat.dwBBitMask = 0x0000001F;
00451 hr = m_pDD->CreateSurface(&ddsd, &m_pVideoSurface, NULL);
00452 }
00453
00454 if(FAILED(hr))
00455 return hr;
00456 }
00457
00458 if(s.iAPSurfaceUsage == VIDRNDT_AP_TEXTURE3D)
00459 m_pVideoTexture = m_pVideoSurface;
00460
00461 DDBLTFX fx;
00462 INITDDSTRUCT(fx);
00463 fx.dwFillColor = 0;
00464 hr = m_pVideoSurface->Blt(NULL, NULL, NULL, DDBLT_WAIT|DDBLT_COLORFILL, &fx);
00465
00466 return S_OK;
00467 }
00468
00469 void CDX7AllocatorPresenter::DeleteSurfaces()
00470 {
00471 CAutoLock cAutoLock(this);
00472
00473 m_pVideoTexture = NULL;
00474 m_pVideoSurface = NULL;
00475 }
00476
00477
00478
00479 STDMETHODIMP CDX7AllocatorPresenter::CreateRenderer(IUnknown** ppRenderer)
00480 {
00481 return E_NOTIMPL;
00482 }
00483
00484 STDMETHODIMP_(bool) CDX7AllocatorPresenter::Paint(bool fAll)
00485 {
00486 CAutoLock cAutoLock(this);
00487
00488 if(m_WindowRect.right <= m_WindowRect.left || m_WindowRect.bottom <= m_WindowRect.top
00489 || m_NativeVideoSize.cx <= 0 || m_NativeVideoSize.cy <= 0
00490 || !m_pPrimary || !m_pBackBuffer || !m_pVideoSurface)
00491 return(false);
00492
00493 HRESULT hr;
00494
00495 CRect rSrcVid(CPoint(0, 0), m_NativeVideoSize);
00496 CRect rDstVid(m_VideoRect);
00497
00498 CRect rSrcPri(CPoint(0, 0), m_WindowRect.Size());
00499 CRect rDstPri(m_WindowRect);
00500 MapWindowRect(m_hWnd, HWND_DESKTOP, &rDstPri);
00501
00502 if(fAll)
00503 {
00504
00505
00506 CRect rl(0, 0, rDstVid.left, rSrcPri.bottom);
00507 CRect rr(rDstVid.right, 0, rSrcPri.right, rSrcPri.bottom);
00508 CRect rt(0, 0, rSrcPri.right, rDstVid.top);
00509 CRect rb(0, rDstVid.bottom, rSrcPri.right, rSrcPri.bottom);
00510
00511 DDBLTFX fx;
00512 INITDDSTRUCT(fx);
00513 fx.dwFillColor = 0;
00514 hr = m_pBackBuffer->Blt(NULL, NULL, NULL, DDBLT_WAIT|DDBLT_COLORFILL, &fx);
00515
00516
00517
00518 if(!rDstVid.IsRectEmpty())
00519 {
00520 if(m_pVideoTexture)
00521 {
00522 Vector v[4];
00523 Transform(rDstVid, v);
00524 hr = TextureBlt(m_pD3DDev, m_pVideoTexture, v, rSrcVid);
00525 }
00526 else
00527 {
00528 hr = m_pBackBuffer->Blt(rDstVid, m_pVideoSurface, rSrcVid, DDBLT_WAIT, NULL);
00529 }
00530 }
00531
00532
00533
00534 AlphaBltSubPic(rSrcPri.Size());
00535 }
00536
00537
00538
00539 m_pDD->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, NULL);
00540
00541
00542
00543 hr = m_pPrimary->Blt(rDstPri, m_pBackBuffer, rSrcPri, DDBLT_WAIT, NULL);
00544
00545 if(hr == DDERR_SURFACELOST)
00546 {
00547 HRESULT hr = DDERR_WRONGMODE;
00548
00549 if(hr == DDERR_WRONGMODE)
00550 {
00551 DeleteSurfaces();
00552 if(SUCCEEDED(CreateDevice()) || FAILED(hr = AllocSurfaces()))
00553 return(true);
00554 }
00555
00556 hr = S_OK;
00557 }
00558
00559 return(true);
00560 }
00561
00562 STDMETHODIMP CDX7AllocatorPresenter::GetDIB(BYTE* lpDib, DWORD* size)
00563 {
00564 CheckPointer(size, E_POINTER);
00565
00566 HRESULT hr;
00567
00568 DDSURFACEDESC2 ddsd;
00569 INITDDSTRUCT(ddsd);
00570 if(FAILED(m_pVideoSurface->GetSurfaceDesc(&ddsd)))
00571 return E_FAIL;
00572
00573 if(ddsd.ddpfPixelFormat.dwRGBBitCount != 16 && ddsd.ddpfPixelFormat.dwRGBBitCount != 32)
00574 return E_FAIL;
00575
00576 DWORD required = sizeof(BITMAPINFOHEADER) + (ddsd.dwWidth*ddsd.dwHeight*32>>3);
00577 if(!lpDib) {*size = required; return S_OK;}
00578 if(*size < required) return E_OUTOFMEMORY;
00579 *size = required;
00580
00581 INITDDSTRUCT(ddsd);
00582 if(FAILED(hr = m_pVideoSurface->Lock(NULL, &ddsd, DDLOCK_WAIT|DDLOCK_SURFACEMEMORYPTR|DDLOCK_READONLY|DDLOCK_NOSYSLOCK, NULL)))
00583 {
00584
00585 return hr;
00586 }
00587
00588 BITMAPINFOHEADER* bih = (BITMAPINFOHEADER*)lpDib;
00589 memset(bih, 0, sizeof(BITMAPINFOHEADER));
00590 bih->biSize = sizeof(BITMAPINFOHEADER);
00591 bih->biWidth = ddsd.dwWidth;
00592 bih->biHeight = ddsd.dwHeight;
00593 bih->biBitCount = 32;
00594 bih->biPlanes = 1;
00595 bih->biSizeImage = bih->biWidth*bih->biHeight*bih->biBitCount>>3;
00596
00597 BitBltFromRGBToRGB(
00598 bih->biWidth, bih->biHeight,
00599 (BYTE*)(bih + 1), bih->biWidth*bih->biBitCount>>3, bih->biBitCount,
00600 (BYTE*)ddsd.lpSurface + ddsd.lPitch*(ddsd.dwHeight-1), -(int)ddsd.lPitch, ddsd.ddpfPixelFormat.dwRGBBitCount);
00601
00602 m_pVideoSurface->Unlock(NULL);
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614 return S_OK;
00615 }
00616
00617
00618
00619
00620
00621 #define MY_USER_ID 0x6ABE51
00622
00623 CVMR7AllocatorPresenter::CVMR7AllocatorPresenter(HWND hWnd, HRESULT& hr)
00624 : CDX7AllocatorPresenter(hWnd, hr)
00625 , m_fUseInternalTimer(true)
00626 {
00627 if(FAILED(hr))
00628 return;
00629
00630 if(FAILED(hr = m_pSA.CoCreateInstance(CLSID_AllocPresenter)))
00631 {
00632 hr = E_FAIL;
00633 return;
00634 }
00635 }
00636
00637 STDMETHODIMP CVMR7AllocatorPresenter::NonDelegatingQueryInterface(REFIID riid, void** ppv)
00638 {
00639 CheckPointer(ppv, E_POINTER);
00640
00641 return
00642 QI(IVMRSurfaceAllocator)
00643 QI(IVMRImagePresenter)
00644 QI(IVMRWindowlessControl)
00645 __super::NonDelegatingQueryInterface(riid, ppv);
00646 }
00647
00648 HRESULT CVMR7AllocatorPresenter::CreateDevice()
00649 {
00650 HRESULT hr = __super::CreateDevice();
00651 if(FAILED(hr)) return hr;
00652
00653 if(m_pIVMRSurfAllocNotify)
00654 {
00655 HMONITOR hMonitor = MonitorFromWindow(m_hWnd, MONITOR_DEFAULTTONEAREST);
00656 if(FAILED(hr = m_pIVMRSurfAllocNotify->ChangeDDrawDevice(m_pDD, hMonitor)))
00657 return(false);
00658 }
00659
00660 return hr;
00661 }
00662
00663 void CVMR7AllocatorPresenter::DeleteSurfaces()
00664 {
00665 CAutoLock cAutoLock(this);
00666
00667 m_pSA->FreeSurface(MY_USER_ID);
00668
00669 __super::DeleteSurfaces();
00670 }
00671
00672
00673
00674 STDMETHODIMP CVMR7AllocatorPresenter::CreateRenderer(IUnknown** ppRenderer)
00675 {
00676 CheckPointer(ppRenderer, E_POINTER);
00677
00678 *ppRenderer = NULL;
00679
00680 HRESULT hr;
00681
00682 do
00683 {
00684 CComPtr<IBaseFilter> pBF;
00685
00686 if(FAILED(hr = pBF.CoCreateInstance(CLSID_VideoMixingRenderer)))
00687 break;
00688
00689 CComQIPtr<IVMRFilterConfig> pConfig = pBF;
00690 if(!pConfig)
00691 break;
00692
00693 if(FAILED(hr = pConfig->SetRenderingMode(VMRMode_Renderless)))
00694 break;
00695
00696 CComQIPtr<IVMRSurfaceAllocatorNotify> pSAN = pBF;
00697 if(!pSAN)
00698 break;
00699
00700 if(FAILED(hr = pSAN->AdviseSurfaceAllocator(MY_USER_ID, static_cast<IVMRSurfaceAllocator*>(this)))
00701 || FAILED(hr = AdviseNotify(pSAN)))
00702 break;
00703
00704 CComPtr<IPin> pPin = GetFirstPin(pBF);
00705 HookNewSegment((IPinC*)(IPin*)pPin);
00706
00707 *ppRenderer = (IUnknown*)pBF.Detach();
00708
00709 return S_OK;
00710 }
00711 while(0);
00712
00713 return E_FAIL;
00714 }
00715
00716 STDMETHODIMP_(void) CVMR7AllocatorPresenter::SetTime(REFERENCE_TIME rtNow)
00717 {
00718 m_fUseInternalTimer = false;
00719 __super::SetTime(rtNow);
00720 }
00721
00722
00723
00724 STDMETHODIMP CVMR7AllocatorPresenter::AllocateSurface(DWORD_PTR dwUserID, VMRALLOCATIONINFO* lpAllocInfo, DWORD* lpdwBuffer, LPDIRECTDRAWSURFACE7* lplpSurface)
00725 {
00726 if(!lpAllocInfo || !lpdwBuffer || !lplpSurface)
00727 return E_POINTER;
00728
00729 if(!m_pIVMRSurfAllocNotify)
00730 return E_FAIL;
00731
00732 HRESULT hr;
00733
00734 DeleteSurfaces();
00735
00736
00737
00738
00739
00740
00741 if(lpAllocInfo->lpHdr->biBitCount < 16)
00742 return E_FAIL;
00743
00744 hr = m_pSA->AllocateSurface(dwUserID, lpAllocInfo, lpdwBuffer, lplpSurface);
00745 if(FAILED(hr))
00746 return hr;
00747
00748 m_NativeVideoSize = CSize(abs(lpAllocInfo->lpHdr->biWidth), abs(lpAllocInfo->lpHdr->biHeight));
00749 m_AspectRatio = m_NativeVideoSize;
00750 int arx = lpAllocInfo->szAspectRatio.cx, ary = lpAllocInfo->szAspectRatio.cy;
00751 if(arx > 0 && ary > 0) m_AspectRatio.SetSize(arx, ary);
00752
00753 if(FAILED(hr = AllocSurfaces()))
00754 return hr;
00755
00756
00757 if(FAILED(hr = m_pVideoSurface->Blt(NULL, *lplpSurface, NULL, DDBLT_WAIT, NULL)))
00758 {
00759 DeleteSurfaces();
00760 return hr;
00761 }
00762
00763 DDBLTFX fx;
00764 INITDDSTRUCT(fx);
00765 fx.dwFillColor = 0;
00766 m_pVideoSurface->Blt(NULL, NULL, NULL, DDBLT_WAIT|DDBLT_COLORFILL, &fx);
00767
00768 return hr;
00769 }
00770
00771 STDMETHODIMP CVMR7AllocatorPresenter::FreeSurface(DWORD_PTR dwUserID)
00772 {
00773 DeleteSurfaces();
00774 return S_OK;
00775 }
00776
00777 STDMETHODIMP CVMR7AllocatorPresenter::PrepareSurface(DWORD_PTR dwUserID, IDirectDrawSurface7* lpSurface, DWORD dwSurfaceFlags)
00778 {
00779 if(!lpSurface)
00780 return E_POINTER;
00781
00782
00783
00784
00785 return S_OK;
00786
00787
00788
00789 }
00790
00791 STDMETHODIMP CVMR7AllocatorPresenter::AdviseNotify(IVMRSurfaceAllocatorNotify* lpIVMRSurfAllocNotify)
00792 {
00793 CAutoLock cAutoLock(this);
00794
00795 m_pIVMRSurfAllocNotify = lpIVMRSurfAllocNotify;
00796
00797 HRESULT hr;
00798 HMONITOR hMonitor = MonitorFromWindow(m_hWnd, MONITOR_DEFAULTTONEAREST);
00799 if(FAILED(hr = m_pIVMRSurfAllocNotify->SetDDrawDevice(m_pDD, hMonitor)))
00800 return hr;
00801
00802 return m_pSA->AdviseNotify(lpIVMRSurfAllocNotify);
00803 }
00804
00805
00806
00807 STDMETHODIMP CVMR7AllocatorPresenter::StartPresenting(DWORD_PTR dwUserID)
00808 {
00809 CAutoLock cAutoLock(this);
00810
00811 ASSERT(m_pD3DDev);
00812
00813 return m_pD3DDev ? S_OK : E_FAIL;
00814 }
00815
00816 STDMETHODIMP CVMR7AllocatorPresenter::StopPresenting(DWORD_PTR dwUserID)
00817 {
00818 return S_OK;
00819 }
00820
00821 STDMETHODIMP CVMR7AllocatorPresenter::PresentImage(DWORD_PTR dwUserID, VMRPRESENTATIONINFO* lpPresInfo)
00822 {
00823 HRESULT hr;
00824
00825 {
00826 if(!lpPresInfo || !lpPresInfo->lpSurf)
00827 return E_POINTER;
00828
00829 CAutoLock cAutoLock(this);
00830
00831 hr = m_pVideoSurface->Blt(NULL, lpPresInfo->lpSurf, NULL, DDBLT_WAIT, NULL);
00832
00833 if(lpPresInfo->rtEnd > lpPresInfo->rtStart)
00834 {
00835 REFERENCE_TIME rtTimePerFrame = lpPresInfo->rtEnd - lpPresInfo->rtStart;
00836 m_fps = 10000000.0 / rtTimePerFrame;
00837 if(m_pSubPicQueue)
00838 {
00839 m_pSubPicQueue->SetFPS(m_fps);
00840 if(m_fUseInternalTimer) __super::SetTime(g_tSegmentStart + lpPresInfo->rtStart);
00841 }
00842 }
00843
00844 CSize VideoSize = m_NativeVideoSize;
00845 int arx = lpPresInfo->szAspectRatio.cx, ary = lpPresInfo->szAspectRatio.cy;
00846 if(arx > 0 && ary > 0) VideoSize.cx = VideoSize.cy*arx/ary;
00847 if(VideoSize != GetVideoSize())
00848 {
00849 m_AspectRatio.SetSize(arx, ary);
00850 AfxGetApp()->m_pMainWnd->PostMessage(WM_REARRANGERENDERLESS);
00851 }
00852
00853 Paint(true);
00854
00855 hr = S_OK;
00856 }
00857
00858 return S_OK;
00859 }
00860
00861
00862
00863
00864
00865
00866
00867 STDMETHODIMP CVMR7AllocatorPresenter::GetNativeVideoSize(LONG* lpWidth, LONG* lpHeight, LONG* lpARWidth, LONG* lpARHeight)
00868 {
00869 CSize vs = m_NativeVideoSize, ar = m_AspectRatio;
00870
00871 vs.cx = vs.cy * ar.cx / ar.cy;
00872 if(lpWidth) *lpWidth = vs.cx;
00873 if(lpHeight) *lpHeight = vs.cy;
00874 if(lpARWidth) *lpARWidth = ar.cx;
00875 if(lpARHeight) *lpARHeight = ar.cy;
00876 return S_OK;
00877 }
00878
00879 STDMETHODIMP CVMR7AllocatorPresenter::GetMinIdealVideoSize(LONG* lpWidth, LONG* lpHeight) {return E_NOTIMPL;}
00880 STDMETHODIMP CVMR7AllocatorPresenter::GetMaxIdealVideoSize(LONG* lpWidth, LONG* lpHeight) {return E_NOTIMPL;}
00881 STDMETHODIMP CVMR7AllocatorPresenter::SetVideoPosition(const LPRECT lpSRCRect, const LPRECT lpDSTRect) {return E_NOTIMPL;}
00882
00883 STDMETHODIMP CVMR7AllocatorPresenter::GetVideoPosition(LPRECT lpSRCRect, LPRECT lpDSTRect)
00884 {
00885 CopyRect(lpSRCRect, CRect(CPoint(0, 0), m_NativeVideoSize));
00886 CopyRect(lpDSTRect, &m_VideoRect);
00887
00888 GetNativeVideoSize(&lpSRCRect->right, &lpSRCRect->bottom, NULL, NULL);
00889 return S_OK;
00890 }
00891
00892 STDMETHODIMP CVMR7AllocatorPresenter::GetAspectRatioMode(DWORD* lpAspectRatioMode)
00893 {
00894 if(lpAspectRatioMode) *lpAspectRatioMode = AM_ARMODE_STRETCHED;
00895 return S_OK;
00896 }
00897
00898 STDMETHODIMP CVMR7AllocatorPresenter::SetAspectRatioMode(DWORD AspectRatioMode) {return E_NOTIMPL;}
00899 STDMETHODIMP CVMR7AllocatorPresenter::SetVideoClippingWindow(HWND hwnd) {return E_NOTIMPL;}
00900 STDMETHODIMP CVMR7AllocatorPresenter::RepaintVideo(HWND hwnd, HDC hdc) {return E_NOTIMPL;}
00901 STDMETHODIMP CVMR7AllocatorPresenter::DisplayModeChanged() {return E_NOTIMPL;}
00902 STDMETHODIMP CVMR7AllocatorPresenter::GetCurrentImage(BYTE** lpDib) {return E_NOTIMPL;}
00903 STDMETHODIMP CVMR7AllocatorPresenter::SetBorderColor(COLORREF Clr) {return E_NOTIMPL;}
00904
00905 STDMETHODIMP CVMR7AllocatorPresenter::GetBorderColor(COLORREF* lpClr)
00906 {
00907 if(lpClr) *lpClr = 0;
00908 return S_OK;
00909 }
00910
00911 STDMETHODIMP CVMR7AllocatorPresenter::SetColorKey(COLORREF Clr) {return E_NOTIMPL;}
00912 STDMETHODIMP CVMR7AllocatorPresenter::GetColorKey(COLORREF* lpClr) {return E_NOTIMPL;}
00913
00914
00915
00916 static HRESULT AllocDX7Surface(IDirectDraw7* pDD, CSize size, DWORD compression, int bpp, IDirectDrawSurface7** pSurface)
00917 {
00918 if(!pDD || !pSurface || size.cx <= 0 || size.cy <= 0)
00919 return E_POINTER;
00920
00921 *pSurface = NULL;
00922
00923 DDSURFACEDESC2 ddsd;
00924 INITDDSTRUCT(ddsd);
00925 ddsd.dwFlags = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT;
00926 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN|DDSCAPS_VIDEOMEMORY;
00927 ddsd.dwWidth = size.cx;
00928 ddsd.dwHeight = size.cy;
00929 ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
00930
00931 if(compression >= 0x1000)
00932 {
00933 ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC;
00934 ddsd.ddpfPixelFormat.dwFourCC = compression;
00935 }
00936 else if((compression == 0 || compression == 3) && (bpp == 15 || bpp == 16 || bpp == 24 || bpp == 32))
00937 {
00938 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
00939 ddsd.ddpfPixelFormat.dwRGBBitCount = max(bpp, 16);
00940 ddsd.ddpfPixelFormat.dwRGBAlphaBitMask = (bpp == 16) ? 0x0000 : (bpp == 15) ? 0x8000 : 0xFF000000;
00941 ddsd.ddpfPixelFormat.dwRBitMask = (bpp == 16) ? 0xf800 : (bpp == 15) ? 0x7c00 : 0x00FF0000;
00942 ddsd.ddpfPixelFormat.dwGBitMask = (bpp == 16) ? 0x07e0 : (bpp == 15) ? 0x03e0 : 0x0000FF00;
00943 ddsd.ddpfPixelFormat.dwBBitMask = (bpp == 16) ? 0x001F : (bpp == 15) ? 0x001F : 0x000000FF;
00944 }
00945
00946 return pDD->CreateSurface(&ddsd, pSurface, NULL);
00947 }
00948
00949
00950
00951
00952
00953 CRM7AllocatorPresenter::CRM7AllocatorPresenter(HWND hWnd, HRESULT& hr)
00954 : CDX7AllocatorPresenter(hWnd, hr)
00955 {
00956 }
00957
00958 STDMETHODIMP CRM7AllocatorPresenter::NonDelegatingQueryInterface(REFIID riid, void** ppv)
00959 {
00960 CheckPointer(ppv, E_POINTER);
00961
00962 return
00963 QI2(IRMAVideoSurface)
00964 __super::NonDelegatingQueryInterface(riid, ppv);
00965 }
00966
00967 HRESULT CRM7AllocatorPresenter::AllocSurfaces()
00968 {
00969 CAutoLock cAutoLock(this);
00970
00971 m_pVideoSurfaceOff = NULL;
00972 m_pVideoSurfaceYUY2 = NULL;
00973
00974 DDSURFACEDESC2 ddsd;
00975 DDBLTFX fx;
00976
00977 INITDDSTRUCT(ddsd);
00978 ddsd.dwFlags = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT;
00979 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
00980 ddsd.dwWidth = m_NativeVideoSize.cx;
00981 ddsd.dwHeight = m_NativeVideoSize.cy;
00982 ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
00983 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
00984 ddsd.ddpfPixelFormat.dwRGBBitCount = 32;
00985 ddsd.ddpfPixelFormat.dwRGBAlphaBitMask = 0xFF000000;
00986 ddsd.ddpfPixelFormat.dwRBitMask = 0x00FF0000;
00987 ddsd.ddpfPixelFormat.dwGBitMask = 0x0000FF00;
00988 ddsd.ddpfPixelFormat.dwBBitMask = 0x000000FF;
00989
00990 HRESULT hr = m_pDD->CreateSurface(&ddsd, &m_pVideoSurfaceOff, NULL);
00991 if(FAILED(hr)) return E_FAIL;
00992
00993 INITDDSTRUCT(fx);
00994 fx.dwFillColor = 0;
00995 m_pVideoSurfaceOff->Blt(NULL, NULL, NULL, DDBLT_WAIT|DDBLT_COLORFILL, &fx);
00996
00997 INITDDSTRUCT(ddsd);
00998 ddsd.dwFlags = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT;
00999 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
01000 ddsd.dwWidth = m_NativeVideoSize.cx;
01001 ddsd.dwHeight = m_NativeVideoSize.cy;
01002 ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
01003 ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC;
01004 ddsd.ddpfPixelFormat.dwYUVBitCount = 16;
01005 ddsd.ddpfPixelFormat.dwFourCC = '2YUY';
01006
01007 hr = m_pDD->CreateSurface(&ddsd, &m_pVideoSurfaceYUY2, NULL);
01008
01009 if(FAILED(m_pVideoSurfaceOff->Blt(NULL, m_pVideoSurfaceYUY2, NULL, DDBLT_WAIT, NULL)))
01010 m_pVideoSurfaceYUY2 = NULL;
01011
01012 if(m_pVideoSurfaceYUY2)
01013 {
01014 INITDDSTRUCT(fx);
01015 fx.dwFillColor = 0x80108010;
01016 m_pVideoSurfaceYUY2->Blt(NULL, NULL, NULL, DDBLT_WAIT|DDBLT_COLORFILL, &fx);
01017 }
01018
01019 return __super::AllocSurfaces();
01020 }
01021
01022 void CRM7AllocatorPresenter::DeleteSurfaces()
01023 {
01024 CAutoLock cAutoLock(this);
01025
01026 m_pVideoSurfaceOff = NULL;
01027 m_pVideoSurfaceYUY2 = NULL;
01028
01029 __super::DeleteSurfaces();
01030 }
01031
01032
01033
01034 STDMETHODIMP CRM7AllocatorPresenter::Blt(UCHAR* pImageData, RMABitmapInfoHeader* pBitmapInfo, REF(PNxRect) inDestRect, REF(PNxRect) inSrcRect)
01035 {
01036 if(!m_pVideoSurface || !m_pVideoSurfaceOff)
01037 return E_FAIL;
01038
01039 bool fRGB = false;
01040 bool fYUY2 = false;
01041
01042 CRect src((RECT*)&inSrcRect), dst((RECT*)&inDestRect), src2(CPoint(0,0), src.Size());
01043 if(src.Width() > dst.Width() || src.Height() > dst.Height())
01044 return E_FAIL;
01045
01046 DDSURFACEDESC2 ddsd;
01047
01048 if(pBitmapInfo->biCompression == '024I')
01049 {
01050 DWORD pitch = pBitmapInfo->biWidth;
01051 DWORD size = pitch*abs(pBitmapInfo->biHeight);
01052
01053 BYTE* y = pImageData + src.top*pitch + src.left;
01054 BYTE* u = pImageData + size + src.top*(pitch/2) + src.left/2;
01055 BYTE* v = pImageData + size + size/4 + src.top*(pitch/2) + src.left/2;
01056
01057 if(m_pVideoSurfaceYUY2)
01058 {
01059 INITDDSTRUCT(ddsd);
01060 if(SUCCEEDED(m_pVideoSurfaceYUY2->Lock(src2, &ddsd, DDLOCK_WAIT|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WRITEONLY, NULL)))
01061 {
01062 BitBltFromI420ToYUY2(src.Width(), src.Height(), (BYTE*)ddsd.lpSurface, ddsd.lPitch, y, u, v, pitch);
01063 m_pVideoSurfaceYUY2->Unlock(src2);
01064 fYUY2 = true;
01065 }
01066 }
01067 else
01068 {
01069 INITDDSTRUCT(ddsd);
01070 if(SUCCEEDED(m_pVideoSurfaceOff->Lock(src2, &ddsd, DDLOCK_WAIT|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WRITEONLY, NULL)))
01071 {
01072 BitBltFromI420ToRGB(src.Width(), src.Height(), (BYTE*)ddsd.lpSurface, ddsd.lPitch, ddsd.ddpfPixelFormat.dwRGBBitCount, y, u, v, pitch);
01073 m_pVideoSurfaceOff->Unlock(src2);
01074 fRGB = true;
01075 }
01076 }
01077 }
01078 else if(pBitmapInfo->biCompression == '2YUY')
01079 {
01080 DWORD w = pBitmapInfo->biWidth;
01081 DWORD h = abs(pBitmapInfo->biHeight);
01082 DWORD pitch = pBitmapInfo->biWidth*2;
01083
01084 BYTE* yvyu = pImageData + src.top*pitch + src.left*2;
01085
01086 if(m_pVideoSurfaceYUY2)
01087 {
01088 INITDDSTRUCT(ddsd);
01089 if(SUCCEEDED(m_pVideoSurfaceYUY2->Lock(src2, &ddsd, DDLOCK_WAIT|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WRITEONLY, NULL)))
01090 {
01091 BitBltFromYUY2ToYUY2(src.Width(), src.Height(), (BYTE*)ddsd.lpSurface, ddsd.lPitch, yvyu, pitch);
01092 m_pVideoSurfaceYUY2->Unlock(src2);
01093 fYUY2 = true;
01094 }
01095 }
01096 else
01097 {
01098 INITDDSTRUCT(ddsd);
01099 if(SUCCEEDED(m_pVideoSurfaceOff->Lock(src2, &ddsd, DDLOCK_WAIT|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WRITEONLY, NULL)))
01100 {
01101 BitBltFromYUY2ToRGB(src.Width(), src.Height(), (BYTE*)ddsd.lpSurface, ddsd.lPitch, ddsd.ddpfPixelFormat.dwRGBBitCount, yvyu, pitch);
01102 m_pVideoSurfaceOff->Unlock(src2);
01103 fRGB = true;
01104 }
01105 }
01106 }
01107 else if(pBitmapInfo->biCompression == 0 || pBitmapInfo->biCompression == 3
01108 || pBitmapInfo->biCompression == 'BGRA')
01109 {
01110 DWORD w = pBitmapInfo->biWidth;
01111 DWORD h = abs(pBitmapInfo->biHeight);
01112 DWORD pitch = pBitmapInfo->biWidth*pBitmapInfo->biBitCount>>3;
01113
01114 BYTE* rgb = pImageData + src.top*pitch + src.left*(pBitmapInfo->biBitCount>>3);
01115
01116 INITDDSTRUCT(ddsd);
01117 if(SUCCEEDED(m_pVideoSurfaceOff->Lock(src2, &ddsd, DDLOCK_WAIT|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WRITEONLY, NULL)))
01118 {
01119 BYTE* lpSurface = (BYTE*)ddsd.lpSurface;
01120 if(pBitmapInfo->biHeight > 0) {lpSurface += ddsd.lPitch*(src.Height()-1); ddsd.lPitch = -ddsd.lPitch;}
01121 BitBltFromRGBToRGB(src.Width(), src.Height(), lpSurface, ddsd.lPitch, ddsd.ddpfPixelFormat.dwRGBBitCount, rgb, pitch, pBitmapInfo->biBitCount);
01122 fRGB = true;
01123 m_pVideoSurfaceOff->Unlock(src2);
01124 }
01125 }
01126
01127 if(!fRGB && !fYUY2)
01128 {
01129 DDBLTFX fx;
01130 INITDDSTRUCT(fx);
01131 fx.dwFillColor = 0;
01132 m_pVideoSurfaceOff->Blt(NULL, NULL, NULL, DDBLT_WAIT|DDBLT_COLORFILL, &fx);
01133
01134 HDC hDC;
01135 if(SUCCEEDED(m_pVideoSurfaceOff->GetDC(&hDC)))
01136 {
01137 CString str;
01138 str.Format(_T("Sorry, this format is not supported"));
01139
01140 SetBkColor(hDC, 0);
01141 SetTextColor(hDC, 0x404040);
01142 TextOut(hDC, 10, 10, str, str.GetLength());
01143
01144 m_pVideoSurfaceOff->ReleaseDC(hDC);
01145
01146 fRGB = true;
01147 }
01148 }
01149
01150
01151 HRESULT hr;
01152
01153 if(fRGB)
01154 hr = m_pVideoSurface->Blt(dst, m_pVideoSurfaceOff, src2, DDBLT_WAIT, NULL);
01155 if(fYUY2)
01156 hr = m_pVideoSurface->Blt(dst, m_pVideoSurfaceYUY2, src2, DDBLT_WAIT, NULL);
01157
01158 Paint(true);
01159
01160 return PNR_OK;
01161 }
01162
01163 STDMETHODIMP CRM7AllocatorPresenter::BeginOptimizedBlt(RMABitmapInfoHeader* pBitmapInfo)
01164 {
01165 CAutoLock cAutoLock(this);
01166 DeleteSurfaces();
01167 m_NativeVideoSize = m_AspectRatio = CSize(pBitmapInfo->biWidth, abs(pBitmapInfo->biHeight));
01168 if(FAILED(AllocSurfaces())) return E_FAIL;
01169 return PNR_NOTIMPL;
01170 }
01171
01172 STDMETHODIMP CRM7AllocatorPresenter::OptimizedBlt(UCHAR* pImageBits, REF(PNxRect) rDestRect, REF(PNxRect) rSrcRect)
01173 {
01174 return PNR_NOTIMPL;
01175 }
01176
01177 STDMETHODIMP CRM7AllocatorPresenter::EndOptimizedBlt()
01178 {
01179 return PNR_NOTIMPL;
01180 }
01181
01182 STDMETHODIMP CRM7AllocatorPresenter::GetOptimizedFormat(REF(RMA_COMPRESSION_TYPE) ulType)
01183 {
01184 return PNR_NOTIMPL;
01185 }
01186
01187 STDMETHODIMP CRM7AllocatorPresenter::GetPreferredFormat(REF(RMA_COMPRESSION_TYPE) ulType)
01188 {
01189 ulType = RMA_I420;
01190 return PNR_OK;
01191 }
01192
01193
01194
01195
01196
01197 CQT7AllocatorPresenter::CQT7AllocatorPresenter(HWND hWnd, HRESULT& hr)
01198 : CDX7AllocatorPresenter(hWnd, hr)
01199 {
01200 }
01201
01202 STDMETHODIMP CQT7AllocatorPresenter::NonDelegatingQueryInterface(REFIID riid, void** ppv)
01203 {
01204 CheckPointer(ppv, E_POINTER);
01205
01206 return
01207 QI(IQTVideoSurface)
01208 __super::NonDelegatingQueryInterface(riid, ppv);
01209 }
01210
01211 HRESULT CQT7AllocatorPresenter::AllocSurfaces()
01212 {
01213 CAutoLock cAutoLock(this);
01214
01215 m_pVideoSurfaceOff = NULL;
01216
01217 DDSURFACEDESC2 ddsd;
01218 INITDDSTRUCT(ddsd);
01219 ddsd.dwFlags = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT;
01220 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
01221 ddsd.dwWidth = m_NativeVideoSize.cx;
01222 ddsd.dwHeight = m_NativeVideoSize.cy;
01223 ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
01224 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
01225 ddsd.ddpfPixelFormat.dwRGBBitCount = 32;
01226 ddsd.ddpfPixelFormat.dwRGBAlphaBitMask = 0xFF000000;
01227 ddsd.ddpfPixelFormat.dwRBitMask = 0x00FF0000;
01228 ddsd.ddpfPixelFormat.dwGBitMask = 0x0000FF00;
01229 ddsd.ddpfPixelFormat.dwBBitMask = 0x000000FF;
01230
01231 HRESULT hr = m_pDD->CreateSurface(&ddsd, &m_pVideoSurfaceOff, NULL);
01232 if(FAILED(hr)) return E_FAIL;
01233
01234 DDBLTFX fx;
01235 INITDDSTRUCT(fx);
01236 fx.dwFillColor = 0;
01237 m_pVideoSurfaceOff->Blt(NULL, NULL, NULL, DDBLT_WAIT|DDBLT_COLORFILL, &fx);
01238
01239 return __super::AllocSurfaces();
01240 }
01241
01242 void CQT7AllocatorPresenter::DeleteSurfaces()
01243 {
01244 CAutoLock cAutoLock(this);
01245
01246 m_pVideoSurfaceOff = NULL;
01247
01248 __super::DeleteSurfaces();
01249 }
01250
01251
01252
01253 STDMETHODIMP CQT7AllocatorPresenter::BeginBlt(const BITMAP& bm)
01254 {
01255 CAutoLock cAutoLock(this);
01256
01257 DeleteSurfaces();
01258
01259 m_NativeVideoSize = m_AspectRatio = CSize(bm.bmWidth, abs(bm.bmHeight));
01260
01261 HRESULT hr;
01262 if(FAILED(hr = AllocSurfaces()))
01263 return hr;
01264
01265 return S_OK;
01266 }
01267
01268 STDMETHODIMP CQT7AllocatorPresenter::DoBlt(const BITMAP& bm)
01269 {
01270 if(!m_pVideoSurface || !m_pVideoSurfaceOff)
01271 return E_FAIL;
01272
01273 bool fOk = false;
01274
01275 DDSURFACEDESC2 ddsd;
01276 INITDDSTRUCT(ddsd);
01277 if(FAILED(m_pVideoSurfaceOff->GetSurfaceDesc(&ddsd)))
01278 return E_FAIL;
01279
01280 int w = bm.bmWidth;
01281 int h = abs(bm.bmHeight);
01282 int bpp = bm.bmBitsPixel;
01283
01284 if((bpp == 16 || bpp == 24 || bpp == 32) && w == ddsd.dwWidth && h == ddsd.dwHeight)
01285 {
01286 INITDDSTRUCT(ddsd);
01287 if(SUCCEEDED(m_pVideoSurfaceOff->Lock(NULL, &ddsd, DDLOCK_WAIT|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WRITEONLY, NULL)))
01288 {
01289 BitBltFromRGBToRGB(
01290 w, h,
01291 (BYTE*)ddsd.lpSurface, ddsd.lPitch, ddsd.ddpfPixelFormat.dwRGBBitCount,
01292 (BYTE*)bm.bmBits, bm.bmWidthBytes, bm.bmBitsPixel);
01293 m_pVideoSurfaceOff->Unlock(NULL);
01294 fOk = true;
01295 }
01296 }
01297
01298 if(!fOk)
01299 {
01300 DDBLTFX fx;
01301 INITDDSTRUCT(fx);
01302 fx.dwFillColor = 0;
01303 m_pVideoSurfaceOff->Blt(NULL, NULL, NULL, DDBLT_WAIT|DDBLT_COLORFILL, &fx);
01304
01305 HDC hDC;
01306 if(SUCCEEDED(m_pVideoSurfaceOff->GetDC(&hDC)))
01307 {
01308 CString str;
01309 str.Format(_T("Sorry, this format is not supported"));
01310
01311 SetBkColor(hDC, 0);
01312 SetTextColor(hDC, 0x404040);
01313 TextOut(hDC, 10, 10, str, str.GetLength());
01314
01315 m_pVideoSurfaceOff->ReleaseDC(hDC);
01316
01317 }
01318 }
01319
01320 m_pVideoSurface->Blt(NULL, m_pVideoSurfaceOff, NULL, DDBLT_WAIT, NULL);
01321
01322 Paint(true);
01323
01324 return S_OK;
01325 }