From f0e037e7ef30e386c4d800b2305edb130f58c45f Mon Sep 17 00:00:00 2001 From: Marten Richter Date: Mon, 3 Nov 2014 08:26:26 +0100 Subject: [PATCH] Split OsdWin into OsdWinPixel and WindowsOsd as preparation for Vector based Windows osd --- defines.h | 1 + dsallocator.cc | 62 ++--- osdwin.cc | 634 ------------------------------------------------- osdwin.h | 127 ---------- osdwinpixel.cc | 113 +++++++++ osdwinpixel.h | 60 +++++ surfacewin.cc | 18 +- videowin.cc | 24 +- windowsosd.cc | 605 ++++++++++++++++++++++++++++++++++++++++++++++ windowsosd.h | 127 ++++++++++ winmain.cc | 12 +- 11 files changed, 968 insertions(+), 815 deletions(-) delete mode 100644 osdwin.cc delete mode 100644 osdwin.h create mode 100644 osdwinpixel.cc create mode 100644 osdwinpixel.h create mode 100644 windowsosd.cc create mode 100644 windowsosd.h diff --git a/defines.h b/defines.h index b09dc65..beb9146 100644 --- a/defines.h +++ b/defines.h @@ -45,6 +45,7 @@ int getClockRealTime(struct timespec *tp); #define Surface_TYPE SurfaceWin #define Thread_TYPE ThreadWin #define ThreadID_TYPE unsigned int + #define Osd_TYPE OsdWinPixel #define RemoteStartDev ""//No devices passed diff --git a/dsallocator.cc b/dsallocator.cc index 841cc5a..c41d90d 100644 --- a/dsallocator.cc +++ b/dsallocator.cc @@ -20,8 +20,10 @@ #define INITGUID -#include "osdwin.h" +#include "osd.h" +#include "windowsosd.h" #include "dsallocator.h" +#include "log.h" #include @@ -51,8 +53,8 @@ DsAllocator::DsAllocator() { } DsAllocator::~DsAllocator() { - ((OsdWin*)Osd::getInstance())->SetEVRStatus(OsdWin::EVR_pres_off); - ((OsdWin*)Osd::getInstance())->setExternalDriving(NULL,vwidth,vheight); + dynamic_cast(Osd::getInstance())->SetEVRStatus(WindowsOsd::EVR_pres_off); + dynamic_cast(Osd::getInstance())->setExternalDriving(NULL, vwidth, vheight); CleanupSurfaces(); } @@ -129,8 +131,8 @@ HRESULT STDMETHODCALLTYPE DsAllocator::AdviseNotify(IVMRSurfaceAllocatorNotify9* surfallocnotify=allnoty; IDirect3DDevice9 *d3ddev; //OK lets set the direct3d object from the osd - d3ddev=((OsdWin*)Osd::getInstance())->getD3dDev(); - HMONITOR hmon=((OsdWin*)Osd::getInstance())->getD3d()->GetAdapterMonitor(D3DADAPTER_DEFAULT); + d3ddev=dynamic_cast(Osd::getInstance())->getD3dDev(); + HMONITOR hmon=dynamic_cast(Osd::getInstance())->getD3d()->GetAdapterMonitor(D3DADAPTER_DEFAULT); HRESULT hres=surfallocnotify->SetD3DDevice(d3ddev,hmon); Unlock(); return hres; @@ -139,19 +141,19 @@ HRESULT STDMETHODCALLTYPE DsAllocator::AdviseNotify(IVMRSurfaceAllocatorNotify9* HRESULT STDMETHODCALLTYPE DsAllocator::StartPresenting(DWORD_PTR userid){ //MessageBox(0,"drive me","drive me",0); - ((OsdWin*)Osd::getInstance())->setExternalDriving(this,vwidth,vheight); + dynamic_cast(Osd::getInstance())->setExternalDriving(this,vwidth,vheight); start_get_evr_samples=false; return S_OK; } HRESULT STDMETHODCALLTYPE DsAllocator::StopPresenting(DWORD_PTR userid){ - ((OsdWin*)Osd::getInstance())->setExternalDriving(NULL,0,0); + dynamic_cast(Osd::getInstance())->setExternalDriving(NULL,0,0); start_get_evr_samples=false; return S_OK; } HRESULT STDMETHODCALLTYPE DsAllocator::PresentImage(DWORD_PTR userid,VMR9PresentationInfo* presinf){ - ((OsdWin*)Osd::getInstance())->RenderDS(presinf->lpSurf); //render and return + dynamic_cast(Osd::getInstance())->RenderDS(presinf->lpSurf); //render and return return S_OK; } @@ -184,7 +186,7 @@ HRESULT STDMETHODCALLTYPE DsAllocator::QueryInterface(REFIID refiid,void ** obj) AddRef(); return S_OK; } else if (refiid==IID_IDirect3DDeviceManager9) { - IDirect3DDeviceManager9 *d3dman=((OsdWin*)Osd::getInstance())->getD3dMan(); + IDirect3DDeviceManager9 *d3dman=dynamic_cast(Osd::getInstance())->getD3dMan(); if (d3dman){ return d3dman->QueryInterface(refiid,obj); } @@ -246,7 +248,7 @@ HRESULT STDMETHODCALLTYPE DsAllocator::ReleaseServicePointers() inevrmode=false; /* TODO Set RenderState , sample type etc.*/ - ((OsdWin*)Osd::getInstance())->setExternalDriving(NULL,0,0); + dynamic_cast(Osd::getInstance())->setExternalDriving(NULL, 0, 0); if (mftransform) mftransform->Release(); mftransform=NULL; @@ -267,7 +269,7 @@ HRESULT STDMETHODCALLTYPE DsAllocator::GetService(const GUID &guid,const IID &ii { if (guid==MR_VIDEO_ACCELERATION_SERVICE) { - IDirect3DDeviceManager9 *d3dman=((OsdWin*)Osd::getInstance())->getD3dMan(); + IDirect3DDeviceManager9 *d3dman=dynamic_cast(Osd::getInstance())->getD3dMan(); if (d3dman) { return d3dman->QueryInterface (__uuidof(IDirect3DDeviceManager9), (void**) obj); @@ -409,14 +411,14 @@ HRESULT STDMETHODCALLTYPE DsAllocator::ProcessMessage(MFVP_MESSAGE_TYPE mess,ULO case MFVP_MESSAGE_BEGINSTREAMING:{ Log::getInstance()->log("DsAllocator", Log::DEBUG , "EVR Message MFVP_MESSAGE_BEGINSTREAMING received"); ResetSyncOffsets(); - ((OsdWin*)Osd::getInstance())->setExternalDriving(this,vwidth,vheight); + dynamic_cast(Osd::getInstance())->setExternalDriving(this,vwidth,vheight); //((OsdWin*)Osd::getInstance())->SetEVRStatus(OsdWin::EVR_pres_started);//No need to do this causes misbehaviout endofstream=false; }break; case MFVP_MESSAGE_ENDSTREAMING: { Log::getInstance()->log("DsAllocator", Log::DEBUG , "EVR Message MFVP_MESSAGE_ENDSTREAMING received"); - ((OsdWin*)Osd::getInstance())->SetEVRStatus(OsdWin::EVR_pres_off); - ((OsdWin*)Osd::getInstance())->setExternalDriving(NULL,vwidth,vheight); + dynamic_cast(Osd::getInstance())->SetEVRStatus(WindowsOsd::EVR_pres_off); + dynamic_cast(Osd::getInstance())->setExternalDriving(NULL, vwidth, vheight); start_get_evr_samples=false; //FlushEVRSamples(); //if (mfmediatype) mfmediatype->Release(); @@ -424,15 +426,15 @@ HRESULT STDMETHODCALLTYPE DsAllocator::ProcessMessage(MFVP_MESSAGE_TYPE mess,ULO } break; case MFVP_MESSAGE_ENDOFSTREAM: { Log::getInstance()->log("DsAllocator", Log::DEBUG , "EVR Message MFVP_MESSAGE_ENDOFSTREAM received"); - MessageBox(0,"endofstream","endofstream",0); + //MessageBox(0,"endofstream","endofstream",0); endofstream=true; start_get_evr_samples=false; } break; case MFVP_MESSAGE_STEP: { Log::getInstance()->log("DsAllocator", Log::DEBUG , "EVR Message MFVP_MESSAGE_STEP received"); - ((OsdWin*)Osd::getInstance())->setExternalDriving(this,vwidth,vheight); - ((OsdWin*)Osd::getInstance())->SetEVRStatus(OsdWin::EVR_pres_pause); - MessageBox(0,"steppy","steppy",0); + dynamic_cast(Osd::getInstance())->setExternalDriving(this, vwidth, vheight); + dynamic_cast(Osd::getInstance())->SetEVRStatus(WindowsOsd::EVR_pres_pause); + //MessageBox(0,"steppy","steppy",0); FlushEVRSamples(/*LOWORD(mess_para)*/); //Message sending, has to be done after compeletion }; break; case MFVP_MESSAGE_CANCELSTEP: { @@ -451,9 +453,9 @@ HRESULT STDMETHODCALLTYPE DsAllocator::OnClockStart(MFTIME systime,LONGLONG star timeBeginPeriod(1); if (PRESENTATION_CURRENT_POSITION!=startoffset) FlushEVRSamples(); - ((OsdWin*)Osd::getInstance())->setExternalDriving(this,vwidth,vheight); + dynamic_cast(Osd::getInstance())->setExternalDriving(this, vwidth, vheight); Log::getInstance()->log("DsAllocator", Log::DEBUG , "OnClockStart"); - ((OsdWin*)Osd::getInstance())->SetEVRStatus(OsdWin::EVR_pres_started); + dynamic_cast(Osd::getInstance())->SetEVRStatus(WindowsOsd::EVR_pres_started); //GetEVRSamples(); return S_OK; @@ -463,10 +465,10 @@ HRESULT STDMETHODCALLTYPE DsAllocator::OnClockStop(MFTIME systime) { timeEndPeriod(1); - ((OsdWin*)Osd::getInstance())->SetEVRStatus(OsdWin::EVR_pres_off); + dynamic_cast(Osd::getInstance())->SetEVRStatus(WindowsOsd::EVR_pres_off); - Log::getInstance()->log("DsAllocator", Log::DEBUG , "OnClockStop"); - ((OsdWin*)Osd::getInstance())->setExternalDriving(NULL,vwidth,vheight); + Log::getInstance()->log("DsAllocator", Log::DEBUG , "OnClockStop"); + dynamic_cast(Osd::getInstance())->setExternalDriving(NULL, vwidth, vheight); FlushEVRSamples(); return S_OK; } @@ -474,19 +476,19 @@ HRESULT STDMETHODCALLTYPE DsAllocator::OnClockStop(MFTIME systime) HRESULT STDMETHODCALLTYPE DsAllocator::OnClockPause(MFTIME systime) { timeEndPeriod(1); - ((OsdWin*)Osd::getInstance())->setExternalDriving(this,vwidth,vheight); + dynamic_cast(Osd::getInstance())->setExternalDriving(this, vwidth, vheight); Log::getInstance()->log("DsAllocator", Log::DEBUG , "OnClockPause"); - ((OsdWin*)Osd::getInstance())->SetEVRStatus(OsdWin::EVR_pres_pause); + dynamic_cast(Osd::getInstance())->SetEVRStatus(WindowsOsd::EVR_pres_pause); return S_OK; } HRESULT STDMETHODCALLTYPE DsAllocator::OnClockRestart(MFTIME systime) { - ((OsdWin*)Osd::getInstance())->setExternalDriving(this,vwidth,vheight); + dynamic_cast(Osd::getInstance())->setExternalDriving(this, vwidth, vheight); - Log::getInstance()->log("DsAllocator", Log::DEBUG , "OnClockRestart"); - ((OsdWin*)Osd::getInstance())->SetEVRStatus(OsdWin::EVR_pres_started); + Log::getInstance()->log("DsAllocator", Log::DEBUG , "OnClockRestart"); + dynamic_cast(Osd::getInstance())->SetEVRStatus(WindowsOsd::EVR_pres_started); return S_OK; } @@ -498,7 +500,7 @@ HRESULT STDMETHODCALLTYPE DsAllocator::OnClockSetRate(MFTIME systime,float rate) } HRESULT STDMETHODCALLTYPE DsAllocator::GetCurrentMediaType(IMFVideoMediaType **mtype) -{ MessageBox(0,"mediatype","mediatype",0); +{// MessageBox(0,"mediatype","mediatype",0); if (mtype==NULL) return E_POINTER; Lock(); if (mfmediatype==NULL) @@ -610,7 +612,7 @@ void DsAllocator::AllocateEVRSurfaces() CleanupSurfaces(); Lock(); - OsdWin* osdwin=(OsdWin*)Osd::getInstance(); + WindowsOsd* osdwin = dynamic_cast(Osd::getInstance()); LPDIRECT3DDEVICE9 d3ddev=osdwin->getD3dDev(); osdwin->BeginPainting(); surfaces.resize(10); diff --git a/osdwin.cc b/osdwin.cc deleted file mode 100644 index 0a99ec3..0000000 --- a/osdwin.cc +++ /dev/null @@ -1,634 +0,0 @@ -/* - Copyright 2004-2005 Chris Tallon - - This file is part of VOMP. - - VOMP is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - VOMP is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with VOMP; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#include "osdwin.h" -#include "mtd.h" -#include "videowin.h" -#include "surfacewin.h" - -#include "dsallocator.h" -#include "message.h" -#include "command.h" - -#define BACKBUFFER_WIDTH 1920 -#define BACKBUFFER_HEIGHT 1080 - - - -typedef HRESULT (__stdcall *FCT_DXVA2CreateDirect3DDeviceManager9)(UINT* pResetToken, IDirect3DDeviceManager9** ppDeviceManager); -typedef HRESULT (__stdcall *FCT_MFCreateVideoSampleFromSurface)(IUnknown* pUnkSurface, IMFSample** ppSample); - -FCT_DXVA2CreateDirect3DDeviceManager9 ptrDXVA2CreateDirect3DDeviceManager9=NULL; -FCT_MFCreateVideoSampleFromSurface ptrMFCreateVideoSampleFromSurface=NULL; - -//This is stuff for rendering the OSD - - -OsdWin::OsdWin() -{ - d3d=NULL; - d3ddevice=NULL; - d3drtsurf=NULL; - swappy=NULL; - swapsurf=NULL; - evrstate=EVR_pres_off; - window=NULL; - - external_driving=false; - dsallocator=NULL; - filter_type=D3DTEXF_FORCE_DWORD; - lastrendertime=timeGetTime(); - event = CreateEvent(NULL,/*FALSE*/TRUE,FALSE,NULL); - d3dmutex = CreateMutex(NULL,FALSE,NULL); - /*EVR stuff*/ - dxvadevicehandle=NULL; - evrsupported=true; - HMODULE hlib=NULL; - hlib=LoadLibrary("dxva2.dll"); - if (!hlib) { - evrsupported=false; - return; - } - ptrDXVA2CreateDirect3DDeviceManager9=(FCT_DXVA2CreateDirect3DDeviceManager9)GetProcAddress(hlib, "DXVA2CreateDirect3DDeviceManager9"); - if (!ptrDXVA2CreateDirect3DDeviceManager9){ - evrsupported=false; - return; - } - - hlib=LoadLibrary("evr.dll"); - if (!hlib) { - evrsupported=false; - return; - } - - ptrMFCreateVideoSampleFromSurface = (FCT_MFCreateVideoSampleFromSurface)GetProcAddress(hlib,"MFCreateVideoSampleFromSurface"); - if (!ptrMFCreateVideoSampleFromSurface){ - evrsupported=false; - return; - } - -} - -OsdWin::~OsdWin() -{ - - if (initted) - { - threadStop(); - shutdown(); - } - CloseHandle(event); - CloseHandle(d3dmutex); -} - -int OsdWin::getFD() -{ - if (!initted) return 0; - return fdOsd; -} - -Surface * OsdWin::createNewSurface(){ - return (Surface*)new SurfaceWin(); -} - -int OsdWin::init(void* device) -{ - if (initted) return 0; - Video* video = Video::getInstance(); - window=*((HWND*)device); - //First Create Direct 3D Object - d3d=Direct3DCreate9(D3D_SDK_VERSION); - if (!d3d) - { - Log::getInstance()->log("OSD", Log::WARN, "Could not create Direct3D9 object!"); - return 0; - } - // then create the Device - D3DPRESENT_PARAMETERS d3dparas; - ZeroMemory(&d3dparas,sizeof(d3dparas)); - d3dparas.BackBufferWidth=BACKBUFFER_WIDTH; - d3dparas.BackBufferHeight=BACKBUFFER_HEIGHT; - d3dparas.Windowed=TRUE; - d3dparas.SwapEffect=D3DSWAPEFFECT_COPY; - if (d3d->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,*((HWND*) device), - D3DCREATE_SOFTWARE_VERTEXPROCESSING |D3DCREATE_MULTITHREADED,&d3dparas,&d3ddevice)!=D3D_OK) { - Log::getInstance()->log("OSD", Log::WARN, "Could not create Direct3D9 device!"); - return 0; - } - d3ddevice->GetRenderTarget(0,&d3drtsurf); - - /* - if (!InitVertexBuffer()) { - Log::getInstance()->log("OSD", Log::WARN, "Could not create Direct3D9 vertex buf!"); - return 0; - }*/ - /* We have to determine which kind of filtering is supported*/ - D3DCAPS9 caps; - d3ddevice->GetDeviceCaps(&caps); - if ( ((caps.StretchRectFilterCaps & D3DPTFILTERCAPS_MINFLINEAR)!=0) - && ((caps.StretchRectFilterCaps & D3DPTFILTERCAPS_MAGFLINEAR)!=0)) { - if (filter_type==D3DTEXF_FORCE_DWORD) { - filter_type=D3DTEXF_LINEAR; - } - } else { - if (filter_type==D3DTEXF_LINEAR) - { - filter_type=D3DTEXF_POINT; - } - } - - if ( ((caps.StretchRectFilterCaps & D3DPTFILTERCAPS_MINFPOINT)!=0) - && ((caps.StretchRectFilterCaps & D3DPTFILTERCAPS_MAGFPOINT)!=0)) { - if (filter_type==D3DTEXF_FORCE_DWORD) - { - filter_type=D3DTEXF_POINT; - } - } else { - if (filter_type==D3DTEXF_POINT) { - filter_type=D3DTEXF_NONE; - } - } - if (filter_type==D3DTEXF_FORCE_DWORD) { - filter_type=D3DTEXF_NONE; - } - - if (evrsupported) - { - if (ptrDXVA2CreateDirect3DDeviceManager9(&dxvatoken,&d3ddevman)!=S_OK) evrsupported=false; - else { - d3ddevman->ResetDevice(d3ddevice,dxvatoken); - } - } - - GdiplusStartup(&gdiptoken, &gdipstartup, NULL); - - - //Now we will create the Screen - screen = new SurfaceWin(Surface::SCREEN); - SetEvent(event);//Now all devices are ready - screen->create(video->getScreenWidth(), video->getScreenHeight()); - screen->display(); - initted = 1; // must set this here or create surface won't work - threadStart(); - - return 1; -} - -void OsdWin::LockDevice() -{ - if (!evrsupported) return; - if (!dxvadevicehandle) - { - d3ddevman->OpenDeviceHandle(&dxvadevicehandle); - } - IDirect3DDevice9 *temp; - d3ddevman->LockDevice(dxvadevicehandle,&temp,TRUE); - -} - -void OsdWin::UnlockDevice() -{ - if (!evrsupported) return; - if (!initted) return; - d3ddevman->UnlockDevice(dxvadevicehandle,TRUE); - if (dxvadevicehandle) - { - d3ddevman->CloseDeviceHandle(dxvadevicehandle); - dxvadevicehandle=NULL; - } - -} - -DWORD OsdWin::getFilterCaps() -{ - if (!initted) return NULL; - D3DCAPS9 caps; - d3ddevice->GetDeviceCaps(&caps); - return caps.StretchRectFilterCaps; -} - -LPDIRECT3DVERTEXBUFFER9 OsdWin::InitVertexBuffer(DWORD width, DWORD height) -{ - LPDIRECT3DVERTEXBUFFER9 ret =NULL; - Video* video=Video::getInstance(); - FLOAT texx=((float)video->getScreenWidth())/1024.f; - FLOAT texy=((float)video->getScreenHeight())/1024.f; - D3DCOLOR osdcolor=D3DCOLOR_RGBA(255,255,255,255); - osdvertices[0].c=osdcolor; - osdvertices[0].x=0.f-0.5f; - osdvertices[0].y=0.f-0.5f; - osdvertices[0].z=0.5f; - osdvertices[0].rhw=1.f; - osdvertices[0].u=0.f; - osdvertices[0].v=0.f; - osdvertices[1].c=osdcolor; - osdvertices[1].x=((float)width)-0.5f; - osdvertices[1].y=0.f-0.5f; - osdvertices[1].z=0.5f; - osdvertices[1].u=texx; - osdvertices[1].v=0.f; - osdvertices[1].rhw=1.f; - osdvertices[2].c=osdcolor; - osdvertices[2].x=((float)width)-0.5f; - osdvertices[2].y=((float)height)-0.5f; - osdvertices[2].z=0.5f; - osdvertices[2].rhw=1.f; - osdvertices[2].u=texx; - osdvertices[2].v=texy; - osdvertices[3].c=osdcolor; - osdvertices[3].x=0.f-0.5f; - osdvertices[3].y=((float)height)-0.5f; - osdvertices[3].z=0.5f; - osdvertices[3].rhw=1.f; - osdvertices[3].u=0.f; - osdvertices[3].v=texy; - - if (d3ddevice->CreateVertexBuffer(4*sizeof(OSDVERTEX),0,D3DFVF_OSDVERTEX,D3DPOOL_MANAGED, - &ret,NULL)!=D3D_OK) { - return NULL; - } - void *pvertex=NULL; - if (ret->Lock(0,sizeof(osdvertices),&pvertex,0)!=D3D_OK) { - return NULL; - } - memcpy(pvertex,osdvertices,sizeof(osdvertices)); - ret->Unlock(); - return ret; -} - -int OsdWin::shutdown() -{ - if (!initted) return 0; - initted = 0; - evrsupported=0; - if (d3ddevman) d3ddevman->Release(); - d3drtsurf->Release(); - d3ddevice->Release(); - d3d->Release(); - if (swapsurf) swapsurf->Release(); - if (swappy) swappy->Release(); - Gdiplus::GdiplusShutdown(gdiptoken); - - return 1; -} - -void OsdWin::screenShot(const char* fileName) -{ - screen->screenShot(fileName); -} - -void OsdWin::threadMethod() -{ - while (true) - { - DWORD waittime=10; - if (initted){ - if (evrstate==EVR_pres_off || evrstate==EVR_pres_pause) - { - Render(); - } else if (evrstate==EVR_pres_started) - { - LPDIRECT3DSURFACE9 surf; - if (dsallocator) dsallocator->GetNextSurface(&surf,&waittime); - if (surf==NULL) - { - Render(); - } - else - { - RenderDS(surf); - surf->Release(); - if (dsallocator) dsallocator->DiscardSurfaceandgetWait(&waittime); - } - } - } - threadCheckExit(); - if (waittime!=0) Sleep(min(10,waittime)); - //Sleep(1); - } -} - - -void OsdWin::threadPostStopCleanup() -{ - //Doing nothing - //goo; -} - - -// This function is called from the WinMain function in order to get Screen updates -void OsdWin::Render() -{ - if (!initted) return ; - if (external_driving) { - DWORD time1=timeGetTime(); //Updates the Menue - if ((time1-lastrendertime)>200) {//5 fps for OSD updates are enough, avoids tearing - InternalRendering(NULL); - lastrendertime=timeGetTime(); - } else { - //Sleep(5); //Sleep for 5 ms, in order to avoid blocking the other threads - } - } else { - DWORD time1=timeGetTime(); - if ((time1-lastrendertime)>50) {//10 fps for OSD updates are enough, avoids tearing - InternalRendering(NULL); - lastrendertime=timeGetTime(); - } else { - //Sleep(5); - - } - - } -} - -void OsdWin::RenderDS(LPDIRECT3DSURFACE9 present){ - if (!initted) return; - if (external_driving) { - InternalRendering(present); - lastrendertime=timeGetTime(); - } -} - - -void OsdWin::InternalRendering(LPDIRECT3DSURFACE9 present){ - BeginPainting(); - HRESULT losty=d3ddevice->TestCooperativeLevel(); - if (losty==D3DERR_DEVICELOST) { - //Sleep(10); - EndPainting(); - return; //Device Lost - } - if (losty==D3DERR_DEVICENOTRESET){ - EndPainting(); - DoLost(); - return; - } - WaitForSingleObject(event,INFINITE); - - - - - LPDIRECT3DSURFACE9 targetsurf; - if (swappy) - { - targetsurf=swapsurf; - d3ddevice->SetRenderTarget(0,swapsurf);//Stupid VMR manipulates the render target - } - else - { - targetsurf=d3drtsurf; - d3ddevice->SetRenderTarget(0,d3drtsurf);//Stupid VMR manipulates the render target - } - D3DSURFACE_DESC targetdesc; - targetsurf->GetDesc(&targetdesc); - - if (external_driving) { - //Copy video to Backbuffer - if (present!=NULL ) { - VideoWin* video =(VideoWin*) Video::getInstance(); - /*calculating destination rect */ - RECT destrect={0,0,/*video->getScreenWidth()*/ targetdesc.Width, - /*video->getScreenHeight()*/targetdesc.Height}; - const VideoDisplay &vd=video->getVideoDisplay(); - int addx, addy; - addx = addy = 0; - - switch (vd.mode) { - case Eighth: - destrect.right=destrect.right/2; - destrect.bottom=destrect.bottom/2; - case Quarter: - destrect.right=destrect.right/2; - destrect.bottom=destrect.bottom/2; - break; - case Window: - float imageaspect = 720.f / 576.f; - float boxaspect = ((float)vd.width) / ((float)vd.height) ; - float videoaspect = ((float)targetdesc.Width) / ((float)targetdesc.Height); - if (imageaspect > boxaspect) { - destrect.right = (int)(((float)destrect.right) * ((float)vd.width) / 720.f); - destrect.bottom = (int)(((float)destrect.right)/videoaspect); - addy += (((float)vd.height) - ((float)vd.width) / imageaspect)*0.5f / 576.f - *((float)targetdesc.Height); - } - else { - destrect.bottom = (int)(((float)destrect.bottom) * ((float)vd.height) / 576.f); - destrect.right = (int)(((float)destrect.bottom)*videoaspect); - addx += (((float)vd.width) - ((float)vd.height) * imageaspect)*0.5f / 720.f - *((float)targetdesc.Width); - } - - - break; - }; - switch (vd.mode) { - case Quarter: - case Eighth: - case Window: - destrect.left = (int)(((float)vd.x*targetdesc.Width) / 720.f)+addx; - destrect.top = (int)(((float)vd.y*targetdesc.Height) / 576.f)+addy; - destrect.right += destrect.left; - destrect.bottom += destrect.top; - break; - } - d3ddevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); - D3DSURFACE_DESC surf_desc; - present->GetDesc(&surf_desc);//for chop sides - RECT sourcerect= {0,0,surf_desc.Width,surf_desc.Height}; - if (video->getPseudoTVsize()==Video::ASPECT4X3 - && video->getMode()==Video::NORMAL - && video->getAspectRatio()==Video::ASPECT16X9) { - unsigned int correction=((double) (surf_desc.Width))*4.*9./3./16.; - sourcerect.left=(surf_desc.Width-correction)/2; - sourcerect.right=sourcerect.left+correction; - } - d3ddevice->StretchRect(present,&sourcerect,targetsurf ,&destrect,filter_type); - - } - } else { - VideoWin* video =(VideoWin*) Video::getInstance(); - //Clear Background - if (!video->isVideoOn()) d3ddevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,0),1.0f,0); - } - LPDIRECT3DVERTEXBUFFER9 vb=NULL; - vb=InitVertexBuffer(targetdesc.Width,targetdesc.Height); - - //Drawing the OSD - if (d3ddevice->BeginScene()==D3D_OK) { - d3ddevice->SetStreamSource(0,vb,0,sizeof(OSDVERTEX)); - d3ddevice->SetFVF(D3DFVF_OSDVERTEX); - d3ddevice->SetTexture(0,((SurfaceWin*)screen)->getD3dtexture()); - //d3ddevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE); - d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAOP,D3DTOP_MODULATE); - - d3ddevice->SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_LINEAR); - d3ddevice->SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_LINEAR); - - - d3ddevice->SetRenderState(D3DRS_ALPHABLENDENABLE,TRUE); - d3ddevice->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA); - d3ddevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); - d3ddevice->SetRenderState(D3DRS_LIGHTING,FALSE); - - - d3ddevice->DrawPrimitive(D3DPT_TRIANGLEFAN,0,2); - d3ddevice->EndScene(); - //Show it to the user! - HRESULT hres; - if (swappy) - { - if (hres=swappy->Present(NULL,NULL,NULL,NULL,0)==D3DERR_DEVICELOST){ - //EndPainting(); - if (!external_driving) DoLost(); - } - } - else - { - if (hres=d3ddevice->Present(NULL,NULL,NULL,NULL)==D3DERR_DEVICELOST){ - //EndPainting(); - if (!external_driving) DoLost(); - } - } - - } - - vb->Release(); - EndPainting(); - - -// if (!external_driving) { -// Sleep(4);//The User can wait for 4 milliseconds to see his changes -// } -} - -bool OsdWin::DoLost(){ - Log::getInstance()->log("OSD", Log::WARN, "Direct3D Device Lost! Reobtaining..."); - ResetEvent(event); - if (external_driving && dsallocator!=NULL) { - dsallocator->LostDevice(d3ddevice,d3d); //Propagate the information through DS - } - //First we free up all resources - Video* video = Video::getInstance(); - ((SurfaceWin*)screen)->ReleaseSurface(); - if (d3drtsurf) d3drtsurf->Release(); - d3drtsurf=NULL; - D3DPRESENT_PARAMETERS d3dparas; - ZeroMemory(&d3dparas,sizeof(d3dparas)); - d3dparas.BackBufferWidth=BACKBUFFER_WIDTH; - d3dparas.BackBufferHeight=BACKBUFFER_HEIGHT; - d3dparas.Windowed=TRUE; - d3dparas.SwapEffect=D3DSWAPEFFECT_COPY; - - if (swapsurf) {swapsurf->Release();swapsurf=NULL;}; - if (swappy) {swappy->Release();swappy=NULL;}; - - if (d3ddevice->Reset(&d3dparas)!=D3D_OK){ - return false; - } - d3ddevice->GetRenderTarget(0,&d3drtsurf); - if (d3ddevman) d3ddevman->ResetDevice(d3ddevice,dxvatoken); - //InitVertexBuffer(); - //Redraw Views, Chris could you add a member function to BoxStack, so that - // I can cause it to completely redraw the Views? - // Otherwise the OSD would be distorted after Device Lost - // FIXME - - SetEvent(event); - - - screen->create(video->getScreenWidth(), video->getScreenHeight()); - screen->display(); - - return true; - -} -LPDIRECT3DDEVICE9 OsdWin::getD3dDev() { - WaitForSingleObject(event,INFINITE);//We will only return if we are initted - return d3ddevice; -} - -LPDIRECT3D9 OsdWin::getD3d() { - WaitForSingleObject(event,INFINITE);//We will only return if we are initted - return d3d; -} - -void OsdWin::BeginPainting() {//We synchronize calls to d3d between different threads - WaitForSingleObject(d3dmutex,INFINITE); - LockDevice(); -} - -void OsdWin::EndPainting() { - UnlockDevice(); - ReleaseMutex(d3dmutex); -} - -void OsdWin::setExternalDriving(DsAllocator* dsall,DWORD width, DWORD height) { - - if (swappy) - { - BeginPainting(); - d3ddevice->StretchRect(swapsurf,NULL,d3drtsurf,NULL,filter_type); - LPDIRECT3DSWAPCHAIN9 temp=swappy; - LPDIRECT3DSURFACE9 tempsurf=swapsurf; - swappy=NULL; - swapsurf=NULL; - EndPainting(); - tempsurf->Release(); - temp->Release(); - } - - if (dsall==NULL) { - external_driving=false; - dsallocator=NULL; - return; - } - WaitForSingleObject(event,INFINITE);//We will only return if we are initted - BeginPainting(); - - if (width>BACKBUFFER_WIDTH || height>BACKBUFFER_HEIGHT) - { - D3DPRESENT_PARAMETERS d3dparas; - ZeroMemory(&d3dparas,sizeof(d3dparas)); - d3dparas.BackBufferWidth=width; - d3dparas.BackBufferHeight=height; - d3dparas.Windowed=TRUE; - d3dparas.SwapEffect=D3DSWAPEFFECT_COPY; - if (d3ddevice->CreateAdditionalSwapChain(&d3dparas,&swappy)!=D3D_OK){ - Log::getInstance()->log("OSD", Log::WARN, "Could not create Swap Chain!"); - //return 0; - } else { - swappy->GetBackBuffer(0,D3DBACKBUFFER_TYPE_MONO,&swapsurf); - } - Log::getInstance()->log("OSD", Log::INFO, "Create Additional Swap Chain %d %d!",width,height); - } - - dsallocator=dsall; - external_driving=true; - - EndPainting(); -} - -void OsdWin::Blank() { - WaitForSingleObject(event,INFINITE); - BeginPainting(); - d3ddevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,0),1.0f,0); - EndPainting(); -} diff --git a/osdwin.h b/osdwin.h deleted file mode 100644 index 5800f99..0000000 --- a/osdwin.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - Copyright 2004-2005 Chris Tallon - - This file is part of VOMP. - - VOMP is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - VOMP is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with VOMP; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#ifndef OSDWIN_H -#define OSDWIN_H - -#include - -#include "osd.h" -#include "defines.h" -#include "log.h" -#include "threadwin.h" -#include -#include -#include -#include - -struct OSDVERTEX -{ - FLOAT x,y,z,rhw; - DWORD c; - FLOAT u,v; -}; - -#define D3DFVF_OSDVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE| D3DFVF_TEX1) - -class DsAllocator; - - - -class OsdWin : public Osd, public ThreadWin -{ - public: - OsdWin(); - ~OsdWin(); - - int init(void* device); - int shutdown(); - - int getFD(); - - void screenShot(const char* fileName); - - Surface * createNewSurface(); - - void threadMethod(); - void threadPostStopCleanup(); - - LPDIRECT3DDEVICE9 getD3dDev() ; - LPDIRECT3D9 getD3d() ; - // This function is called from the WinMain function in order to get Screen updates - void Render(); - void RenderDS(LPDIRECT3DSURFACE9 present); - void BeginPainting(); - void EndPainting(); - void setExternalDriving(DsAllocator* dsall,DWORD width, DWORD height); - void Blank(); - DWORD getFilterCaps(); - DWORD getFilterType(){return filter_type;}; - void setFilterType(D3DTEXTUREFILTERTYPE type) {filter_type=type;}; - - - - - - enum EVR_state { - EVR_pres_off=0, - EVR_pres_started, - EVR_pres_pause - }; - - void SetEVRStatus(EVR_state new_state){evrstate=new_state;}; - - IDirect3DDeviceManager9 * getD3dMan() {return d3ddevman;}; - bool IsEvrSupported() {return evrsupported;}; - HWND getWindow() {return window;}; - -private: - void LockDevice(); - void UnlockDevice(); - - LPDIRECT3D9 d3d; - LPDIRECT3DDEVICE9 d3ddevice; -// LPDIRECT3DVERTEXBUFFER9 d3dvb; - LPDIRECT3DSURFACE9 d3drtsurf; - LPDIRECT3DSWAPCHAIN9 swappy; - LPDIRECT3DSURFACE9 swapsurf; - DsAllocator* dsallocator; - // This indicates, that currently a video is played, thus the osd updates are driven by the Directshow Filtersystem - bool external_driving; - HANDLE d3dmutex; - DWORD lastrendertime; - void InternalRendering(LPDIRECT3DSURFACE9 present); - bool DoLost(); - LPDIRECT3DVERTEXBUFFER9 InitVertexBuffer(DWORD width, DWORD height); - OSDVERTEX osdvertices[4]; - HANDLE event; - D3DTEXTUREFILTERTYPE filter_type; - EVR_state evrstate; - bool evrsupported; - HWND window; - ULONG_PTR gdiptoken; - Gdiplus::GdiplusStartupInput gdipstartup; - - UINT dxvatoken; - IDirect3DDeviceManager9 *d3ddevman; - HANDLE dxvadevicehandle; -}; - -#endif diff --git a/osdwinpixel.cc b/osdwinpixel.cc new file mode 100644 index 0000000..a57a8a3 --- /dev/null +++ b/osdwinpixel.cc @@ -0,0 +1,113 @@ +/* + Copyright 2004-2005 Chris Tallon + + This file is part of VOMP. + + VOMP is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + VOMP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with VOMP; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + + +#include "osdwinpixel.h" +#include "mtd.h" +#include "videowin.h" +#include "surfacewin.h" + + +#include "message.h" +#include "command.h" + + + +//This is stuff for rendering the OSD + +OsdWinPixel::OsdWinPixel() +{ + + + +} + +OsdWinPixel::~OsdWinPixel() +{ + if (initted) + { + shutdown(); + } +} + +int OsdWinPixel::getFD() +{ + if (!initted) return 0; + return fdOsd; +} + +Surface * OsdWinPixel::createNewSurface(){ + return (Surface*)new SurfaceWin(); +} + +int OsdWinPixel::init(void* device) +{ + if (initted) return 0; + + if (!createDirect3D9Objects()) return 0; + GdiplusStartup(&gdiptoken, &gdipstartup, NULL); + + VideoWin* video = (VideoWin*)Video::getInstance(); + //Now we will create the Screen + screen = new SurfaceWin(Surface::SCREEN); + screen->create(video->getScreenWidth(), video->getScreenHeight()); + screen->display(); + initted = 1; // must set this here or create surface won't work + + startRenderLoop(); + + return 1; +} + + +int OsdWinPixel::shutdown() +{ + if (!initted) return 0; + initted = 0; + shutdownDirect3D9Objects(); + + Gdiplus::GdiplusShutdown(gdiptoken); + + return 1; +} + +void OsdWinPixel::screenShot(const char* fileName) +{ + screen->screenShot(fileName); +} + +LPDIRECT3DTEXTURE9 OsdWinPixel::getNextOsdTexture() +{ + return ((SurfaceWin*)screen)->getD3dtexture(); +} + +void OsdWinPixel::lostDestroyObjects() +{ + ((SurfaceWin*)screen)->ReleaseSurface(); +} + +void OsdWinPixel::lostRecreateObjects() +{ + Video *video = Video::getInstance(); + screen->create(video->getScreenWidth(), video->getScreenHeight()); + screen->display(); +} + + diff --git a/osdwinpixel.h b/osdwinpixel.h new file mode 100644 index 0000000..042f38f --- /dev/null +++ b/osdwinpixel.h @@ -0,0 +1,60 @@ +/* + Copyright 2004-2005 Chris Tallon + + This file is part of VOMP. + + VOMP is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + VOMP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with VOMP; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef OSDWINPIXEL_H +#define OSDWINPIXEL_H + +#include + +#include "osd.h" +#include "defines.h" +#include "log.h" +#include "windowsosd.h" +#include + + +class OsdWinPixel : public Osd, public WindowsOsd +{ + public: + OsdWinPixel(); + ~OsdWinPixel(); + + int init(void* device); + int shutdown(); + + int isInitialized() { return initted; } + + int getFD(); + + void screenShot(const char* fileName); + + Surface * createNewSurface(); + +protected: + LPDIRECT3DTEXTURE9 getNextOsdTexture(); + void lostDestroyObjects(); + void lostRecreateObjects(); + + ULONG_PTR gdiptoken; + Gdiplus::GdiplusStartupInput gdipstartup; + +}; + +#endif diff --git a/surfacewin.cc b/surfacewin.cc index ba9face..302f35c 100644 --- a/surfacewin.cc +++ b/surfacewin.cc @@ -19,7 +19,7 @@ */ #include "surfacewin.h" -#include "osdwin.h" +#include "osdwinpixel.h" #include "bitmap.h" #include "log.h" #include @@ -43,7 +43,7 @@ SurfaceWin::~SurfaceWin() int SurfaceWin::create(UINT width, UINT height) { - OsdWin* osd=((OsdWin*)(Osd::getInstance())); + OsdWinPixel* osd=((OsdWinPixel*)(Osd::getInstance())); LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev(); @@ -97,7 +97,7 @@ int SurfaceWin::fillblt(int x, int y, int width, int height, const DrawStyle& c) { WaitForSingleObject(event,INFINITE); //since this might be called before surface //allocation we will wait in this case, hopefully without deadlocks - OsdWin* osd=((OsdWin*)(Osd::getInstance())); + OsdWinPixel* osd=((OsdWinPixel*)(Osd::getInstance())); if (!d3dsurface) { return 0; //why does this happen @@ -149,7 +149,7 @@ void SurfaceWin::startFastDraw(){ if (!d3dsurface) { return; //why does this happen } - OsdWin* osd=((OsdWin*)(Osd::getInstance())); + OsdWinPixel* osd=((OsdWinPixel*)(Osd::getInstance())); LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev(); if (screen==this) { //This should not happen! @@ -167,7 +167,7 @@ void SurfaceWin::startFastDraw(){ // fastdraw=true; } void SurfaceWin::endFastDraw(){ - OsdWin* osd=((OsdWin*)(Osd::getInstance())); + OsdWinPixel* osd=((OsdWinPixel*)(Osd::getInstance())); if (d3dsurface->UnlockRect()!=D3D_OK) { osd->EndPainting(); return ; @@ -188,14 +188,14 @@ void SurfaceWin::drawPixel(int x, int y, Colour & colour, bool fastdraw) { void SurfaceWin::drawPixel(int x, int y, unsigned int c, bool fastdraw) { //FixMe: locking for every single Pixel will be painfully slow - OsdWin* osd; + OsdWinPixel* osd; if (!fastdraw) { WaitForSingleObject(event,INFINITE); //since this might be called before surface //allocation we will wait in this case, hopefully without deadlocks if (!d3dsurface) { return; //why does this happen } - osd=((OsdWin*)(Osd::getInstance())); + osd=((OsdWinPixel*)(Osd::getInstance())); } if (x>=swidth || y>=sheight) return; //do not draw outside the surface if (screen==this) { @@ -254,7 +254,7 @@ int SurfaceWin::updateToScreen(int sx, int sy, int w, int h, int dx, int dy) // if (!d3dsurface) { return 0; //why does this happen } - OsdWin* osd=((OsdWin*)(Osd::getInstance())); + OsdWinPixel* osd=((OsdWinPixel*)(Osd::getInstance())); LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev(); LPDIRECT3DSURFACE9 screensurface=((SurfaceWin*)screen)->getD3dsurface(); if (!screensurface) return 0; @@ -303,7 +303,7 @@ void SurfaceWin::drawJpeg(const char *fileName, int x, int y, int *width, int *h if (!d3dsurface) { return; //why does this happen } - OsdWin* osd = ((OsdWin*)(Osd::getInstance())); + OsdWinPixel* osd = ((OsdWinPixel*)(Osd::getInstance())); osd->BeginPainting(); HDC dc; diff --git a/videowin.cc b/videowin.cc index cf97375..b6da2bb 100644 --- a/videowin.cc +++ b/videowin.cc @@ -25,7 +25,7 @@ #include "dssourcefilter.h" #include "dsallocator.h" #include "vdr.h" -#include "osdwin.h" +#include "windowsosd.h" #include "audiowin.h" #include "wwinvideofilter.h" #include "wwinvideoh264filter.h" @@ -427,7 +427,7 @@ bool VideoWin::loadOptionsfromServer(VDR* vdr) currentpresenter=EVR; } } - if (!((OsdWin*)Osd::getInstance())->IsEvrSupported()) { + if (!dynamic_cast(Osd::getInstance())->IsEvrSupported()) { currentpresenter=VMR9; } @@ -451,11 +451,11 @@ bool VideoWin::loadOptionsfromServer(VDR* vdr) name=vdr->configLoad("DirectGraphics", "StretchFiltering"); if (name!=NULL) { if (STRCASECMP(name,"None")==0) { - ((OsdWin*)Osd::getInstance())->setFilterType(D3DTEXF_NONE); + dynamic_cast(Osd::getInstance())->setFilterType(D3DTEXF_NONE); } else if (STRCASECMP(name,"Point")==0) { - ((OsdWin*)Osd::getInstance())->setFilterType(D3DTEXF_POINT); + dynamic_cast(Osd::getInstance())->setFilterType(D3DTEXF_POINT); } else if (STRCASECMP(name,"Linear")==0) { - ((OsdWin*)Osd::getInstance())->setFilterType(D3DTEXF_LINEAR); + dynamic_cast(Osd::getInstance())->setFilterType(D3DTEXF_LINEAR); } } @@ -472,11 +472,11 @@ bool VideoWin::handleOptionChanges(Option* option) switch(option->id) { case 1: { if (STRCASECMP(option->options[option->userSetChoice],"None")==0) { - ((OsdWin*)Osd::getInstance())->setFilterType(D3DTEXF_NONE); + dynamic_cast(Osd::getInstance())->setFilterType(D3DTEXF_NONE); } else if (STRCASECMP(option->options[option->userSetChoice],"Point")==0) { - ((OsdWin*)Osd::getInstance())->setFilterType(D3DTEXF_POINT); + dynamic_cast(Osd::getInstance())->setFilterType(D3DTEXF_POINT); } else if (STRCASECMP(option->options[option->userSetChoice],"Linear")==0) { - ((OsdWin*)Osd::getInstance())->setFilterType(D3DTEXF_LINEAR); + dynamic_cast(Osd::getInstance())->setFilterType(D3DTEXF_LINEAR); } return true; } break; @@ -542,7 +542,7 @@ bool VideoWin::addOptionsToPanes(int panenumber,Options *options,WOptionPane* pa Option* option; if (panenumber == 2) { - DWORD scalingcaps=((OsdWin*)Osd::getInstance())->getFilterCaps(); + DWORD scalingcaps=dynamic_cast(Osd::getInstance())->getFilterCaps(); char **scalingopts=new char *[3]; int i=0; scalingopts[i]=new char[strlen("None")+1]; @@ -568,7 +568,7 @@ bool VideoWin::addOptionsToPanes(int panenumber,Options *options,WOptionPane* pa options->push_back(option); pane->addOptionLine(option); - if (((OsdWin*)Osd::getInstance())->IsEvrSupported()) + if (dynamic_cast(Osd::getInstance())->IsEvrSupported()) { static const char* presenteropts[]={"EVR","VMR9"}; option = new Option(3,tr("Video Presenter Filter"),"DirectShow", "VideoPresenter",Option::TYPE_TEXT,2, @@ -1102,7 +1102,7 @@ int VideoWin::dsInitVideoFilter() } evr_services->Release(); - mfvideodisplaycontrol->SetVideoWindow(((OsdWin*) Osd::getInstance())->getWindow()); + mfvideodisplaycontrol->SetVideoWindow(((WindowsOsd*) Osd::getInstance())->getWindow()); //RECT client; //GetClientRect(((OsdWin*) Osd::getInstance())->getWindow(), &client); //mfvideodisplaycontrol->SetVideoPosition(NULL,&client); @@ -1526,7 +1526,7 @@ int VideoWin::attachFrameBuffer() int VideoWin::blank(void) { - ((OsdWin*)Osd::getInstance())->Blank(); + dynamic_cast(Osd::getInstance())->Blank(); return 1; } diff --git a/windowsosd.cc b/windowsosd.cc new file mode 100644 index 0000000..86ec942 --- /dev/null +++ b/windowsosd.cc @@ -0,0 +1,605 @@ +/* + Copyright 2014 Marten Richter + + This file is part of VOMP. + + VOMP is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + VOMP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with VOMP; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + + +#include "windowsosd.h" +#include "dsallocator.h" +#include "video.h" +#include "videowin.h" +#include "log.h" + +#define BACKBUFFER_WIDTH 1920 +#define BACKBUFFER_HEIGHT 1080 + +typedef HRESULT(__stdcall *FCT_DXVA2CreateDirect3DDeviceManager9)(UINT* pResetToken, IDirect3DDeviceManager9** ppDeviceManager); +typedef HRESULT(__stdcall *FCT_MFCreateVideoSampleFromSurface)(IUnknown* pUnkSurface, IMFSample** ppSample); + +FCT_DXVA2CreateDirect3DDeviceManager9 ptrDXVA2CreateDirect3DDeviceManager9 = NULL; +FCT_MFCreateVideoSampleFromSurface ptrMFCreateVideoSampleFromSurface = NULL; + + +WindowsOsd::WindowsOsd() +{ + d3d = NULL; + d3ddevice = NULL; + d3drtsurf = NULL; + + evrsupported = true; + filter_type = D3DTEXF_FORCE_DWORD; + evrstate = EVR_pres_off; + + swappy = NULL; + swapsurf = NULL; + window = NULL; + + external_driving = false; + dsallocator = NULL; + + lastrendertime = timeGetTime(); + event = CreateEvent(NULL,/*FALSE*/TRUE, FALSE, NULL); + d3dmutex = CreateMutex(NULL, FALSE, NULL); + + /*EVR stuff*/ + dxvadevicehandle = NULL; + HMODULE hlib = NULL; + hlib = LoadLibrary("dxva2.dll"); + if (!hlib) { + evrsupported = false; + return; + } + ptrDXVA2CreateDirect3DDeviceManager9 = (FCT_DXVA2CreateDirect3DDeviceManager9)GetProcAddress(hlib, "DXVA2CreateDirect3DDeviceManager9"); + if (!ptrDXVA2CreateDirect3DDeviceManager9){ + evrsupported = false; + return; + } + + hlib = LoadLibrary("evr.dll"); + if (!hlib) { + evrsupported = false; + return; + } + + ptrMFCreateVideoSampleFromSurface = (FCT_MFCreateVideoSampleFromSurface)GetProcAddress(hlib, "MFCreateVideoSampleFromSurface"); + if (!ptrMFCreateVideoSampleFromSurface){ + evrsupported = false; + return; + } + +} + +WindowsOsd::~WindowsOsd() +{ + CloseHandle(event); + CloseHandle(d3dmutex); +} + + +void WindowsOsd::LockDevice() +{ + if (!evrsupported) return; + if (!dxvadevicehandle) + { + d3ddevman->OpenDeviceHandle(&dxvadevicehandle); + } + IDirect3DDevice9 *temp; + d3ddevman->LockDevice(dxvadevicehandle, &temp, TRUE); + +} + +void WindowsOsd::UnlockDevice() +{ + if (!evrsupported) return; + if (!isInitialized()) return; + d3ddevman->UnlockDevice(dxvadevicehandle, TRUE); + if (dxvadevicehandle) + { + d3ddevman->CloseDeviceHandle(dxvadevicehandle); + dxvadevicehandle = NULL; + } + +} + +int WindowsOsd::createDirect3D9Objects() +{ + Video* video = Video::getInstance(); + //First Create Direct 3D Object + d3d = Direct3DCreate9(D3D_SDK_VERSION); + if (!d3d) + { + Log::getInstance()->log("OSD", Log::WARN, "Could not create Direct3D9 object!"); + return 0; + } + // then create the Device + D3DPRESENT_PARAMETERS d3dparas; + ZeroMemory(&d3dparas, sizeof(d3dparas)); + d3dparas.BackBufferWidth = BACKBUFFER_WIDTH; + d3dparas.BackBufferHeight = BACKBUFFER_HEIGHT; + d3dparas.Windowed = TRUE; + d3dparas.SwapEffect = D3DSWAPEFFECT_COPY; + if (d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window, + D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED, &d3dparas, &d3ddevice) != D3D_OK) { + Log::getInstance()->log("OSD", Log::WARN, "Could not create Direct3D9 device!"); + return 0; + } + d3ddevice->GetRenderTarget(0, &d3drtsurf); + + /* + if (!InitVertexBuffer()) { + Log::getInstance()->log("OSD", Log::WARN, "Could not create Direct3D9 vertex buf!"); + return 0; + }*/ + /* We have to determine which kind of filtering is supported*/ + D3DCAPS9 caps; + d3ddevice->GetDeviceCaps(&caps); + if (((caps.StretchRectFilterCaps & D3DPTFILTERCAPS_MINFLINEAR) != 0) + && ((caps.StretchRectFilterCaps & D3DPTFILTERCAPS_MAGFLINEAR) != 0)) { + if (filter_type == D3DTEXF_FORCE_DWORD) { + filter_type = D3DTEXF_LINEAR; + } + } + else { + if (filter_type == D3DTEXF_LINEAR) + { + filter_type = D3DTEXF_POINT; + } + } + + if (((caps.StretchRectFilterCaps & D3DPTFILTERCAPS_MINFPOINT) != 0) + && ((caps.StretchRectFilterCaps & D3DPTFILTERCAPS_MAGFPOINT) != 0)) { + if (filter_type == D3DTEXF_FORCE_DWORD) + { + filter_type = D3DTEXF_POINT; + } + } + else { + if (filter_type == D3DTEXF_POINT) { + filter_type = D3DTEXF_NONE; + } + } + if (filter_type == D3DTEXF_FORCE_DWORD) { + filter_type = D3DTEXF_NONE; + } + + if (evrsupported) + { + if (ptrDXVA2CreateDirect3DDeviceManager9(&dxvatoken, &d3ddevman) != S_OK) evrsupported = false; + else { + d3ddevman->ResetDevice(d3ddevice, dxvatoken); + } + } + SetEvent(event);//Now all devices are ready + return 1; +} + +void WindowsOsd::startRenderLoop() +{ + threadStart(); +} + +void WindowsOsd::shutdownDirect3D9Objects() +{ + threadStop(); + evrsupported = 0; + if (d3ddevman) d3ddevman->Release(); + d3drtsurf->Release(); + d3ddevice->Release(); + d3d->Release(); + if (swapsurf) swapsurf->Release(); + if (swappy) swappy->Release(); +} + +void WindowsOsd::threadMethod() +{ + while (true) + { + DWORD waittime = 10; + if (isInitialized()){ + if (evrstate == EVR_pres_off || evrstate == EVR_pres_pause) + { + Render(); + } + else if (evrstate == EVR_pres_started) + { + LPDIRECT3DSURFACE9 surf; + if (dsallocator) dsallocator->GetNextSurface(&surf, &waittime); + if (surf == NULL) + { + Render(); + } + else + { + RenderDS(surf); + surf->Release(); + if (dsallocator) dsallocator->DiscardSurfaceandgetWait(&waittime); + } + } + } + threadCheckExit(); + if (waittime != 0) Sleep(min(10, waittime)); + //Sleep(1); + } +} + + +void WindowsOsd::threadPostStopCleanup() +{ + //Doing nothing + //goo; +} + +void WindowsOsd::setExternalDriving(DsAllocator* dsall, DWORD width, DWORD height) { + + if (swappy) + { + BeginPainting(); + d3ddevice->StretchRect(swapsurf, NULL, d3drtsurf, NULL, filter_type); + LPDIRECT3DSWAPCHAIN9 temp = swappy; + LPDIRECT3DSURFACE9 tempsurf = swapsurf; + swappy = NULL; + swapsurf = NULL; + EndPainting(); + tempsurf->Release(); + temp->Release(); + } + + if (dsall == NULL) { + external_driving = false; + dsallocator = NULL; + return; + } + WaitForSingleObject(event, INFINITE);//We will only return if we are initted + BeginPainting(); + + if (width>BACKBUFFER_WIDTH || height>BACKBUFFER_HEIGHT) + { + D3DPRESENT_PARAMETERS d3dparas; + ZeroMemory(&d3dparas, sizeof(d3dparas)); + d3dparas.BackBufferWidth = width; + d3dparas.BackBufferHeight = height; + d3dparas.Windowed = TRUE; + d3dparas.SwapEffect = D3DSWAPEFFECT_COPY; + if (d3ddevice->CreateAdditionalSwapChain(&d3dparas, &swappy) != D3D_OK){ + Log::getInstance()->log("OSD", Log::WARN, "Could not create Swap Chain!"); + //return 0; + } + else { + swappy->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &swapsurf); + } + Log::getInstance()->log("OSD", Log::INFO, "Create Additional Swap Chain %d %d!", width, height); + } + + dsallocator = dsall; + external_driving = true; + + EndPainting(); +} + +// This function is called from the WinMain function in order to get Screen updates +void WindowsOsd::Render() +{ + if (!isInitialized()) return; + if (external_driving) { + DWORD time1 = timeGetTime(); //Updates the Menue + if ((time1 - lastrendertime)>200) {//5 fps for OSD updates are enough, avoids tearing + InternalRendering(NULL); + lastrendertime = timeGetTime(); + } + else { + //Sleep(5); //Sleep for 5 ms, in order to avoid blocking the other threads + } + } + else { + DWORD time1 = timeGetTime(); + if ((time1 - lastrendertime)>50) {//10 fps for OSD updates are enough, avoids tearing + InternalRendering(NULL); + lastrendertime = timeGetTime(); + } + else { + //Sleep(5); + + } + + } +} + +void WindowsOsd::RenderDS(LPDIRECT3DSURFACE9 present){ + if (!isInitialized()) return; + if (external_driving) { + InternalRendering(present); + lastrendertime = timeGetTime(); + } +} + + +void WindowsOsd::BeginPainting() {//We synchronize calls to d3d between different threads + WaitForSingleObject(d3dmutex, INFINITE); + LockDevice(); +} + +void WindowsOsd::EndPainting() { + UnlockDevice(); + ReleaseMutex(d3dmutex); +} + +DWORD WindowsOsd::getFilterCaps() +{ + if (!isInitialized()) return NULL; + D3DCAPS9 caps; + d3ddevice->GetDeviceCaps(&caps); + return caps.StretchRectFilterCaps; +} + +LPDIRECT3DDEVICE9 WindowsOsd::getD3dDev() { + WaitForSingleObject(event, INFINITE);//We will only return if we are initted + return d3ddevice; +} + +LPDIRECT3D9 WindowsOsd::getD3d() { + WaitForSingleObject(event, INFINITE);//We will only return if we are initted + return d3d; +} + + +void WindowsOsd::Blank() { + WaitForSingleObject(event, INFINITE); + BeginPainting(); + d3ddevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); + EndPainting(); +} + +void WindowsOsd::InternalRendering(LPDIRECT3DSURFACE9 present){ + BeginPainting(); + HRESULT losty = d3ddevice->TestCooperativeLevel(); + if (losty == D3DERR_DEVICELOST) { + //Sleep(10); + EndPainting(); + return; //Device Lost + } + if (losty == D3DERR_DEVICENOTRESET){ + EndPainting(); + DoLost(); + return; + } + WaitForSingleObject(event, INFINITE); + + LPDIRECT3DSURFACE9 targetsurf; + if (swappy) + { + targetsurf = swapsurf; + d3ddevice->SetRenderTarget(0, swapsurf);//Stupid VMR manipulates the render target + } + else + { + targetsurf = d3drtsurf; + d3ddevice->SetRenderTarget(0, d3drtsurf);//Stupid VMR manipulates the render target + } + D3DSURFACE_DESC targetdesc; + targetsurf->GetDesc(&targetdesc); + + if (external_driving) { + //Copy video to Backbuffer + if (present != NULL) { + VideoWin* video = (VideoWin*)Video::getInstance(); + /*calculating destination rect */ + RECT destrect = { 0, 0,/*video->getScreenWidth()*/ targetdesc.Width, + /*video->getScreenHeight()*/targetdesc.Height }; + const VideoDisplay &vd = video->getVideoDisplay(); + int addx, addy; + addx = addy = 0; + + switch (vd.mode) { + case Eighth: + destrect.right = destrect.right / 2; + destrect.bottom = destrect.bottom / 2; + case Quarter: + destrect.right = destrect.right / 2; + destrect.bottom = destrect.bottom / 2; + break; + case Window: + float imageaspect = 720.f / 576.f; + float boxaspect = ((float)vd.width) / ((float)vd.height); + float videoaspect = ((float)targetdesc.Width) / ((float)targetdesc.Height); + if (imageaspect > boxaspect) { + destrect.right = (int)(((float)destrect.right) * ((float)vd.width) / 720.f); + destrect.bottom = (int)(((float)destrect.right) / videoaspect); + addy += (((float)vd.height) - ((float)vd.width) / imageaspect)*0.5f / 576.f + *((float)targetdesc.Height); + } + else { + destrect.bottom = (int)(((float)destrect.bottom) * ((float)vd.height) / 576.f); + destrect.right = (int)(((float)destrect.bottom)*videoaspect); + addx += (((float)vd.width) - ((float)vd.height) * imageaspect)*0.5f / 720.f + *((float)targetdesc.Width); + } + + + break; + }; + switch (vd.mode) { + case Quarter: + case Eighth: + case Window: + destrect.left = (int)(((float)vd.x*targetdesc.Width) / 720.f) + addx; + destrect.top = (int)(((float)vd.y*targetdesc.Height) / 576.f) + addy; + destrect.right += destrect.left; + destrect.bottom += destrect.top; + break; + } + d3ddevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); + D3DSURFACE_DESC surf_desc; + present->GetDesc(&surf_desc);//for chop sides + RECT sourcerect = { 0, 0, surf_desc.Width, surf_desc.Height }; + if (video->getPseudoTVsize() == Video::ASPECT4X3 + && video->getMode() == Video::NORMAL + && video->getAspectRatio() == Video::ASPECT16X9) { + unsigned int correction = ((double)(surf_desc.Width))*4.*9. / 3. / 16.; + sourcerect.left = (surf_desc.Width - correction) / 2; + sourcerect.right = sourcerect.left + correction; + } + d3ddevice->StretchRect(present, &sourcerect, targetsurf, &destrect, filter_type); + + } + } + else { + VideoWin* video = (VideoWin*)Video::getInstance(); + //Clear Background + if (!video->isVideoOn()) d3ddevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); + } + LPDIRECT3DVERTEXBUFFER9 vb = NULL; + vb = InitVertexBuffer(targetdesc.Width, targetdesc.Height); + + //Drawing the OSD + if (d3ddevice->BeginScene() == D3D_OK) { + d3ddevice->SetStreamSource(0, vb, 0, sizeof(OSDVERTEX)); + d3ddevice->SetFVF(D3DFVF_OSDVERTEX); + LPDIRECT3DTEXTURE9 osdtex = getNextOsdTexture(); + d3ddevice->SetTexture(0, osdtex); + //d3ddevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE); + d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + + d3ddevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + d3ddevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); + + + d3ddevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + d3ddevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + d3ddevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + d3ddevice->SetRenderState(D3DRS_LIGHTING, FALSE); + + + d3ddevice->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2); + d3ddevice->EndScene(); + //Show it to the user! + HRESULT hres; + if (swappy) + { + if (hres = swappy->Present(NULL, NULL, NULL, NULL, 0) == D3DERR_DEVICELOST){ + //EndPainting(); + if (!external_driving) DoLost(); + } + } + else + { + if (hres = d3ddevice->Present(NULL, NULL, NULL, NULL) == D3DERR_DEVICELOST){ + //EndPainting(); + if (!external_driving) DoLost(); + } + } + + } + + vb->Release(); + EndPainting(); + + + // if (!external_driving) { + // Sleep(4);//The User can wait for 4 milliseconds to see his changes + // } +} + +bool WindowsOsd::DoLost(){ + Log::getInstance()->log("OSD", Log::WARN, "Direct3D Device Lost! Reobtaining..."); + ResetEvent(event); + if (external_driving && dsallocator != NULL) { + dsallocator->LostDevice(d3ddevice, d3d); //Propagate the information through DS + } + //First we free up all resources + Video* video = Video::getInstance(); + lostDestroyObjects(); + if (d3drtsurf) d3drtsurf->Release(); + d3drtsurf = NULL; + D3DPRESENT_PARAMETERS d3dparas; + ZeroMemory(&d3dparas, sizeof(d3dparas)); + d3dparas.BackBufferWidth = BACKBUFFER_WIDTH; + d3dparas.BackBufferHeight = BACKBUFFER_HEIGHT; + d3dparas.Windowed = TRUE; + d3dparas.SwapEffect = D3DSWAPEFFECT_COPY; + + if (swapsurf) { swapsurf->Release(); swapsurf = NULL; }; + if (swappy) { swappy->Release(); swappy = NULL; }; + + if (d3ddevice->Reset(&d3dparas) != D3D_OK){ + return false; + } + d3ddevice->GetRenderTarget(0, &d3drtsurf); + if (d3ddevman) d3ddevman->ResetDevice(d3ddevice, dxvatoken); + //InitVertexBuffer(); + //Redraw Views, Chris could you add a member function to BoxStack, so that + // I can cause it to completely redraw the Views? + // Otherwise the OSD would be distorted after Device Lost + // FIXME + + SetEvent(event); + + lostRecreateObjects(); + + + return true; + +} + +LPDIRECT3DVERTEXBUFFER9 WindowsOsd::InitVertexBuffer(DWORD width, DWORD height) +{ + LPDIRECT3DVERTEXBUFFER9 ret = NULL; + Video* video = Video::getInstance(); + FLOAT texx = ((float)video->getScreenWidth()) / 1024.f; + FLOAT texy = ((float)video->getScreenHeight()) / 1024.f; + D3DCOLOR osdcolor = D3DCOLOR_RGBA(255, 255, 255, 255); + osdvertices[0].c = osdcolor; + osdvertices[0].x = 0.f - 0.5f; + osdvertices[0].y = 0.f - 0.5f; + osdvertices[0].z = 0.5f; + osdvertices[0].rhw = 1.f; + osdvertices[0].u = 0.f; + osdvertices[0].v = 0.f; + osdvertices[1].c = osdcolor; + osdvertices[1].x = ((float)width) - 0.5f; + osdvertices[1].y = 0.f - 0.5f; + osdvertices[1].z = 0.5f; + osdvertices[1].u = texx; + osdvertices[1].v = 0.f; + osdvertices[1].rhw = 1.f; + osdvertices[2].c = osdcolor; + osdvertices[2].x = ((float)width) - 0.5f; + osdvertices[2].y = ((float)height) - 0.5f; + osdvertices[2].z = 0.5f; + osdvertices[2].rhw = 1.f; + osdvertices[2].u = texx; + osdvertices[2].v = texy; + osdvertices[3].c = osdcolor; + osdvertices[3].x = 0.f - 0.5f; + osdvertices[3].y = ((float)height) - 0.5f; + osdvertices[3].z = 0.5f; + osdvertices[3].rhw = 1.f; + osdvertices[3].u = 0.f; + osdvertices[3].v = texy; + + if (d3ddevice->CreateVertexBuffer(4 * sizeof(OSDVERTEX), 0, D3DFVF_OSDVERTEX, D3DPOOL_MANAGED, + &ret, NULL) != D3D_OK) { + return NULL; + } + void *pvertex = NULL; + if (ret->Lock(0, sizeof(osdvertices), &pvertex, 0) != D3D_OK) { + return NULL; + } + memcpy(pvertex, osdvertices, sizeof(osdvertices)); + ret->Unlock(); + return ret; +} diff --git a/windowsosd.h b/windowsosd.h new file mode 100644 index 0000000..5f1e81e --- /dev/null +++ b/windowsosd.h @@ -0,0 +1,127 @@ +/* + Copyright 2004-2005 Marten Richter + + This file is part of VOMP. + + VOMP is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + VOMP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with VOMP; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef WINDOWSOSD_H +#define WINDOWSOSD_H + +#include +#include +#include +#include "threadwin.h" + +class DsAllocator; + +struct OSDVERTEX +{ + FLOAT x, y, z, rhw; + DWORD c; + FLOAT u, v; +}; + +#define D3DFVF_OSDVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE| D3DFVF_TEX1) + + +// This class defines all necessary interfaces +// for windows osd to communicate with other windows base classes + +class WindowsOsd : public ThreadWin { +public: + WindowsOsd(); + virtual ~WindowsOsd(); + + bool IsEvrSupported() { return evrsupported; }; + void setExternalDriving(DsAllocator* dsall, DWORD width, DWORD height); + + + DWORD getFilterType(){ return filter_type; }; + void setFilterType(D3DTEXTUREFILTERTYPE type) { filter_type = type; }; + + LPDIRECT3DDEVICE9 getD3dDev(); + LPDIRECT3D9 getD3d(); + IDirect3DDeviceManager9 * getD3dMan() { return d3ddevman; }; + DWORD getFilterCaps(); + HWND getWindow() { return window; }; + void setWindow(HWND twnd) { window = twnd; }; + + // This function is called in order to get Screen updates + void Render(); + void RenderDS(LPDIRECT3DSURFACE9 present); + void Blank(); + void BeginPainting(); + void EndPainting(); + + virtual int isInitialized()=0; + + void threadMethod(); + void threadPostStopCleanup(); + + + enum EVR_state { + EVR_pres_off = 0, + EVR_pres_started, + EVR_pres_pause + }; + + void SetEVRStatus(EVR_state new_state){ evrstate = new_state; }; +protected: + + int createDirect3D9Objects(); + void shutdownDirect3D9Objects(); + void startRenderLoop(); + void InternalRendering(LPDIRECT3DSURFACE9 present); + bool DoLost(); + virtual void lostDestroyObjects()=0; + virtual void lostRecreateObjects()=0; + + void LockDevice(); + void UnlockDevice(); + + virtual LPDIRECT3DTEXTURE9 getNextOsdTexture()=0; + + LPDIRECT3DVERTEXBUFFER9 InitVertexBuffer(DWORD width, DWORD height); + OSDVERTEX osdvertices[4]; + + bool evrsupported; + EVR_state evrstate; + D3DTEXTUREFILTERTYPE filter_type; + + LPDIRECT3D9 d3d; + LPDIRECT3DDEVICE9 d3ddevice; + LPDIRECT3DSWAPCHAIN9 swappy; + LPDIRECT3DSURFACE9 swapsurf; + LPDIRECT3DSURFACE9 d3drtsurf; + + UINT dxvatoken; + IDirect3DDeviceManager9 *d3ddevman; + HANDLE dxvadevicehandle; + + DsAllocator* dsallocator; + + bool external_driving; + HANDLE d3dmutex; + HANDLE event; + DWORD lastrendertime; + HWND window; + +}; + + + +#endif \ No newline at end of file diff --git a/winmain.cc b/winmain.cc index f66d054..be754e5 100644 --- a/winmain.cc +++ b/winmain.cc @@ -38,7 +38,12 @@ #include "videowin.h" #include "audiowin.h" #include "vdr.h" -#include "osdwin.h" +#include "windowsosd.h" +#ifndef GRADIENT_DRAWING +#include "osdwinpixel.h" +#else + +#endif #include "boxstack.h" #include "command.h" #include "wol.h" @@ -157,7 +162,7 @@ INT WINAPI WinMain( HINSTANCE hinst , HINSTANCE previnst, LPSTR cmdline, int cmd mtd = new MtdWin(); led = new LedWin(); timers = new Timers(); - osd = new OsdWin(); + osd = new Osd_TYPE(); vdr = new VDR(); video = new VideoWin(); audio = new AudioWin(); @@ -261,7 +266,8 @@ INT WINAPI WinMain( HINSTANCE hinst , HINSTANCE previnst, LPSTR cmdline, int cmd return 0; } - success = osd->init((void*)&win); + dynamic_cast(osd)->setWindow(win); + success = osd->init(NULL); if (success) { logger->log("Core", Log::INFO, "OSD module initialised"); -- 2.39.2