On Sun, Nov 03, 2013 at 10:01:54PM +0200, Marko Mäkelä wrote:
On Fri, Nov 01, 2013 at 11:19:48PM +0200, Marko Mäkelä wrote:
If I change the assignment to isTrueColor=false, the square goes
away and I will get the familiar gray rectangles on the screen
(from the "else" block that I omitted above).
I did some further studying. The truecolor OSD was implemented early
2011. As far as I understand, the softdevice plugin is converting
palette-based bitmaps into an ARGB layer. There is a comment at the
end of the definition of class cOsd in osd.h that shows how the
conversion should be done.
It looks like I should simply follow this example, possibly
implementing some kind of threshold mapping on the Alpha channel in
case the Matrox does not implement 8-bit translucency but just a
1-bit transparency flag. So, I will try to remove the palette mapping
from SoftOsd.c and replace the GetBitmap() call with the
RenderPixmaps() loop.
I figured this out for the most part. The pixmap gets first converted to
an ARGB buffer cSoftOsd::OSD_Bitmap in FlushPixmaps() and
DrawConvertPixmap(). From OSD_Bitmap it gets converted to the screen
memory. I did not change the latter conversion.
Maybe I did something wrong regarding DirtyDrawPort and DirtyViewport,
because I got occasional crashes when activating the OSD. When using a
full-screen OSD (filling the entire 1280×1024 panel) the bottom 4 or so
lines were never erased.
I did not get to see DVB subtitles yet, either due to them not being
present in the live sendings at the moment I tested, or due to
misconfiguration. I guess that VDR 2.0 would allow the subtitles to be
alpha-blended with the OSD layer.
My patch against softdevice-cvs is attached. I compiled it with the
following:
vdr 2.0.4
ffmpeg 0.5.13
DirectFB 1.0.1
DFB++ 1.0.0
Best regards,
Marko
Index: SoftOsd.c
===================================================================
RCS file: /cvsroot/softdevice/softdevice/SoftOsd.c,v
retrieving revision 1.37
diff -p -u -r1.37 SoftOsd.c
--- SoftOsd.c 17 Apr 2011 16:06:31 -0000 1.37
+++ SoftOsd.c 3 Nov 2013 22:35:48 -0000
@@ -25,7 +25,6 @@
//#define SCALEDEBV(out...) printf(out)
//#define SCALEDEBH(out...) printf(out)
-
#ifndef OSDDEB
#define OSDDEB(out...)
#endif
@@ -55,16 +54,17 @@
#define COLOR_64BIT(x) ( ((x)<<32) | (x) )
#define ALPHA_VALUE(x) ( (x) << 24 )
-// the same constants for MMX mode
+//#undef USE_MMX
+//#undef USE_MMX2
+
+#ifdef USE_MMX2
static uint64_t transparent_thr= COLOR_64BIT(ALPHA_VALUE(TRANSPARENT_THRESHOLD>>1));
static uint64_t opacity_thr= COLOR_64BIT(ALPHA_VALUE(OPACITY_THRESHOLD>>1));
static uint64_t pseudo_transparent = COLOR_64BIT(COLOR_KEY);
+#endif // USE_MMX2
int cSoftOsd::colorkey;
-//#undef USE_MMX
-//#undef USE_MMX2
-
#undef SPLAT_U16
#ifdef USE_MMX2
#define SPLAT_U16(X) " pshufw $0b0, " X ", " X " \n"
@@ -85,7 +85,7 @@ cSoftOsd::cSoftOsd(cVideoOut *VideoOut,
OSDDEB("cSoftOsd constructor\n");
OutputConvert=&cSoftOsd::ARGB_to_ARGB32;
bitmap_Format=PF_None; // forces a clear after first SetMode
- OSD_Bitmap=new uint32_t[OSD_STRIDE*(OSD_HEIGHT+4)];
+ OSD_Bitmap=new tColor[OSD_STRIDE*(OSD_HEIGHT+4)];
videoOut = VideoOut;
xPan = yPan = 0;
@@ -93,9 +93,10 @@ cSoftOsd::cSoftOsd(cVideoOut *VideoOut,
voutMutex.Lock();
videoOut->OpenOSD();
colorkey=videoOut->GetOSDColorkey();
+#ifdef USE_MMX2
pseudo_transparent=(uint64_t)colorkey | ((uint64_t) colorkey)<<32;
+#endif // USE_MMX2
- xOfs=X;yOfs=Y;
ScreenOsdWidth=ScreenOsdHeight=0;
int Depth=16; bool HasAlpha=false; bool AlphaInversed=false;
bool IsYUV=false;
@@ -115,9 +116,6 @@ void cSoftOsd::Clear() {
for (int i=OSD_STRIDE*(OSD_HEIGHT+2)-1; i!=0; i--)
OSD_Bitmap[i]=fill;
OSD_Bitmap[0]=fill;
-
- // no dirty lines, everything has to be redrawn anyway
- memset(dirty_lines,false,sizeof(dirty_lines));
}
/* --------------------------------------------------------------------------*/
@@ -302,7 +300,7 @@ bool cSoftOsd::SetMode(int Depth, bool H
// format change, redraw everything
bitmap_Format= PF_AYUV;
Clear();
- FlushBitmaps(false);
+ FlushPixmaps();
OSDDEB("SetMode switched to YUV mode\n");
return true;
};
@@ -338,7 +336,7 @@ bool cSoftOsd::SetMode(int Depth, bool H
if (old_bitmap_Format != bitmap_Format ||
videoOut->OSDNeedsRedraw()) {
Clear();
- FlushBitmaps(false);
+ FlushPixmaps();
OSDDEB("SetMode switched old_bitmap_Format %d -> bitmap_Format %d\n",
old_bitmap_Format,bitmap_Format);
return true;
@@ -357,15 +355,14 @@ void cSoftOsd::Flush(void) {
return;
#endif
- bool OSD_changed=FlushBitmaps(true);
+ FlushPixmaps();
voutMutex.Lock();
#ifdef HAVE_YAEPGPATCH
if (vidWin.bpp!=0)
videoOut->SetVidWin(1,vidWin.x1,vidWin.y1,vidWin.x2,vidWin.y2);
#endif
- if (OSD_changed)
- OsdCommit();
+ OsdCommit();
voutMutex.Unlock();
// give priority to the other threads
@@ -380,15 +377,12 @@ void cSoftOsd::Flush(void) {
}
/* -------------------------------------------------------------------------*/
-bool cSoftOsd::FlushBitmaps(bool OnlyDirty) {
- cBitmap *Bitmap;
- bool OSD_changed=false;
- OSDDEB("FlushBitmaps (OnlyDirty: %d)\n",OnlyDirty);
-
- for (int i = 0; (Bitmap = GetBitmap(i)) != NULL; i++) {
- OSD_changed |= DrawConvertBitmap(Bitmap,OnlyDirty);
- }
- return OSD_changed;
+void cSoftOsd::FlushPixmaps(void) {
+ LOCK_PIXMAPS;
+ while (cPixmapMemory *pm = RenderPixmaps()) {
+ DrawConvertPixmap(pm);
+ delete pm;
+ }
};
/*--------------------------------------------------------------------------*/
@@ -413,8 +407,7 @@ void cSoftOsd::ConvertPalette(tColor *pa
};
// replace transparent colors with color key
- if ( IS_TRANSPARENT( GET_A((uint32_t)palette[i]) ) ) {
- //if (((uint32_t)palette[i] & 0xFF000000) == 0x000000 ) {
+ if (IS_TRANSPARENT(GET_A((uint32_t)palette[i]))) {
palette[i] = 0x00000000; // color key;
};
};
@@ -430,54 +423,31 @@ void cSoftOsd::ConvertPalette(tColor *pa
};
/*--------------------------------------------------------------------------*/
-bool cSoftOsd::DrawConvertBitmap(cBitmap *bitmap, bool OnlyDirty) {
+void cSoftOsd::DrawConvertPixmap(cPixmapMemory *pm) {
int x1,x2,y1,y2;
- cMutexLock dirty(&dirty_Mutex);
- OSDDEB("DrawConvertBitmap %p, OnlyDirty %d\n",bitmap,OnlyDirty);
+ OSDDEB("DrawConvertPixmap %p\n",pm);
- if ( !bitmap->Dirty(x1,y1,x2,y2) && OnlyDirty)
- return false;
-
- if (!OnlyDirty) {
- x1=0;
- x2=bitmap->Width()-1;
- y1=0;
- y2=bitmap->Height()-1;
- };
-
- int maxColors;
- const tColor *orig_palette=bitmap->Colors(maxColors);
- tColor palette[256];
- ConvertPalette(palette,orig_palette,maxColors);
- /*
- for (int i =0; i< maxColors; i++)
- printf("color[%d]: 0x%08x \n",i,palette[i]);
- */
- OSDDEB("drawing bitmap %p at P0 (%d,%d) from (%d,%d) to (%d,%d) \n",
- bitmap,bitmap->X0(),bitmap->Y0(),x1,y1,x2,y2);
-
- y2++;
- x2++;
- y2= yOfs+y2+bitmap->Y0() > OSD_HEIGHT ?
- OSD_HEIGHT-bitmap->Y0()-yOfs : y2;
- x2= xOfs+x2+bitmap->X0() > OSD_WIDTH ?
- OSD_WIDTH-bitmap->X0()-xOfs : x2;
-
- int bitmap_yOfs=yOfs+bitmap->Y0()+Y_OFFSET;
- uint32_t *OSD_pointer=&OSD_Bitmap[(bitmap_yOfs+y1)*OSD_STRIDE+
- xOfs+bitmap->X0()+x1+X_OFFSET];
- int missing_line_length=OSD_STRIDE-(x2-x1);
- bool *dirty_line=&dirty_lines[bitmap_yOfs+y1];
+ x1=Left() + pm->DirtyViewPort().X();
+ x2=x1 + pm->DirtyViewPort().Width();
+ y1=Top() + pm->DirtyViewPort().Y();
+ y2=y1 + pm->DirtyViewPort().Height();
+
+ OSDDEB("drawing pixmap %p from (%d,%d) to (%d,%d)\n",
+ pm,x1,y1,x2,y2);
+
+ if (y2 > OSD_HEIGHT) y2 = OSD_HEIGHT;
+ if (x2 > OSD_WIDTH) x2 = OSD_WIDTH;
+
+ tColor *dst=&OSD_Bitmap[y1*OSD_STRIDE+x1];
+ const tColor* src = reinterpret_cast<const tColor*>(pm->Data()) +
+ pm->DirtyDrawPort().X() +
+ pm->DirtyDrawPort().Y() * pm->DrawPort().Width();
for (int y=y1; y<y2; y++) {
- for (int x=x1; x<x2; x++) {
- *(OSD_pointer++)=palette[*bitmap->Data(x,y)];
- }
- OSD_pointer+=missing_line_length;
- *(dirty_line++)=true;
- };
- bitmap->Clean();
- return true;
+ memcpy(dst, src, (x2 - x1) * sizeof(tColor));
+ src += pm->DrawPort().Width();
+ dst += OSD_STRIDE;
+ }
};
/*----------------------------------------------------------------------*/
@@ -1133,7 +1103,6 @@ void cSoftOsd::NoVScaleCopyToBitmap(uint
int Ystride, int UVstride,
int dest_Width, int dest_Height, bool RefreshAll) {
OSDDEB("CopyToBitmap YUV no Vscale\n");
- cMutexLock dirty(&dirty_Mutex);
color *pixmap=(color*) OSD_Bitmap;
int dest_Stride=(dest_Width+32) & ~0xf;
color tmp_pixmap1[2*dest_Stride];
@@ -1150,12 +1119,6 @@ void cSoftOsd::NoVScaleCopyToBitmap(uint
for (int y=0; y<dest_Height; y+=2) {
- int is_dirty=RefreshAll;
- is_dirty |= dirty_lines[y] || dirty_lines[y+1];
-
- if (!is_dirty)
- continue;
-
if (dest_Width==OSD_WIDTH) {
tmp_pixmap=&pixmap[y*OSD_STRIDE];
} else {
@@ -1178,7 +1141,6 @@ void cSoftOsd::NoVScaleCopyToBitmap(uint
// dest_Width);
tmp_pixmap,&tmp_pixmap[dest_Stride],dest_Width);
};
- memset(dirty_lines,false,sizeof(dirty_lines));
OSDDEB("CopyToBitmap YUV no Vscale end \n");
};
@@ -1199,10 +1161,9 @@ void cSoftOsd::ScaleVDownCopyToBitmap(ui
// convert bitmap to ayuv
bitmap_Format = PF_AYUV;
Clear();
- FlushBitmaps(false);
+ FlushPixmaps();
};
- cMutexLock dirty(&dirty_Mutex);
color *pixmap=(color*) OSD_Bitmap;
color tmp_pixmap[2*OSD_STRIDE];
uint8_t *pY;uint8_t *pU;uint8_t *pV;
@@ -1228,13 +1189,6 @@ void cSoftOsd::ScaleVDownCopyToBitmap(ui
int32_t start_pos=new_pixel_height*y%ScaleFactor-ScaleFactor;
//int32_t start_pos=new_pixel_height*y-ScaleFactor*(start_row+1);
- int is_dirty=RefreshAll;
- for (int i=0; i<lines_count; i++)
- is_dirty|=dirty_lines[start_row+i];
-
- if (!is_dirty)
- continue;
-
scaleH_strtIdx=SCALEH_IDX(lines_count-2);
for (int i=0; i<lines_count; i++) {
scaleH_Reference[i]=&scaleH_pixmap[SCALEH_IDX(i)*OSD_STRIDE];
@@ -1285,7 +1239,6 @@ void cSoftOsd::ScaleVDownCopyToBitmap(ui
// dest_Width);
tmp_pixmap,&tmp_pixmap[OSD_STRIDE],dest_Width);
};
- memset(dirty_lines,false,sizeof(dirty_lines));
OSDDEB("CopyToBitmap YUV down end \n");
};
@@ -1319,10 +1272,9 @@ void cSoftOsd::ScaleVUpCopyToBitmap(uint
// convert bitmap to argb
bitmap_Format = PF_ARGB32;
Clear();
- FlushBitmaps(false);
+ FlushPixmaps();
};
- cMutexLock dirty(&dirty_Mutex);
const int dest_stride=(dest_Width+32)&~0xF;
void (cSoftOsd::*ScaleHoriz)(uint32_t * dest, int dest_Width, color * pixmap,int Pixel);
ScaleHoriz= dest_Width<OSD_WIDTH ? &cSoftOsd::ScaleDownHoriz_MMX :
@@ -1349,12 +1301,6 @@ void cSoftOsd::ScaleVUpCopyToBitmap(uint
for (int y=0; y<dest_Height; y++) {
int start_row=new_pixel_height*y/ScaleFactor;
- int is_dirty=RefreshAll;
- is_dirty|=dirty_lines[start_row] | dirty_lines[start_row+1];
-
- if (!is_dirty)
- continue;
-
int32_t start_pos=new_pixel_height*y%ScaleFactor;
//int32_t start_pos=new_pixel_height*y-ScaleFactor*(start_row+1);
//printf("Scaling to line %d from start_row: %d start_pos %d\n",
@@ -1403,7 +1349,6 @@ void cSoftOsd::ScaleVUpCopyToBitmap(uint
src+=dest_Width*4;
};
};
- memset(dirty_lines,false,sizeof(dirty_lines));
OSDDEB("CopyToBitmap RGB up end\n");
};
@@ -1419,10 +1364,9 @@ void cSoftOsd::NoVScaleCopyToBitmap(uint
// convert bitmap to argb
bitmap_Format = PF_ARGB32;
Clear();
- FlushBitmaps(false);
+ FlushPixmaps();
};
- cMutexLock dirty(&dirty_Mutex);
uint8_t *buf;
color *pixmap=(color*) OSD_Bitmap;
const int dest_stride=(dest_Width+32)&~0xF;
@@ -1435,9 +1379,6 @@ void cSoftOsd::NoVScaleCopyToBitmap(uint
for (int y=0; y<OSD_HEIGHT; y++) {
- if (!RefreshAll && !dirty_lines[y])
- continue;
-
if (dest_Width==OSD_WIDTH) {
tmp_pixmap=&pixmap[y*OSD_STRIDE];
} else {
@@ -1452,7 +1393,6 @@ void cSoftOsd::NoVScaleCopyToBitmap(uint
dest_dirtyLines[y]=true;
};
- memset(dirty_lines,false,sizeof(dirty_lines));
OSDDEB("CopyToBitmap RGB down end\n");
};
@@ -1468,10 +1408,9 @@ void cSoftOsd::ScaleVDownCopyToBitmap(ui
// convert bitmap to argb
bitmap_Format = PF_ARGB32;
Clear();
- FlushBitmaps(false);
+ FlushPixmaps();
};
- cMutexLock dirty(&dirty_Mutex);
uint8_t *buf;
color *pixmap=(color*) OSD_Bitmap;
const int dest_stride=(dest_Width+32)&~0xF;
@@ -1496,13 +1435,6 @@ void cSoftOsd::ScaleVDownCopyToBitmap(ui
for (int y=0; y<dest_Height; y++) {
int start_row=new_pixel_height*y/ScaleFactor;
- int is_dirty=RefreshAll;
- for (int i=0; i<lines_count; i++)
- is_dirty|=dirty_lines[start_row+i];
-
- if (!is_dirty)
- continue;
-
int32_t start_pos=new_pixel_height*y%ScaleFactor-ScaleFactor;
//int32_t start_pos=new_pixel_height*y-ScaleFactor*(start_row+1);
//printf("Scaling to line %d from start_row: %d lines_count %d\n",
@@ -1527,7 +1459,6 @@ void cSoftOsd::ScaleVDownCopyToBitmap(ui
dest_dirtyLines[y]=true;
};
- memset(dirty_lines,false,sizeof(dirty_lines));
OSDDEB("CopyToBitmap RGB down end\n");
};
Index: SoftOsd.h
===================================================================
RCS file: /cvsroot/softdevice/softdevice/SoftOsd.h,v
retrieving revision 1.21
diff -p -u -r1.21 SoftOsd.h
--- SoftOsd.h 17 Apr 2011 17:22:18 -0000 1.21
+++ SoftOsd.h 3 Nov 2013 22:35:48 -0000
@@ -37,16 +37,9 @@
#define IS_BACKGROUND(a) (((a) < OPACITY_THRESHOLD) && ((a) > TRANSPARENT_THRESHOLD))
#define IS_TRANSPARENT(a) ((a) < TRANSPARENT_THRESHOLD)
-#define IS_OPAQUE(a) ((a) > OPACITY_THRESHOLD)
#include "video.h"
-#define X_OFFSET 0
-#define Y_OFFSET 0
-
-
-#define COLOR_RGB16(r,g,b) (((b >> 3)& 0x1F) | ((g & 0xF8) << 2)| ((r & 0xF8)<<10) )
-
#define GET_A(x) ((x) >> 24 & 0xFF)
#define GET_R(x) ((x) >> 16 & 0xFF)
#define GET_G(x) ((x) >> 8 & 0xFF)
@@ -56,15 +49,8 @@
#define SET_R(x) ((x) << 16 & 0x00FF0000)
#define SET_G(x) ((x) << 8 & 0x0000FF00)
#define SET_B(x) ((x) << 0 & 0x000000FF)
-/*
-struct color {
- unsigned char b;
- unsigned char g;
- unsigned char r;
- unsigned char a;
-};
-*/
-typedef uint32_t color;
+
+typedef tColor color;
class cVideoOut;
@@ -76,11 +62,8 @@ private:
cVideoOut *videoOut;
protected:
static int colorkey;
- int xOfs, yOfs;
int xPan, yPan;
- uint32_t *OSD_Bitmap;
- bool dirty_lines[OSD_HEIGHT+10];
- cMutex dirty_Mutex;
+ tColor* OSD_Bitmap;
void (*OutputConvert)(uint8_t * dest, color * pixmap, int Pixel, int odd);
enum PixFormat {
@@ -124,8 +107,8 @@ public:
protected:
bool SetMode(int Depth, bool HasAlpha, bool AlphaInversed, bool IsYUV);
- bool FlushBitmaps(bool OnlyDirty);
- bool DrawConvertBitmap(cBitmap *Bitmap, bool OnlyDirty);
+ void FlushPixmaps(void);
+ void DrawConvertPixmap(cPixmapMemory* pm);
void OsdCommit(bool forced = false);
// may only be called if the caller holds voutMutex
Index: VideoFilter.c
===================================================================
RCS file: /cvsroot/softdevice/softdevice/VideoFilter.c,v
retrieving revision 1.11
diff -p -u -r1.11 VideoFilter.c
--- VideoFilter.c 18 Apr 2008 15:10:35 -0000 1.11
+++ VideoFilter.c 3 Nov 2013 22:35:48 -0000
@@ -286,7 +286,7 @@ void cImageConvert::Filter(sPicBuffer *&
#ifdef USE_SWSCALE
sws_scale(img_convert_ctx, avpic_src.data, avpic_src.linesize,
0, orig->height, avpic_dest.data, avpic_dest.linesize);
-#else
+#elif 0
if (img_convert(&avpic_dest,PIX_FMT_YUV420P,
&avpic_src, orig->format,
orig->width, orig->height) < 0) {
@@ -295,6 +295,9 @@ void cImageConvert::Filter(sPicBuffer *&
"[softdevice] error, libavcodec img_convert failure\n");
return;
}
+#else
+ dest = orig;
+ return;
#endif
CopyPicBufferContext(dest,orig);
}
Index: configure
===================================================================
RCS file: /cvsroot/softdevice/softdevice/configure,v
retrieving revision 1.50
diff -p -u -r1.50 configure
--- configure 21 Sep 2008 12:55:57 -0000 1.50
+++ configure 3 Nov 2013 22:35:49 -0000
@@ -218,7 +218,7 @@ if test "${use_pkgconfig}" = "yes" ; the
if test "${ffmpeg_use_path}" = "no" ; then
echo "try to use pkg-config." >> config.log
-ffmpeg_l1="libavformat libavcodec"
+ffmpeg_l1="libavformat libavcodec libavutil zlib"
pkg-config --libs libpostproc >> config.log 2>&1 && { ffmpeg_l1="$ffmpeg_l1 libpostproc";libpostproc="yes"; }
Index: i18n.c
===================================================================
RCS file: /cvsroot/softdevice/softdevice/i18n.c,v
retrieving revision 1.25
diff -p -u -r1.25 i18n.c
--- i18n.c 14 Apr 2008 02:28:09 -0000 1.25
+++ i18n.c 3 Nov 2013 22:35:49 -0000
@@ -7,6 +7,7 @@
*/
#include "i18n.h"
+#if 0
const tI18nPhrase Phrases[] = {
{ "Softdevice", // 1
@@ -1343,3 +1344,4 @@ const tI18nPhrase Phrases[] = {
},
{ NULL }
};
+#endif
Index: i18n.h
===================================================================
RCS file: /cvsroot/softdevice/softdevice/i18n.h,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 i18n.h
--- i18n.h 1 Aug 2004 05:07:04 -0000 1.1.1.1
+++ i18n.h 3 Nov 2013 22:35:49 -0000
@@ -11,6 +11,4 @@
#include <vdr/i18n.h>
-extern const tI18nPhrase Phrases[];
-
#endif //_I18N__H
Index: mpeg2decoder.c
===================================================================
RCS file: /cvsroot/softdevice/softdevice/mpeg2decoder.c,v
retrieving revision 1.90
diff -p -u -r1.90 mpeg2decoder.c
--- mpeg2decoder.c 17 Apr 2011 17:22:18 -0000 1.90
+++ mpeg2decoder.c 3 Nov 2013 22:35:49 -0000
@@ -162,7 +162,7 @@ cStreamDecoder::cStreamDecoder(AVCodecCo
#if HAS_ERROR_RECOGNITION
context->error_recognition=1;
#else
- context->error_resilience=1;
+ context->error_concealment=1;
#endif
CMDDEB("Neuer StreamDecoder Pid: %d context %p type %d\n",
getpid(),context,context->codec_type );
Index: softdevice.c
===================================================================
RCS file: /cvsroot/softdevice/softdevice/softdevice.c,v
retrieving revision 1.99
diff -p -u -r1.99 softdevice.c
--- softdevice.c 17 Apr 2011 17:22:19 -0000 1.99
+++ softdevice.c 3 Nov 2013 22:35:50 -0000
@@ -1306,7 +1306,7 @@ bool cPluginSoftDevice::Service(const ch
bool cPluginSoftDevice::Start(void)
{
// Start any background activities the plugin shall perform.
- RegisterI18n(Phrases);
+ I18nRegister("softdevice");
return true;
}
_______________________________________________
vdr mailing list
vdr@xxxxxxxxxxx
http://www.linuxtv.org/cgi-bin/mailman/listinfo/vdr