[vdr-plugin-rpihddevice] 01/03: Imported Upstream version 1.0.3

Tobias Grimm tiber-guest at moszumanska.debian.org
Sun Apr 24 16:46:48 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-rpihddevice.

commit caaee665a1dd875c6ba297a1057c16648a30517c
Author: Tobias Grimm <git at e-tobi.net>
Date:   Sun Apr 24 18:40:51 2016 +0200

    Imported Upstream version 1.0.3
---
 HISTORY       |  29 ++++++++++++++++
 Makefile      |   5 +++
 README        |   5 +++
 audio.c       |  82 ++++++++++++++++++++++++++++++--------------
 audio.h       |  17 ++++++++--
 display.c     | 107 ++++++++++++++++++++++++++++++++++++++++------------------
 display.h     |  43 ++++++++++++++---------
 omx.c         |  63 +++++++++++++++++++++++++++-------
 omx.h         |  22 +++++++++---
 omxdevice.c   |  79 +++++++++++++++++++++++++++++--------------
 omxdevice.h   |  26 +++++++++++---
 ovgosd.c      |  55 +++++++++++++++++++++---------
 ovgosd.h      |  17 ++++++++--
 rpihddevice.c |  22 +++++++++---
 setup.c       |  63 +++++++++++++++++++++++++++-------
 setup.h       |  29 ++++++++++++++--
 tools.h       |  50 ++++++++++++++-------------
 17 files changed, 529 insertions(+), 185 deletions(-)

diff --git a/HISTORY b/HISTORY
index c365b6f..a9acf89 100644
--- a/HISTORY
+++ b/HISTORY
@@ -1,6 +1,35 @@
 VDR Plugin 'rpihddevice' Revision History
 -----------------------------------------
 
+2016-04-23: Version 1.0.3
+-------------------------
+- new:
+  - re-enable advanced deinterlacer for SD streams, requires recent firmware
+- fixed:
+  - don't ignore audio frames for slow trick speeds to keep clock in sync
+  
+2016-04-04: Version 1.0.2
+-------------------------
+- fixed:
+  - send proper end of sequence packet after playing single video frame
+
+2016-03-29: Version 1.0.1
+-------------------------
+- new:
+  - set device name
+  - add option for dual display usage, see README
+  - experimental support for AAC-LATM, use "make ENABLE_AAC_LATM=1" to enable
+- fixed:
+  - fixed HDMI channel mapping and stream type (reported by Rüdiger Follmann)
+  - fixed drawing of cached images with high level OSD
+  - only cache images in GPU when high level OSD is active
+  - added proper GPL header to every source file (suggested by Tobias Grimm)
+  - wait until dispmanx element is removed after OSD reset
+  - proper release default surface after OSD reset
+  - don't ignore anti alias option for scaled bitmap drawing
+  - ignore pts from erroneous packets to avoid pts jumps on broken streams
+  - use omxplayer's parameters for deinterlacer
+
 2015-10-18: Version 1.0.0
 -------------------------
 - new:
diff --git a/Makefile b/Makefile
index 3d2167a..a0605b8 100644
--- a/Makefile
+++ b/Makefile
@@ -79,6 +79,11 @@ ifeq ($(DEBUG_BUFFERS), 1)
     DEFINES += -DDEBUG_BUFFERS
 endif
 
+ENABLE_AAC_LATM ?= 0
+ifeq ($(ENABLE_AAC_LATM), 1)
+    DEFINES += -DENABLE_AAC_LATM
+endif
+
 # ffmpeg/libav configuration
 ifdef EXT_LIBAV
 	LIBAV_PKGCFG = $(shell PKG_CONFIG_PATH=$(EXT_LIBAV)/lib/pkgconfig pkg-config $(1))
diff --git a/README b/README
index 8698888..3faf2c2 100644
--- a/README
+++ b/README
@@ -70,6 +70,11 @@ Options:
                      OSD is used, when selecting rpihddevice as primary device.
   -v, --video-layer  Specify the dispmanx layer for video (default 0)
   -o, --osd-layer    Specify the dispmanx layer for OSD (default 2)
+      --display      display used for output:
+                     0: default display (default)
+                     4: LCD
+                     5: TV/HDMI
+                     6: non-default display
 
 Plugin-Setup:
 
diff --git a/audio.c b/audio.c
index 6a2864a..bffd73e 100644
--- a/audio.c
+++ b/audio.c
@@ -1,7 +1,20 @@
 /*
- * See the README file for copyright information and how to reach the author.
+ * rpihddevice - VDR HD output device for Raspberry Pi
+ * Copyright (C) 2014, 2015, 2016 Thomas Reufer
  *
- * $Id$
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include "audio.h"
@@ -16,6 +29,10 @@ extern "C" {
 #include <libavutil/log.h>
 #include <libavutil/opt.h>
 
+#ifdef ENABLE_AAC_LATM
+#warning "experimental AAC-LATM frame parser enabled, only 2ch/48kHz supported!"
+#endif
+
 // ffmpeg's resampling
 #ifdef HAVE_LIBSWRESAMPLE
 #  include <libswresample/swresample.h>
@@ -37,14 +54,15 @@ extern "C" {
 
 // legacy libavcodec
 #if LIBAVCODEC_VERSION_MAJOR < 55
-#  define av_frame_alloc   avcodec_alloc_frame
-#  define av_frame_free    avcodec_free_frame
-#  define av_frame_unref   avcodec_get_frame_defaults
-#  define AV_CODEC_ID_MP3  CODEC_ID_MP3
-#  define AV_CODEC_ID_AC3  CODEC_ID_AC3
-#  define AV_CODEC_ID_EAC3 CODEC_ID_EAC3
-#  define AV_CODEC_ID_AAC  CODEC_ID_AAC
-#  define AV_CODEC_ID_DTS  CODEC_ID_DTS
+#  define av_frame_alloc       avcodec_alloc_frame
+#  define av_frame_free        avcodec_free_frame
+#  define av_frame_unref       avcodec_get_frame_defaults
+#  define AV_CODEC_ID_MP3      CODEC_ID_MP3
+#  define AV_CODEC_ID_AC3      CODEC_ID_AC3
+#  define AV_CODEC_ID_EAC3     CODEC_ID_EAC3
+#  define AV_CODEC_ID_AAC      CODEC_ID_AAC
+#  define AV_CODEC_ID_AAC_LATM CODEC_ID_AAC_LATM
+#  define AV_CODEC_ID_DTS      CODEC_ID_DTS
 #endif
 
 #if LIBAVCODEC_VERSION_MAJOR < 54
@@ -283,11 +301,19 @@ private:
 						codec = cAudioCodec::eEAC3;
 				}
 				break;
+
 			case cAudioCodec::eAAC:
 				if (AdtsCheck(p, n, frameSize, channels, samplingRate))
 					codec = cAudioCodec::eAAC;
 				break;
 
+#ifdef ENABLE_AAC_LATM
+			case cAudioCodec::eAAC_LATM:
+				if (LatmCheck(p, n, frameSize, channels, samplingRate))
+					codec = cAudioCodec::eAAC_LATM;
+				break;
+#endif
+
 			case cAudioCodec::eDTS:
 				if (DtsCheck(p, n, frameSize, channels, samplingRate))
 					codec = cAudioCodec::eDTS;
@@ -368,10 +394,13 @@ private:
 
 	static cAudioCodec::eCodec FastCheck(const uint8_t *p)
 	{
-		return 	FastMpegCheck(p)  ? cAudioCodec::eMPG :
-				FastAc3Check (p)  ? cAudioCodec::eAC3 :
-				FastAdtsCheck(p)  ? cAudioCodec::eAAC :
-				FastDtsCheck (p)  ? cAudioCodec::eDTS :
+		return 	FastMpegCheck(p)  ? cAudioCodec::eMPG      :
+				FastAc3Check (p)  ? cAudioCodec::eAC3      :
+				FastAdtsCheck(p)  ? cAudioCodec::eAAC      :
+#ifdef ENABLE_AAC_LATM
+				FastLatmCheck(p)  ? cAudioCodec::eAAC_LATM :
+#endif
+				FastDtsCheck (p)  ? cAudioCodec::eDTS      :
 									cAudioCodec::eInvalid;
 	}
 
@@ -577,7 +606,7 @@ private:
 		return true;
 	}
 
-#if 0
+#ifdef ENABLE_AAC_LATM
 	///
 	///	Fast check for AAC LATM audio.
 	///
@@ -1072,6 +1101,10 @@ private:
 
 		if (m_codec != cAudioCodec::eInvalid)
 		{
+			if (m_port == cRpiAudioPort::eHDMI)
+				cRpiSetup::SetHDMIChannelMapping(m_codec != cAudioCodec::ePCM,
+						m_outChannels);
+
 			m_omx->SetupAudioRender(m_codec, m_outChannels, m_port,
 					m_samplingRate, m_frameSize);
 
@@ -1080,10 +1113,6 @@ private:
 					cAudioCodec::Str(m_codec),
 					m_samplingRate / 1000, (m_samplingRate % 1000) / 100,
 					m_codec != cAudioCodec::ePCM ? " (pass-through)" : "");
-
-			if (m_port == cRpiAudioPort::eHDMI)
-				cRpiSetup::SetHDMIChannelMapping(m_codec != cAudioCodec::ePCM,
-						m_outChannels);
 		}
 		m_running = m_codec != cAudioCodec::eInvalid;
 		m_configured = true;
@@ -1176,12 +1205,15 @@ int cRpiAudioDecoder::Init(void)
 			SysLogLevel > 1 ? AV_LOG_INFO : AV_LOG_ERROR);
 	av_log_set_callback(&Log);
 
-	m_codecs[cAudioCodec::ePCM ].codec = NULL;
-	m_codecs[cAudioCodec::eMPG ].codec = avcodec_find_decoder(AV_CODEC_ID_MP3);
-	m_codecs[cAudioCodec::eAC3 ].codec = avcodec_find_decoder(AV_CODEC_ID_AC3);
-	m_codecs[cAudioCodec::eEAC3].codec = avcodec_find_decoder(AV_CODEC_ID_EAC3);
-	m_codecs[cAudioCodec::eAAC ].codec = avcodec_find_decoder(AV_CODEC_ID_AAC);
-	m_codecs[cAudioCodec::eDTS ].codec = avcodec_find_decoder(AV_CODEC_ID_DTS);
+	m_codecs[cAudioCodec::ePCM     ].codec = NULL;
+	m_codecs[cAudioCodec::eMPG     ].codec = avcodec_find_decoder(AV_CODEC_ID_MP3);
+	m_codecs[cAudioCodec::eAC3     ].codec = avcodec_find_decoder(AV_CODEC_ID_AC3);
+	m_codecs[cAudioCodec::eEAC3    ].codec = avcodec_find_decoder(AV_CODEC_ID_EAC3);
+	m_codecs[cAudioCodec::eAAC     ].codec = avcodec_find_decoder(AV_CODEC_ID_AAC);
+#ifdef ENABLE_AAC_LATM
+	m_codecs[cAudioCodec::eAAC_LATM].codec = avcodec_find_decoder(AV_CODEC_ID_AAC_LATM);
+#endif
+	m_codecs[cAudioCodec::eDTS     ].codec = avcodec_find_decoder(AV_CODEC_ID_DTS);
 
 	for (int i = 0; i < cAudioCodec::eNumCodecs; i++)
 	{
diff --git a/audio.h b/audio.h
index 8ff2b47..1092ebe 100644
--- a/audio.h
+++ b/audio.h
@@ -1,7 +1,20 @@
 /*
- * See the README file for copyright information and how to reach the author.
+ * rpihddevice - VDR HD output device for Raspberry Pi
+ * Copyright (C) 2014, 2015, 2016 Thomas Reufer
  *
- * $Id$
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #ifndef AUDIO_H
diff --git a/display.c b/display.c
index a03fc00..f4f5273 100644
--- a/display.c
+++ b/display.c
@@ -1,7 +1,20 @@
 /*
- * See the README file for copyright information and how to reach the author.
+ * rpihddevice - VDR HD output device for Raspberry Pi
+ * Copyright (C) 2014, 2015, 2016 Thomas Reufer
  *
- * $Id$
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include "display.h"
@@ -24,29 +37,48 @@ cRpiDisplay* cRpiDisplay::GetInstance(void)
 {
 	if (!s_instance)
 	{
+		int id = cRpiSetup::Display();
 		TV_DISPLAY_STATE_T tvstate;
-		memset(&tvstate, 0, sizeof(TV_DISPLAY_STATE_T));
-
 		if (!vc_tv_get_display_state(&tvstate))
 		{
-			// HDMI
-			if (tvstate.state & (VC_HDMI_HDMI | VC_HDMI_DVI))
-				s_instance = new cRpiHDMIDisplay(
+			DBG("default display is %s",
+					tvstate.state & VC_HDMI_HDMI            ? "HDMI" :
+					tvstate.state & VC_HDMI_DVI             ? "DVI"  :
+					tvstate.state & VC_LCD_ATTACHED_DEFAULT ? "LCD"  :
+							"unknown");
+
+			// HDMI is default and enabled by plugin options
+			if ((tvstate.state & (VC_HDMI_HDMI | VC_HDMI_DVI)) &&
+					(id == VC_DISPLAY_TV_HDMI || id == VC_DISPLAY_DEFAULT))
+
+				s_instance = new cRpiHDMIDisplay(id,
 						tvstate.display.hdmi.width,
 						tvstate.display.hdmi.height,
 						tvstate.display.hdmi.frame_rate,
+						tvstate.display.hdmi.scan_mode != 0,
 						tvstate.display.hdmi.group,
 						tvstate.display.hdmi.mode);
-			else
-				s_instance = new cRpiCompositeDisplay(
-						tvstate.display.sdtv.width,
-						tvstate.display.sdtv.height,
-						tvstate.display.sdtv.frame_rate);
 		}
 		else
+			ELOG("failed to get default display state!");
+
+		if (!s_instance)
 		{
-			ELOG("failed to get display parameters - assuming analog SDTV!");
-			s_instance = new cRpiCompositeDisplay(720, 576, 50);
+			DISPMANX_DISPLAY_HANDLE_T display = vc_dispmanx_display_open(id);
+			if (display)
+			{
+				DISPMANX_MODEINFO_T mode;
+				if (vc_dispmanx_display_get_info(display, &mode) >= 0)
+					s_instance = new cRpiDefaultDisplay(id,
+							mode.width, mode.height);
+
+				vc_dispmanx_display_close(display);
+			}
+		}
+		if (!s_instance)
+		{
+			ELOG("failed to get display information!");
+			s_instance = new cRpiDefaultDisplay(id, 720, 576);
 		}
 	}
 
@@ -60,13 +92,14 @@ void cRpiDisplay::DropInstance(void)
 	s_instance = 0;
 }
 
-cRpiDisplay::cRpiDisplay(int width, int height, int frameRate,
-		cRpiVideoPort::ePort port) :
+cRpiDisplay::cRpiDisplay(int id, int width, int height, int frameRate,
+		bool interlaced, bool fixedMode) :
+	m_id(id),
 	m_width(width),
 	m_height(height),
 	m_frameRate(frameRate),
-	m_interlaced(false),
-	m_port(port)
+	m_interlaced(interlaced),
+	m_fixedMode(fixedMode)
 {
 }
 
@@ -117,20 +150,29 @@ int cRpiDisplay::SetHvsSyncUpdate(cScanMode::eMode scanMode)
 			scanMode == cScanMode::eBottomFieldFirst ? 2 : 0);
 }
 
-cRpiVideoPort::ePort cRpiDisplay::GetVideoPort(void)
+bool cRpiDisplay::IsProgressive(void)
+{
+	cRpiDisplay* instance = GetInstance();
+	if (instance)
+		return !instance->m_interlaced;
+
+	return false;
+}
+
+bool cRpiDisplay::IsFixedMode(void)
 {
 	cRpiDisplay* instance = GetInstance();
 	if (instance)
-		return instance->m_port;
+		return instance->m_fixedMode;
 
-	return cRpiVideoPort::eComposite;
+	return false;
 }
 
-bool cRpiDisplay::IsProgressive(void)
+int cRpiDisplay::GetId(void)
 {
 	cRpiDisplay* instance = GetInstance();
 	if (instance)
-		return !instance->m_interlaced;
+		return instance->m_id;
 
 	return false;
 }
@@ -141,7 +183,7 @@ int cRpiDisplay::Snapshot(unsigned char* frame, int width, int height)
 	if (instance)
 	{
 		DISPMANX_DISPLAY_HANDLE_T display = vc_dispmanx_display_open(
-				instance->m_port == cRpiVideoPort::eHDMI ? 0 : 1);
+				instance->m_id);
 
 		if (display)
 		{
@@ -165,8 +207,9 @@ int cRpiDisplay::Snapshot(unsigned char* frame, int width, int height)
 
 int cRpiDisplay::Update(const cVideoFrameFormat *frameFormat)
 {
-	if (cRpiSetup::GetVideoResolution() == cVideoResolution::eDontChange &&
-				cRpiSetup::GetVideoFrameRate() == cVideoFrameRate::eDontChange)
+	if (m_fixedMode || (
+			cRpiSetup::GetVideoResolution() == cVideoResolution::eDontChange &&
+			cRpiSetup::GetVideoFrameRate() == cVideoFrameRate::eDontChange))
 		return 0;
 
 	int newWidth = m_width;
@@ -237,9 +280,9 @@ public:
 	int nModes;
 };
 
-cRpiHDMIDisplay::cRpiHDMIDisplay(int width, int height, int frameRate,
-		int group, int mode) :
-	cRpiDisplay(width, height, frameRate, cRpiVideoPort::eHDMI),
+cRpiHDMIDisplay::cRpiHDMIDisplay(int id, int width, int height, int frameRate,
+		bool interlaced, int group, int mode) :
+	cRpiDisplay(id, width, height, frameRate, interlaced, false),
 	m_modes(new cRpiHDMIDisplay::ModeList()),
 	m_group(group),
 	m_mode(mode),
@@ -371,9 +414,7 @@ void cRpiHDMIDisplay::TvServiceCallback(void *data, unsigned int reason,
 
 /* ------------------------------------------------------------------------- */
 
-cRpiCompositeDisplay::cRpiCompositeDisplay(int width, int height,
-		int frameRate) :
-	cRpiDisplay(width, height, frameRate, cRpiVideoPort::eComposite)
+cRpiDefaultDisplay::cRpiDefaultDisplay(int id, int width, int height) :
+	cRpiDisplay(id, width, height, 50, false, true)
 {
-
 }
diff --git a/display.h b/display.h
index 5af4e02..7a203e3 100644
--- a/display.h
+++ b/display.h
@@ -1,7 +1,20 @@
 /*
- * See the README file for copyright information and how to reach the author.
+ * rpihddevice - VDR HD output device for Raspberry Pi
+ * Copyright (C) 2014, 2015, 2016 Thomas Reufer
  *
- * $Id$
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #ifndef DISPLAY_H
@@ -20,8 +33,10 @@ public:
 	static int GetSize(int &width, int &height);
 	static int GetSize(int &width, int &height, double &aspect);
 
-	static cRpiVideoPort::ePort GetVideoPort(void);
 	static bool IsProgressive(void);
+	static bool IsFixedMode(void);
+
+	static int GetId(void);
 
 	static int Snapshot(unsigned char* frame, int width, int height);
 
@@ -29,24 +44,25 @@ public:
 
 protected:
 
-	cRpiDisplay(int width, int height, int frameRate,
-			cRpiVideoPort::ePort port);
+	cRpiDisplay(int id, int width, int height, int frameRate, bool interlaced,
+			bool fixedMode);
 	virtual ~cRpiDisplay();
 
 	int Update(const cVideoFrameFormat *videoFormat);
 
 	virtual int SetMode(int width, int height, int frameRate,
 			cScanMode::eMode scanMode) {
-		return -1;
+		return 0;
 	}
 
 	static int SetHvsSyncUpdate(cScanMode::eMode scanMode);
 
+	int m_id;
 	int m_width;
 	int m_height;
 	int m_frameRate;
 	bool m_interlaced;
-	cRpiVideoPort::ePort m_port;
+	bool m_fixedMode;
 
 	static cRpiDisplay *s_instance;
 
@@ -62,7 +78,8 @@ class cRpiHDMIDisplay : public cRpiDisplay
 
 public:
 
-	cRpiHDMIDisplay(int width, int height, int frameRate, int group, int mode);
+	cRpiHDMIDisplay(int id, int width, int height, int frameRate, bool interlaced,
+			int group, int mode);
 	virtual ~cRpiHDMIDisplay();
 
 private:
@@ -85,19 +102,13 @@ private:
 	bool m_modified;
 };
 
-class cRpiCompositeDisplay : public cRpiDisplay
+class cRpiDefaultDisplay : public cRpiDisplay
 {
 
 public:
 
-	cRpiCompositeDisplay(int width, int height, int frameRate);
-
-private:
+	cRpiDefaultDisplay(int id, int width, int height);
 
-	virtual int SetMode(int width, int height, int frameRate,
-			cScanMode::eMode scanMode) {
-		return 0;
-	}
 };
 
 #endif
diff --git a/omx.c b/omx.c
index b3aa466..3881c14 100644
--- a/omx.c
+++ b/omx.c
@@ -1,7 +1,20 @@
 /*
- * See the README file for copyright information and how to reach the author.
+ * rpihddevice - VDR HD output device for Raspberry Pi
+ * Copyright (C) 2014, 2015, 2016 Thomas Reufer
  *
- * $Id$
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include <queue>
@@ -290,6 +303,13 @@ void cOmx::HandlePortSettingsChanged(unsigned int portId)
 				&portdef) != OMX_ErrorNone)
 			ELOG("failed to get video decoder port format!");
 
+		OMX_CONFIG_POINTTYPE pixelAspect;
+		OMX_INIT_STRUCT(pixelAspect);
+		pixelAspect.nPortIndex = 131;
+		if (OMX_GetParameter(ILC_GET_HANDLE(m_comp[eVideoDecoder]), OMX_IndexParamBrcmPixelAspectRatio,
+				&pixelAspect) != OMX_ErrorNone)
+			ELOG("failed to get pixel aspect ratio!");
+
 		OMX_CONFIG_INTERLACETYPE interlace;
 		OMX_INIT_STRUCT(interlace);
 		interlace.nPortIndex = 131;
@@ -299,6 +319,8 @@ void cOmx::HandlePortSettingsChanged(unsigned int portId)
 
 		m_videoFrameFormat.width = portdef.format.video.nFrameWidth;
 		m_videoFrameFormat.height = portdef.format.video.nFrameHeight;
+		m_videoFrameFormat.pixelWidth = pixelAspect.nX;
+		m_videoFrameFormat.pixelHeight = pixelAspect.nY;
 		m_videoFrameFormat.scanMode =
 				interlace.eMode == OMX_InterlaceProgressive ? cScanMode::eProgressive :
 				interlace.eMode == OMX_InterlaceFieldSingleUpperFirst ? cScanMode::eTopFieldFirst :
@@ -343,13 +365,11 @@ void cOmx::HandlePortSettingsChanged(unsigned int portId)
 			bool fastDeinterlace = portdef.format.video.nFrameWidth *
 					portdef.format.video.nFrameHeight > 576 * 720;
 
-			filterparam.nNumParams = fastDeinterlace ? 1 : 2;
+			filterparam.nNumParams = 4;
 			filterparam.nParams[0] = 3;
-
-			// explicitly set frame interval for advanced deinterlacer
-			// see: https://github.com/raspberrypi/firmware/issues/234
-			filterparam.nParams[1] = 1000000 /
-					(portdef.format.video.xFramerate >> 16);
+			filterparam.nParams[1] = 0; // default frame interval
+			filterparam.nParams[2] = 0; // half framerate
+			filterparam.nParams[3] = 1; // use qpus
 
 			filterparam.eImageFilter = fastDeinterlace ?
 					OMX_ImageFilterDeInterlaceFast :
@@ -454,7 +474,7 @@ cOmx::~cOmx()
 	delete m_portEvents;
 }
 
-int cOmx::Init(int layer)
+int cOmx::Init(int display, int layer)
 {
 	m_client = ilclient_init();
 	if (m_client == NULL)
@@ -529,7 +549,7 @@ int cOmx::Init(int layer)
 	ilclient_change_component_state(m_comp[eVideoFx], OMX_StateIdle);
 	ilclient_change_component_state(m_comp[eAudioRender], OMX_StateIdle);
 
-	SetDisplayLayer(layer);
+	SetDisplay(display, layer);
 	SetClockLatencyTarget();
 	SetBufferStallThreshold(20000);
 	SetClockReference(cOmx::eClockRefVideo);
@@ -1196,6 +1216,21 @@ void cOmx::SetDisplayMode(bool fill, bool noaspect)
 		ELOG("failed to set display region!");
 }
 
+void cOmx::SetPixelAspectRatio(int width, int height)
+{
+	OMX_CONFIG_DISPLAYREGIONTYPE region;
+	OMX_INIT_STRUCT(region);
+	region.nPortIndex = 90;
+	region.set = (OMX_DISPLAYSETTYPE)(OMX_DISPLAY_SET_PIXEL);
+
+	region.pixel_x = width;
+	region.pixel_y = height;
+
+	if (OMX_SetConfig(ILC_GET_HANDLE(m_comp[eVideoRender]),
+			OMX_IndexConfigDisplayRegion, &region) != OMX_ErrorNone)
+		ELOG("failed to set pixel apect ratio!");
+}
+
 void cOmx::SetDisplayRegion(int x, int y, int width, int height)
 {
 	OMX_CONFIG_DISPLAYREGIONTYPE region;
@@ -1215,17 +1250,19 @@ void cOmx::SetDisplayRegion(int x, int y, int width, int height)
 		ELOG("failed to set display region!");
 }
 
-void cOmx::SetDisplayLayer(int layer)
+void cOmx::SetDisplay(int display, int layer)
 {
 	OMX_CONFIG_DISPLAYREGIONTYPE region;
 	OMX_INIT_STRUCT(region);
 	region.nPortIndex = 90;
 	region.layer = layer;
-	region.set = (OMX_DISPLAYSETTYPE)(OMX_DISPLAY_SET_LAYER);
+	region.num = display;
+	region.set = (OMX_DISPLAYSETTYPE)
+			(OMX_DISPLAY_SET_LAYER | OMX_DISPLAY_SET_NUM);
 
 	if (OMX_SetConfig(ILC_GET_HANDLE(m_comp[eVideoRender]),
 			OMX_IndexConfigDisplayRegion, &region) != OMX_ErrorNone)
-		ELOG("failed to set display region!");
+		ELOG("failed to set display number and layer!");
 }
 
 OMX_BUFFERHEADERTYPE* cOmx::GetAudioBuffer(int64_t pts)
diff --git a/omx.h b/omx.h
index 957db98..c0daffa 100644
--- a/omx.h
+++ b/omx.h
@@ -1,7 +1,20 @@
 /*
- * See the README file for copyright information and how to reach the author.
+ * rpihddevice - VDR HD output device for Raspberry Pi
+ * Copyright (C) 2014, 2015, 2016 Thomas Reufer
  *
- * $Id$
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #ifndef OMX_H
@@ -26,7 +39,7 @@ public:
 
 	cOmx();
 	virtual ~cOmx();
-	int Init(int layer);
+	int Init(int display, int layer);
 	int DeInit(void);
 
 	void SetBufferStallCallback(void (*onBufferStall)(void*), void* data);
@@ -86,8 +99,9 @@ public:
 	}
 
 	void SetDisplayMode(bool letterbox, bool noaspect);
+	void SetPixelAspectRatio(int width, int height);
 	void SetDisplayRegion(int x, int y, int width, int height);
-	void SetDisplayLayer(int layer);
+	void SetDisplay(int display, int layer);
 
 	OMX_BUFFERHEADERTYPE* GetAudioBuffer(int64_t pts = OMX_INVALID_PTS);
 	OMX_BUFFERHEADERTYPE* GetVideoBuffer(int64_t pts = OMX_INVALID_PTS);
diff --git a/omxdevice.c b/omxdevice.c
index c5df12a..684f68d 100644
--- a/omxdevice.c
+++ b/omxdevice.c
@@ -1,7 +1,20 @@
 /*
- * See the README file for copyright information and how to reach the author.
+ * rpihddevice - VDR HD output device for Raspberry Pi
+ * Copyright (C) 2014, 2015, 2016 Thomas Reufer
  *
- * $Id$
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include "omxdevice.h"
@@ -33,11 +46,14 @@ const int cOmxDevice::s_liveSpeeds[eNumLiveSpeeds] = {
 	S(0.999f), S(0.99985f), S(1.000f), S(1.00015), S(1.001)
 };
 
-const uchar cOmxDevice::PesVideoHeader[14] = {
+const uchar cOmxDevice::s_pesVideoHeader[14] = {
 	0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x80, 0x80, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00
 };
 
-cOmxDevice::cOmxDevice(void (*onPrimaryDevice)(void), int layer) :
+const uchar cOmxDevice::s_mpeg2EndOfSequence[4]  = { 0x00, 0x00, 0x01, 0xb7 };
+const uchar cOmxDevice::s_h264EndOfSequence[8] = { 0x00, 0x00, 0x01, 0x0a, 0x00, 0x00, 0x01, 0x0b };
+
+cOmxDevice::cOmxDevice(void (*onPrimaryDevice)(void), int display, int layer) :
 	cDevice(),
 	m_onPrimaryDevice(onPrimaryDevice),
 	m_omx(new cOmx()),
@@ -57,6 +73,7 @@ cOmxDevice::cOmxDevice(void (*onPrimaryDevice)(void), int layer) :
 	m_audioPts(0),
 	m_videoPts(0),
 	m_lastStc(0),
+	m_display(display),
 	m_layer(layer)
 {
 }
@@ -73,7 +90,7 @@ cOmxDevice::~cOmxDevice()
 
 int cOmxDevice::Init(void)
 {
-	if (m_omx->Init(m_layer) < 0)
+	if (m_omx->Init(m_display, m_layer) < 0)
 	{
 		ELOG("failed to initialize OMX!");
 		return -1;
@@ -197,13 +214,13 @@ void cOmxDevice::StillPicture(const uchar *Data, int Length)
 		{
 			// some plugins deliver raw MPEG data, but PlayVideo() needs a
 			// complete PES packet with valid header
-			pesLength = Length + sizeof(PesVideoHeader);
+			pesLength = Length + sizeof(s_pesVideoHeader);
 			pesPacket = MALLOC(uchar, pesLength);
 			if (!pesPacket)
 				return;
 
-			memcpy(pesPacket, PesVideoHeader, sizeof(PesVideoHeader));
-			memcpy(pesPacket + sizeof(PesVideoHeader), Data, Length);
+			memcpy(pesPacket, s_pesVideoHeader, sizeof(s_pesVideoHeader));
+			memcpy(pesPacket + sizeof(s_pesVideoHeader), Data, Length);
 		}
 		else
 			codec = ParseVideoCodec(Data + PesPayloadOffset(Data),
@@ -218,9 +235,9 @@ void cOmxDevice::StillPicture(const uchar *Data, int Length)
 		m_hasVideo = false;
 		m_omx->StopClock();
 
-		// to get a picture displayed, PlayVideo() needs to be called
-		// 4x for MPEG2 and 10x for H264... ?
-		int repeat = codec == cVideoCodec::eMPEG2 ? 4 : 10;
+		// since the stream might be interlaced, we send each frame twice, so
+		// the advanced deinterlacer is able to render an output picture
+		int repeat = 2;
 		while (repeat--)
 		{
 			int length = pesPacket ? pesLength : Length;
@@ -239,18 +256,18 @@ void cOmxDevice::StillPicture(const uchar *Data, int Length)
 				length -= pktLen;
 			}
 		}
-		SubmitEOS();
-		m_mutex->Unlock();
-
 		if (pesPacket)
 			free(pesPacket);
+
+		SubmitEOS();
+		m_mutex->Unlock();
 	}
 }
 
 int cOmxDevice::PlayAudio(const uchar *Data, int Length, uchar Id)
 {
-	// ignore audio packets during trick speeds for non-radio recordings
-	if (m_playbackSpeed != eNormal && m_playMode != pmAudioOnly)
+	// ignore audio packets during fast trick speeds for non-radio recordings
+	if (m_playbackSpeed > eNormal && m_playMode != pmAudioOnly)
 	{
 		DLOG("audio packet ignored!");
 		return Length;
@@ -333,16 +350,19 @@ int cOmxDevice::PlayVideo(const uchar *Data, int Length, bool EndOfFrame)
 
 	m_mutex->Lock();
 	int ret = Length;
-	int64_t pts = PesHasPts(Data) ? PesGetPts(Data) : OMX_INVALID_PTS;
+
+	cVideoCodec::eCodec codec = ParseVideoCodec(Data + PesPayloadOffset(Data),
+			Length - PesPayloadOffset(Data));
+
+	int64_t pts = PesHasPts(Data) && codec != cVideoCodec::eInvalid ?
+			PesGetPts(Data) : OMX_INVALID_PTS;
 
 	if (!m_hasVideo && pts != OMX_INVALID_PTS &&
 			m_videoCodec == cVideoCodec::eInvalid)
 	{
-		m_videoCodec = ParseVideoCodec(Data + PesPayloadOffset(Data),
-				Length - PesPayloadOffset(Data));
-
-		if (m_videoCodec != cVideoCodec::eInvalid)
+		if (codec != cVideoCodec::eInvalid)
 		{
+			m_videoCodec = codec;
 			if (cRpiSetup::IsVideoCodecSupported(m_videoCodec))
 			{
 				m_omx->SetVideoCodec(m_videoCodec);
@@ -435,8 +455,13 @@ bool cOmxDevice::SubmitEOS(void)
 	DBG("SubmitEOS()");
 	OMX_BUFFERHEADERTYPE *buf = m_omx->GetVideoBuffer(0);
 	if (buf)
-		buf->nFlags = /*OMX_BUFFERFLAG_ENDOFFRAME | */ OMX_BUFFERFLAG_EOS;
-
+	{
+		buf->nFlags = OMX_BUFFERFLAG_EOS | OMX_BUFFERFLAG_ENDOFFRAME;
+		buf->nFilledLen = m_videoCodec == cVideoCodec::eMPEG2 ?
+				sizeof(s_mpeg2EndOfSequence) : sizeof(s_h264EndOfSequence);
+		memcpy(buf->pBuffer, m_videoCodec == cVideoCodec::eMPEG2 ?
+				s_mpeg2EndOfSequence : s_h264EndOfSequence, buf->nFilledLen);
+	}
 	return m_omx->EmptyVideoBuffer(buf);
 }
 
