summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorscop <scop>2005-04-17 16:41:17 +0000
committerscop <scop>2005-04-17 16:41:17 +0000
commit74d8232de848f462ad36a8c0f51c26ad400ee8ec (patch)
treefac415de30c23adc3f4522bc7b98051ab76c7ced
parent9216c55e163f619a33770119339ae0651cd1e417 (diff)
downloadvdr-plugin-dxr3-74d8232de848f462ad36a8c0f51c26ad400ee8ec.tar.gz
vdr-plugin-dxr3-74d8232de848f462ad36a8c0f51c26ad400ee8ec.tar.bz2
Sync with Luca's workspace.
-rw-r--r--dxr3colormanager.c36
-rw-r--r--dxr3colormanager.h2
-rw-r--r--dxr3interface_spu_encoder.c66
-rw-r--r--dxr3interface_spu_encoder.h5
-rw-r--r--dxr3osd_subpicture.c97
-rw-r--r--dxr3osd_subpicture.h2
6 files changed, 149 insertions, 59 deletions
diff --git a/dxr3colormanager.c b/dxr3colormanager.c
index d2aa7ff..0bddb60 100644
--- a/dxr3colormanager.c
+++ b/dxr3colormanager.c
@@ -56,33 +56,6 @@
#include <stdio.h>
#include <string.h>
-//#define timingdebug
-// Enables some time measure debugging code
-// (taken from the osdteletext plugin, thanks folks)
-#ifdef timingdebug
- #include <sys/timeb.h>
-
- class cTime {
- // Debugging: Simple class to measure time
- timeb start;
- public:
- void Start() {
- ftime(&start);
- }
- void Stop(char *txt) {
- timeb t;
- ftime(&t);
- int s=t.time-start.time;
- int ms=t.millitm-start.millitm;
- if (ms<0) {
- s--;
- ms+=1000;
- }
- printf("%s: %i.%03i\n",txt,s,ms);
- }
- };
-#endif
-
// ==================================
//! constructor
cColorManager::cColorManager()
@@ -132,11 +105,6 @@ void cColorManager::EncodeColors(int width, int height, unsigned char* map, unsi
unsigned char ColorIndex;
int mapoffset=0;
- #ifdef timingdebug
- cTime t;
- t.Start();
- #endif
-
OpenRegion(0);
for (int y = 0; y < height; ++y) {
oldcolor=0xFF;
@@ -173,10 +141,6 @@ void cColorManager::EncodeColors(int width, int height, unsigned char* map, unsi
//close the last highligt region
CloseRegion(height);
- #ifdef timingdebug
- t.Stop("EncodeColors");
- #endif
-
//#define colordebug
#ifdef colordebug
{
diff --git a/dxr3colormanager.h b/dxr3colormanager.h
index 6048105..0091688 100644
--- a/dxr3colormanager.h
+++ b/dxr3colormanager.h
@@ -48,7 +48,7 @@ private:
#define OSD_SPU_CM_DUMP 0
#define MAX_NO_OF_SECTIONS 15
-#define MAX_NO_OF_REGIONS 60
+#define MAX_NO_OF_REGIONS 100
// ==================================
diff --git a/dxr3interface_spu_encoder.c b/dxr3interface_spu_encoder.c
index a9a0907..da8fdf2 100644
--- a/dxr3interface_spu_encoder.c
+++ b/dxr3interface_spu_encoder.c
@@ -338,8 +338,6 @@ int cSPUEncoder::Cmd(OSD_Command cmd, int color, int x0, int y0, int x1, int y1,
m_windows[m_lastwindow].opacity[i] = opacity;
col++;
}
- int colors = 0;
- cDxr3Interface::Instance().SetPalette((unsigned int*)m_palManager.Colors(colors));
return 0;
break;
@@ -352,13 +350,13 @@ int cSPUEncoder::Cmd(OSD_Command cmd, int color, int x0, int y0, int x1, int y1,
// returns 0 on success, -1 on clipping all pixel
CopyBlockIntoOSD
- (
+ ( m_lastwindow,
color,
- m_windows[m_lastwindow].x0 + x0,
- m_windows[m_lastwindow].y0 + y0,
- m_windows[m_lastwindow].x0 + x1,
- m_windows[m_lastwindow].y0 + y1,
- (u_char *)data
+ x0,
+ y0,
+ x1,
+ y1,
+ (tIndex *)data
);
break;
@@ -425,10 +423,41 @@ int cSPUEncoder::Cmd(OSD_Command cmd, int color, int x0, int y0, int x1, int y1,
}
-//===================================
-//Flushes the OSD content into the spu
-int cSPUEncoder::Flush(void)
+//========================================
+//Sets the palette indexes to use for one
+//window taking into account the global
+//palette (with colors needed by all windows)
+
+void cSPUEncoder::SetPalette(int numWindow, cPalette* commonPalette, cPalette* windowPalette)
+{
+ int NumColors;
+ const tColor *Colors = windowPalette->Colors(NumColors);
+ if (Colors) {
+ for (int i=0; i<NumColors; i++) {
+ int idx=commonPalette->Index(Colors[i]);
+ int opacity=((Colors[i] & 0xFF000000) >> 24) * 0xF / 0xFF;
+ m_windows[numWindow].colors[i]=(opacity<<4) | idx;
+ }
+ }
+}
+
+//=============================================================
+//Sets the spu palette and flushes the OSD content into the spu
+int cSPUEncoder::Flush(cPalette *Palette)
{
+
+ int NumColors;
+ const tColor *Colors = Palette->Colors(NumColors);
+ if (Colors) {
+ unsigned int palcolors[16];
+ for (int i=0; i<NumColors; i++) {
+ // convert AARRGGBB to AABBGGRR (the driver expected the the colors the wrong way, so does Rgb2YCrCb and friends)
+ unsigned int color = ((Colors[i] & 0x0000FF) << 16) | (Colors[i] & 0x00FF00) | ((Colors[i] & 0xFF0000) >> 16);
+ palcolors[i]=Tools::Rgb2YCrCb(color);
+ }
+ cDxr3Interface::Instance().SetPalette(palcolors);
+ }
+
// calculate osd size (actually dead code)
CalculateActiveOsdArea();
@@ -455,25 +484,30 @@ int cSPUEncoder::Flush(void)
// ==================================
// stamps window content into full osd bitmap
-void cSPUEncoder::CopyBlockIntoOSD(int linewidth, int x0, int y0, int x1, int y1, u_char *data)
+void cSPUEncoder::CopyBlockIntoOSD(int numWindow, int linewidth, int x0, int y0, int x1, int y1, const tIndex *data)
{
int i;
int w;
- u_char *cp;
- u_char *sp = data;
+ 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[m_lastwindow].x1 - m_windows[m_lastwindow].x0;
+ 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];
@@ -481,7 +515,7 @@ void cSPUEncoder::CopyBlockIntoOSD(int linewidth, int x0, int y0, int x1, int y1
{
for (int xx=0; xx <= (x1-x0); xx++)
{
- *(cp+xx) = m_windows[m_lastwindow].colors[*(sp+xx) & 0x0f];
+ *(cp+xx) = m_windows[numWindow].colors[*(sp+xx) & 0x0f];
}
}
else
diff --git a/dxr3interface_spu_encoder.h b/dxr3interface_spu_encoder.h
index 300dbe6..a2a6b79 100644
--- a/dxr3interface_spu_encoder.h
+++ b/dxr3interface_spu_encoder.h
@@ -118,14 +118,15 @@ public:
~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(void);
+ 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);
private:
cSPUEncoder(cSPUEncoder&); // no copy constructor
// helper functions
- void CopyBlockIntoOSD(int linewidth, int x0,int y0, int x1, int y1, u_char *data);
void EncodePixelbufRle(int x, int y, int w, int h, u_char *inbuf, int stride, encodedata *ed);
#ifndef USE_XINE_SCALER
void ScaleOSD(double fac, unsigned char* buf, unsigned char NumColors=4);
diff --git a/dxr3osd_subpicture.c b/dxr3osd_subpicture.c
index ddd0e28..6765faa 100644
--- a/dxr3osd_subpicture.c
+++ b/dxr3osd_subpicture.c
@@ -1,5 +1,31 @@
#include "dxr3osd_subpicture.h"
+// Enables some time measure debugging code
+// (taken from the osdteletext plugin, thanks folks)
+#ifdef timingdebug
+ #include <sys/timeb.h>
+
+ class cTime {
+ // Debugging: Simple class to measure time
+ timeb start;
+ public:
+ void Start() {
+ ftime(&start);
+ }
+ void Stop(char *txt) {
+ timeb t;
+ ftime(&t);
+ int s=t.time-start.time;
+ int ms=t.millitm-start.millitm;
+ if (ms<0) {
+ s--;
+ ms+=1000;
+ }
+ printf("%s: %i.%03i\n",txt,s,ms);
+ }
+ };
+#endif
+
#if VDRVERSNUM >= 10307
#define MAXNUMWINDOWS 7 // OSD windows are counted 1...7
@@ -9,6 +35,8 @@
cDxr3SubpictureOsd::cDxr3SubpictureOsd(int Left, int Top) : cOsd(Left, Top)
{
shown = false;
+ oldPalette = new cPalette(4);
+ newPalette = new cPalette(4);
#if VDRVERSNUM >= 10318
last = new cTimeMs();
last->Set(-FLUSHRATE);
@@ -40,6 +68,8 @@ cDxr3SubpictureOsd::~cDxr3SubpictureOsd()
}
}
Spu->StopSpu();
+ delete oldPalette;
+ delete newPalette;
#if VDRVERSNUM >= 10318
delete last;
#endif
@@ -96,8 +126,61 @@ void cDxr3SubpictureOsd::Flush()
last = time_ms();
#endif
+ #ifdef timingdebug
+ cTime t;
+ t.Start();
+ #endif
+
cBitmap *Bitmap;
+ int oldi;
+ int newi;
+ int i;
+ int indexfree[16];
+ int firstfree=-1;
+ int indexnoassigned[16];
+ int firstnoassigned=-1;
+ bool colfree[16];
+ int NumNewColors;
+ int NumOldColors;
+ //first pass: determine the palette used by all bitmaps
+ newPalette->Reset();
+ for (i=0; i<16; i++) colfree[i]=true;
+ for (i=0; (Bitmap = GetBitmap(i)) != NULL; i++) newPalette->Take(*Bitmap);
+ const tColor *newColors=newPalette->Colors(NumNewColors);
+ const tColor *oldColors=oldPalette->Colors(NumOldColors);
+ //colors already assigned
+ for (newi=0;newi<NumNewColors;newi++) {
+ for(oldi=0;oldi<NumOldColors;oldi++) {
+ if (newColors[newi]==oldColors[oldi]) {
+ colfree[oldi]=false;
+ break;
+ }
+ }
+ if (oldi>=NumOldColors) {
+ firstnoassigned++;
+ indexnoassigned[firstnoassigned]=newi;
+ }
+ }
+ //unused colors
+ for (i=0; i<NumOldColors; i++) {
+ if(colfree[i]) {
+ firstfree++;
+ indexfree[firstfree]=i;
+ }
+ }
+ //replace unused colors with unassigned ones
+ for (i=0; i<=firstnoassigned; i++) {
+ newi=indexnoassigned[i];
+ if (firstfree>=0) {
+ oldPalette->SetColor(indexfree[firstfree], newColors[newi]);
+ firstfree--;
+ } else {
+ oldPalette->Index(newColors[newi]);
+ }
+ }
+
+ //second pass: shove the bitmaps
for (int i = 0; (Bitmap = GetBitmap(i)) != NULL; i++)
{
Spu->Cmd(OSD_SetWindow, 0, i + 1);
@@ -113,7 +196,7 @@ void cDxr3SubpictureOsd::Flush()
//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!)
-
+ /*
while ((x1 > 0 || x2 < Bitmap->Width() - 1) && ((x2 - x1) & 7) != 7)
{
if (x2 < Bitmap->Width() - 1)
@@ -150,8 +233,9 @@ void cDxr3SubpictureOsd::Flush()
x1--;
}
}
-
+ */
// commit colors:
+ /*
int NumColors;
const tColor *Colors = Bitmap->Colors(NumColors);
@@ -170,14 +254,19 @@ void cDxr3SubpictureOsd::Flush()
//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->Cmd(OSD_SetBlock, Bitmap->Width(), x1, y1, x2, y2, Bitmap->Data(x1, y1));
+ Spu->SetPalette(i+1,oldPalette,Bitmap);
+ Spu->CopyBlockIntoOSD(i+1, Bitmap->Width(), x1, y1, x2, y2, Bitmap->Data(x1, y1));
}
Bitmap->Clean();
}
- Spu->Flush();
+ Spu->Flush(oldPalette);
shown = true;
+ #ifdef timingdebug
+ t.Stop("cDxr3SubpictureOsd::Flush");
+ #endif
}
#endif /*VDRVERSNUM*/
diff --git a/dxr3osd_subpicture.h b/dxr3osd_subpicture.h
index 0708da7..cd24122 100644
--- a/dxr3osd_subpicture.h
+++ b/dxr3osd_subpicture.h
@@ -21,6 +21,8 @@ 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
#if VDRVERSNUM >= 10318
cTimeMs *last;
#else