summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Gmeiner <christian.gmeiner@gmail.com>2009-01-07 14:21:00 +0100
committerChristian Gmeiner <christian.gmeiner@gmail.com>2009-01-07 14:21:00 +0100
commit31cee7f11b870c98f2707440212321cb2e9d0fe1 (patch)
tree6b6bd05dfe74b25fad2bc027d55009b918f526f4
parent48c753433b7e2aab49ba3924ff07e15d04980026 (diff)
downloadvdr-plugin-dxr3-31cee7f11b870c98f2707440212321cb2e9d0fe1.tar.gz
vdr-plugin-dxr3-31cee7f11b870c98f2707440212321cb2e9d0fe1.tar.bz2
upps... missing changes
-rw-r--r--Makefile2
-rw-r--r--dxr3configdata.c1
-rw-r--r--dxr3configdata.h17
-rw-r--r--dxr3osd.c278
-rw-r--r--dxr3osd.h21
5 files changed, 297 insertions, 22 deletions
diff --git a/Makefile b/Makefile
index 3bfd4be..0efa259 100644
--- a/Makefile
+++ b/Makefile
@@ -61,7 +61,7 @@ OBJS = $(PLUGIN).o dxr3multichannelaudio.o dxr3sysclock.o dxr3colormanager.o \
dxr3syncbuffer.o dxr3audiodecoder.o dxr3blackframe.o dxr3nextpts.o \
dxr3pesframe.o dxr3demuxdevice.o dxr3configdata.o dxr3ffmpeg.o \
dxr3interface_spu_encoder.o dxr3interface.o dxr3device.o \
- dxr3outputthread.o dxr3osd.o dxr3osd_subpicture.o dxr3spudecoder.o
+ dxr3outputthread.o dxr3osd.o dxr3spudecoder.o
### Default target:
diff --git a/dxr3configdata.c b/dxr3configdata.c
index 0ae0929..f3b682d 100644
--- a/dxr3configdata.c
+++ b/dxr3configdata.c
@@ -30,7 +30,6 @@ cDxr3ConfigData::cDxr3ConfigData()
m_card = 0;
m_forceletterbox = 0;
m_videomode = PAL;
- m_menumode = SUBPICTURE;
m_brightness = 500;
m_contrast = 500;
m_saturation = 500;
diff --git a/dxr3configdata.h b/dxr3configdata.h
index 778de89..0fe6b8e 100644
--- a/dxr3configdata.h
+++ b/dxr3configdata.h
@@ -35,14 +35,6 @@ enum eVideoMode
};
// ==================================
-// possible menu modes
-enum eMenuMode
-{
- SUBPICTURE = 0,
- MPEG
-};
-
-// ==================================
//! global interface to access all config datas of this plugin
/*
With this singleton you can access very easy all possible
@@ -87,14 +79,6 @@ public:
{
return m_videomode = videoMode;
}
- eMenuMode GetMenuMode() const
- {
- return m_menumode;
- }
- eMenuMode SetMenuMode(eMenuMode menuMode)
- {
- return m_menumode = menuMode;
- }
int GetBrightness() const
{
@@ -151,7 +135,6 @@ public:
protected:
eVideoMode m_videomode;
int m_usewss;
- eMenuMode m_menumode;
int m_digitaloutput;
int m_card;
int m_forceletterbox;
diff --git a/dxr3osd.c b/dxr3osd.c
index 9af522e..70503d7 100644
--- a/dxr3osd.c
+++ b/dxr3osd.c
@@ -31,15 +31,287 @@
#include "dxr3osd.h"
#include "dxr3interface_spu_encoder.h"
-#include "dxr3osd_subpicture.h"
-
// ==================================
// ! create osd at (Left, Top, Level)
cOsd *cDxr3OsdProvider::CreateOsd(int Left, int Top, uint Level)
{
- return new cDxr3SubpictureOsd(Left, Top, Level);
+ return new cDxr3Osd(Left, Top, Level);
}
+// 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
+
+#define MAXNUMWINDOWS 7 // OSD windows are counted 1...7
+
+// ==================================
+//! constructor
+cDxr3Osd::cDxr3Osd(int Left, int Top, uint Level)
+ : cOsd(Left, Top, Level)
+{
+ shown = false;
+ Palette = new cPalette(4);
+ last = new cTimeMs();
+ last->Set(-cDxr3ConfigData::Instance().GetOsdFlushRate());
+ Spu = &cSPUEncoder::Instance();
+}
+
+// ==================================
+cDxr3Osd::~cDxr3Osd()
+{
+ SetActive(false);
+ delete Palette;
+ delete last;
+}
+
+// ==================================
+void cDxr3Osd::SetActive(bool On)
+{
+ if (On != Active())
+ {
+ // Clears the OSD screen image when it becomes active
+ // removes it from screen when it becomes inactive
+ cOsd::SetActive(On);
+ if (On)
+ {
+ Spu->Clear();
+ }
+ else
+ {
+ Spu->StopSpu();
+ }
+ }
+}
+
+// ==================================
+eOsdError cDxr3Osd::CanHandleAreas(const tArea *Areas, int NumAreas)
+{
+
+ eOsdError Result = cOsd::CanHandleAreas(Areas, NumAreas);
+ if (Result == oeOk)
+ {
+ if (NumAreas > MAXNUMWINDOWS)
+ {
+ return oeTooManyAreas;
+ }
+
+ for (int i = 0; i < NumAreas; i++)
+ {
+ if (Areas[i].bpp != 1 &&
+ Areas[i].bpp != 2 &&
+ Areas[i].bpp != 4 &&
+ Areas[i].bpp != 8)
+ {
+ return oeBppNotSupported;
+ }
+
+ if ((Areas[i].Width() & (8 / Areas[i].bpp - 1)) != 0)
+ {
+ return oeWrongAlignment;
+ }
+ }
+ }
+ return Result;
+}
+
+eOsdError cDxr3Osd::SetAreas(const tArea *Areas, int NumAreas)
+{
+ if (shown)
+ {
+ Spu->Clear();
+ shown = false;
+ }
+ return cOsd::SetAreas(Areas, NumAreas);
+}
+
+// ==================================
+void cDxr3Osd::Flush()
+{
+ if (!Active())
+ return;
+ if (last->Elapsed() < cDxr3ConfigData::Instance().GetOsdFlushRate())
+ return;
+ last->Set();
+
+#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;
+
+ //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++)
+ {
+ 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 = Palette->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)
+ {
+ Palette->SetColor(indexfree[firstfree], newColors[newi]);
+ firstfree--;
+ } else {
+ Palette->Index(newColors[newi]);
+ }
+ }
+ delete newPalette;
+
+ // Shove the bitmaps to the OSD global bitmap
+ for (int i = 0; (Bitmap = GetBitmap(i)) != NULL; i++)
+ {
+ 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 of 8 bits wide, and (dx * dy) also has to be a
+ multiple of 8. 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.
+ */
+
+// http://article.gmane.org/gmane.linux.vdr/21572
+//#define optimize_bitmap_transfer
+#ifdef optimize_bitmap_transfer
+ while ((x1 > 0 || x2 < Bitmap->Width() - 1) &&
+ ((x2 - x1) & 7) != 7)
+ {
+ if (x2 < Bitmap->Width() - 1)
+ {
+ x2++;
+ }
+ else if (x1 > 0)
+ {
+ x1--;
+ }
+ }
+
+ //TODO "... / 2" <==> Bpp???
+ while ((y1 > 0 || y2 < Bitmap->Height() - 1) &&
+ (((x2 - x1 + 1) * (y2 - y1 + 1) / 2) & 7) != 0)
+ {
+ if (y2 < Bitmap->Height() - 1)
+ {
+ y2++;
+ }
+ else if (y1 > 0)
+ {
+ y1--;
+ }
+ }
+
+ while ((x1 > 0 || x2 < Bitmap->Width() - 1) &&
+ (((x2 - x1 + 1) * (y2 - y1 + 1) / 2) & 7) != 0)
+ {
+ if (x2 < Bitmap->Width() - 1)
+ {
+ x2++;
+ }
+ else if (x1 > 0)
+ {
+ x1--;
+ }
+ }
+#else
+ x1 = 0;
+ y1 = 0;
+ x2 = Bitmap->Width() - 1;
+ y2 = Bitmap->Height() - 1;
+#endif
+
+ 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();
+ }
+ }
+
+ Spu->Flush(Palette);
+ shown = true;
+#ifdef timingdebug
+ t.Stop("cDxr3SubpictureOsd::Flush");
+#endif
+}
+
+
// Local variables:
// mode: c++
// c-file-style: "stroustrup"
diff --git a/dxr3osd.h b/dxr3osd.h
index 588e90f..8514252 100644
--- a/dxr3osd.h
+++ b/dxr3osd.h
@@ -13,6 +13,27 @@ public:
virtual cOsd *CreateOsd(int Left, int Top, uint Level);
};
+// ==================================
+// osd interface
+class cDxr3Osd : public cOsd
+{
+private:
+ cSPUEncoder* Spu; ///< interface to cSPUEncoder
+ bool shown; ///< is the osd shown?
+ cPalette* Palette; ///< global palette (needed by all bitmaps)
+ cTimeMs *last;
+protected:
+ virtual void SetActive(bool On);
+public:
+ cDxr3Osd(int Left, int Top, uint Level);
+ ~cDxr3Osd();
+
+ eOsdError CanHandleAreas(const tArea *Areas, int NumAreas);
+ eOsdError SetAreas(const tArea *Areas, int NumAreas);
+
+ void Flush();
+};
+
#endif /*_DXR3_OSD_H_*/
// Local variables: