]> git.vomp.tv Git - vompclient.git/commitdiff
Split OsdWin into OsdWinPixel and WindowsOsd as preparation for Vector
authorMarten Richter <marten.richter@freenet.de>
Mon, 3 Nov 2014 07:26:26 +0000 (08:26 +0100)
committerMarten Richter <marten.richter@freenet.de>
Mon, 3 Nov 2014 07:26:26 +0000 (08:26 +0100)
based Windows osd

defines.h
dsallocator.cc
osdwin.cc [deleted file]
osdwin.h [deleted file]
osdwinpixel.cc [new file with mode: 0644]
osdwinpixel.h [new file with mode: 0644]
surfacewin.cc
videowin.cc
windowsosd.cc [new file with mode: 0644]
windowsosd.h [new file with mode: 0644]
winmain.cc

index b09dc657a3532072a88dcc38151479c5a8f5ba0c..beb9146a5e5112d86392b8015e070ac013804c50 100644 (file)
--- 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
 
index 841cc5a0eec197ae783aa0ac33bdf41431a3d06b..c41d90d58e8332e154f97b1d6db553f16e53c516 100644 (file)
 
 #define INITGUID
 
-#include "osdwin.h"
+#include "osd.h"
+#include "windowsosd.h"
 #include "dsallocator.h"
+#include "log.h"
 
 #include <math.h>
 
@@ -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<WindowsOsd*>(Osd::getInstance())->SetEVRStatus(WindowsOsd::EVR_pres_off);
+       dynamic_cast<WindowsOsd*>(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<WindowsOsd*>(Osd::getInstance())->getD3dDev();
+    HMONITOR hmon=dynamic_cast<WindowsOsd*>(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<WindowsOsd*>(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<WindowsOsd*>(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<WindowsOsd*>(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<WindowsOsd*>(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<WindowsOsd*>(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<WindowsOsd*>(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<WindowsOsd*>(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<WindowsOsd*>(Osd::getInstance())->SetEVRStatus(WindowsOsd::EVR_pres_off);
+                       dynamic_cast<WindowsOsd*>(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<WindowsOsd*>(Osd::getInstance())->setExternalDriving(this, vwidth, vheight);
+                       dynamic_cast<WindowsOsd*>(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<WindowsOsd*>(Osd::getInstance())->setExternalDriving(this, vwidth, vheight);
      Log::getInstance()->log("DsAllocator", Log::DEBUG , "OnClockStart");
-    ((OsdWin*)Osd::getInstance())->SetEVRStatus(OsdWin::EVR_pres_started);
+        dynamic_cast<WindowsOsd*>(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<WindowsOsd*>(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<WindowsOsd*>(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<WindowsOsd*>(Osd::getInstance())->setExternalDriving(this, vwidth, vheight);
     
      Log::getInstance()->log("DsAllocator", Log::DEBUG , "OnClockPause");
-    ((OsdWin*)Osd::getInstance())->SetEVRStatus(OsdWin::EVR_pres_pause);
+        dynamic_cast<WindowsOsd*>(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<WindowsOsd*>(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<WindowsOsd*>(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<WindowsOsd*>(Osd::getInstance());
     LPDIRECT3DDEVICE9 d3ddev=osdwin->getD3dDev();
     osdwin->BeginPainting();
     surfaces.resize(10);
diff --git a/osdwin.cc b/osdwin.cc
deleted file mode 100644 (file)
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 (file)
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 <stdio.h>
-
-#include "osd.h"
-#include "defines.h"
-#include "log.h"
-#include "threadwin.h"
-#include <winsock2.h>
-#include <d3d9.h>
-#include <Dxva2api.h>
-#include <gdiplus.h>
-
-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 (file)
index 0000000..a57a8a3
--- /dev/null
@@ -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 (file)
index 0000000..042f38f
--- /dev/null
@@ -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 <stdio.h>
+
+#include "osd.h"
+#include "defines.h"
+#include "log.h"
+#include "windowsosd.h"
+#include <gdiplus.h>
+
+
+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
index ba9face3f4bfed592b1f92b6dd3a1517ca3e435e..302f35c7d32c27560c000896d0d71f75587de6ec 100644 (file)
@@ -19,7 +19,7 @@
 */
 
 #include "surfacewin.h"
-#include "osdwin.h"
+#include "osdwinpixel.h"
 #include "bitmap.h"
 #include "log.h"
 #include <gdiplus.h>
@@ -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;
index cf97375c2a7c22d3f1cb3e16a67fe0a56e682537..b6da2bb92626ed4d620b8c9dfaacfa4c8d639d96 100644 (file)
@@ -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<WindowsOsd*>(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<WindowsOsd*>(Osd::getInstance())->setFilterType(D3DTEXF_NONE);
        } else if (STRCASECMP(name,"Point")==0) {
-           ((OsdWin*)Osd::getInstance())->setFilterType(D3DTEXF_POINT);
+           dynamic_cast<WindowsOsd*>(Osd::getInstance())->setFilterType(D3DTEXF_POINT);
        } else if (STRCASECMP(name,"Linear")==0) {
-           ((OsdWin*)Osd::getInstance())->setFilterType(D3DTEXF_LINEAR);
+           dynamic_cast<WindowsOsd*>(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<WindowsOsd*>(Osd::getInstance())->setFilterType(D3DTEXF_NONE);
             } else if (STRCASECMP(option->options[option->userSetChoice],"Point")==0) {
-                ((OsdWin*)Osd::getInstance())->setFilterType(D3DTEXF_POINT);
+                               dynamic_cast<WindowsOsd*>(Osd::getInstance())->setFilterType(D3DTEXF_POINT);
             } else if (STRCASECMP(option->options[option->userSetChoice],"Linear")==0) {
-                ((OsdWin*)Osd::getInstance())->setFilterType(D3DTEXF_LINEAR);
+                               dynamic_cast<WindowsOsd*>(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<WindowsOsd*>(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<WindowsOsd*>(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<WindowsOsd*>(Osd::getInstance())->Blank();
   return 1;
 }
 
diff --git a/windowsosd.cc b/windowsosd.cc
new file mode 100644 (file)
index 0000000..86ec942
--- /dev/null
@@ -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 (file)
index 0000000..5f1e81e
--- /dev/null
@@ -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 <winsock2.h>
+#include <d3d9.h>
+#include <Dxva2api.h>
+#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
index f66d0545798c760ce1e419b24c4819304875f07e..be754e5af262d92d2abd6d88a5dd3353b9364fd6 100644 (file)
 #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<WindowsOsd*>(osd)->setWindow(win);
+  success = osd->init(NULL);
   if (success)
   {
     logger->log("Core", Log::INFO, "OSD module initialised");