[vdr-plugin-softhddevice] 02/08: Imported Upstream version 0.6.0+git20151102

Tobias Grimm tiber-guest at moszumanska.debian.org
Fri Jan 8 23:33:39 UTC 2016


This is an automated email from the git hooks/post-receive script.

tiber-guest pushed a commit to branch master
in repository vdr-plugin-softhddevice.

commit 94684c0cfc49a41c289fe0ee5612a81c62fa4de1
Author: Tobias Grimm <etobi at debian.org>
Date:   Mon Nov 2 21:55:23 2015 +0100

    Imported Upstream version 0.6.0+git20151102
---
 ChangeLog        |  24 ++++
 Makefile         |   8 +-
 codec.c          |  49 +++++++-
 codec.h          |   9 +-
 po/de_DE.po      |   9 +-
 softhddev.c      |  19 ++-
 softhddev.h      |   5 +-
 softhddevice.cpp | 187 ++++++++++++++++++++++++----
 video.c          | 363 +++++++++++++++++++++++++++++++++++++++----------------
 video.h          |  12 +-
 10 files changed, 534 insertions(+), 151 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 679636b..c09fb55 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,30 @@
 User johns
 Date:
 
+    Added VDPAU multi decoder loop changes to VA-API code.
+    Reenabled VA-API auto detection.
+    Check and enforce USE_PIP is defined, for new code.
+    Fix comment spelling.
+    Disabled old code before removement.
+    Handle change of audio ac3 downmix direct.
+    Speedup queuing output surface, when decoder buffers are full.
+    Fix bug: info shows wrong decoded video surfaces.
+    Calculate queued output surfaces and show them in info message.
+    Add support for new API of vdr 2.3.1.
+    Fix bug: EnableDPMSatBlackScreen only available with USE_SCREENSAVER.
+    - H264_EOS_TRICKSPEED and USE_MPEG_COMPLETE enabled as default.
+
+User 	master_red
+Date:	Mon Aug 10 15:29:33 CEST 2015
+
+    Configurable enable DPMS, while black screen is displayed.
+
+User johns
+Date:	Tue Jun 30 10:12:09 CET 2015
+
+    Fix bug: wrong and crash, if vdr draws pixmaps outside OSD.
+    Fix bug: wrong version number check for av_frame_alloc(), ...
+    Workaround for ffmpeg 2.6 artifacts.
     Fix bug: brightness and .. are calculated wrong.
     Add automatic frame rate detection for older ffmpeg versions.
     Fix bug: destroyed vdpau surfaces still used in queue.
diff --git a/Makefile b/Makefile
index eea795b..2a41981 100644
--- a/Makefile
+++ b/Makefile
@@ -18,9 +18,9 @@ OSS ?= 1
     # support VDPAU video output module
 VDPAU ?= $(shell pkg-config --exists vdpau && echo 1)
     # support VA-API video output module (deprecated)
-#VAAPI ?= $(shell pkg-config --exists libva && echo 1)
+VAAPI ?= $(shell pkg-config --exists libva && echo 1)
     # support glx output
-#OPENGL ?= $(shell pkg-config --exists gl glu && echo 1)
+OPENGL ?= $(shell pkg-config --exists gl glu && echo 1)
     # screensaver disable/enable
 SCREENSAVER ?= 1
     # use ffmpeg libswresample
@@ -38,8 +38,8 @@ CONFIG += -DUSE_PIP			# PIP support
 #CONFIG += -DHAVE_PTHREAD_NAME		# supports new pthread_setname_np
 #CONFIG += -DNO_TS_AUDIO		# disable ts audio parser
 #CONFIG += -DUSE_TS_VIDEO		# build new ts video parser
-#CONFIG += -DUSE_MPEG_COMPLETE		# support only complete mpeg packets
-#CONFIG += -DH264_EOS_TRICKSPEED	# insert seq end packets for trickspeed
+CONFIG += -DUSE_MPEG_COMPLETE		# support only complete mpeg packets
+CONFIG += -DH264_EOS_TRICKSPEED		# insert seq end packets for trickspeed
 #CONDIF += -DDUMP_TRICKSPEED		# dump trickspeed packets
 #CONFIG += -DUSE_BITMAP			# VDPAU, use bitmap surface for OSD
 CONFIG += -DUSE_VDR_SPU			# use VDR SPU decoder.
diff --git a/codec.c b/codec.c
index 10011c3..35ef61c 100644
--- a/codec.c
+++ b/codec.c
@@ -1,7 +1,7 @@
 ///
 ///	@file codec.c	@brief Codec functions
 ///
-///	Copyright (c) 2009 - 2014 by Johns.  All Rights Reserved.
+///	Copyright (c) 2009 - 2015 by Johns.  All Rights Reserved.
 ///
 ///	Contributor(s):
 ///
@@ -94,6 +94,16 @@
 #include "codec.h"
 
 //----------------------------------------------------------------------------
+
+    // correct is AV_VERSION_INT(56,35,101) but some gentoo i* think
+    // they must change it.
+#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56,26,100)
+    /// ffmpeg 2.6 started to show artifacts after channel switch
+    /// to SDTV channels
+#define FFMPEG_WORKAROUND_ARTIFACTS	1
+#endif
+
+//----------------------------------------------------------------------------
 //	Global
 //----------------------------------------------------------------------------
 
@@ -105,6 +115,9 @@
       ///
 static pthread_mutex_t CodecLockMutex;
 
+    /// Flag prefer fast channel switch
+char CodecUsePossibleDefectFrames;
+
 //----------------------------------------------------------------------------
 //	Video
 //----------------------------------------------------------------------------
@@ -126,6 +139,9 @@ struct _video_decoder_
     int GetFormatDone;			///< flag get format called!
     AVCodec *VideoCodec;		///< video codec
     AVCodecContext *VideoCtx;		///< video codec context
+#ifdef FFMPEG_WORKAROUND_ARTIFACTS
+    int FirstKeyFrame;			///< flag first frame
+#endif
     AVFrame *Frame;			///< decoded video frame
 };
 
@@ -525,6 +541,9 @@ void CodecVideoOpen(VideoDecoder * decoder, const char *name, int codec_id)
     }
     // reset buggy ffmpeg/libav flag
     decoder->GetFormatDone = 0;
+#ifdef FFMPEG_WORKAROUND_ARTIFACTS
+    decoder->FirstKeyFrame = 1;
+#endif
 }
 
 /**
@@ -611,8 +630,22 @@ void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt)
     }
 
     if (got_frame) {			// frame completed
+#ifdef FFMPEG_WORKAROUND_ARTIFACTS
+	if (!CodecUsePossibleDefectFrames && decoder->FirstKeyFrame) {
+	    decoder->FirstKeyFrame++;
+	    if (frame->key_frame) {
+		Debug(3, "codec: key frame after %d frames\n",
+		    decoder->FirstKeyFrame);
+		decoder->FirstKeyFrame = 0;
+	    }
+	} else {
+	    //DisplayPts(video_ctx, frame);
+	    VideoRenderFrame(decoder->HwDecoder, video_ctx, frame);
+	}
+#else
 	//DisplayPts(video_ctx, frame);
 	VideoRenderFrame(decoder->HwDecoder, video_ctx, frame);
+#endif
     } else {
 	// some frames are needed for references, interlaced frames ...
 	// could happen with h264 dvb streams, just drop data.
@@ -681,7 +714,7 @@ struct _audio_decoder_
     int HwSampleRate;			///< hw sample rate
     int HwChannels;			///< hw channels
 
-#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(58,28,1)
+#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56,28,1)
     AVFrame *Frame;			///< decoded audio frame buffer
 #endif
 
@@ -761,7 +794,7 @@ AudioDecoder *CodecAudioNewDecoder(void)
     if (!(audio_decoder = calloc(1, sizeof(*audio_decoder)))) {
 	Fatal(_("codec: can't allocate audio decoder\n"));
     }
-#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(58,28,1)
+#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56,28,1)
     if (!(audio_decoder->Frame = av_frame_alloc())) {
 	Fatal(_("codec: can't allocate audio decoder frame buffer\n"));
     }
@@ -777,7 +810,7 @@ AudioDecoder *CodecAudioNewDecoder(void)
 */
 void CodecAudioDelDecoder(AudioDecoder * decoder)
 {
-#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(58,28,1)
+#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56,28,1)
     av_frame_free(&decoder->Frame);	// callee does checks
 #endif
     free(decoder);
@@ -1604,6 +1637,7 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
 */
 static void CodecAudioSetClock(AudioDecoder * audio_decoder, int64_t pts)
 {
+#ifdef USE_AUDIO_DRIFT_CORRECTION
     struct timespec nowtime;
     int64_t delay;
     int64_t tim_diff;
@@ -1718,6 +1752,9 @@ static void CodecAudioSetClock(AudioDecoder * audio_decoder, int64_t pts)
 		audio_decoder->DriftCorr, drift * 1000 / 90, corr);
 	}
     }
+#else
+    AudioSetClock(pts);
+#endif
 }
 
 /**
@@ -1803,7 +1840,7 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
 {
     AVCodecContext *audio_ctx;
 
-#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58,28,1)
+#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(56,28,1)
     AVFrame frame[1];
 #else
     AVFrame *frame;
@@ -1816,7 +1853,7 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
     // FIXME: don't need to decode pass-through codecs
 
     // new AVFrame API
-#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58,28,1)
+#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(56,28,1)
     avcodec_get_frame_defaults(frame);
 #else
     frame = audio_decoder->Frame;
diff --git a/codec.h b/codec.h
index 995573a..eccaf00 100644
--- a/codec.h
+++ b/codec.h
@@ -1,7 +1,7 @@
 ///
 ///	@file codec.h	@brief Codec module headerfile
 ///
-///	Copyright (c) 2009 - 2013 by Johns.  All Rights Reserved.
+///	Copyright (c) 2009 - 2013, 2015 by Johns.  All Rights Reserved.
 ///
 ///	Contributor(s):
 ///
@@ -44,6 +44,13 @@ typedef struct _video_decoder_ VideoDecoder;
 typedef struct _audio_decoder_ AudioDecoder;
 
 //----------------------------------------------------------------------------
+//	Variables
+//----------------------------------------------------------------------------
+
+    /// Flag prefer fast xhannel switch
+extern char CodecUsePossibleDefectFrames;
+
+//----------------------------------------------------------------------------
 //	Prototypes
 //----------------------------------------------------------------------------
 
diff --git a/po/de_DE.po b/po/de_DE.po
index 68812a4..a0a32c7 100644
--- a/po/de_DE.po
+++ b/po/de_DE.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR \n"
 "Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2014-10-31 12:36+0100\n"
+"POT-Creation-Date: 2015-09-30 10:48+0200\n"
 "PO-Revision-Date: blabla\n"
 "Last-Translator: blabla\n"
 "Language-Team: blabla\n"
@@ -501,6 +501,9 @@ msgstr "Unterbrechen stoppt X11"
 msgid "Video"
 msgstr "Video"
 
+msgid "Enable Screensaver(DPMS) at black screen"
+msgstr "Bildschirmschoner(DPMS) bei schwarzen Bild  aktivieren"
+
 msgid "Video background color (RGB)"
 msgstr "Video Hintergrundfrabe (RGB)"
 
@@ -1325,6 +1328,10 @@ msgid "video/vdpau: can't render mixer: %s\n"
 msgstr ""
 
 #, c-format
+msgid "video/vdpau: can't query status: %s\n"
+msgstr ""
+
+#, c-format
 msgid "video/vdpau: can't block queue: %s\n"
 msgstr ""
 
diff --git a/softhddev.c b/softhddev.c
index 5afe3b5..bc0a3a4 100644
--- a/softhddev.c
+++ b/softhddev.c
@@ -1,7 +1,7 @@
 ///
 ///	@file softhddev.c	@brief A software HD device plugin for VDR.
 ///
-///	Copyright (c) 2011 - 2014 by Johns.  All Rights Reserved.
+///	Copyright (c) 2011 - 2015 by Johns.  All Rights Reserved.
 ///
 ///	Contributor(s):
 ///
@@ -2866,17 +2866,21 @@ void OsdClose(void)
 /**
 **	Draw an OSD pixmap.
 **
+**	@param xi	x-coordinate in argb image
+**	@param yi	y-coordinate in argb image
+**	@paran height	height in pixel in argb image
+**	@paran width	width in pixel in argb image
+**	@param pitch	pitch of argb image
+**	@param argb	32bit ARGB image data
 **	@param x	x-coordinate on screen of argb image
 **	@param y	y-coordinate on screen of argb image
-**	@paran height	height in pixel of argb image
-**	@paran width	width in pixel of argb image
-**	@param argb	height * width 32bit ARGB image data
 */
-void OsdDrawARGB(int x, int y, int height, int width, const uint8_t * argb)
+void OsdDrawARGB(int xi, int yi, int height, int width, int pitch,
+    const uint8_t * argb, int x, int y)
 {
     // wakeup display for showing remote learning dialog
     VideoDisplayWakeup();
-    VideoOsdDrawARGB(x, y, height, width, argb);
+    VideoOsdDrawARGB(xi, yi, height, width, pitch, argb, x, y);
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -2905,6 +2909,7 @@ const char *CommandLineHelp(void)
 	"\talsa-no-close-open\tdisable close open to fix alsa no sound bug\n"
 	"\talsa-close-open-delay\tenable close open delay to fix no sound bug\n"
 	"\tignore-repeat-pict\tdisable repeat pict message\n"
+	"\tuse-possible-defect-frames prefer faster channel switch\n"
 	"  -D\t\tstart in detached mode\n";
 }
 