@@ -671,15 +696,17 @@ void cOmxDevice::HandleStreamStart()
 	DBG("HandleStreamStart()");
 
 	const cVideoFrameFormat *format = m_omx->GetVideoFrameFormat();
-	DLOG("video stream started %dx%d@%d%s",	format->width, format->height,
-			format->frameRate, format->Interlaced() ? "i" : "p");
+	DLOG("video stream started %dx%d@%d%s PAR(%d:%d)",
+			format->width, format->height, format->frameRate,
+			format->Interlaced() ? "i" : "p",
+			format->pixelWidth, format->pixelHeight);
 
 	cRpiDisplay::SetVideoFormat(format);
 }
 
 void cOmxDevice::HandleVideoSetupChanged()
 {
-	DBG("HandleVideoSettingsChanged()");
+	DBG("HandleVideoSetupChanged()");
 
 	switch (cRpiSetup::GetVideoFraming())
 	{
diff --git a/omxdevice.h b/omxdevice.h
index ed69639..aad4566 100644
--- a/omxdevice.h
+++ b/omxdevice.h
@@ -1,7 +1,20 @@
 /*
- * See the README file for copyright information and how to reach the author.
+ * rpihddevice - VDR HD output device for Raspberry Pi
+ * Copyright (C) 2014, 2015, 2016 Thomas Reufer
  *
- * $Id$
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #ifndef OMX_DEVICE_H
@@ -20,9 +33,11 @@ class cOmxDevice : cDevice
 
 public:
 
-	cOmxDevice(void (*onPrimaryDevice)(void), int layer);
+	cOmxDevice(void (*onPrimaryDevice)(void), int display, int layer);
 	virtual ~cOmxDevice();
 
+	virtual cString DeviceName(void) const { return "rpihddevice"; }
+
 	virtual int Init(void);
 	virtual int DeInit(void);
 
@@ -126,7 +141,9 @@ protected:
 	static const int s_playbackSpeeds[eNumDirections][eNumPlaybackSpeeds];
 	static const int s_liveSpeeds[eNumLiveSpeeds];
 
-	static const uchar PesVideoHeader[14];
+	static const uchar s_pesVideoHeader[14];
+	static const uchar s_mpeg2EndOfSequence[4];
+	static const uchar s_h264EndOfSequence[8];
 
 private:
 
@@ -182,6 +199,7 @@ private:
 
 	int64_t	m_lastStc;
 
+	int m_display;
 	int m_layer;
 };
 
diff --git a/ovgosd.c b/ovgosd.c
index 7d94a06..685dadb 100644
--- a/ovgosd.c
+++ b/ovgosd.c
@@ -1,7 +1,20 @@
 /*
- * See the README file for copyright information and how to reach the author.
+ * rpihddevice - VDR HD output device for Raspberry Pi
+ * Copyright (C) 2014, 2015, 2016 Thomas Reufer
  *
- * $Id$
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include <vector>
@@ -128,6 +141,7 @@ public:
 
 		if (FT_Done_FreeType(s_ftLib))
 			ELOG("failed to deinitialize FreeType library!");
+		s_ftLib = 0;
 	}
 
 	cOvgGlyph* Glyph(uint charCode) const
@@ -1538,15 +1552,14 @@ public:
 		if (!m_target->MakeCurrent(egl))
 			return false;
 
-		VGint height = vgGetParameteri(*m_image, VG_IMAGE_HEIGHT);
-
 		vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
 		vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_NORMAL);
 		vgSeti(VG_IMAGE_QUALITY, VG_IMAGE_QUALITY_BETTER);
 		vgSeti(VG_BLEND_MODE, VG_BLEND_SRC);
 
 		vgLoadIdentity();
-		vgTranslate(m_x, m_target->height - height - m_y);
+		vgScale(1.0f, -1.0f);
+		vgTranslate(m_x, m_y - m_target->height);
 
 		vgDrawImage(*m_image);
 		return true;
@@ -1563,11 +1576,12 @@ class cOvgCmdDrawBitmap : public cOvgCmd
 {
 public:
 
-	cOvgCmdDrawBitmap(cOvgRenderTarget *target,
-			int x, int y, int w, int h, tColor *argb,
-			bool overlay = false, double scaleX = 1.0f, double scaleY = 1.0f) :
+	cOvgCmdDrawBitmap(cOvgRenderTarget *target,	int x, int y, int w, int h,
+			tColor *argb, bool overlay = false,	double scaleX = 1.0f,
+			double scaleY = 1.0f, bool antiAliased = true) :
 		cOvgCmd(target), m_x(x), m_y(y), m_w(w), m_h(h), m_argb(argb),
-		m_overlay(overlay), m_scaleX(scaleX), m_scaleY(scaleY) { }
+		m_overlay(overlay), m_scaleX(scaleX), m_scaleY(scaleY),
+		m_antiAliased(antiAliased) { }
 
 	virtual ~cOvgCmdDrawBitmap()
 	{
@@ -1589,7 +1603,8 @@ public:
 
 		vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
 		vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_NORMAL);
-		vgSeti(VG_IMAGE_QUALITY, VG_IMAGE_QUALITY_BETTER);
+		vgSeti(VG_IMAGE_QUALITY, m_antiAliased ?
+				VG_IMAGE_QUALITY_BETTER : VG_IMAGE_QUALITY_NONANTIALIASED);
 		vgSeti(VG_BLEND_MODE, m_overlay ? VG_BLEND_SRC_OVER : VG_BLEND_SRC);
 
 		vgLoadIdentity();
@@ -1625,6 +1640,7 @@ protected:
 	bool m_overlay;
 	double m_scaleX;
 	double m_scaleY;
+	bool m_antiAliased;
 };
 
 /* ------------------------------------------------------------------------- */
@@ -1804,7 +1820,7 @@ protected:
 		while (Running())
 		{
 			DISPMANX_DISPLAY_HANDLE_T display = vc_dispmanx_display_open(
-				cRpiDisplay::GetVideoPort() == cRpiVideoPort::eHDMI ? 0 : 1);
+					cRpiDisplay::GetId());
 			DISPMANX_UPDATE_HANDLE_T update = vc_dispmanx_update_start(0);
 
 			cRpiDisplay::GetSize(egl.window.width, egl.window.height);
@@ -1837,8 +1853,8 @@ protected:
 						cEgl::errStr(eglGetError()));
 
 			if (eglMakeCurrent(egl.display, egl.surface, egl.surface,
-					egl.context) ==	EGL_FALSE)
-				ELOG("failed to connect context to surface: %s!",
+					egl.context) == EGL_FALSE)
+				ELOG("[EGL] failed to connect context to surface: %s!",
 						cEgl::errStr(eglGetError()));
 
 			egl.currentSurface = egl.surface;
