diff options
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | ffnetdev.c | 32 | ||||
-rw-r--r-- | netosd.c | 23 | ||||
-rw-r--r-- | osdworker.c | 169 | ||||
-rw-r--r-- | osdworker.h | 13 | ||||
-rw-r--r-- | tableinitcmtemplate.c | 4 |
6 files changed, 112 insertions, 133 deletions
@@ -31,7 +31,7 @@ TMPDIR = /tmp ### The version number of VDR (taken from VDR's "config.h"): -VDRVERSION = $(shell grep 'define VDRVERSION ' $(VDRDIR)/config.h | awk '{ print $$3 }' | sed -e 's/"//g') +APIVERSION = $(shell grep 'define APIVERSION ' $(VDRDIR)/config.h | awk '{ print $$3 }' | sed -e 's/"//g') ### The name of the distribution archive: @@ -95,7 +95,7 @@ libvdr-$(PLUGIN).so: $(SERVEROBJS) $(COMMONOBJS) %.so: $(CXX) $(CXXFLAGS) -shared $^ -o $@ - @cp $@ $(LIBDIR)/$@.$(VDRVERSION) + @cp $@ $(LIBDIR)/$@.$(APIVERSION) dist: clean @-rm -rf $(TMPDIR)/$(ARCHIVE) @@ -85,7 +85,7 @@ const char *cPluginFFNetDev::CommandLineHelp(void) bool cPluginFFNetDev::ProcessArgs(int argc, char *argv[]) { // Implement command line argument processing here if applicable. - fprintf (stderr, "[ffnetdev] processing args.\n"); + dsyslog("[ffnetdev] processing args.\n"); static struct option long_options[] = { { "tsport", required_argument , NULL, 't' }, { "osdport", required_argument , NULL, 'o' }, @@ -97,33 +97,34 @@ bool cPluginFFNetDev::ProcessArgs(int argc, char *argv[]) while ((c = getopt_long(argc, argv, "t:o:e", long_options, NULL)) != -1) { switch (c) { case 'e': EnableRemote = true; + dsyslog("[ffnetdev] Remote enabled\n"); break; case 't': if (isnumber(optarg)) { int n = atoi(optarg); if (0 < n && n < 65536) { TSPort = n; - fprintf(stderr, "[ffnetdev] TS Port: %d\n", n); + dsyslog("[ffnetdev] TS Port: %d\n", n); break; } } - fprintf(stderr, "[ffnetdev] invalid port number: %s\n", optarg); + esyslog("[ffnetdev] invalid port number: %s\n", optarg); return 2; break; case 'o': if (isnumber(optarg)) { int n = atoi(optarg); if (0 < n && n < 65536) { OSDPort = n; - fprintf(stderr, "[ffnetdev] OSD Port: %d\n", n); + dsyslog("[ffnetdev] OSD Port: %d\n", n); break; } } - fprintf(stderr, "[ffnetdev] invalid port number: %s\n", optarg); + esyslog("[ffnetdev] invalid port number: %s\n", optarg); return 2; break; default : return 2; } } - fprintf (stderr, "[ffnetdev] finished processing args.\n"); + dsyslog("[ffnetdev] finished processing args.\n"); return true; } @@ -156,7 +157,7 @@ bool cPluginFFNetDev::Start(void) bool cPluginFFNetDev::Initialize(void) { // Start any background activities the plugin shall perform. - fprintf(stderr,"[ffnetdev] initializing plugin.\n"); + dsyslog("[ffnetdev] initializing plugin.\n"); m_StreamDevice = new cStreamDevice(); return true; } @@ -169,7 +170,7 @@ void cPluginFFNetDev::Housekeeping(void) cOsdObject *cPluginFFNetDev::MainMenuAction(void) { // Perform the action when selected from the main VDR menu. - fprintf (stderr, "[ffnetdev] MainMenuAction called.\n"); + dsyslog("[ffnetdev] MainMenuAction called.\n"); // return new cMenuSetupSoftdevice; return NULL; } @@ -223,17 +224,11 @@ void cPluginFFNetDev::SetPrimaryDevice() if (!cRemote::HasKeys()) new cLearningThread(); -#ifdef DEBUG - fprintf(stderr, "[ffnetdev] remote control enabled.\n"); -#endif - isyslog("[ffnetdev] remote control enabled.\n"); + dsyslog("[ffnetdev] remote control enabled.\n"); } else { -#ifdef DEBUG - fprintf(stderr, "[ffnetdev] remote control disabled.\n"); -#endif - isyslog("[ffnetdev] remote control disabled.\n"); + dsyslog("[ffnetdev] remote control disabled.\n"); } } @@ -244,10 +239,7 @@ void cPluginFFNetDev::RestorePrimaryDevice() while ((cOsd::IsOpen() > 0) && (i-- > 0)) cRemote::Put(kBack); -#ifdef DEBUG - fprintf(stderr, "[ffnetdev] remote control disabled.\n"); -#endif - isyslog("[ffnetdev] remote control disabled.\n"); + dsyslog("[ffnetdev] remote control disabled.\n"); if (m_origPrimaryDevice != -1) { @@ -29,8 +29,8 @@ eOsdError cNetOSD::CanHandleAreas(const tArea *Areas, int NumAreas) { eOsdError Result = cOsd::CanHandleAreas(Areas, NumAreas); if (Result == oeOk) { - if (NumAreas > 1) // Handle only one big area (because we support VNC colour map mode) - return oeTooManyAreas; // We cannot handle multiple areas having different colour maps. We need a single colourmap. Thus, only one area. + if (NumAreas > 7) + return oeTooManyAreas; int TotalMemory = 0; for (int i = 0; i < NumAreas; i++) { if (Areas[i].bpp != 1 && Areas[i].bpp != 2 && Areas[i].bpp != 4 && Areas[i].bpp != 8) @@ -48,31 +48,28 @@ eOsdError cNetOSD::CanHandleAreas(const tArea *Areas, int NumAreas) return Result; } + void cNetOSD::Flush(void) { cBitmap *Bitmap; + int x1=0, x2=0, y1=0, y2=0; for (int i = 0; (Bitmap = GetBitmap(i)) != NULL; i++) - { - int x1=0, x2=0, y1=0, y2=0; + { if (Bitmap->Dirty(x1, y1, x2, y2)) { - // commit colors: - int NumColors; - const tColor *Colors = Bitmap->Colors(NumColors); - if (Colors) { - cOSDWorker::SendCMAP(NumColors , Colors); - } #ifdef DEBUG fprintf(stderr, "[ffnetdev] NetOSD: Left: %d, Top: %d, X0: %d, Y0: %d, Width: %d, Height: %d\n", Left(), Top(), Bitmap->X0(), Bitmap->Y0(), Bitmap->Width(), Bitmap->Height()); fprintf(stderr, "[ffnetdev] NetOSD: Dirty area x1: %d, y1: %d, x2: %d, y2: %d\n",x1,y1,x2,y2); #endif - // commit modified data: - cOSDWorker::SendScreen(Bitmap->Width(), Left()+x1 +Bitmap->X0(), Top()+y1+Bitmap->Y0(), x2-x1+1, y2-y1+1, Bitmap->Data(x1, y1)); + cOSDWorker::DrawBitmap(Left() + Bitmap->X0(), Top() + Bitmap->Y0(), *Bitmap); + } Bitmap->Clean(); - } + } + + cOSDWorker::SendScreen(); } diff --git a/osdworker.c b/osdworker.c index 2d8769b..c354685 100644 --- a/osdworker.c +++ b/osdworker.c @@ -47,20 +47,20 @@ cOSDWorker::cOSDWorker(void) ServerFormat.blueShift = 0; ServerFormat.blueMax = 255; - memset(&m_OSDBuffer, 0, sizeof(m_OSDBuffer)); + m_pOsdBitmap = NULL; numOSDColors = 1; memset(&OSDColors, 0, sizeof(OSDColors)); - m_notupdatedLeft = -1; - m_notupdatedTop = -1; - m_notupdatedRight = -1; - m_notupdatedBottom = -1; + m_pOsdBitmap = new cBitmap(720, 576, 8, 0, 0); + m_pOsdBitmap->DrawRectangle(0, 0, 720, 576, clrTransparent); + memset(&m_lasttime, 0, sizeof(m_lasttime)); memset(&m_lastupdate, 0, sizeof(m_lastupdate)); memset(&ClientFormat, 0, sizeof(ClientFormat)); ClientFormat.trueColour = 1; + m_bOSDisClear = true; } cOSDWorker::~cOSDWorker() { @@ -70,11 +70,13 @@ cOSDWorker::~cOSDWorker() { { m_pEncoder->LogStats(); delete m_pEncoder; - m_pEncoder = NULL; } if (m_pSendBuffer != NULL) delete [] m_pSendBuffer; + + if (m_pOsdBitmap != NULL) + delete m_pOsdBitmap; } @@ -156,97 +158,81 @@ void cOSDWorker::CreateSendBuffer(int SendBufferSize) bool cOSDWorker::ClearScreen(void) { - if (m_Instance == NULL) + if ((m_Instance == NULL) || (m_Instance->m_pOsdBitmap == NULL)) return false; // this should be improved; // 1) maybe we should send a our very "special" pseudo encoding[CLEAR_SCREEN] to our "special" VNC client to get an empty screen really fast - m_Instance->numOSDColors = 1; - memset(&m_Instance->OSDColors, 0, sizeof(m_Instance->OSDColors)); - SendCMAP(m_Instance->numOSDColors, m_Instance->OSDColors); - - bool bRetVal = false; - memset(&(m_Instance->m_OSDBuffer), 0, 720*576); memset(&(m_Instance->m_lasttime), 0, sizeof(m_Instance->m_lasttime)); - bRetVal = SendScreen(720,0,0,720,576,&(m_Instance->m_OSDBuffer)); - return bRetVal; + m_Instance->m_pOsdBitmap->DrawRectangle(0, 0, 720, 576, clrTransparent); + m_Instance->SendScreen(); + + rfbBellMsg fu; + fu.type=rfbBell; + OSDWrite((unsigned char*)&fu, sz_rfbBellMsg); + + m_Instance->m_bOSDisClear = true; + + return true; +} + +bool cOSDWorker::DrawBitmap(int x1, int y1, cBitmap &pOsdBitmap) +{ + if (m_Instance->m_pOsdBitmap != NULL) + { + m_Instance->m_pOsdBitmap->DrawBitmap(x1, y1, pOsdBitmap); + return true; + } + + return false; } -bool cOSDWorker::SendScreen(unsigned int stride, unsigned int x1, unsigned int y1, unsigned int w, unsigned int h, const void *data) +bool cOSDWorker::SendScreen(int x1, int y1, int x2, int y2) { - if (m_Instance == NULL) + if ((m_Instance == NULL) || (m_Instance->m_pOsdBitmap == NULL)) return false; - - rfbFramebufferUpdateMsg fu; - rfbFramebufferUpdateRectHeader furh; - - unsigned int x; - unsigned int y; - for (y=0; y<h; y++) - for (x=0; x<w; x++) - m_Instance->m_OSDBuffer[(720*(y+y1))+x+x1] = *((unsigned char *)data+(y*stride)+x); - - x = x1; - y = y1; - x1 = (m_Instance->m_notupdatedLeft != -1 && m_Instance->m_notupdatedLeft < (int)x1) - ? m_Instance->m_notupdatedLeft : x1; - y1 = (m_Instance->m_notupdatedTop != -1 && m_Instance->m_notupdatedTop < (int)y1) - ? m_Instance->m_notupdatedTop : y1; - - w = (m_Instance->m_notupdatedRight != -1 && m_Instance->m_notupdatedRight > (int)(x1 + w)) - ? m_Instance->m_notupdatedRight - x1 : w + (x - x1); - h = (m_Instance->m_notupdatedBottom != -1 && m_Instance->m_notupdatedBottom > (int)(y1 + h)) - ? m_Instance->m_notupdatedBottom - y1 : h + (y - y1); - - struct timeval curtime; - gettimeofday(&curtime, 0); - curtime.tv_sec = curtime.tv_sec - (((int)curtime.tv_sec / 1000000) * 1000000); - if ((curtime.tv_sec * 1000 + (curtime.tv_usec / 1000) < m_Instance->m_lasttime.tv_sec * 1000 + (m_Instance->m_lasttime.tv_usec / 1000) + 100) || - (m_Instance->m_pEncoder == NULL)) - { - m_Instance->m_notupdatedLeft = (int)x1; - m_Instance->m_notupdatedTop = (int)y1; - m_Instance->m_notupdatedRight = (int)(x1 + w); - m_Instance->m_notupdatedBottom = (int)(y1 + h); - m_Instance->m_lasttime = curtime; - return false; - } - else - { - m_Instance->m_notupdatedLeft = -1; - m_Instance->m_notupdatedTop = -1; - m_Instance->m_notupdatedRight = -1; - m_Instance->m_notupdatedBottom = -1; - m_Instance->m_lasttime = curtime; - m_Instance->m_lastupdate = curtime; - } - - if ((m_Instance->state==HANDSHAKE_OK) && (m_Instance->m_pEncoder != NULL)) { - RECT rect = {x1, y1, x1 + w, y1 + h}; + if ((m_Instance->state==HANDSHAKE_OK) && (m_Instance->m_pEncoder != NULL) && + (x1 || x2 || y1 || y2 || (m_Instance->m_pOsdBitmap->Dirty(x1, y1, x2, y2)))) + { + rfbFramebufferUpdateMsg fu; + struct timeval curtime; + gettimeofday(&curtime, 0); + curtime.tv_sec = curtime.tv_sec - (((int)curtime.tv_sec / 1000000) * 1000000); + if ((curtime.tv_sec * 1000 + (curtime.tv_usec / 1000) < m_Instance->m_lasttime.tv_sec * 1000 + (m_Instance->m_lasttime.tv_usec / 1000) + 100) || + (m_Instance->m_pEncoder == NULL)) + { + m_Instance->m_lasttime = curtime; + return false; + } + else + { + m_Instance->m_lasttime = curtime; + m_Instance->m_lastupdate = curtime; + } + + if (m_Instance->m_pEncoder != NULL) + m_Instance->m_pEncoder->SetLocalFormat(m_Instance->ServerFormat, 720, 576); + + RECT rect = {x1, y1, x2, y2}; fu.type=rfbFramebufferUpdate; fu.nRects=Swap16IfLE(1); OSDWrite((unsigned char*)&fu, sz_rfbFramebufferUpdateMsg); - - int BufferSize = m_Instance->m_pEncoder->RequiredBuffSize(w, h); + int BufferSize = m_Instance->m_pEncoder->RequiredBuffSize(x2-x1, y2-y1); m_Instance->CreateSendBuffer(BufferSize); - BufferSize = m_Instance->m_pEncoder->EncodeRect( &(m_Instance->m_OSDBuffer[0]), m_Instance->m_pSendBuffer, rect); + BufferSize = m_Instance->m_pEncoder->EncodeRect((BYTE*)(m_Instance->m_pOsdBitmap->Data(0, 0)), m_Instance->m_pSendBuffer, rect); #ifdef DEBUG fprintf(stderr, "[ffnetdev] VNC: Send OSD Data %d Bytes\n", BufferSize); #endif dsyslog("[ffnetdev] VNC: Send OSD Data %d Bytes\n", BufferSize); OSDWrite((unsigned char*)m_Instance->m_pSendBuffer, BufferSize); + m_Instance->m_pOsdBitmap->Clean(); + + m_Instance->m_bOSDisClear = false; - if ((m_Instance->numOSDColors == 0) || ((m_Instance->numOSDColors == 1) && (m_Instance->OSDColors[0] == 0))) - { - rfbBellMsg fu; - fu.type=rfbBell; - OSDWrite((unsigned char*)&fu, sz_rfbBellMsg); - } - return true; } else { @@ -255,6 +241,16 @@ bool cOSDWorker::SendScreen(unsigned int stride, unsigned int x1, unsigned int y } +bool cOSDWorker::GetOSDColors(const tColor **OSDColors, int *numOSDColors) +{ + if ((m_Instance == NULL) || (m_Instance->m_pOsdBitmap == NULL)) + return false; + + *OSDColors = (tColor*)m_Instance->m_pOsdBitmap->Colors(*numOSDColors); + return true; +} + + bool cOSDWorker::SendCMAP(int NumColors, const tColor *Colors) { if (m_Instance == NULL) @@ -488,6 +484,8 @@ void cOSDWorker::HandleClientRequests(cTBSelect *select) m_pEncoder->SetQualityLevel(9); m_pEncoder->SetRemoteFormat(ClientFormat); } + + ClearScreen(); } break; case rfbFramebufferUpdateRequest: @@ -512,18 +510,18 @@ void cOSDWorker::HandleClientRequests(cTBSelect *select) Swap16IfLE(msg.fur.h) ); - if (numOSDColors > 0) + + if (m_bOSDisClear) { - SendCMAP(numOSDColors, OSDColors); - SendScreen(720, //stride - Swap16IfLE(msg.fur.x), Swap16IfLE(msg.fur.y), - Swap16IfLE(msg.fur.w), Swap16IfLE(msg.fur.h), - &m_OSDBuffer); + ClearScreen(); } else { - ClearScreen(); + SendScreen( Swap16IfLE(msg.fur.x), Swap16IfLE(msg.fur.y), + Swap16IfLE(msg.fur.x + msg.fur.w), + Swap16IfLE(msg.fur.y + msg.fur.h)); } + break; case rfbKeyEvent: if (!RFBRead( ((char*)&msg.ke)+1, sz_rfbKeyEventMsg-1)) return; @@ -747,15 +745,10 @@ void cOSDWorker::Action(void) { struct timeval curtime; gettimeofday(&curtime, 0); curtime.tv_sec = curtime.tv_sec - (((int)curtime.tv_sec / 1000000) * 1000000); - if ((curtime.tv_sec * 1000 + (curtime.tv_usec / 1000) > m_lastupdate.tv_sec * 1000 + (m_lastupdate.tv_usec / 1000) + 500) && - (m_notupdatedLeft != -1) && (m_notupdatedTop != -1) && (m_notupdatedRight != -1) && - (m_notupdatedBottom != -1)) + if ((curtime.tv_sec * 1000 + (curtime.tv_usec / 1000) > m_lastupdate.tv_sec * 1000 + (m_lastupdate.tv_usec / 1000) + 500)) { memset(&m_lasttime, 0, sizeof(m_lasttime)); - SendScreen(720, m_notupdatedLeft, m_notupdatedTop, - m_notupdatedRight - m_notupdatedLeft, - m_notupdatedBottom - m_notupdatedTop, - &(m_Instance->m_OSDBuffer[m_notupdatedTop * 720 + m_notupdatedLeft])); + SendScreen(); } } // while(m_Active) diff --git a/osdworker.h b/osdworker.h index 10c0c3c..9491ff5 100644 --- a/osdworker.h +++ b/osdworker.h @@ -67,11 +67,11 @@ private: rfbPixelFormat ClientFormat; rfbPixelFormat ServerFormat; - BYTE m_OSDBuffer[720*576]; -// BYTE m_oldOSDData[720*576]; BYTE *m_pSendBuffer; int m_SendBufferSize; + cBitmap *m_pOsdBitmap; tColor OSDColors[256]; + bool m_bOSDisClear; void HandleClientRequests(cTBSelect *select); bool RFBRead(char *buffer, int len); @@ -81,10 +81,6 @@ private: struct timeval m_lasttime; struct timeval m_lastupdate; - int m_notupdatedLeft; - int m_notupdatedTop; - int m_notupdatedRight; - int m_notupdatedBottom; cPluginFFNetDev *m_pPlugin; @@ -103,11 +99,12 @@ public: static void CloseOSDClient(void); static bool ClearScreen(void); - static bool SendScreen(unsigned int stride, unsigned int x1, unsigned int y1, unsigned int w, unsigned int h, const void *data); + static bool DrawBitmap(int x1, int y1, cBitmap &pOsdBitmap); + static bool SendScreen(int x1=0, int y1=0, int x2=0, int y2=0); static bool SendCMAP(int NumColors, const tColor *Colors); static bool OSDWrite(unsigned char *data, unsigned int data_length); static bool SendPlayMode(ePlayMode PlayMode); - static void GetOSDColors(tColor **OSDColors, int *numOSDColors) { *OSDColors = &m_Instance->OSDColors[0]; (*numOSDColors) = m_Instance->numOSDColors; }; + static bool GetOSDColors(const tColor **OSDColors, int *numOSDColors); }; inline bool cOSDWorker::Active(void) { diff --git a/tableinitcmtemplate.c b/tableinitcmtemplate.c index b282326..e31b5b4 100644 --- a/tableinitcmtemplate.c +++ b/tableinitcmtemplate.c @@ -63,7 +63,7 @@ rfbInitColourMapSingleTableOUT (char **table, ReleaseDC(NULL, hDC); */ - tColor *pColors; + const tColor *pColors; int NumColors; cOSDWorker::GetOSDColors(&pColors, &NumColors); @@ -74,7 +74,7 @@ rfbInitColourMapSingleTableOUT (char **table, OUT_T outRed, outGreen, outBlue; OUT_T *t = (OUT_T *)*table; - tColor *pColor = pColors; + const tColor *pColor = pColors; for (i = 0; i < NumColors; i++) { // Split down the RGB data |