summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dxr3interface_spu_encoder.c213
-rw-r--r--dxr3interface_spu_encoder.h21
-rw-r--r--dxr3osd_subpicture.c92
-rw-r--r--dxr3osd_subpicture.h3
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