@@ -2986,6 +2991,8 @@ int ProcessArgs(int argc, char *const argv[])
 		    AudioAlsaCloseOpenDelay = 1;
 		} else if (!strcasecmp("ignore-repeat-pict", optarg)) {
 		    VideoIgnoreRepeatPict = 1;
+		} else if (!strcasecmp("use-possible-defect-frames", optarg)) {
+		    CodecUsePossibleDefectFrames = 1;
 		} else {
 		    fprintf(stderr, _("Workaround '%s' unsupported\n"),
 			optarg);
diff --git a/softhddev.h b/softhddev.h
index a793503..efb2e25 100644
--- a/softhddev.h
+++ b/softhddev.h
@@ -1,7 +1,7 @@
 ///
 ///	@file softhddev.h	@brief software HD device plugin header file.
 ///
-///	Copyright (c) 2011 - 2014 by Johns.  All Rights Reserved.
+///	Copyright (c) 2011 - 2015 by Johns.  All Rights Reserved.
 ///
 ///	Contributor(s):
 ///
@@ -34,7 +34,8 @@ extern "C"
     /// C plugin close osd
     extern void OsdClose(void);
     /// C plugin draw osd pixmap
-    extern void OsdDrawARGB(int, int, int, int, const uint8_t *);
+    extern void OsdDrawARGB(int, int, int, int, int, const uint8_t *, int,
+	int);
 
     /// C plugin play audio packet
     extern int PlayAudio(const uint8_t *, int, uint8_t);
diff --git a/softhddevice.cpp b/softhddevice.cpp
index e933955..70994d7 100644
--- a/softhddevice.cpp
+++ b/softhddevice.cpp
@@ -1,7 +1,7 @@
 ///
 ///	@file softhddevice.cpp	@brief A software HD device plugin for VDR.
 ///
-///	Copyright (c) 2011 - 2013 by Johns.  All Rights Reserved.
+///	Copyright (c) 2011 - 2015 by Johns.  All Rights Reserved.
 ///
 ///	Contributor(s):
 ///
@@ -47,6 +47,13 @@ extern "C"
 #include "codec.h"
 }
 
+#if APIVERSNUM >= 20301
+#define MURKS ->
+#else
+#define MURKS .
+#define LOCK_CHANNELS_READ	do { } while (0)
+#endif
+
 //////////////////////////////////////////////////////////////////////////////
 
     /// vdr-plugin version number.
@@ -165,6 +172,10 @@ static int ConfigPipAltVideoWidth;	///< config pip alt. video width in %
 static int ConfigPipAltVideoHeight = 50;	///< config pip alt. video height in %
 #endif
 
+#ifdef USE_SCREENSAVER
+static char ConfigEnableDPMSatBlackScreen;	///< Enable DPMS(Screensaver) while displaying black screen(radio)
+#endif
+
 static volatile int DoMakePrimary;	///< switch primary device to this
 
 #define SUSPEND_EXTERNAL	-1	///< play external suspend mode
@@ -431,6 +442,8 @@ void cSoftOsd::Flush(void)
 	// draw all bitmaps
 	for (i = 0; (bitmap = GetBitmap(i)); ++i) {
 	    uint8_t *argb;
+	    int xs;
+	    int ys;
 	    int x;
 	    int y;
 	    int w;
@@ -449,22 +462,52 @@ void cSoftOsd::Flush(void)
 	    } else if (!bitmap->Dirty(x1, y1, x2, y2)) {
 		continue;		// nothing dirty continue
 	    }
-	    // convert and upload only dirty areas
+	    // convert and upload only visible dirty areas
+	    xs = bitmap->X0() + Left();
+	    ys = bitmap->Y0() + Top();
+	    // FIXME: negtative position bitmaps
 	    w = x2 - x1 + 1;
 	    h = y2 - y1 + 1;
+	    // clip to screen
 	    if (1) {			// just for the case it makes trouble
 		int width;
 		int height;
 		double video_aspect;
 
+		if (xs < 0) {
+		    if (xs + x1 < 0) {
+			x1 -= xs + x1;
+			w += xs + x1;
+			if (w <= 0) {
+			    continue;
+			}
+		    }
+		    xs = 0;
+		}
+		if (ys < 0) {
+		    if (ys + y1 < 0) {
+			y1 -= ys + y1;
+			h += ys + y1;
+			if (h <= 0) {
+			    continue;
+			}
+		    }
+		    ys = 0;
+		}
 		::GetOsdSize(&width, &height, &video_aspect);
-		if (w > width) {
-		    w = width;
-		    x2 = x1 + width - 1;
+		if (w > width - xs - x1) {
+		    w = width - xs - x1;
+		    if (w <= 0) {
+			continue;
+		    }
+		    x2 = x1 + w - 1;
 		}
-		if (h > height) {
-		    h = height;
-		    y2 = y1 + height - 1;
+		if (h > height - ys - y1) {
+		    h = height - ys - y1;
+		    if (h <= 0) {
+			continue;
+		    }
+		    y2 = y1 + h - 1;
 		}
 	    }
 #ifdef DEBUG
@@ -482,10 +525,10 @@ void cSoftOsd::Flush(void)
 	    }
 #ifdef OSD_DEBUG
 	    dsyslog("[softhddev]%s: draw %dx%d%+d%+d bm\n", __FUNCTION__, w, h,
-		Left() + bitmap->X0() + x1, Top() + bitmap->Y0() + y1);
+		xs + x1, ys + y1);
 #endif
-	    OsdDrawARGB(Left() + bitmap->X0() + x1, Top() + bitmap->Y0() + y1,
-		w, h, argb);
+	    OsdDrawARGB(0, 0, w, h, w * sizeof(uint32_t), argb, xs + x1,
+		ys + y1);
 
 	    bitmap->Clean();
 	    // FIXME: reuse argb
