VDR+DXR3 - stability problems (possible patch)

Message ID 1116268516.2084.58.camel@bobcat.mine.nu
State New
Headers

Commit Message

Ville Skyttä May 16, 2005, 6:35 p.m. UTC
  On Mon, 2005-05-16 at 10:35 +0200, Martin Cap wrote:
> Seppo Ingalsuo wrote:

> > However the problem where OSD graphics start to jump and flicker for a 
> > while and VDR gets stuck for quite long time is still present. It 
> > happens repeatably also in mp3 plugin or muggle plugin usage where 
> > playback of a song gets interrupted every now and then for a couple of 
> > seconds which is pretty annoying. Mp3 plugin worked better due to more 
> > stable OSD with the earlier dxr3 plugin version I mentioned. Have other 
> > dxr3 users seen this?
>
> Sure. But concerning the OSD going beserk, you can try playing around 
> with the value
> DEFINES+=-DFLUSHRATE=40 in the Makefile. I might help a little. But this is
> still an open issue.

Yep.  Try -DFLUSHRATE=50, with that I don't remember ever seeing the
flicker effect, but on the other hand 50ms is also just about where the
delay starts to be somewhat annoying for example when quickly switching
between entries in the OSD menus.

Something in addition to that; attached is a patch that backports the
DXR3 hardware SPU decoder functionality from CVS HEAD to the vdr-
dxr3-0-2 branch.  It improves things somewhat here (in particular it
fixes colors of DVD subtitles), but also triggers another "feature".

The palette seems to be changed slightly too early at times, for example
when repeatedly opening/closing the channel info OSD, the info turns
momentarily all green here before disappearing (or white if there are
DVB subtitles in the current channel showing immediately after the
channel info closes).

If someone tries this out, let me know how it works for you.
  

Patch

Index: dxr3device.c
===================================================================
RCS file: /cvsroot/dxr3plugin/dxr3/dxr3device.c,v
retrieving revision 1.2.2.18
diff -u -r1.2.2.18 dxr3device.c
--- dxr3device.c	19 Apr 2005 18:19:37 -0000	1.2.2.18
+++ dxr3device.c	16 May 2005 17:52:24 -0000
@@ -508,7 +508,7 @@ 
 
 // ==================================
 // get spudecoder
