From patchwork Sun Nov 3 22:42:32 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?TWFya28gTcOka2Vsw6Q=?= X-Patchwork-Id: 20578 Received: from localhost ([127.0.0.1] helo=www.linuxtv.org) by www.linuxtv.org with esmtp (Exim 4.72) (envelope-from ) id 1Vd6Ns-0005Qh-QN; Sun, 03 Nov 2013 23:43:04 +0100 Received: from mail.tu-berlin.de ([130.149.7.33]) by www.linuxtv.org with esmtp (Exim 4.72) (envelope-from ) id 1Vd6NP-0005Py-LW for vdr@linuxtv.org; Sun, 03 Nov 2013 23:43:02 +0100 X-tubIT-Incoming-IP: 62.142.5.110 Received: from emh04.mail.saunalahti.fi ([62.142.5.110]) by mail.tu-berlin.de (exim-4.72/mailfrontend-6) with esmtps [TLSv1:AES256-SHA:256] for id 1Vd6NO-0003zC-3m; Sun, 03 Nov 2013 23:42:35 +0100 Received: from localhost (a88-115-98-209.elisa-laajakaista.fi [88.115.98.209]) by emh04.mail.saunalahti.fi (Postfix) with ESMTP id 0DF821A25CE for ; Mon, 4 Nov 2013 00:42:33 +0200 (EET) Date: Mon, 4 Nov 2013 00:42:32 +0200 From: Marko =?iso-8859-1?B?TeRrZWzk?= To: vdr@linuxtv.org Message-ID: <20131103224232.GB3987@x220> References: <20131101211948.GB4509@x220> <20131103200154.GA3987@x220> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20131103200154.GA3987@x220> User-Agent: Mutt/1.5.21 (2010-09-15) X-PMX-Version: 6.0.0.2142326, Antispam-Engine: 2.7.2.2107409, Antispam-Data: 2013.11.3.223314 X-PMX-Spam: Gauge=IIIIIIII, Probability=8%, Report=' HTML_00_01 0.05, HTML_00_10 0.05, MIME_TEXT_ONLY_MP_MIXED 0.05, MSGID_ADDED_BY_MTA 0.05, BODYTEXTP_SIZE_3000_LESS 0, BODY_SIZE_10000_PLUS 0, INVALID_MSGID_NO_FQDN 0, NO_URI_FOUND 0, __BOUNCE_CHALLENGE_SUBJ 0, __BOUNCE_NDR_SUBJ_EXEMPT 0, __CD 0, __CT 0, __CTE 0, __CTYPE_HAS_BOUNDARY 0, __CTYPE_MULTIPART 0, __CTYPE_MULTIPART_MIXED 0, __FORWARDED_MSG 0, __HAS_FROM 0, __HAS_MSGID 0, __IN_REP_TO 0, __MIME_TEXT_ONLY 0, __MIME_VERSION 0, __SANE_MSGID 0, __SUBJ_ALPHA_NEGATE 0, __TO_MALFORMED_2 0, __TO_NO_NAME 0, __USER_AGENT 0' X-LSpam-Score: -1.1 (-) X-LSpam-Report: No, score=-1.1 required=5.0 tests=BAYES_00=-1.9, RDNS_NONE=0.793 autolearn=no Subject: Re: [vdr] Trouble with softdevice -vo dfb:mgatv OSD with vdr 2.0.4 X-BeenThere: vdr@linuxtv.org X-Mailman-Version: 2.1.13 Precedence: list Reply-To: VDR Mailing List List-Id: VDR Mailing List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: vdr-bounces@linuxtv.org Errors-To: vdr-bounces@linuxtv.org 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(pm->Data()) + + pm->DirtyDrawPort().X() + + pm->DirtyDrawPort().Y() * pm->DrawPort().Width(); for (int y=y1; yData(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 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 -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; }