@@ -497,21 +540,76 @@ void cSoftOsd::Flush(void)
 
     LOCK_PIXMAPS;
     while ((pm = (dynamic_cast < cPixmapMemory * >(RenderPixmaps())))) {
+	int xp;
+	int yp;
+	int stride;
 	int x;
 	int y;
 	int w;
 	int h;
 
-	x = Left() + pm->ViewPort().X();
-	y = Top() + pm->ViewPort().Y();
+	x = pm->ViewPort().X();
+	y = pm->ViewPort().Y();
 	w = pm->ViewPort().Width();
 	h = pm->ViewPort().Height();
+	stride = w * sizeof(tColor);
+
+	// clip to osd
+	xp = 0;
+	if (x < 0) {
+	    xp = -x;
+	    w -= xp;
+	    x = 0;
+	}
+
+	yp = 0;
+	if (y < 0) {
+	    yp = -y;
+	    h -= yp;
+	    y = 0;
+	}
 
+	if (w > Width() - x) {
+	    w = Width() - x;
+	}
+	if (h > Height() - y) {
+	    h = Height() - y;
+	}
+
+	x += Left();
+	y += Top();
+
+	// clip to screen
+	if (1) {			// just for the case it makes trouble
+	    // and it can happen!
+	    int width;
+	    int height;
+	    double video_aspect;
+
+	    if (x < 0) {
+		w += x;
+		xp += -x;
+		x = 0;
+	    }
+	    if (y < 0) {
+		h += y;
+		yp += -y;
+		y = 0;
+	    }
+
+	    ::GetOsdSize(&width, &height, &video_aspect);
+	    if (w > width - x) {
+		w = width - x;
+	    }
+	    if (h > height - y) {
+		h = height - y;
+	    }
+	}
 #ifdef OSD_DEBUG
-	dsyslog("[softhddev]%s: draw %dx%d%+d%+d %p\n", __FUNCTION__, w, h, x,
-	    y, pm->Data());
+	dsyslog("[softhddev]%s: draw %dx%d%+d%+d*%d -> %+d%+d %p\n",
+	    __FUNCTION__, w, h, xp, yp, stride, x, y, pm->Data());
 #endif
-	OsdDrawARGB(x, y, w, h, pm->Data());
+	OsdDrawARGB(xp, yp, w, h, stride, pm->Data(), x, y);
 
 #if APIVERSNUM >= 20110
 	DestroyPixmap(pm);
@@ -677,6 +775,9 @@ class cMenuSetupSoft:public cMenuSetupPage
     int PipAltVideoHeight;
 #endif
 
+#ifdef USE_SCREENSAVER
+    int EnableDPMSatBlackScreen;
+#endif
     /// @}
   private:
      inline cOsdItem * CollapsedItem(const char *, int &, const char * = NULL);
@@ -795,6 +896,11 @@ void cMenuSetupSoft::Create(void)
     //
     Add(CollapsedItem(tr("Video"), Video));
     if (Video) {
+#ifdef USE_SCREENSAVER
+	Add(new
+	    cMenuEditBoolItem(tr("Enable Screensaver(DPMS) at black screen"),
+		&EnableDPMSatBlackScreen, trVDR("no"), trVDR("yes")));
+#endif
 	Add(new cMenuEditStraItem(trVDR("4:3 video display format"),
 		&Video4to3DisplayFormat, 3, video_display_formats_4_3));
 	Add(new cMenuEditStraItem(trVDR("16:9+other video display format"),
@@ -1111,6 +1217,11 @@ cMenuSetupSoft::cMenuSetupSoft(void)
     PipAltVideoWidth = ConfigPipAltVideoWidth;
     PipAltVideoHeight = ConfigPipAltVideoHeight;
 #endif
+
+#ifdef USE_SCREENSAVER
+    EnableDPMSatBlackScreen = ConfigEnableDPMSatBlackScreen;
+#endif
+
     Create();
 }
 
@@ -1225,6 +1336,12 @@ void cMenuSetupSoft::Store(void)
     VideoSetAudioDelay(ConfigVideoAudioDelay);
     SetupStore("AudioDrift", ConfigAudioDrift = AudioDrift);
     CodecSetAudioDrift(ConfigAudioDrift);
+
+    // FIXME: can handle more audio state changes here
+    // downmix changed reset audio, to get change direct
+    if (ConfigAudioDownmix != AudioDownmix) {
+	ResetChannelId();
+    }
     ConfigAudioPassthrough = (AudioPassthroughPCM ? CodecPCM : 0)
 	| (AudioPassthroughAC3 ? CodecAC3 : 0)
 	| (AudioPassthroughEAC3 ? CodecEAC3 : 0);
@@ -1275,6 +1392,12 @@ void cMenuSetupSoft::Store(void)
     SetupStore("pip.Alt.VideoHeight", ConfigPipAltVideoHeight =
 	PipAltVideoHeight);
 #endif
+
+#ifdef USE_SCREENSAVER
+    SetupStore("EnableDPMSatBlackScreen", ConfigEnableDPMSatBlackScreen =
+	EnableDPMSatBlackScreen);
+    SetDPMSatBlackScreen(ConfigEnableDPMSatBlackScreen);
+#endif
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -1390,7 +1513,11 @@ class cSoftReceiver:public cReceiver
 {
   protected:
     virtual void Activate(bool);
+#if APIVERSNUM >= 20301
+    virtual void Receive(const uchar *, int);
+#else
     virtual void Receive(uchar *, int);
+#endif
   public:
      cSoftReceiver(const cChannel *);	///< receiver constructor
      virtual ~ cSoftReceiver();		///< receiver destructor
@@ -1524,7 +1651,11 @@ static void PipPesParse(const uint8_t * data, int size, int is_start)
 **	@param data	ts packet
 **	@param size	size (#TS_PACKET_SIZE=188) of tes packet
 */
+#if APIVERSNUM >= 20301
+void cSoftReceiver::Receive(const uchar * data, int size)
+#else
 void cSoftReceiver::Receive(uchar * data, int size)
+#endif
 {
     const uint8_t *p;
 
@@ -1616,7 +1747,8 @@ static void NewPip(int channel_nr)
     if (!channel_nr) {
 	channel_nr = cDevice::CurrentChannel();
     }
-    if (channel_nr && (channel = Channels.GetByNumber(channel_nr))
+    LOCK_CHANNELS_READ;
+    if (channel_nr && (channel = Channels MURKS GetByNumber(channel_nr))
 	&& (device = cDevice::GetDevice(channel, 0, false, false))) {
 
 	DelPip();
@@ -1662,14 +1794,16 @@ static void PipNextAvailableChannel(int direction)
 
     DelPip();				// disable PIP to free the device
 
+    LOCK_CHANNELS_READ;
     while (channel) {
 	bool ndr;
 	cDevice *device;
 
-	channel = direction > 0 ? Channels.Next(channel)
-	    : Channels.Prev(channel);
+	channel = direction > 0 ? Channels MURKS Next(channel)
+	    : Channels MURKS Prev(channel);
 	if (!channel && Setup.ChannelsWrap) {
-	    channel = direction > 0 ? Channels.First() : Channels.Last();
+	    channel =
+		direction > 0 ? Channels MURKS First() : Channels MURKS Last();
 	}
 	if (channel && !channel->GroupSep()
 	    && (device = cDevice::GetDevice(channel, 0, false, true))
@@ -1698,7 +1832,9 @@ static void SwapPipChannels(void)
     NewPip(0);
 
     if (channel) {
-	Channels.SwitchTo(channel->Number());
+	LOCK_CHANNELS_READ;
+
+	Channels MURKS SwitchTo(channel->Number());
     }
 }
 
@@ -3154,6 +3290,15 @@ bool cPluginSoftHdDevice::SetupParse(const char *name, const char *value)
 	return true;
     }
 #endif
+
+#ifdef USE_SCREENSAVER
+    if (!strcasecmp(name, "EnableDPMSatBlackScreen")) {
+	ConfigEnableDPMSatBlackScreen = atoi(value);
+	SetDPMSatBlackScreen(ConfigEnableDPMSatBlackScreen);
+	return true;
+    }
+#endif
+
     return false;
 }
 
diff --git a/video.c b/video.c
index 08d0bca..d9534b4 100644
--- a/video.c
+++ b/video.c
@@ -1,7 +1,7 @@
 ///
 ///	@file video.c	@brief Video module
 ///
-///	Copyright (c) 2009 - 2014 by Johns.  All Rights Reserved.
+///	Copyright (c) 2009 - 2015 by Johns.  All Rights Reserved.
 ///
 ///	Contributor(s):
 ///
@@ -280,7 +280,8 @@ typedef struct _video_module_
 
     void (*const OsdClear) (void);	///< clear OSD
     /// draw OSD ARGB area
-    void (*const OsdDrawARGB) (int, int, int, int, const uint8_t *);
+    void (*const OsdDrawARGB) (int, int, int, int, int, const uint8_t *, int,
+	int);
     void (*const OsdInit) (int, int);	///< initialize OSD
     void (*const OsdExit) (void);	///< cleanup OSD
 
@@ -429,6 +430,11 @@ static int OsdDirtyHeight;		///< osd dirty area height
 
 static int64_t VideoDeltaPTS;		///< FIXME: fix pts
 
+#ifdef USE_SCREENSAVER
+static char DPMSDisabled;		///< flag we have disabled dpms
+static char EnableDPMSatBlackScreen;	///< flag we should enable dpms at black screen
+#endif
+
 //----------------------------------------------------------------------------
 //	Common Functions
 //----------------------------------------------------------------------------
@@ -437,6 +443,13 @@ static void VideoThreadLock(void);	///< lock video thread
 static void VideoThreadUnlock(void);	///< unlock video thread
 static void VideoThreadExit(void);	///< exit/kill video thread
 
+#ifdef USE_SCREENSAVER
+static void X11SuspendScreenSaver(xcb_connection_t *, int);
+static int X11HaveDPMS(xcb_connection_t *);
+static void X11DPMSReenable(xcb_connection_t *);
+static void X11DPMSDisable(xcb_connection_t *);
+#endif
+
 ///
 ///	Update video pts.
 ///
@@ -887,17 +900,22 @@ static void GlxOsdExit(void)
 ///
 ///	Upload ARGB image to texture.
 ///
-///	@param x	x coordinate of image in osd texture
-///	@param y	y coordinate of image in osd texture
-///	@param width	width of image
-///	@param height	height of image
-///	@param argb	argb image
+///	@param xi	x-coordinate in argb image
+///	@param yi	y-coordinate in argb image
+///	@paran height	height in pixel in argb image
+///	@paran width	width in pixel in argb image
+///	@param pitch	pitch of argb image
+///	@param argb	32bit ARGB image data
+///	@param x	x-coordinate on screen of argb image
+///	@param y	y-coordinate on screen of argb image
 ///
 ///	@note looked by caller
 ///
-static void GlxOsdDrawARGB(int x, int y, int width, int height,
-    const uint8_t * argb)
+static void GlxOsdDrawARGB(int xi, int yi, int width, int height, int pitch,
+    const uint8_t * argb, int x, int y)
 {
+    uint8_t *tmp;
+
 #ifdef DEBUG
     uint32_t start;
     uint32_t end;
@@ -918,9 +936,21 @@ static void GlxOsdDrawARGB(int x, int y, int width, int height,
 	Error(_("video/glx: can't make glx context current\n"));
 	return;
     }
-    GlxUploadOsdTexture(x, y, width, height, argb);
-    glXMakeCurrent(XlibDisplay, None, NULL);
+    // FIXME: faster way
+    tmp = malloc(width * height * 4);
+    if (tmp) {
+	int i;
+
+	for (i = 0; i < height; ++i) {
+	    memcpy(tmp + i * width * 4, argb + xi * 4 + (i + yi) * pitch,
+		width * 4);
+	}
 
+	GlxUploadOsdTexture(x, y, width, height, tmp);
+	glXMakeCurrent(XlibDisplay, None, NULL);
+
+	free(tmp);
+    }
 #ifdef DEBUG
     end = GetMsTicks();
 
@@ -1331,11 +1361,11 @@ static int AutoCropTolerance;		///< auto-crop tolerance
 ///
 ///	@param data	Y plane pixel data
 ///	@param length	number of pixel to check
-///	@param stride	offset of pixels
+///	@param pitch	offset of pixels
 ///
 ///	@note 8 pixel are checked at once, all values must be 8 aligned
 ///
-static int AutoCropIsBlackLineY(const uint8_t * data, int length, int stride)
+static int AutoCropIsBlackLineY(const uint8_t * data, int length, int pitch)
 {
     int n;
     int o;
@@ -1343,13 +1373,13 @@ static int AutoCropIsBlackLineY(const uint8_t * data, int length, int stride)
     const uint64_t *p;
 
 #ifdef DEBUG
-    if ((size_t) data & 0x7 || stride & 0x7) {
+    if ((size_t) data & 0x7 || pitch & 0x7) {
 	abort();
     }
 #endif
     p = (const uint64_t *)data;
     n = length;				// FIXME: can remove n
-    o = stride / 8;
+    o = pitch / 8;
 
     r = 0UL;
     while (--n >= 0) {
@@ -2422,7 +2452,6 @@ static int VaapiInit(const char *display_name)
 		&entrypoint_n)) {
 
 	    for (i = 0; i < entrypoint_n; i++) {
-		fprintf(stderr, "oops %d\n", i);
 		if (entrypoints[i] == VAEntrypointVideoProc) {
 		    Info("video/vaapi: supports video processing\n");
 		    VaapiVideoProcessing = 1;
@@ -4891,7 +4920,20 @@ static void VaapiDisplayFrame(void)
 	    decoder->LastSurface = decoder->BlackSurface;
 #endif
 	    VaapiMessage(3, "video/vaapi: black surface displayed\n");
+#ifdef USE_SCREENSAVER
+	    if (EnableDPMSatBlackScreen && DPMSDisabled) {
+		Debug(3, "Black surface, DPMS enabled");
+		X11DPMSReenable(Connection);
+		X11SuspendScreenSaver(Connection, 1);
+	    }
+#endif
 	    continue;
+#ifdef USE_SCREENSAVER
+	} else if (!DPMSDisabled) {	// always disable
+	    Debug(3, "DPMS disabled");
+	    X11DPMSDisable(Connection);
+	    X11SuspendScreenSaver(Connection, 0);
+#endif
 	}
 
 	surface = decoder->SurfacesRb[decoder->SurfaceRead];
@@ -5212,8 +5254,9 @@ static void VaapiSyncDecoder(VaapiDecoder * decoder)
 	    8888 ? ((video_clock - audio_clock) / 90) : 8888,
 	    AudioGetDelay() / 90, (int)VideoDeltaPTS / 90,
 	    VideoGetBuffers(decoder->Stream),
-	    (1 + decoder->Interlaced) * atomic_read(&decoder->SurfacesFilled)
-	    - decoder->SurfaceField);
+	    decoder->Interlaced ? (2 * atomic_read(&decoder->SurfacesFilled)
+		- decoder->SurfaceField)
+	    : atomic_read(&decoder->SurfacesFilled));
 	if (!(decoder->FramesDisplayed % (5 * 60 * 60))) {
 	    VaapiPrintFrames(decoder);
 	}
@@ -5262,8 +5305,22 @@ static void VaapiSyncRenderFrame(VaapiDecoder * decoder,
     }
 #endif
 
+#if 1
+#ifndef USE_PIP
+#error	"-DUSE_PIP or #define USE_PIP is needed,"
+#endif
     // if video output buffer is full, wait and display surface.
     // loop for interlace
+    if (atomic_read(&decoder->SurfacesFilled) >= VIDEO_SURFACES_MAX) {
+#ifdef DEBUG
+	Fatal("video/vdpau: this code part shouldn't be used\n");
+#else
+	Info("video/vdpau: this code part shouldn't be used\n");
+#endif
+	return;
+    }
+#else
+    // FIXME: this part code should be no longer be needed with new mpeg fix
     while (atomic_read(&decoder->SurfacesFilled) >= VIDEO_SURFACES_MAX - 1) {
 	struct timespec abstime;
 
@@ -5292,6 +5349,7 @@ static void VaapiSyncRenderFrame(VaapiDecoder * decoder,
 
 	VaapiSyncDisplayFrame();
     }
+#endif
 
     if (!decoder->Closing) {
 	VideoSetPts(&decoder->PTS, decoder->Interlaced, video_ctx, frame);
@@ -5334,49 +5392,66 @@ static void VaapiSetVideoMode(void)
 ///
 ///	Handle a va-api display.
 ///
-///	@todo FIXME: only a single decoder supported.
-///
 static void VaapiDisplayHandlerThread(void)
 {
+    int i;
     int err;
-    int filled;
+    int allfull;
+    int decoded;
     struct timespec nowtime;
     VaapiDecoder *decoder;
 
-    if (!(decoder = VaapiDecoders[0])) {	// no stream available
-	return;
-    }
-    //
-    // fill frame output ring buffer
-    //
-    filled = atomic_read(&decoder->SurfacesFilled);
-    if (filled < VIDEO_SURFACES_MAX - 1) {
-	// FIXME: hot polling
-	pthread_mutex_lock(&VideoLockMutex);
-	// fetch+decode or reopen
-	err = VideoDecodeInput(decoder->Stream);
-	pthread_mutex_unlock(&VideoLockMutex);
-    } else {
-	err = VideoPollInput(decoder->Stream);
-    }
-    if (err) {
-	// FIXME: sleep on wakeup
-	usleep(5 * 1000);		// nothing buffered
-	if (err == -1 && decoder->Closing) {
-	    decoder->Closing--;
-	    if (!decoder->Closing) {
-		Debug(3, "video/vaapi: closing eof\n");
-		decoder->Closing = -1;
+    allfull = 1;
+    decoded = 0;
+    pthread_mutex_lock(&VideoLockMutex);
+    for (i = 0; i < VaapiDecoderN; ++i) {
+	int filled;
+
+	decoder = VaapiDecoders[i];
+
+	//
+	// fill frame output ring buffer
+	//
+	filled = atomic_read(&decoder->SurfacesFilled);
+	if (filled < VIDEO_SURFACES_MAX) {
+	    // FIXME: hot polling
+	    // fetch+decode or reopen
+	    allfull = 0;
+	    err = VideoDecodeInput(decoder->Stream);
+	} else {
+	    err = VideoPollInput(decoder->Stream);
+	}
+	// decoder can be invalid here
+	if (err) {
+	    // nothing buffered?
+	    if (err == -1 && decoder->Closing) {
+		decoder->Closing--;
+		if (!decoder->Closing) {
+		    Debug(3, "video/vdpau: closing eof\n");
+		    decoder->Closing = -1;
+		}
 	    }
+	    continue;
 	}
+	decoded = 1;
     }
+    pthread_mutex_unlock(&VideoLockMutex);
 
-    clock_gettime(CLOCK_MONOTONIC, &nowtime);
-    // time for one frame over?
-    if ((nowtime.tv_sec - decoder->FrameTime.tv_sec)
-	* 1000 * 1000 * 1000 + (nowtime.tv_nsec - decoder->FrameTime.tv_nsec) <
-	15 * 1000 * 1000) {
-	return;
+    if (!decoded) {			// nothing decoded, sleep
+	// FIXME: sleep on wakeup
+	usleep(1 * 1000);
+    }
+    // all decoder buffers are full
+    // speed up filling display queue, wait on display queue empty
+    if (!allfull) {
+	clock_gettime(CLOCK_MONOTONIC, &nowtime);
+	// time for one frame over?
+	if ((nowtime.tv_sec -
+		VaapiDecoders[0]->FrameTime.tv_sec) * 1000 * 1000 * 1000 +
+	    (nowtime.tv_nsec - VaapiDecoders[0]->FrameTime.tv_nsec) <
+	    15 * 1000 * 1000) {
+	    return;
+	}
     }
 
     pthread_mutex_lock(&VideoLockMutex);
@@ -5438,16 +5513,19 @@ static void VaapiOsdClear(void)
 ///
 ///	Upload ARGB to subpicture image.
 ///
-///	@param x	x position of image in osd
-///	@param y	y position of image in osd
-///	@param width	width of image
-///	@param height	height of image
-///	@param argb	argb image
+///	@param xi	x-coordinate in argb image
+///	@param yi	y-coordinate in argb image
+///	@paran height	height in pixel in argb image
+///	@paran width	width in pixel in argb image
+///	@param pitch	pitch of argb image
+///	@param argb	32bit ARGB image data
+///	@param x	x-coordinate on screen of argb image
+///	@param y	y-coordinate on screen of argb image
 ///
 ///	@note looked by caller
 ///
-static void VaapiOsdDrawARGB(int x, int y, int width, int height,
-    const uint8_t * argb)
+static void VaapiOsdDrawARGB(int xi, int yi, int width, int height, int pitch,
+    const uint8_t * argb, int x, int y)
 {
 #ifdef DEBUG
     uint32_t start;
@@ -5474,7 +5552,7 @@ static void VaapiOsdDrawARGB(int x, int y, int width, int height,
     // copy argb to image
     for (o = 0; o < height; ++o) {
 	memcpy(image_buffer + (x + (y + o) * VaOsdImage.width) * 4,
-	    argb + o * width * 4, width * 4);
+	    argb + xi * 4 + (o + yi) * pitch, width * 4);
     }
 
     if (vaUnmapBuffer(VaDisplay, VaOsdImage.buf) != VA_STATUS_SUCCESS) {
@@ -5816,6 +5894,7 @@ static VdpChromaType VdpauChromaType;	///< best video surface chroma format
     /// display surface ring buffer
 static VdpOutputSurface VdpauSurfacesRb[OUTPUT_SURFACES_MAX];
 static int VdpauSurfaceIndex;		///< current display surface
+static int VdpauSurfaceQueued;		///< number of display surfaces queued
 static struct timespec VdpauFrameTime;	///< time of last display
 
 #ifdef USE_BITMAP
@@ -8540,7 +8619,29 @@ static void VdpauDisplayFrame(void)
 	}
     }
     //
-    //	wait for surface visible (blocks max ~5ms)
+    //	check how many surfaces are queued
+    //
+    VdpauSurfaceQueued = 0;
+    for (i = 0; i < OUTPUT_SURFACES_MAX; ++i) {
+	VdpPresentationQueueStatus qstatus;
+
+	status =
+	    VdpauPresentationQueueQuerySurfaceStatus(VdpauQueue,
+	    VdpauSurfacesRb[(VdpauSurfaceIndex + i) % OUTPUT_SURFACES_MAX],
+	    &qstatus, &first_time);
+	if (status != VDP_STATUS_OK) {
+	    Error(_("video/vdpau: can't query status: %s\n"),
+		VdpauGetErrorString(status));
+	    break;
+	}
+	if (qstatus == VDP_PRESENTATION_QUEUE_STATUS_IDLE) {
+	    continue;
+	}
+	// STATUS_QUEUED | STATUS_VISIBLE
+	VdpauSurfaceQueued++;
+    }
+    //
+    //	wait for surface no longer visible (blocks max ~5ms)
     //
     status =
 	VdpauPresentationQueueBlockUntilSurfaceIdle(VdpauQueue,
@@ -8584,8 +8685,21 @@ static void VdpauDisplayFrame(void)
 		|| decoder->Closing < -300) {
 		VdpauBlackSurface(decoder);
 		VdpauMessage(3, "video/vdpau: black surface displayed\n");
+#ifdef USE_SCREENSAVER
+		if (EnableDPMSatBlackScreen && DPMSDisabled) {
+		    VdpauMessage(3, "Black surface, DPMS enabled\n");
+		    X11DPMSReenable(Connection);
+		    X11SuspendScreenSaver(Connection, 1);
+		}
+#endif
 	    }
 	    continue;
+#ifdef USE_SCREENSAVER
+	} else if (!DPMSDisabled) {	// always disable
+	    VdpauMessage(3, "DPMS disabled\n");
+	    X11DPMSDisable(Connection);
+	    X11SuspendScreenSaver(Connection, 0);
+#endif
 	}
 
 	VdpauMixVideo(decoder, i);
@@ -8853,14 +8967,15 @@ static void VdpauSyncDecoder(VdpauDecoder * decoder)
 	if (!err) {
 	    VdpauMessage(0, NULL);
 	}
-	Info("video: %s%+5" PRId64 " %4" PRId64 " %3d/\\ms %3d%+d v-buf\n",
+	Info("video: %s%+5" PRId64 " %4" PRId64 " %3d/\\ms %3d%+d%+d v-buf\n",
 	    Timestamp2String(video_clock),
 	    abs((video_clock - audio_clock) / 90) <
 	    8888 ? ((video_clock - audio_clock) / 90) : 8888,
 	    AudioGetDelay() / 90, (int)VideoDeltaPTS / 90,
 	    VideoGetBuffers(decoder->Stream),
-	    (1 + decoder->Interlaced) * atomic_read(&decoder->SurfacesFilled)
-	    - decoder->SurfaceField);
+	    decoder->Interlaced ? 2 * atomic_read(&decoder->SurfacesFilled)
+	    - decoder->SurfaceField : atomic_read(&decoder->SurfacesFilled),
+	    VdpauSurfaceQueued);
 	if (!(decoder->FramesDisplayed % (5 * 60 * 60))) {
 	    VdpauPrintFrames(decoder);
 	}
@@ -8920,16 +9035,23 @@ static void VdpauSyncRenderFrame(VdpauDecoder * decoder,
 	}
 	return;
     }
+#if 1
+#ifndef USE_PIP
+#error	"-DUSE_PIP or #define USE_PIP is needed,"
+#endif
     // if video output buffer is full, wait and display surface.
     // loop for interlace
-    // FIXME: wrong for multiple streams
-#ifdef DEBUG
     if (atomic_read(&decoder->SurfacesFilled) >= VIDEO_SURFACES_MAX) {
-	Debug(3, "video/vdpau: this code part shouldn't be used\n");
-    }
+#ifdef DEBUG
+	Fatal("video/vdpau: this code part shouldn't be used\n");
+#else
+	Info("video/vdpau: this code part shouldn't be used\n");
 #endif
-
-#if 1
+	return;
+    }
+#else
+    // FIXME: disabled for remove
+    // FIXME: wrong for multiple streams
     // FIXME: this part code should be no longer be needed with new mpeg fix
     while (atomic_read(&decoder->SurfacesFilled) >= VIDEO_SURFACES_MAX) {
 	struct timespec abstime;
@@ -9064,16 +9186,16 @@ static void VdpauSetVideoMode(void)
 ///
 ///	Handle a VDPAU display.
 ///
-///	@todo FIXME: only a single decoder supported.
-///
 static void VdpauDisplayHandlerThread(void)
 {
     int i;
     int err;
+    int allfull;
     int decoded;
     struct timespec nowtime;
     VdpauDecoder *decoder;
 
+    allfull = 1;
     decoded = 0;
     pthread_mutex_lock(&VideoLockMutex);
     for (i = 0; i < VdpauDecoderN; ++i) {
@@ -9088,6 +9210,7 @@ static void VdpauDisplayHandlerThread(void)
 	if (filled < VIDEO_SURFACES_MAX) {
 	    // FIXME: hot polling
 	    // fetch+decode or reopen
+	    allfull = 0;
 	    err = VideoDecodeInput(decoder->Stream);
 	} else {
 	    err = VideoPollInput(decoder->Stream);
@@ -9110,14 +9233,18 @@ static void VdpauDisplayHandlerThread(void)
 
     if (!decoded) {			// nothing decoded, sleep
 	// FIXME: sleep on wakeup
-	usleep(5 * 1000);
+	usleep(1 * 1000);
     }
-
-    clock_gettime(CLOCK_MONOTONIC, &nowtime);
-    // time for one frame over?
-    if ((nowtime.tv_sec - VdpauFrameTime.tv_sec) * 1000 * 1000 * 1000 +
-	(nowtime.tv_nsec - VdpauFrameTime.tv_nsec) < 15 * 1000 * 1000) {
-	return;
+    // all decoder buffers are full
+    // and display is not preempted
+    // speed up filling display queue, wait on display queue empty
+    if (!allfull || VdpauPreemption) {
+	clock_gettime(CLOCK_MONOTONIC, &nowtime);
+	// time for one frame over?
+	if ((nowtime.tv_sec - VdpauFrameTime.tv_sec) * 1000 * 1000 * 1000 +
+	    (nowtime.tv_nsec - VdpauFrameTime.tv_nsec) < 15 * 1000 * 1000) {
+	    return;
+	}
     }
 
     if (VdpauPreemption) {		// display preempted
@@ -9240,16 +9367,19 @@ static void VdpauOsdClear(void)
 ///
 ///	Upload ARGB to subpicture image.
 ///
-///	@param x	x position of image in osd
-///	@param y	y position of image in osd
-///	@param width	width of image
-///	@param height	height of image
-///	@param argb	argb image
+///	@param xi	x-coordinate in argb image
+///	@param yi	y-coordinate in argb image
+///	@paran height	height in pixel in argb image
+///	@paran width	width in pixel in argb image
+///	@param pitch	pitch of argb image
+///	@param argb	32bit ARGB image data
+///	@param x	x-coordinate on screen of argb image
+///	@param y	y-coordinate on screen of argb image
 ///
 ///	@note looked by caller
 ///
-static void VdpauOsdDrawARGB(int x, int y, int width, int height,
-    const uint8_t * argb)
+static void VdpauOsdDrawARGB(int xi, int yi, int width, int height, int pitch,
+    const uint8_t * argb, int x, int y)
 {
     VdpStatus status;
     void const *data[1];
@@ -9283,8 +9413,8 @@ static void VdpauOsdDrawARGB(int x, int y, int width, int height,
     dst_rect.y0 = y;
     dst_rect.x1 = dst_rect.x0 + width;
     dst_rect.y1 = dst_rect.y0 + height;
-    data[0] = argb;
-    pitches[0] = width * 4;
+    data[0] = argb + xi * 4 + yi * pitch;
+    pitches[0] = pitch;
 
 #ifdef USE_BITMAP
     status =
@@ -9499,20 +9629,26 @@ static void NoopOsdInit( __attribute__ ((unused))
 ///
 ///	Draw OSD ARGB image.
 ///
-///	@param x	x position of image in osd
-///	@param y	y position of image in osd
-///	@param width	width of image
-///	@param height	height of image
-///	@param argb	argb image
+///	@param xi	x-coordinate in argb image
+///	@param yi	y-coordinate in argb image
+///	@paran height	height in pixel in argb image
+///	@paran width	width in pixel in argb image
+///	@param pitch	pitch of argb image
+///	@param argb	32bit ARGB image data
+///	@param x	x-coordinate on screen of argb image
+///	@param y	y-coordinate on screen of argb image
 ///
 ///	@note looked by caller
 ///
 static void NoopOsdDrawARGB( __attribute__ ((unused))
-    int x, __attribute__ ((unused))
-    int y, __attribute__ ((unused))
+    int xi, __attribute__ ((unused))
+    int yi, __attribute__ ((unused))
     int width, __attribute__ ((unused))
     int height, __attribute__ ((unused))
-    const uint8_t * argb)
+    int pitch, __attribute__ ((unused))
+    const uint8_t * argb, __attribute__ ((unused))
+    int x, __attribute__ ((unused))
+    int y)
 {
 }
 
@@ -9631,14 +9767,17 @@ void VideoOsdClear(void)
 ///
 ///	Draw an OSD ARGB image.
 ///
-///	@param x	x position of image in osd
-///	@param y	y position of image in osd
-///	@param width	width of image
-///	@param height	height of image
-///	@param argb	argb image
+///	@param xi	x-coordinate in argb image
+///	@param yi	y-coordinate in argb image
+///	@paran height	height in pixel in argb image
+///	@paran width	width in pixel in argb image
+///	@param pitch	pitch of argb image
+///	@param argb	32bit ARGB image data
+///	@param x	x-coordinate on screen of argb image
+///	@param y	y-coordinate on screen of argb image
 ///
-void VideoOsdDrawARGB(int x, int y, int width, int height,
-    const uint8_t * argb)
+void VideoOsdDrawARGB(int xi, int yi, int width, int height, int pitch,
+    const uint8_t * argb, int x, int y)
 {
     VideoThreadLock();
     // update dirty area
@@ -9663,7 +9802,7 @@ void VideoOsdDrawARGB(int x, int y, int width, int height,
     Debug(4, "video: osd dirty %dx%d%+d%+d -> %dx%d%+d%+d\n", width, height, x,
 	y, OsdDirtyWidth, OsdDirtyHeight, OsdDirtyX, OsdDirtyY);
 
-    VideoUsedModule->OsdDrawARGB(x, y, width, height, argb);
+    VideoUsedModule->OsdDrawARGB(xi, yi, width, height, pitch, argb, x, y);
     OsdShown = 1;
 
     VideoThreadUnlock();
@@ -10057,8 +10196,10 @@ static const VideoModule *VideoModules[] = {
     &VaapiModule,
 #endif
 #ifdef USE_GLX
+#ifdef USE_VAAPI
     &VaapiGlxModule,			// FIXME: if working, prefer this
 #endif
+#endif
     &NoopModule
 };
 
@@ -10539,8 +10680,6 @@ void VideoGetVideoSize(VideoHwDecoder * hw_decoder, int *width, int *height,
 //	DPMS / Screensaver
 //----------------------------------------------------------------------------
 
-static char DPMSDisabled;		///< flag we have disabled dpms
-
 ///
 ///	Suspend X11 screen saver.
 ///
@@ -10631,11 +10770,11 @@ static void X11DPMSDisable(xcb_connection_t * connection)
 	if (reply) {
 	    if (reply->state) {
 		Debug(3, "video: dpms was enabled\n");
-		DPMSDisabled = 1;
 		xcb_dpms_disable(connection);	// monitor powersave off
 	    }
 	    free(reply);
 	}
+	DPMSDisabled = 1;
     }
 }
 
@@ -11271,6 +11410,18 @@ void VideoSetAutoCrop(int interval, int delay, int tolerance)
 }
 
 ///
+///	Set EnableDPMSatBlackScreen
+///
+///	Currently this only choose the driver.
+///
+void SetDPMSatBlackScreen(int enable)
+{
+#ifdef USE_SCREENSAVER
+    EnableDPMSatBlackScreen = enable;
+#endif
+}
+
+///
 ///	Raise video window.
 ///
 int VideoRaiseWindow(void)
diff --git a/video.h b/video.h
index 0587393..7b676db 100644
--- a/video.h
+++ b/video.h
@@ -1,7 +1,7 @@
 ///
 ///	@file video.h	@brief Video module header file
 ///
-///	Copyright (c) 2009 - 2013 by Johns.  All Rights Reserved.
+///	Copyright (c) 2009 - 2015 by Johns.  All Rights Reserved.
 ///
 ///	Contributor(s):
 ///
@@ -168,7 +168,8 @@ extern void VideoSetAutoCrop(int, int, int);
 extern void VideoOsdClear(void);
 
     /// Draw an OSD ARGB image.
-extern void VideoOsdDrawARGB(int, int, int, int, const uint8_t *);
+extern void VideoOsdDrawARGB(int, int, int, int, int, const uint8_t *, int,
+    int);
 
     /// Get OSD size.
 extern void VideoGetOsdSize(int *, int *);
@@ -221,7 +222,10 @@ extern int VideoDecodeInput(VideoStream *);
     /// Get number of input buffers.
 extern int VideoGetBuffers(const VideoStream *);
 
-       /// Raise the frontend window
-extern int VideoRaiseWindow();
+    /// Set DPMS at Blackscreen switch
+extern void SetDPMSatBlackScreen(int);
+
+    /// Raise the frontend window
+extern int VideoRaiseWindow(void);
 
 /// @}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-vdr-dvb/vdr-plugin-softhddevice.git



More information about the pkg-vdr-dvb-changes mailing list