@@ -1877,11 +1893,18 @@ protected:
 				}
 			}
 
+			if (eglMakeCurrent(egl.display, EGL_NO_SURFACE, EGL_NO_SURFACE,
+					EGL_NO_CONTEXT) == EGL_FALSE)
+				ELOG("[EGL] failed to release active surface from context: %s!",
+						cEgl::errStr(eglGetError()));
+
 			if (eglDestroySurface(egl.display, egl.surface) == EGL_FALSE)
 				ELOG("[EGL] failed to destroy surface: %s!",
 						cEgl::errStr(eglGetError()));
 
+			update = vc_dispmanx_update_start(0);
 			vc_dispmanx_element_remove(update, egl.window.element);
+			vc_dispmanx_update_submit_sync(update);
 			vc_dispmanx_display_close(display);
 
 			DLOG("cOvgThread() thread reset");
@@ -2077,7 +2100,7 @@ public:
 
 		m_ovg->DoCmd(new cOvgCmdDrawBitmap(m_buffer, Point.X(), Point.Y(),
 				Bitmap.Width(), Bitmap.Height(), argb, false,
-				FactorX, FactorY));
+				FactorX, FactorY, AntiAlias));
 
 		SetDirty();
 		MarkDrawPortDirty(cRect(Point, cSize(
@@ -2436,7 +2459,7 @@ public:
 
 		m_pixmaps[0]->DrawScaledBitmap(
 				cPoint(x, y) - m_pixmaps[0]->ViewPort().Point(),
-				Bitmap, FactorX, FactorY);
+				Bitmap, FactorX, FactorY, AntiAlias);
 	}
 
 	virtual void DrawImage(const cPoint &Point, int ImageHandle)
@@ -2720,7 +2743,7 @@ cOsd *cRpiOsdProvider::CreateOsd(int Left, int Top, uint Level)
 
 int cRpiOsdProvider::StoreImageData(const cImage &Image)
 {
-	int id = m_ovg->StoreImageData(Image);
+	int id = cRpiSetup::IsHighLevelOsd() ? m_ovg->StoreImageData(Image) : 0;
 	return id ? id : cOsdProvider::StoreImageData(Image);
 }
 
diff --git a/ovgosd.h b/ovgosd.h
index 9803c4a..dd9ea77 100644
--- a/ovgosd.h
+++ b/ovgosd.h
@@ -1,7 +1,20 @@
 /*
- * See the README file for copyright information and how to reach the author.
+ * rpihddevice - VDR HD output device for Raspberry Pi
+ * Copyright (C) 2014, 2015, 2016 Thomas Reufer
  *
- * $Id$
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #ifndef OVG_OSD_H
diff --git a/rpihddevice.c b/rpihddevice.c
index b738d0a..51a2c44 100644
--- a/rpihddevice.c
+++ b/rpihddevice.c
@@ -1,7 +1,20 @@
 /*
- * See the README file for copyright information and how to reach the author.
+ * rpihddevice - VDR HD output device for Raspberry Pi
+ * Copyright (C) 2014, 2015, 2016 Thomas Reufer
  *
- * $Id$
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include <vdr/plugin.h>
@@ -13,7 +26,7 @@
 #include "display.h"
 #include "tools.h"
 
-static const char *VERSION        = "1.0.0";
+static const char *VERSION        = "1.0.3";
 static const char *DESCRIPTION    = trNOOP("HD output device for Raspberry Pi");
 
 class cPluginRpiHdDevice : public cPlugin
@@ -65,7 +78,8 @@ bool cPluginRpiHdDevice::Initialize(void)
 	if (!cRpiSetup::IsVideoCodecSupported(cVideoCodec::eMPEG2))
 		DLOG("MPEG2 video decoder not enabled!");
 
-	m_device = new cOmxDevice(&OnPrimaryDevice, cRpiSetup::VideoLayer());
+	m_device = new cOmxDevice(&OnPrimaryDevice,
+			cRpiDisplay::GetId(), cRpiSetup::VideoLayer());
 
 	if (m_device)
 		return !m_device->Init();
diff --git a/setup.c b/setup.c
index 7d4296c..99b90d6 100644
--- a/setup.c
+++ b/setup.c
@@ -1,7 +1,20 @@
 /*
- * See the README file for copyright information and how to reach the author.
+ * rpihddevice - VDR HD output device for Raspberry Pi
+ * Copyright (C) 2014, 2015, 2016 Thomas Reufer
  *
- * $Id$
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include "setup.h"
@@ -101,7 +114,7 @@ private:
 		int current = Current();
 		Clear();
 
-		if (cRpiDisplay::GetVideoPort() == cRpiVideoPort::eHDMI)
+		if (!cRpiDisplay::IsFixedMode())
 		{
 			Add(new cMenuEditStraItem(
 				tr("Resolution"), &m_video.resolution, 6, m_videoResolution));
@@ -181,8 +194,7 @@ bool cRpiSetup::HwInit(void)
 	int width, height;
 	if (!cRpiDisplay::GetSize(width, height))
 	{
-		ILOG("HwInit() done, using %s video out at %dx%d",
-		cRpiVideoPort::Str(cRpiDisplay::GetVideoPort()), width, height);
+		ILOG("HwInit() done, display size is %dx%d", width, height);
 	}
 	else
 		ELOG("failed to get video port information!");
@@ -243,7 +255,7 @@ void cRpiSetup::SetHDMIChannelMapping(bool passthrough, int channels)
 	char command[80], response[80];
 
 	sprintf(command, "hdmi_stream_channels %d", passthrough ? 1 : 0);
-	vc_gencmd(response, sizeof response, command);
+	vc_gencmd(response, sizeof(response), command);
 
 	uint32_t channel_map = 0;
 
@@ -278,7 +290,7 @@ void cRpiSetup::SetHDMIChannelMapping(bool passthrough, int channels)
 	}
 
 	sprintf(command, "hdmi_channel_map 0x%08x", channel_map);
-	vc_gencmd(response, sizeof response, command);
+	vc_gencmd(response, sizeof(response), command);
 }
 
 cMenuSetupPage* cRpiSetup::GetSetupPage(void)
@@ -331,10 +343,13 @@ void cRpiSetup::Set(AudioParameters audio, VideoParameters video,
 
 bool cRpiSetup::ProcessArgs(int argc, char *argv[])
 {
+	const int cDisplayOpt = 0x100;
 	static struct option long_options[] = {
-			{ "disable-osd", no_argument,       NULL, 'd' },
-			{ "video-layer", required_argument, NULL, 'v' },
-			{ "osd-layer",   required_argument, NULL, 'o' },
+			{ "disable-osd", no_argument,       NULL, 'd'         },
+			{ "display",     required_argument, NULL, cDisplayOpt },
+			{ "video-layer", required_argument, NULL, 'v'         },
+			{ "osd-layer",   required_argument, NULL, 'o'         },
+			{ 0, 0, 0, 0 }
 	};
 	int c;
 	while ((c = getopt_long(argc, argv, "do:v:", long_options, NULL)) != -1)
@@ -350,13 +365,30 @@ bool cRpiSetup::ProcessArgs(int argc, char *argv[])
 		case 'v':
 			m_plugin.videoLayer = atoi(optarg);
 			break;
+		case cDisplayOpt:
+		{
+			int d = atoi(optarg);
+			switch (d)
+			{
+			case 0:
+			case 4:
+			case 5:
+			case 6:
+				m_plugin.display = d;
+				break;
+			default:
+				ELOG("invalid device id (%d), using default display!", d);
+				break;
+			}
+		}
+			break;
 		default:
 			return false;
 		}
 	}
-	DBG("dispmanx layers: video=%d, osd=%d (%s)",
+	DBG("dispmanx layers: video=%d, osd=%d (%s), display=%d",
 			m_plugin.videoLayer, m_plugin.osdLayer,
-			m_plugin.hasOsd ? "enabled" : "disabled");
+			m_plugin.hasOsd ? "enabled" : "disabled", m_plugin.display);
 
 	return true;
 }
@@ -365,5 +397,10 @@ const char *cRpiSetup::CommandLineHelp(void)
 {
 	return	"  -d,       --disable-osd  disable OSD\n"
 			"  -v,       --video-layer  dispmanx layer for video (default 0)\n"
-			"  -o,       --osd-layer    dispmanx layer for OSD (default 2)\n";
+			"  -o,       --osd-layer    dispmanx layer for OSD (default 2)\n"
+			"            --display      display used for output:\n"
+			"                           0: default display (default)\n"
+			"                           4: LCD\n"
+			"                           5: TV/HDMI\n"
+			"                           6: non-default display\n";
 }
diff --git a/setup.h b/setup.h
index 33585f6..a91b8e1 100644
--- a/setup.h
+++ b/setup.h
@@ -1,7 +1,20 @@
 /*
- * See the README file for copyright information and how to reach the author.
+ * rpihddevice - VDR HD output device for Raspberry Pi
+ * Copyright (C) 2014, 2015, 2016 Thomas Reufer
  *
- * $Id$
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #ifndef SETUP_H
@@ -10,6 +23,11 @@
 #include "omx.h"
 #include "tools.h"
 
+#define VC_DISPLAY_DEFAULT     0
+#define VC_DISPLAY_LCD         4
+#define VC_DISPLAY_TV_HDMI     5
+#define VC_DISPLAY_NON_DEFAULT 6
+
 class cRpiSetup
 {
 
@@ -61,9 +79,10 @@ public:
 	struct PluginParameters
 	{
 		PluginParameters() :
-			hasOsd(true), videoLayer(0), osdLayer(2) { }
+			hasOsd(true), display(0), videoLayer(0), osdLayer(2) { }
 
 		bool hasOsd;
+		int display;
 		int videoLayer;
 		int osdLayer;
 	};
@@ -123,6 +142,10 @@ public:
 		return GetInstance()->m_plugin.hasOsd;
 	}
 
+	static int Display(void) {
+		return GetInstance()->m_plugin.display;
+	}
+
 	static int VideoLayer(void) {
 		return GetInstance()->m_plugin.videoLayer;
 	}
diff --git a/tools.h b/tools.h
index f218a99..c6d198f 100644
--- a/tools.h
+++ b/tools.h
@@ -1,7 +1,20 @@
 /*
- * See the README file for copyright information and how to reach the author.
+ * rpihddevice - VDR HD output device for Raspberry Pi
+ * Copyright (C) 2014, 2015, 2016 Thomas Reufer
  *
- * $Id$
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #ifndef TOOLS_H
@@ -96,18 +109,20 @@ public:
 		eAC3,
 		eEAC3,
 		eAAC,
+		eAAC_LATM,
 		eDTS,
 		eNumCodecs,
 		eInvalid
 	};
 
 	static const char* Str(eCodec codec) {
-		return  (codec == ePCM)  ? "PCM"   :
-				(codec == eMPG)  ? "MPEG"  :
-				(codec == eAC3)  ? "AC3"   :
-				(codec == eEAC3) ? "E-AC3" :
-				(codec == eAAC)  ? "AAC"   :
-				(codec == eDTS)  ? "DTS"   : "unknown";
+		return  (codec == ePCM)      ? "PCM"      :
+				(codec == eMPG)      ? "MPEG"     :
+				(codec == eAC3)      ? "AC3"      :
+				(codec == eEAC3)     ? "E-AC3"    :
+				(codec == eAAC)      ? "AAC"      :
+				(codec == eAAC_LATM) ? "AAC-LATM" :
+				(codec == eDTS)      ? "DTS"      : "unknown";
 	}
 };
 
@@ -160,21 +175,6 @@ public:
 	}
 };
 
-class cRpiVideoPort
-{
-public:
-
-	enum ePort {
-		eComposite,
-		eHDMI
-	};
-
-	static const char* Str(ePort port) {
-		return 	(port == eComposite) ? "composite" :
-				(port == eHDMI)      ? "HDMI"      : "unknown";
-	}
-};
-
 class cScanMode
 {
 public:
@@ -201,12 +201,14 @@ class cVideoFrameFormat
 public:
 
 	cVideoFrameFormat() : width(0), height(0), frameRate(0),
-		scanMode(cScanMode::eProgressive) { };
+		scanMode(cScanMode::eProgressive), pixelWidth(0), pixelHeight(0) { };
 
 	int width;
 	int height;
 	int frameRate;
 	cScanMode::eMode scanMode;
+	int pixelWidth;
+	int pixelHeight;
 
 	bool Interlaced(void) const {
 		return cScanMode::Interlaced(scanMode);

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



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