diff options
author | scop <scop> | 2005-04-17 21:39:38 +0000 |
---|---|---|
committer | scop <scop> | 2005-04-17 21:39:38 +0000 |
commit | 5c005097e6be8d7dec3df1b965be41c7d5692403 (patch) | |
tree | cb4bfed988de78b616d1bdd60832289de980c006 | |
parent | 125577765a9ae8f0bdf22fa2c817ffb9bf54d180 (diff) | |
download | vdr-plugin-dxr3-5c005097e6be8d7dec3df1b965be41c7d5692403.tar.gz vdr-plugin-dxr3-5c005097e6be8d7dec3df1b965be41c7d5692403.tar.bz2 |
More OSD work from Luca.
-rw-r--r-- | dxr3interface_spu_encoder.c | 213 | ||||
-rw-r--r-- | dxr3interface_spu_encoder.h | 21 | ||||
-rw-r--r-- | dxr3osd_subpicture.c | 92 | ||||
-rw-r--r-- | dxr3osd_subpicture.h | 3 |
4 files changed, 55 insertions, 274 deletions
diff --git a/dxr3interface_spu_encoder.c b/dxr3interface_spu_encoder.c index da8fdf2..771ca07 100644 --- a/dxr3interface_spu_encoder.c +++ b/dxr3interface_spu_encoder.c @@ -269,157 +269,6 @@ cSPUEncoder::cSPUEncoder() // set active area to 0 //m_x0 = m_x1 = m_y0 = m_y1 = 0; - // 16 Colors max. - m_palManager.SetBpp(4); -} - -// ================================== -// main function for the osd -// makes life nicer :) -int cSPUEncoder::Cmd(OSD_Command cmd, int color, int x0, int y0, int x1, int y1, const void *data) -{ - u_char *cp; - unsigned char idx = 0; - int opacity = 0; -#if VDRVERSNUM >= 10307 - const tColor *col; -#else - eDvbColor *col; -#endif - - switch (cmd) - { - case OSD_SetWindow: - // (x0) set window with number 0<x0<8 as current - if (x0 < 8 && x0 > 0) - { - m_lastwindow = x0; - return 0; - } - - return -1; - break; - - case OSD_Open: - // (x0,y0,x1,y1,BitPerPixel[2/4/8](color&0x0F),mix[0..15](color&0xF0)) - // Opens OSD with this size and bit depth - // returns 0 on success, -1 on DRAM allocation error, -2 on "already open" - m_windows[m_lastwindow].x0 = x0; - m_windows[m_lastwindow].y0 = y0; - m_windows[m_lastwindow].x1 = x1; - m_windows[m_lastwindow].y1 = y1; - - return 0; - break; - - case OSD_SetPalette: - { - // Spu->Cmd(OSD_SetPalette, 0, NumColors - 1, 0, 0, 0, Colors); - // (firstcolor{color},lastcolor{x0},data) - // Set a number of entries in the palette - // sets the entries "firstcolor" through "lastcolor" from the array "data" - // data has 4 byte for each color: - // R,G,B, and a opacity value: 0->transparent, 1..254->mix, 255->pixel - - #if VDRVERSNUM >= 10307 - col = (tColor*)data; - #else - eDvbColor *col; - col = (eDvbColor*)data; - #endif - - m_windows[m_lastwindow].NumColors = x0; - - for (int x = color, i = 0; x <= x0; x++,i++) - { - idx = m_palManager.Index(Tools::Rgb2YCrCb(*col & 0x00FFFFFF)); - opacity = ((*col & 0xFF000000) >> 24) * 0xF / 0xFF; - m_windows[m_lastwindow].colors[i] = (opacity << 4) | idx; - m_windows[m_lastwindow].opacity[i] = opacity; - col++; - } - - return 0; - break; - } - case OSD_SetBlock: - // (x0,y0,x1,y1,increment{color},data) - // fills pixels x0,y0 through x1,y1 with the content of data[] - // inc contains the width of one line in the data block, - // inc<=0 uses blockwidth as linewidth - // returns 0 on success, -1 on clipping all pixel - - CopyBlockIntoOSD - ( m_lastwindow, - color, - x0, - y0, - x1, - y1, - (tIndex *)data - ); - break; - - case OSD_Close: - // clear colors from palettemanager - m_palManager.Reset(); - - // clear osd - for (size_t i = m_windows[m_lastwindow].y0; i <= m_windows[m_lastwindow].y1; ++i) - { - cp = &OSD_Screen[i*OSDWIDTH + m_windows[m_lastwindow].x0]; - if ((cp+m_windows[m_lastwindow].x1-m_windows[m_lastwindow].x0+1) < &OSD_Screen[OSDWIDTH * OSDHEIGHT-1]) - { - for (size_t xx=0; xx <= (m_windows[m_lastwindow].x1-m_windows[m_lastwindow].x0); xx++) - { - *(cp+xx) = 0x00; - } - } - else - { - continue; - } - } - - - // set windows position to 0 - m_windows[m_lastwindow].x0 = 0; - m_windows[m_lastwindow].y0 = 0; - m_windows[m_lastwindow].x1 = 0; - m_windows[m_lastwindow].y1 = 0; - - return 0; - break; - - case OSD_Clear: - // Sets all pixels to color 0 - // returns 0 on success - - // This should be done in cSPUEncoder::cSPUEncoder - - return 0; - break; - - // not needed - at the moment - case OSD_Show: - case OSD_Hide: - case OSD_Fill: - case OSD_SetColor: - case OSD_SetTrans: - case OSD_SetPixel: - case OSD_GetPixel: - case OSD_SetRow: - case OSD_FillRow: - case OSD_FillBlock: - case OSD_Line: - case OSD_Query: - case OSD_Test: - case OSD_Text: - case OSD_MoveWindow: - break; - }; - - return -1; } @@ -434,13 +283,21 @@ void cSPUEncoder::SetPalette(int numWindow, cPalette* commonPalette, cPalette* w const tColor *Colors = windowPalette->Colors(NumColors); if (Colors) { for (int i=0; i<NumColors; i++) { - int idx=commonPalette->Index(Colors[i]); + int idx=commonPalette->Index(Colors[i] & 0x00FFFFFF); int opacity=((Colors[i] & 0xFF000000) >> 24) * 0xF / 0xFF; - m_windows[numWindow].colors[i]=(opacity<<4) | idx; + bitmapcolor[numWindow][i]=(opacity<<4) | idx; } } } +//======================================== +//Clears the OSD bitmap + +void cSPUEncoder::Clear(void) +{ + memset(OSD_Screen, 0 , sizeof(OSD_Screen)); +} + //============================================================= //Sets the spu palette and flushes the OSD content into the spu int cSPUEncoder::Flush(cPalette *Palette) @@ -486,44 +343,20 @@ int cSPUEncoder::Flush(cPalette *Palette) // stamps window content into full osd bitmap void cSPUEncoder::CopyBlockIntoOSD(int numWindow, int linewidth, int x0, int y0, int x1, int y1, const tIndex *data) { - int i; - int w; - tIndex *cp; - const tIndex *sp = data; - - - // linewidth contains the width of one line in the data block, - // linewidth<=0 uses blockwidth as linewidth - if (linewidth <= 0) - { - w = m_windows[numWindow].x1 - m_windows[numWindow].x0; - } - else - { - w = linewidth; - } - - x0+=m_windows[numWindow].x0; - x1+=m_windows[numWindow].x0; - y0+=m_windows[numWindow].y0; - y1+=m_windows[numWindow].y0; - - for (i = y0; i <= y1; ++i) - { - cp = &OSD_Screen[i*OSDWIDTH + x0]; - if ((cp+x1-x0+1) < &OSD_Screen[OSDWIDTH * OSDHEIGHT-1]) - { - for (int xx=0; xx <= (x1-x0); xx++) - { - *(cp+xx) = m_windows[numWindow].colors[*(sp+xx) & 0x0f]; - } - } - else - { - continue; + tIndex *cp; + const tIndex *sp = data; + + if (x1>=OSDWIDTH) x1=OSDWIDTH-1; + if (y1>=OSDHEIGHT) y1=OSDHEIGHT-1; + cp = &OSD_Screen[y0*OSDWIDTH+x0]; + + for (int y = y0; y <= y1; y++) { + for (int x=x0; x <= x1; x++) { + *(cp++) = bitmapcolor[numWindow][*(sp++) & 0x0f]; } - sp += w; - } + cp+=OSDWIDTH-(x1-x0+1); + sp+=linewidth-(x1-x0+1); + } } // ================================== diff --git a/dxr3interface_spu_encoder.h b/dxr3interface_spu_encoder.h index a2a6b79..d7161c1 100644 --- a/dxr3interface_spu_encoder.h +++ b/dxr3interface_spu_encoder.h @@ -45,21 +45,6 @@ #define OSDHEIGHT 576 // ================================== -// basic infos about one osd "window" -struct sOSD_Window -{ - size_t x0; - size_t y0; - size_t x1; - size_t y1; - - unsigned char colors[16]; - unsigned char opacity[16]; - - size_t NumColors; -}; - -// ================================== // used to get active osd area struct sRectal { @@ -117,11 +102,11 @@ public: cSPUEncoder(); ~cSPUEncoder() {} - int Cmd(OSD_Command cmd, int color = 0, int x0 = 0, int y0 = 0, int x1 = 0, int y1 = 0, const void *data = 0); int Flush(cPalette *Palette); void CopyBlockIntoOSD(int numWindow, int linewidth, int x0,int y0, int x1, int y1, const tIndex *data); void StopSpu(void); void SetPalette(int numWindow, cPalette* commonPalette, cPalette* windowPalette); + void Clear(void); private: cSPUEncoder(cSPUEncoder&); // no copy constructor @@ -139,11 +124,9 @@ private: void CalculateActiveOsdArea(); - sOSD_Window m_windows[8]; - cPalette m_palManager; // name for hysterical raisins ;) + int bitmapcolor[8][16]; cColorManager* m_ColorManager; encodedata m_encodeddata; - int m_lastwindow; // our osd :) u_char OSD_Screen[OSDWIDTH * OSDHEIGHT]; diff --git a/dxr3osd_subpicture.c b/dxr3osd_subpicture.c index 6765faa..1cdd72e 100644 --- a/dxr3osd_subpicture.c +++ b/dxr3osd_subpicture.c @@ -35,8 +35,7 @@ cDxr3SubpictureOsd::cDxr3SubpictureOsd(int Left, int Top) : cOsd(Left, Top) { shown = false; - oldPalette = new cPalette(4); - newPalette = new cPalette(4); + Palette = new cPalette(4); #if VDRVERSNUM >= 10318 last = new cTimeMs(); last->Set(-FLUSHRATE); @@ -44,32 +43,17 @@ cDxr3SubpictureOsd::cDxr3SubpictureOsd(int Left, int Top) : cOsd(Left, Top) last = time_ms() - FLUSHRATE; #endif Spu = &cSPUEncoder::Instance(); - - // must clear all windows here to avoid flashing effects - doesn't work if done - // in Flush() only for the windows that are actually used... - for (int i = 0; i < MAXNUMWINDOWS; i++) - { - Spu->Cmd(OSD_SetWindow, 0, i + 1); - Spu->Cmd(OSD_Clear); - } - + + //Clears the OSD screen image + Spu->Clear(); } // ================================== cDxr3SubpictureOsd::~cDxr3SubpictureOsd() { - if (shown) - { - cBitmap *Bitmap; - for (int i = 0; (Bitmap = GetBitmap(i)) != NULL; i++) - { - Spu->Cmd(OSD_SetWindow, 0, i + 1); - Spu->Cmd(OSD_Close); - } - } + //Remove the OSD from the screen Spu->StopSpu(); - delete oldPalette; - delete newPalette; + delete Palette; #if VDRVERSNUM >= 10318 delete last; #endif @@ -143,12 +127,17 @@ void cDxr3SubpictureOsd::Flush() int NumNewColors; int NumOldColors; - //first pass: determine the palette used by all bitmaps - newPalette->Reset(); + //determine the palette used by all bitmaps (without alpha channel) + + cPalette *newPalette=new cPalette(4); for (i=0; i<16; i++) colfree[i]=true; - for (i=0; (Bitmap = GetBitmap(i)) != NULL; i++) newPalette->Take(*Bitmap); + for (i=0; (Bitmap = GetBitmap(i)) != NULL; i++) { + int nc; + const tColor *col=Bitmap->Colors(nc); + if (col) for (int kk=0; kk<nc; kk++) newPalette->Index(col[kk] & 0x00FFFFFF); + } const tColor *newColors=newPalette->Colors(NumNewColors); - const tColor *oldColors=oldPalette->Colors(NumOldColors); + const tColor *oldColors=Palette->Colors(NumOldColors); //colors already assigned for (newi=0;newi<NumNewColors;newi++) { for(oldi=0;oldi<NumOldColors;oldi++) { @@ -173,30 +162,27 @@ void cDxr3SubpictureOsd::Flush() for (i=0; i<=firstnoassigned; i++) { newi=indexnoassigned[i]; if (firstfree>=0) { - oldPalette->SetColor(indexfree[firstfree], newColors[newi]); + Palette->SetColor(indexfree[firstfree], newColors[newi]); firstfree--; } else { - oldPalette->Index(newColors[newi]); + Palette->Index(newColors[newi]); } } + delete newPalette; - //second pass: shove the bitmaps + //Shove the bitmaps to the OSD global bitmap for (int i = 0; (Bitmap = GetBitmap(i)) != NULL; i++) { - Spu->Cmd(OSD_SetWindow, 0, i + 1); - - if (!shown) - { - Spu->Cmd(OSD_Open, Bitmap->Bpp(), Left() + Bitmap->X0(), Top() + Bitmap->Y0(), Left() + Bitmap->X0() + Bitmap->Width() - 1, Top() + Bitmap->Y0() + Bitmap->Height() - 1, (void *)1); // initially hidden! - } - int x1 = 0, y1 = 0, x2 = 0, y2 = 0; if (Bitmap->Dirty(x1, y1, x2, y2)) { //TODO Workaround: apparently the bitmap sent to the driver always has to be a multiple //TODO of 8 bits wide, and (dx * dy) also has to be a multiple of 8. //TODO Fix driver (should be able to handle any size bitmaps!) - /* + // + // This isn't actually necessary with this plugin, but since other plugins rely + // on this behaviour to work correctly, I left it here. It doesn't hurt too much. + while ((x1 > 0 || x2 < Bitmap->Width() - 1) && ((x2 - x1) & 7) != 7) { if (x2 < Bitmap->Width() - 1) @@ -233,36 +219,16 @@ void cDxr3SubpictureOsd::Flush() x1--; } } - */ - // commit colors: - /* - int NumColors; - const tColor *Colors = Bitmap->Colors(NumColors); - if (Colors) - { - - // TODO this should be fixed in the driver! - tColor colors[NumColors]; - for (int i = 0; i < NumColors; i++) - { - // convert AARRGGBB to AABBGGRR (the driver expects the colors the wrong way): - colors[i] = (Colors[i] & 0xFF000000) | ((Colors[i] & 0x0000FF) << 16) | (Colors[i] & 0x00FF00) | ((Colors[i] & 0xFF0000) >> 16); - } - - Colors = colors; - //TODO end of stuff that should be fixed in the driver - Spu->Cmd(OSD_SetPalette, 0, NumColors - 1, 0, 0, 0, Colors); - } - */ - // commit modified data: - Spu->SetPalette(i+1,oldPalette,Bitmap); - Spu->CopyBlockIntoOSD(i+1, Bitmap->Width(), x1, y1, x2, y2, Bitmap->Data(x1, y1)); + Spu->SetPalette(i+1,Palette,Bitmap); + int origx=Left()+Bitmap->X0(); + int origy=Top()+Bitmap->Y0(); + Spu->CopyBlockIntoOSD(i+1, Bitmap->Width(), origx+x1, origy+y1, origx+x2, origy+y2, Bitmap->Data(x1, y1)); + Bitmap->Clean(); } - Bitmap->Clean(); } - Spu->Flush(oldPalette); + Spu->Flush(Palette); shown = true; #ifdef timingdebug t.Stop("cDxr3SubpictureOsd::Flush"); diff --git a/dxr3osd_subpicture.h b/dxr3osd_subpicture.h index 96ad1f7..cf5bc1d 100644 --- a/dxr3osd_subpicture.h +++ b/dxr3osd_subpicture.h @@ -13,8 +13,7 @@ class cDxr3SubpictureOsd : public cOsd private: cSPUEncoder* Spu; ///< interface to cSPUEncoder bool shown; ///< is the osd shown? - cPalette* oldPalette; ///< palette used in previous flush (do detect changes) - cPalette* newPalette; ///< palette needed now + cPalette* Palette; ///< global palette (needed by all bitmaps) #if VDRVERSNUM >= 10318 cTimeMs *last; #else |