-cSpuDecoder *cDxr3Device::GetSpuDecoder(void)
+cDxr3SpuDecoder *cDxr3Device::GetSpuDecoder(void)
 {
     if (!m_spuDecoder && IsPrimaryDevice())
     {
Index: dxr3device.h
===================================================================
RCS file: /cvsroot/dxr3plugin/dxr3/dxr3device.h,v
retrieving revision 1.1.2.10
diff -u -r1.1.2.10 dxr3device.h
--- dxr3device.h	19 Apr 2005 18:19:34 -0000	1.1.2.10
+++ dxr3device.h	16 May 2005 17:52:24 -0000
@@ -70,7 +70,7 @@ 
     virtual void SetVolumeDevice(int Volume);
 
     // osd
-    virtual cSpuDecoder *GetSpuDecoder();
+    virtual cDxr3SpuDecoder *GetSpuDecoder();
 #if VDRVERSNUM < 10307
     virtual cOsdBase* NewOsd(int x, int y);
 #endif
Index: dxr3osd_subpicture.c
===================================================================
RCS file: /cvsroot/dxr3plugin/dxr3/dxr3osd_subpicture.c,v
retrieving revision 1.1.2.11
diff -u -r1.1.2.11 dxr3osd_subpicture.c
--- dxr3osd_subpicture.c	21 Apr 2005 21:40:06 -0000	1.1.2.11
+++ dxr3osd_subpicture.c	16 May 2005 17:52:24 -0000
@@ -1,4 +1,5 @@ 
 #include "dxr3osd_subpicture.h"
+#include "dxr3device.h"
 
 // Enables some time measure debugging code
 // (taken from the osdteletext plugin, thanks folks)
@@ -45,6 +46,8 @@ 
 #else
     last = time_ms() - FLUSHRATE;
 #endif
+    if(cDxr3Device::InstanceP())
+	cDxr3Device::InstanceP()->GetSpuDecoder()->Disable();
     Spu = &cSPUEncoder::Instance();
 
     //Clears the OSD screen image
@@ -60,6 +63,8 @@ 
 #if VDRVERSNUM >= 10318
     delete last;
 #endif
+    if(cDxr3Device::InstanceP())
+	cDxr3Device::InstanceP()->GetSpuDecoder()->Enable();
 }
 
 // ==================================
Index: dxr3spudecoder.c
===================================================================
RCS file: /cvsroot/dxr3plugin/dxr3/dxr3spudecoder.c,v
retrieving revision 1.1.2.10
diff -u -r1.1.2.10 dxr3spudecoder.c
--- dxr3spudecoder.c	24 Apr 2005 16:09:08 -0000	1.1.2.10
+++ dxr3spudecoder.c	16 May 2005 17:52:24 -0000
@@ -3,9 +3,6 @@ 
  *
  * Copyright (C) 2004 Christian Gmeiner
  *
- * Orginal:
- *    Copyright (C) 2001.2002 Andreas Schultz <aschultz@warp10.net>
- *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
  * as published by the Free Software Foundation; either version 2.1
@@ -22,261 +19,16 @@ 
  *
  */
 
-#include <assert.h>
-#include <string.h>
-#include <inttypes.h>
-#include <math.h>
-
 #include "dxr3spudecoder.h"
-#include "dxr3interface.h"
-#include "dxr3tools.h"
-#include "dxr3log.h"
-
-// ==================================
-#define CMD_SPU_MENU            0x00
-#define CMD_SPU_SHOW            0x01
-#define CMD_SPU_HIDE            0x02
-#define CMD_SPU_SET_PALETTE     0x03
-#define CMD_SPU_SET_ALPHA       0x04
-#define CMD_SPU_SET_SIZE        0x05
-#define CMD_SPU_SET_PXD_OFFSET  0x06
-#define CMD_SPU_CHG_COLCON      0x07
-#define CMD_SPU_EOF             0xff
-
-#define spuU32(i) ((spu[i] << 8) + spu[i+1])
-
-
-/*
- * cDxr3Spubitmap:
- *
- * this is a bitmap of the full screen and two palettes
- * the normal palette for the background and the highlight palette
- *
- * Inputs:
- *  - a SPU rle encoded image on creation, which will be decoded into
- *    the full screen indexed bitmap
- *
- * Output:
- *  - a minimal sized cDxr3SpuBitmap a given palette, the indexed bitmap
- *    will be scanned to get the smallest possible resulting bitmap considering
- *    transparencies
- */
-
-// ==================================
-void cDxr3SpuPalette::setPalette(const uint32_t * pal)
-{
-    for (int i = 0; i < 16; i++)
-	palette[i] = Tools::YUV2Rgb(pal[i]);
-}
-
-// ==================================
-#define setMin(a, b) if (a > b) a = b
-#define setMax(a, b) if (a < b) a = b
-
-#define spuXres 720
-#define spuYres 576
-
-#define revRect(r1, r2) { r1.x1 = r2.x2; r1.y1 = r2.y2; r1.x2 = r2.x1; r1.y2 = r2.y1; }
-
-// ==================================
-cDxr3SpuBitmap::cDxr3SpuBitmap(sDxr3SpuRect size, uint8_t * fodd,
-			       uint8_t * eodd, uint8_t * feven,
-			       uint8_t * eeven)
-{
-    if (size.x1 < 0 || size.y1 < 0 || size.x2 >= spuXres || size.y2 >= spuYres)
-	throw;
-
-    bmpsize = size;
-    revRect(minsize[0], size);
-    revRect(minsize[1], size);
-    revRect(minsize[2], size);
-    revRect(minsize[3], size);
-
-    if (!(bmp = new uint8_t[spuXres * spuYres * sizeof(uint8_t)]))
-	throw;
-
-    memset(bmp, 0, spuXres * spuYres * sizeof(uint8_t));
-    putFieldData(0, fodd, eodd);
-    putFieldData(1, feven, eeven);
-}
-
-// ==================================
-cDxr3SpuBitmap::~cDxr3SpuBitmap()
-{
-    delete[]bmp;
-}
-
-// ==================================
-cBitmap *cDxr3SpuBitmap::getBitmap(const aDxr3SpuPalDescr paldescr,
-				   const cDxr3SpuPalette & pal,
-				   sDxr3SpuRect & size) const
-{
-    int h = size.height();
-    int w = size.width();
-
-    if (size.y1 + h >= spuYres)
-    {
-	h = spuYres - size.y1 - 1;
-    }
-    if (size.x1 + w >= spuXres)
-    {
-	w = spuXres - size.x1 - 1;
-    }
-
-    if (w & 0x03)
-    {
-	w += 4 - (w & 0x03);
-    }
-
-    cBitmap *ret = new cBitmap(w, h, 2);
-
-    // set the palette
-    for (int i = 0; i < 4; i++)
-    {
-	uint32_t color = pal.getColor(paldescr[i].index, paldescr[i].trans);
-	ret->SetColor(i, (tColor) color);
-    }
-
-    // set the content
-    for (int yp = 0; yp < h; yp++)
-    {
-	for (int xp = 0; xp < w; xp++)
-	{
-	    uint8_t idx = bmp[(size.y1 + yp) * spuXres + size.x1 + xp];
-	    ret->SetIndex(xp, yp, idx);
-	}
-    }
-    return ret;
-}
-
-// ==================================
-// find the minimum non-transparent area
-bool cDxr3SpuBitmap::getMinSize(const aDxr3SpuPalDescr paldescr,
-				sDxr3SpuRect & size) const
-{
-    bool ret = false;
-    for (int i = 0; i < 4; i++)
-    {
-	if (paldescr[i].trans != 0)
-	{
-	    if (!ret)
-	    {
-		size = minsize[i];
-	    }
-	    else
-	    {
-		setMin(size.x1, minsize[i].x1);
-		setMin(size.y1, minsize[i].y1);
-		setMax(size.x2, minsize[i].x2);
-		setMax(size.y2, minsize[i].y2);
-	    }
-	    ret = true;
-	}
-    }
-    /*
-    if (ret && cDxr3ConfigData::Instance().GetDebug())
-    {
-	cLog::Instance() << "cDxr3SpuBitmap::getMinSize: ("
-			 << size.x1 ", " << size.y1 << ") x ("
-			 << size.x2 << ", " << size.y2 << ")\n";
-    }
-    */
-    if (size.x1 > size.x2 || size.y1 > size.y2)
-	return false;
-    return ret;
-}
-
-// ==================================
-void cDxr3SpuBitmap::putPixel(int xp, int yp, int len, uint8_t colorid)
-{
-    memset(bmp + spuXres * yp + xp, colorid, len);
-    setMin(minsize[colorid].x1, xp);
-    setMin(minsize[colorid].y1, yp);
-    setMax(minsize[colorid].x2, xp + len - 1);
-    setMax(minsize[colorid].y2, yp + len - 1);
-}
-
-// ==================================
-static uint8_t getBits(uint8_t * &data, uint8_t & bitf)
-{
-    uint8_t ret = *data;
-    if (bitf)
-    {
-	ret >>= 4;
-    }
-    else
-    {
-	data++;
-    }
-
-    bitf ^= 1;
-
-    return (ret & 0xf);
-}
-
-// ==================================
-void cDxr3SpuBitmap::putFieldData(int field, uint8_t * data, uint8_t * endp)
-{
-    int xp = bmpsize.x1;
-    int yp = bmpsize.y1 + field;
-    uint8_t bitf = 1;
-
-    while (data < endp)
-    {
-	uint16_t vlc = getBits(data, bitf);
-	if (vlc < 0x0004)
-	{
-	    vlc = (vlc << 4) | getBits(data, bitf);
-	    if (vlc < 0x0010)
-	    {
-		vlc = (vlc << 4) | getBits(data, bitf);
-		if (vlc < 0x0040)
-		{
-		    vlc = (vlc << 4) | getBits(data, bitf);
-		}
-	    }
-	}
-
-	uint8_t color = vlc & 0x03;
-	int len = vlc >> 2;
-
-	// if len == 0 -> end sequence - fill to end of line
-	len = len ? len : bmpsize.x2 - xp + 1;
-	putPixel(xp, yp, len, color);
-	xp += len;
-
-	if (xp > bmpsize.x2)
-	{
-	    // nextLine
-	    if (!bitf)
-		data++;
-	    bitf = 1;
-	    xp = bmpsize.x1;
-	    yp += 2;
-	    if (yp > bmpsize.y2)
-		return;
-	}
-    }
-}
 
 // ==================================
 // ! constructor
-cDxr3SpuDecoder::cDxr3SpuDecoder()
-{
-    clean = true;
-    scaleMode = eSpuNormal;
-    spu = NULL;
-    osd = NULL;
-    spubmp = NULL;
-    allowedShow = true;
-}
-
-// ==================================
-cDxr3SpuDecoder::~cDxr3SpuDecoder()
+cDxr3SpuDecoder::cDxr3SpuDecoder() :
+    m_Interface(cDxr3Interface::Instance()), m_visible(false)
 {
-    delete spubmp;
-    delete spu;
-    delete osd;
+    m_ScaleMode = eSpuNormal;
+    enabled = true;
+    highlight = false;
 }
 
 // ==================================
@@ -287,389 +39,140 @@ 
 void cDxr3SpuDecoder::processSPU(uint32_t pts, uint8_t * buf)
 #endif
 {
-    setTime(pts);
-
-    if (cDxr3ConfigData::Instance().GetDebug())
+    // size are the first two bits of buf
+    // size = (buf[0] << 8) + buf[1]
+    cMutexLock MutexLock(&mutex);
+    if (enabled)
     {
-	cLog::Instance() << "cDxr3SpuDecoder::processSPU: SPU pushData: pts: "
-			 << pts << "\n";
+	m_Interface.WriteSpu(buf, (buf[0] << 8) + buf[1]);
+	m_Interface.SetSpuPts(pts);
     }
-
-    delete spubmp;
-    spubmp = NULL;
-    delete[]spu;
-    spu = buf;
-    spupts = pts;
-
-    DCSQ_offset = cmdOffs();
-    prev_DCSQ_offset = 0;
-
-    clean = true;
-#if VDRVERSNUM >= 10318
-    allowedShow = AllowedShow;
-#endif
 }
 
 // ==================================
 // ! get scalemode
 cSpuDecoder::eScaleMode cDxr3SpuDecoder::getScaleMode(void)
 {
-    return scaleMode;
+    return m_ScaleMode;
 }
 
 // ==================================
-// ! set scalemode
+// ! set scalemode - not needed
 void cDxr3SpuDecoder::setScaleMode(cSpuDecoder::eScaleMode ScaleMode)
 {
-    scaleMode = ScaleMode;
+    m_ScaleMode = ScaleMode;
 }
 
 // ==================================
-// ! send palette to dxr3
+// ! memo palette
 void cDxr3SpuDecoder::setPalette(uint32_t * pal)
 {
-    palette.setPalette(pal);
-}
-
-// ==================================
-// ! send highlight to dxr3
-void cDxr3SpuDecoder::setHighlight(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint32_t palette)
-{
-    aDxr3SpuPalDescr pld;
-    for (int i = 0; i < 4; i++)
+    for (int i = 0; i < 16; i++)
     {
-	pld[i].index = 0xf & (palette >> (16 + 4 * i));
-	pld[i].trans = 0xf & (palette >> (4 * i));
+	palette[i] = pal[i];
     }
-
-    bool ne = hlpsize.x1 != sx || hlpsize.y1 != sy ||
-	hlpsize.x2 != ex || hlpsize.y2 != ey ||
-	pld[0] != hlpDescr[0] || pld[1] != hlpDescr[1] ||
-	pld[2] != hlpDescr[2] || pld[3] != hlpDescr[3];
-
-    if (ne)
+    cMutexLock MutexLock(&mutex);
+    if (enabled)
     {
-	if (cDxr3ConfigData::Instance().GetDebug())
-	{
-	    cLog::Instance() << "cDxr3SpuDecoder::setHighlight: " << sx
-			     << ", " << sy << ", " << ex << ", " << ey << "\n";
-	}
-
-	hlpsize.x1 = sx;
-	hlpsize.y1 = sy;
-	hlpsize.x2 = ex;
-	hlpsize.y2 = ey;
-	memcpy(hlpDescr, pld, sizeof(aDxr3SpuPalDescr));
-	highlight = true;
-	clean = false;
+	doPalette();
     }
 }
 
 // ==================================
-// ! clear highlight
-void cDxr3SpuDecoder::clearHighlight()
+// ! send palette to dxr3
+void cDxr3SpuDecoder::doPalette(void)
 {
-    clean &= !highlight;
-    highlight = false;
-    hlpsize.x1 = -1;
-    hlpsize.y1 = -1;
-    hlpsize.x2 = -1;
-    hlpsize.y2 = -1;
+    m_Interface.SetPalette(palette);
 }
 
 // ==================================
-int cDxr3SpuDecoder::ScaleYcoord(int value)
+// ! send highlight to dxr3
+void cDxr3SpuDecoder::setHighlight(uint16_t sx, uint16_t sy,
+				   uint16_t ex, uint16_t ey, uint32_t palette)
 {
-    if (scaleMode == eSpuLetterBox)
+    highlight = true;
+    hlsx = sx;
+    hlsy = sy;
+    hlex = ex;
+    hley = ey;
+    hlpalette = palette;
+    cMutexLock MutexLock(&mutex);
+    if (enabled)
     {
-	int offset =
-	    cDevice::PrimaryDevice()->GetVideoSystem() == vsPAL ? 72 : 60;
-	return lround((value * 3.0) / 4.0) + offset;
+	doHighlight();
     }
-    return value;
 }
 
 // ==================================
-int cDxr3SpuDecoder::ScaleYres(int value)
+// ! clear highlight
+void cDxr3SpuDecoder::clearHighlight(void)
 {
-    if (scaleMode == eSpuLetterBox)
+    highlight = false;
+    cMutexLock MutexLock(&mutex);
+    if (enabled)
     {
-	return lround((value * 3.0) / 4.0);
+	doHighlight();
     }
-    return value;
-}
-
-// ==================================
-void cDxr3SpuDecoder::DrawBmp(sDxr3SpuRect & size, cBitmap * bmp)
-{
-    int x2 = size.x2;
-    while ((x2 - size.x1 + 1) & 0x03)
-	x2++;
-    tArea Area = { size.x1, size.y1, x2, size.y2, 2 };
-    osd->SetAreas(&Area, 1);
-    if (x2 > size.x2)
-	osd->DrawRectangle(size.x2 + 1, size.y1, x2, size.y2, clrTransparent);
-    osd->DrawBitmap(size.x1, size.y1, *bmp);
-    delete bmp;
 }
 
-// ==================================
-// ! draw nav, subtitles, ...
-void cDxr3SpuDecoder::Draw()
+void cDxr3SpuDecoder::doHighlight(void)
 {
-    Hide();
-
-    if (!spubmp)
-    {
-	return;
-    }
-
-    cBitmap *fg = NULL;
-    cBitmap *bg = NULL;
-    sDxr3SpuRect bgsize;
-    sDxr3SpuRect hlsize;
-
-    hlsize.x1 = hlpsize.x1;
-    hlsize.y1 = ScaleYcoord(hlpsize.y1);
-    hlsize.x2 = hlpsize.x2;
-    hlsize.y2 = ScaleYcoord(hlpsize.y2);
-
     if (highlight)
     {
-	fg = spubmp->getBitmap(hlpDescr, palette, hlsize);
+	m_Interface.SetButton(hlsx, hlsy, hlex, hley, hlpalette);
     }
-
-    if (spubmp->getMinSize(palDescr, bgsize))
+    else
     {
-	bg = spubmp->getBitmap(palDescr, palette, bgsize);
-	if (scaleMode == eSpuLetterBox)
-	{
-	    // the coordinates have to be modified for letterbox
-	    int y1 = ScaleYres(bgsize.y1) + bgsize.height();
-	    bgsize.y2 = y1 + bgsize.height();
-	    bgsize.y1 = y1;
-	}
+	m_Interface.ClearButton();
     }
 
-    if (bg || fg)
-    {
-	if (osd == NULL)
-	    if ((osd = cOsdProvider::NewOsd(0, 0)) == NULL)
-	    {
-		if (cDxr3ConfigData::Instance().GetDebug())
-		{
-		    cLog::Instance() << "cDxr3SpuDecoder::Draw: New OSD faild!\n";
-		}
-		dsyslog("NewOsd failed\n");
-		return;
-	    }
-
-	if (fg)
-	{
-	    DrawBmp(hlsize, fg);
-	}
-
-	if (bg)
-	{
-	    DrawBmp(bgsize, bg);
-	}
-
-	osd->Flush();
-    }
-
-    clean = true;
+}
+// ==================================
+// ! draw nav, subtitles, ...
+void cDxr3SpuDecoder::Draw(void)
+{
+    m_visible = true;
 }
 
 // ==================================
 // ! hide nav, subtitles, ...
-void cDxr3SpuDecoder::Hide()
+void cDxr3SpuDecoder::Hide(void)
 {
-    delete osd;
-    osd = NULL;
+    m_visible = false;
 }
 
 // ==================================
 // ! clear highlight and osd
-void cDxr3SpuDecoder::Empty()
+void cDxr3SpuDecoder::Empty(void)
 {
-    Hide();
-
-    delete spubmp;
-    spubmp = NULL;
-
-    delete[]spu;
-    spu = NULL;
-
-    clearHighlight();
-    clean = true;
+    m_Interface.ClearOsd();
 }
 
 // ==================================
 // ! set pts
 int cDxr3SpuDecoder::setTime(uint32_t pts)
 {
-    if (!spu)
-    {
-	return 0;
-    }
-
-    if (spu && !clean)
-    {
-	Draw();
-    }
+    m_Interface.SetSpuPts(pts);
+    return (pts == 0) ? 0 : 1;
+}
 
-    while (DCSQ_offset != prev_DCSQ_offset)
-    {
-	// Display Control Sequences
-	int i = DCSQ_offset;
-	state = spNONE;
-
-	uint32_t exec_time = spupts + spuU32(i) * 1024;
-	if ((pts != 0) && (exec_time > pts))
-	{
-	    return 0;
-	}
-
-	if (pts != 0)
-	{
-	    uint16_t feven = 0;
-	    uint16_t fodd = 0;
-
-	    i += 2;
-
-	    prev_DCSQ_offset = DCSQ_offset;
-	    DCSQ_offset = spuU32(i);
-	    i += 2;
-
-	    while (spu[i] != CMD_SPU_EOF)
-	    {
-		// Command Sequence
-		switch (spu[i])
-		{
-		case CMD_SPU_SHOW:
-		    // show subpicture
-		    if (cDxr3ConfigData::Instance().GetDebug())
-		    {
-			cLog::Instance() << "cDxr3SpuDecoder::setTime: show subpicture\n";
-		    }
-		    state = spSHOW;
-		    i++;
-		    break;
-
-		case CMD_SPU_HIDE:
-		    // hide subpicture
-		    if (cDxr3ConfigData::Instance().GetDebug())
-		    {
-			cLog::Instance() << "cDxr3SpuDecoder::setTime: hide subpicture\n";
-		    }
-		    state = spHIDE;
-		    i++;
-		    break;
-
-		case CMD_SPU_SET_PALETTE:
-		    // CLUT
-		    palDescr[0].index = spu[i + 2] & 0xf;
-		    palDescr[1].index = spu[i + 2] >> 4;
-		    palDescr[2].index = spu[i + 1] & 0xf;
-		    palDescr[3].index = spu[i + 1] >> 4;
-		    i += 3;
-		    break;
-
-		case CMD_SPU_SET_ALPHA:
-		    // transparency palette
-		    palDescr[0].trans = spu[i + 2] & 0xf;
-		    palDescr[1].trans = spu[i + 2] >> 4;
-		    palDescr[2].trans = spu[i + 1] & 0xf;
-		    palDescr[3].trans = spu[i + 1] >> 4;
-		    i += 3;
-		    break;
-
-		case CMD_SPU_SET_SIZE:
-		    // image coordinates
-		    size.x1 = (spu[i + 1] << 4) | (spu[i + 2] >> 4);
-		    size.x2 = ((spu[i + 2] & 0x0f) << 8) | spu[i + 3];
-
-		    size.y1 = (spu[i + 4] << 4) | (spu[i + 5] >> 4);
-		    size.y2 = ((spu[i + 5] & 0x0f) << 8) | spu[i + 6];
-
-		    if (cDxr3ConfigData::Instance().GetDebug())
-		    {
-			cLog::Instance() << "cDxr3SpuDecoder::setTime: ("
-					 << size.x1 << ", " << size.y1
-					 << ") x (" << size.x2 << ", "
-					 << size.y2 <<")\n";
-		    }
-		    i += 7;
-		    break;
-
-		case CMD_SPU_SET_PXD_OFFSET:
-		    // image 1 / image 2 offsets
-		    fodd = spuU32(i + 1);
-		    feven = spuU32(i + 3);
-
-		    if (cDxr3ConfigData::Instance().GetDebug())
-		    {
-			cLog::Instance() << "cDxr3SpuDecoder::setTime: odd = "
-					 << fodd << " even = " << feven
-					 << "\n";
-		    }
-		    i += 5;
-		    break;
-
-		case CMD_SPU_CHG_COLCON:
-		{
-		    int size = spuU32(i + 1);
-		    i += 1 + size;
-		}
-		break;
-
-		case CMD_SPU_MENU:
-		    if (cDxr3ConfigData::Instance().GetDebug())
-		    {
-			cLog::Instance() << "cDxr3SpuDecoder::setTime: spu menu\n";
-		    }
-		    state = spMENU;
-
-		    i++;
-		    break;
-
-		default:
-		    esyslog("invalid sequence in control header (%.2x)\n",
-			    spu[i]);
-		    assert(0);
-		    i++;
-		    break;
-		}
-	    }
-	    if (fodd != 0 && feven != 0)
-	    {
-		delete spubmp;
-		spubmp = new cDxr3SpuBitmap(size, spu + fodd, spu + feven,
-					    spu + feven, spu + cmdOffs());
-	    }
-	}
-	else if (!clean)
-	{
-	    state = spSHOW;
-	}
-
-	if ((state == spSHOW && allowedShow) || state == spMENU)
-	{
-	    Draw();
-	}
-
-	if (state == spHIDE)
-	{
-	    Hide();
-	}
-
-	if (pts == 0)
-	{
-	    return 0;
-	}
-    }
+// ==================================
+// ! disable spu decoder (osd in use)
+void cDxr3SpuDecoder::Disable(void)
+{
+    cMutexLock MutexLock(&mutex);
+    enabled = false;
+    m_Interface.ClearButton();
+}
 
-    return 1;
+// ==================================
+// ! re-enable spu decoder (osd no longer in use)
+void cDxr3SpuDecoder::Enable(void)
+{
+    cMutexLock MutexLock(&mutex);
+    enabled = true;
+    doPalette();
+    doHighlight();
 }
 
 // Local variables:
Index: dxr3spudecoder.h
===================================================================
RCS file: /cvsroot/dxr3plugin/dxr3/dxr3spudecoder.h,v
retrieving revision 1.1.2.9
diff -u -r1.1.2.9 dxr3spudecoder.h
--- dxr3spudecoder.h	21 Apr 2005 15:57:02 -0000	1.1.2.9
+++ dxr3spudecoder.h	16 May 2005 17:52:24 -0000
@@ -23,81 +23,21 @@ 
 #define _DXR3SPUDECODER_H_
 
 #include "dxr3vdrincludes.h"
-#include <inttypes.h>
-
-// ==================================
-typedef struct sDxr3SpuPalDescr
-{
-    uint8_t index;
-    uint8_t trans;
-
-    bool operator != (const sDxr3SpuPalDescr pd) const
-    {
-	return index != pd.index && trans != pd.trans;
-    };
-} aDxr3SpuPalDescr[4];
-
-// ==================================
-struct sDxr3SpuRect
-{
-    int x1, y1;
-    int x2, y2;
-
-    int width()
-    {
-	return x2 - x1 + 1;
-    };
-
-    int height()
-    {
-	return y2 - y1 + 1;
-    };
-
-    bool operator != (const sDxr3SpuRect r) const
-    {
-	return r.x1 != x1 || r.y1 != y1 || r.x2 != x2 || r.y2 != y2;
-    };
-};
-
-// ==================================
-class cDxr3SpuPalette
-{
-private:
-    uint32_t palette[16];
-
-public:
-    void setPalette(const uint32_t * pal);
-    uint32_t getColor(uint8_t idx, uint8_t trans) const;
-};
-
-// ==================================
-class cDxr3SpuBitmap
-{
-private:
-    sDxr3SpuRect bmpsize;
-    sDxr3SpuRect minsize[4];
-    uint8_t *bmp;
-
-    void putPixel(int xp, int yp, int len, uint8_t colorid);
-    void putFieldData(int field, uint8_t * data, uint8_t * endp);
-
-public:
-    cDxr3SpuBitmap(sDxr3SpuRect size, uint8_t * fodd, uint8_t * eodd,
-		   uint8_t * feven, uint8_t * eeven);
-    ~cDxr3SpuBitmap();
-
-    bool getMinSize(const aDxr3SpuPalDescr paldescr,
-		    sDxr3SpuRect & size) const;
-    cBitmap *getBitmap(const aDxr3SpuPalDescr paldescr,
-		       const cDxr3SpuPalette & pal, sDxr3SpuRect & size) const;
-};
+#include "dxr3interface.h"
 
 // ==================================
+//! spu decoder
+/*!
+  cDxr3SpuDecoder is used to show DVD
+  navigation and subtitles.
+  We make here use of the DVD-Functions
+  of the dxr3 driver/card.
+*/
 class cDxr3SpuDecoder : public cSpuDecoder
 {
 public:
     cDxr3SpuDecoder();
-    ~cDxr3SpuDecoder();
+    ~cDxr3SpuDecoder() {}
 
     int setTime(uint32_t pts);
 
@@ -108,80 +48,34 @@ 
 		      uint32_t palette);
     void clearHighlight();
     void Empty();
-#if VDRVERSNUM >= 10318
-    void processSPU(uint32_t pts, uint8_t * buf, bool AllowedShow);
-#else
-    void processSPU(uint32_t pts, uint8_t * buf);
-#endif
-
-#if VDRVERSNUM >= 10311
     void Hide();
     void Draw();
     bool IsVisible()
     {
-	return osd != NULL;
+	return m_visible;
     }
+    void Disable();
+    void Enable();
+#if VDRVERSNUM >= 10318
+    void processSPU(uint32_t pts, uint8_t * buf, bool AllowedShow);
+#else
+    void processSPU(uint32_t pts, uint8_t * buf);
 #endif
 
 private:
-    cOsd * osd;
-
-    // processing state
-    uint8_t *spu;
-    uint32_t spupts;
-    bool clean;
-    bool ready;
-    bool allowedShow;
-
-    enum spFlag
-    {
-	spNONE,
-	spHIDE,
-	spSHOW,
-	spMENU
-    };
-    spFlag state;
-
-    cSpuDecoder::eScaleMode scaleMode;
-
-    // highligh area
+    cDxr3Interface& m_Interface;///< interface to dxr3 driver
+    bool m_visible;		///< is anything visible (nav, osd, subtitles)
+    cMutex mutex;
+    bool enabled;
+    uint32_t palette[16];
     bool highlight;
-    sDxr3SpuRect hlpsize;
-    aDxr3SpuPalDescr hlpDescr;
-
-    // palette
-    cDxr3SpuPalette palette;
-
-    // spu info's
-    sDxr3SpuRect size;
-    aDxr3SpuPalDescr palDescr;
-
-    uint16_t DCSQ_offset;
-    uint16_t prev_DCSQ_offset;
-
-    cDxr3SpuBitmap *spubmp;
-
-    int cmdOffs()
-    {
-	return ((spu[2] << 8) | spu[3]);
-    }
-    int spuSize()
-    {
-	return ((spu[0] << 8) | spu[1]);
-    }
-
-    int ScaleYcoord(int value);
-    int ScaleYres(int value);
-    void DrawBmp(sDxr3SpuRect & size, cBitmap * bmp);
+    uint16_t hlsx, hlsy, hlex, hley;
+    uint32_t hlpalette;
+    eScaleMode m_ScaleMode;
+    void doHighlight();
+    void doPalette();
 };
 
-// ==================================
-inline uint32_t cDxr3SpuPalette::getColor(uint8_t idx, uint8_t trans) const
-{
-    uint8_t t = trans == 0x0f ? 0xff : trans << 4;
-    return palette[idx] | (t << 24);
-}
-
 #endif /*_DXR3SPUDECODER_H_*/
 
 // Local variables: