[vdr-plugin-rpihddevice] 02/06: New upstream version 1.0.3+git20180115
Tobias Grimm
tiber-guest at moszumanska.debian.org
Mon Jan 15 19:11:58 UTC 2018
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 c4ad17d6186b8b8b8d26fe8abec1087f6cafb844
Author: Tobias Grimm <git at e-tobi.net>
Date: Mon Jan 15 20:08:42 2018 +0100
New upstream version 1.0.3+git20180115
---
.gitignore | 11 ++++
.project | 79 +++++++++++++++++++++++
HISTORY | 12 ++++
Makefile | 10 ++-
display.c | 210 +++++++++++++++++++++++++++++++++++++++++++++++-------------
display.h | 20 ++++--
omx.c | 40 +++++++++---
omx.h | 4 +-
omxdevice.c | 39 ++++++++---
ovgosd.c | 53 ++++++++++-----
po/de_DE.po | 13 +++-
po/fi_FI.po | 11 +++-
po/fr_FR.po | 11 +++-
po/hu_HU.po | 11 +++-
po/it_IT.po | 11 +++-
setup.c | 30 +++++++--
setup.h | 21 ++++--
tools.c | 111 ++++++++++++++++++++++++++++++++
tools.h | 22 +++++++
19 files changed, 617 insertions(+), 102 deletions(-)
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..91f9a15
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,11 @@
+.dependencies
+*.a
+*.o
+*.so
+*~
+po/*.pot
+po/*.mo
+.settings
+.cproject
+.project
+
diff --git a/.project b/.project
new file mode 100644
index 0000000..b385bd0
--- /dev/null
+++ b/.project
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>rpihddevice</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+ <triggers>clean,full,incremental,</triggers>
+ <arguments>
+ <dictionary>
+ <key>?name?</key>
+ <value></value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.append_environment</key>
+ <value>true</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.autoBuildTarget</key>
+ <value>all</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.buildArguments</key>
+ <value></value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.buildCommand</key>
+ <value>make</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
+ <value>clean</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.contents</key>
+ <value>org.eclipse.cdt.make.core.activeConfigSettings</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.enableAutoBuild</key>
+ <value>false</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.enableCleanBuild</key>
+ <value>true</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.enableFullBuild</key>
+ <value>true</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.fullBuildTarget</key>
+ <value>all</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.stopOnError</key>
+ <value>true</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
+ <value>true</value>
+ </dictionary>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+ <triggers>full,incremental,</triggers>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.cdt.core.cnature</nature>
+ <nature>org.eclipse.cdt.core.ccnature</nature>
+ <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+ <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+ </natures>
+</projectDescription>
diff --git a/HISTORY b/HISTORY
index a9acf89..a9ccd92 100644
--- a/HISTORY
+++ b/HISTORY
@@ -1,6 +1,18 @@
VDR Plugin 'rpihddevice' Revision History
-----------------------------------------
+- new:
+ - updated Hungarian translations (thanks to Füley István)
+ - make use of advanced deinterlacer configurable
+ - add debug option to log number of executed OpenVG commands and flushes
+ - set OMX clock pre-roll to 250ms for live TV (transfer mode)
+- fixed:
+ - reset video format settings on pixel aspect ratio change
+ - always resample audio with less than 2 and more than 6 channels
+ - fixed compilation with GCC-6
+ - implement proper handling of display and pixel aspect ratios
+ - fixed vertical text position
+
2016-04-23: Version 1.0.3
-------------------------
- new:
diff --git a/Makefile b/Makefile
index a0605b8..5c27c65 100644
--- a/Makefile
+++ b/Makefile
@@ -50,6 +50,7 @@ SOFILE = libvdr-$(PLUGIN).so
DEFINES += -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
DEFINES += -DHAVE_LIBOPENMAX=2 -DOMX -DOMX_SKIP64BIT -DUSE_EXTERNAL_OMX -DHAVE_LIBBCM_HOST -DUSE_EXTERNAL_LIBBCM_HOST -DUSE_VCHIQ_ARM
DEFINES += -Wno-psabi -Wno-write-strings -fpermissive
+DEFINES += -D__STL_CONFIG_H
CXXFLAGS += -D__STDC_CONSTANT_MACROS
@@ -59,7 +60,7 @@ VCLIBDIR =$(SDKSTAGE)/opt/vc/lib
INCLUDES += -I$(ILCDIR) -I$(VCINCDIR) -I$(VCINCDIR)/interface/vcos/pthreads
INCLUDES += -I$(VCINCDIR)/interface/vmcs_host/linux
-
+
LDLIBS += -lbcm_host -lvcos -lvchiq_arm -lopenmaxil -lGLESv2 -lEGL -lpthread -lrt
LDLIBS += -Wl,--whole-archive $(ILCDIR)/libilclient.a -Wl,--no-whole-archive
LDFLAGS += -L$(VCLIBDIR)
@@ -79,6 +80,11 @@ ifeq ($(DEBUG_BUFFERS), 1)
DEFINES += -DDEBUG_BUFFERS
endif
+DEBUG_OVGSTAT ?= 0
+ifeq ($(DEBUG_OVGSTAT), 1)
+ DEFINES += -DDEBUG_OVGSTAT
+endif
+
ENABLE_AAC_LATM ?= 0
ifeq ($(ENABLE_AAC_LATM), 1)
DEFINES += -DENABLE_AAC_LATM
@@ -112,7 +118,7 @@ INCLUDES += $(shell pkg-config --cflags freetype2)
### The object files (add further files here):
ILCLIENT = $(ILCDIR)/libilclient.a
-OBJS = $(PLUGIN).o setup.o omx.o audio.o omxdevice.o ovgosd.o display.o
+OBJS = $(PLUGIN).o tools.o setup.o omx.o audio.o omxdevice.o ovgosd.o display.o
### The main target:
diff --git a/display.c b/display.c
index f4f5273..7add79c 100644
--- a/display.c
+++ b/display.c
@@ -55,6 +55,7 @@ cRpiDisplay* cRpiDisplay::GetInstance(void)
tvstate.display.hdmi.width,
tvstate.display.hdmi.height,
tvstate.display.hdmi.frame_rate,
+ tvstate.display.hdmi.aspect_ratio,
tvstate.display.hdmi.scan_mode != 0,
tvstate.display.hdmi.group,
tvstate.display.hdmi.mode);
@@ -70,7 +71,7 @@ cRpiDisplay* cRpiDisplay::GetInstance(void)
DISPMANX_MODEINFO_T mode;
if (vc_dispmanx_display_get_info(display, &mode) >= 0)
s_instance = new cRpiDefaultDisplay(id,
- mode.width, mode.height);
+ mode.width, mode.height, SDTV_ASPECT_4_3);
vc_dispmanx_display_close(display);
}
@@ -78,7 +79,7 @@ cRpiDisplay* cRpiDisplay::GetInstance(void)
if (!s_instance)
{
ELOG("failed to get display information!");
- s_instance = new cRpiDefaultDisplay(id, 720, 576);
+ s_instance = new cRpiDefaultDisplay(id, 720, 576, SDTV_ASPECT_4_3);
}
}
@@ -93,11 +94,12 @@ void cRpiDisplay::DropInstance(void)
}
cRpiDisplay::cRpiDisplay(int id, int width, int height, int frameRate,
- bool interlaced, bool fixedMode) :
+ int aspectRatio, bool interlaced, bool fixedMode) :
m_id(id),
m_width(width),
m_height(height),
m_frameRate(frameRate),
+ m_aspectRatio(aspectRatio),
m_interlaced(interlaced),
m_fixedMode(fixedMode)
{
@@ -126,7 +128,19 @@ int cRpiDisplay::GetSize(int &width, int &height, double &aspect)
{
width = instance->m_width;
height = instance->m_height;
- aspect = (double)width / height;
+ switch (instance->m_aspectRatio)
+ {
+ case HDMI_ASPECT_4_3:
+ aspect = 4.0 / 3.0;
+ break;
+ case HDMI_ASPECT_16_9:
+ aspect = 16.0 / 9.0;
+ break;
+ default:
+ aspect = (double)width / height;
+ break;
+ }
+ aspect /= (double)width / height;
return 0;
}
return -1;
@@ -205,6 +219,62 @@ int cRpiDisplay::Snapshot(unsigned char* frame, int width, int height)
return -1;
}
+void cRpiDisplay::GetModeFormat(const cVideoFrameFormat *format,
+ int &modeX, int &modeY, int &aspectRatio)
+{
+ /* | Format | PAR | Mode | DAR |
+ * -------------------------------------------------------
+ * NTSC SD MPEG-2 | 720x480 | 8:9 | 720x480 | 4:3 |
+ * NTSC SD MPEG-4 | 720x480 | 10:11 | 720x480 | 4:3 |
+ * NTSC SD MPEG-2 | 720x480 | 32:27 | 720x480 | 16:9 |
+ * NTSC SD MPEG-4 | 720x480 | 40:33 | 720x480 | 16:9 |
+ * PAL SD MPEG-2 | 720x576 | 16:15 | 720x576 | 4:3 |
+ * PAL SD MPEG-4 | 720x576 | 12:11 | 720x576 | 4:3 |
+ * PAL SD MPEG-2 | 720x576 | 64:45 | 720x576 | 16:9 |
+ * PAL SD MPEG-4 | 720x576 | 16:11 | 720x576 | 16:9 |
+ * HD | 1280x720 | 1:1 | 1280x720 | 16:9 |
+ * HD | 1280x1080 | 3:2 | 1920x1080 | 16:9 |
+ * HD | 1920x1080 | 1:1 | 1920x1080 | 16:9 |
+ */
+
+ aspectRatio = HDMI_ASPECT_UNKNOWN;
+ modeY = format->height;
+
+ switch (modeY)
+ {
+ case 480:
+ if ((format->pixelWidth == 8 && format->pixelHeight == 9) ||
+ (format->pixelWidth == 10 && format->pixelHeight == 11))
+ aspectRatio = HDMI_ASPECT_4_3;
+ else if ((format->pixelWidth == 32 && format->pixelHeight == 27) ||
+ (format->pixelWidth == 40 && format->pixelHeight == 33))
+ aspectRatio = HDMI_ASPECT_16_9;
+ modeX = format->width;
+ break;
+
+ case 576:
+ if ((format->pixelWidth == 16 && format->pixelHeight == 15) ||
+ (format->pixelWidth == 12 && format->pixelHeight == 11))
+ aspectRatio = HDMI_ASPECT_4_3;
+ else if ((format->pixelWidth == 64 && format->pixelHeight == 45) ||
+ (format->pixelWidth == 16 && format->pixelHeight == 11))
+ aspectRatio = HDMI_ASPECT_16_9;
+ modeX = format->width;
+ break;
+
+ default:
+ ILOG("unknown video frame format: %dx%d@%d%s PAR(%d:%d)",
+ format->width, format->height, format->frameRate,
+ format->Interlaced() ? "i" : "p",
+ format->pixelWidth, format->pixelHeight);
+ case 720:
+ case 1080:
+ aspectRatio = HDMI_ASPECT_16_9;
+ modeX = format->width * format->pixelWidth / format->pixelHeight;
+ break;
+ }
+}
+
int cRpiDisplay::Update(const cVideoFrameFormat *frameFormat)
{
if (m_fixedMode || (
@@ -215,21 +285,49 @@ int cRpiDisplay::Update(const cVideoFrameFormat *frameFormat)
int newWidth = m_width;
int newHeight = m_height;
int newFrameRate = m_frameRate;
+ int newAspectRatio = m_aspectRatio;
bool newInterlaced = m_interlaced;
switch (cRpiSetup::GetVideoResolution())
{
- case cVideoResolution::e480: newWidth = 720; newHeight = 480; break;
- case cVideoResolution::e576: newWidth = 720; newHeight = 576; break;
- case cVideoResolution::e720: newWidth = 1280; newHeight = 720; break;
- case cVideoResolution::e1080: newWidth = 1920; newHeight = 1080; break;
+ case cVideoResolution::e480:
+ newWidth = 720;
+ newHeight = 480;
+ newAspectRatio = HDMI_ASPECT_4_3;
+ break;
+
+ case cVideoResolution::e480w:
+ newWidth = 720;
+ newHeight = 480;
+ newAspectRatio = HDMI_ASPECT_16_9;
+ break;
+
+ case cVideoResolution::e576:
+ newWidth = 720;
+ newHeight = 576;
+ newAspectRatio = HDMI_ASPECT_4_3;
+ break;
+
+ case cVideoResolution::e576w:
+ newWidth = 720;
+ newHeight = 576;
+ newAspectRatio = HDMI_ASPECT_16_9;
+ break;
+
+ case cVideoResolution::e720:
+ newWidth = 1280;
+ newHeight = 720;
+ newAspectRatio = HDMI_ASPECT_16_9;
+ break;
+
+ case cVideoResolution::e1080:
+ newWidth = 1920;
+ newHeight = 1080;
+ newAspectRatio = HDMI_ASPECT_16_9;
+ break;
case cVideoResolution::eFollowVideo:
- if (frameFormat->width && frameFormat->height)
- {
- newWidth = frameFormat->width;
- newHeight = frameFormat->height;
- }
+ GetModeFormat(frameFormat, newWidth, newHeight, newAspectRatio);
break;
default:
@@ -262,13 +360,26 @@ int cRpiDisplay::Update(const cVideoFrameFormat *frameFormat)
// set new mode only if necessary
if (newWidth != m_width || newHeight != m_height ||
- newFrameRate != m_frameRate || newInterlaced != m_interlaced)
- return SetMode(newWidth, newHeight, newFrameRate,
+ newFrameRate != m_frameRate || newInterlaced != m_interlaced ||
+ newAspectRatio != m_aspectRatio)
+ return SetMode(newWidth, newHeight, newFrameRate, newAspectRatio,
newInterlaced ? frameFormat->scanMode : cScanMode::eProgressive);
return 0;
}
+const char* cRpiDisplay::AspectRatioStr(int aspectRatio)
+{
+ return aspectRatio == HDMI_ASPECT_4_3 ? "4:3" :
+ aspectRatio == HDMI_ASPECT_14_9 ? "14:9" :
+ aspectRatio == HDMI_ASPECT_16_9 ? "16:9" :
+ aspectRatio == HDMI_ASPECT_5_4 ? "5:4" :
+ aspectRatio == HDMI_ASPECT_16_10 ? "16:10" :
+ aspectRatio == HDMI_ASPECT_15_9 ? "15:9" :
+ aspectRatio == HDMI_ASPECT_64_27 ? "64:27" :
+ aspectRatio == HDMI_ASPECT_21_9 ? "21:9" : "unknown";
+}
+
/* ------------------------------------------------------------------------- */
#define HDMI_MAX_MODES 64
@@ -281,8 +392,8 @@ public:
};
cRpiHDMIDisplay::cRpiHDMIDisplay(int id, int width, int height, int frameRate,
- bool interlaced, int group, int mode) :
- cRpiDisplay(id, width, height, frameRate, interlaced, false),
+ int aspectRatio, bool interlaced, int group, int mode) :
+ cRpiDisplay(id, width, height, frameRate, aspectRatio, interlaced, false),
m_modes(new cRpiHDMIDisplay::ModeList()),
m_group(group),
m_mode(mode),
@@ -304,7 +415,7 @@ cRpiHDMIDisplay::cRpiHDMIDisplay(int id, int width, int height, int frameRate,
DLOG("supported HDMI modes:");
for (int i = 0; i < m_modes->nModes; i++)
{
- DLOG("%s[%02d]: %4dx%4d@%2d%s | %s | %3d.%03dMHz%s%s",
+ DLOG("%s[%02d]: %4dx%4d@%2d%s | %*s | %3d.%03dMHz%s%s",
m_modes->modes[i].group == HDMI_RES_GROUP_CEA ? "CEA" :
m_modes->modes[i].group == HDMI_RES_GROUP_DMT ? "DMT" : "---",
m_modes->modes[i].code,
@@ -312,14 +423,7 @@ cRpiHDMIDisplay::cRpiHDMIDisplay(int id, int width, int height, int frameRate,
m_modes->modes[i].height,
m_modes->modes[i].frame_rate,
m_modes->modes[i].scan_mode ? "i" : "p",
- m_modes->modes[i].aspect_ratio == HDMI_ASPECT_4_3 ? " 4:3 " :
- m_modes->modes[i].aspect_ratio == HDMI_ASPECT_14_9 ? "14:9 " :
- m_modes->modes[i].aspect_ratio == HDMI_ASPECT_16_9 ? "16:9 " :
- m_modes->modes[i].aspect_ratio == HDMI_ASPECT_5_4 ? " 5:4 " :
- m_modes->modes[i].aspect_ratio == HDMI_ASPECT_16_10 ? "16:10" :
- m_modes->modes[i].aspect_ratio == HDMI_ASPECT_15_9 ? "15:9 " :
- m_modes->modes[i].aspect_ratio == HDMI_ASPECT_21_9 ? "21:9 " :
- "unknown aspect ratio",
+ 5, AspectRatioStr(m_modes->modes[i].aspect_ratio),
m_modes->modes[i].pixel_freq / 1000000,
m_modes->modes[i].pixel_freq % 1000000 / 1000,
m_modes->modes[i].native ? " (native)" : "",
@@ -354,31 +458,50 @@ cRpiHDMIDisplay::~cRpiHDMIDisplay()
}
int cRpiHDMIDisplay::SetMode(int width, int height, int frameRate,
- cScanMode::eMode scanMode)
+ int aspectRatio, cScanMode::eMode scanMode)
{
SetHvsSyncUpdate(scanMode);
- bool interlaced = cScanMode::Interlaced(scanMode);
+ int interlaced = cScanMode::Interlaced(scanMode) ? 1 : 0;
+ int mode = -1, altMode = -1;
- for (int i = 0; i < m_modes->nModes; i++)
+ for (int i = 0; i < m_modes->nModes && mode == -1; i++)
{
if (m_modes->modes[i].width == width &&
m_modes->modes[i].height == height &&
m_modes->modes[i].frame_rate == frameRate &&
+ m_modes->modes[i].aspect_ratio == aspectRatio &&
m_modes->modes[i].scan_mode == interlaced)
- {
- DLOG("setting HDMI mode to %dx%d@%2d%s", width, height,
- frameRate, interlaced ? "i" : "p");
-
- m_width = width;
- m_height = height;
- m_frameRate = frameRate;
- m_interlaced = interlaced;
- return SetMode(m_modes->modes[i].group, m_modes->modes[i].code);
- }
+ mode = i;
+
+ else if (m_modes->modes[i].height == height &&
+ m_modes->modes[i].frame_rate == frameRate &&
+ m_modes->modes[i].aspect_ratio == aspectRatio &&
+ m_modes->modes[i].scan_mode == interlaced)
+ altMode = i;
+ }
+
+ if (mode == -1 && altMode != -1)
+ mode = altMode;
+
+ if (mode != -1)
+ {
+ m_width = m_modes->modes[mode].width;
+ m_height = m_modes->modes[mode].height;
+ m_frameRate = m_modes->modes[mode].frame_rate;
+ m_aspectRatio = m_modes->modes[mode].aspect_ratio;
+ m_interlaced = m_modes->modes[mode].scan_mode;
+
+ DLOG("setting HDMI mode to %dx%d@%2d%s (%s)", m_width, m_height,
+ m_frameRate, m_interlaced ? "i" : "p",
+ AspectRatioStr(m_aspectRatio));
+
+ return SetMode(m_modes->modes[mode].group, m_modes->modes[mode].code);
}
- DLOG("failed to set HDMI mode to %dx%d@%2d%s",
- width, height, frameRate, interlaced ? "i" : "p");
+ DLOG("failed to set HDMI mode to %dx%d@%2d%s (%s)",
+ width, height, frameRate, interlaced ? "i" : "p",
+ AspectRatioStr(aspectRatio));
+
return -1;
}
@@ -414,7 +537,8 @@ void cRpiHDMIDisplay::TvServiceCallback(void *data, unsigned int reason,
/* ------------------------------------------------------------------------- */
-cRpiDefaultDisplay::cRpiDefaultDisplay(int id, int width, int height) :
- cRpiDisplay(id, width, height, 50, false, true)
+cRpiDefaultDisplay::cRpiDefaultDisplay(int id, int width, int height,
+ int aspectRatio) :
+ cRpiDisplay(id, width, height, 50, aspectRatio, false, true)
{
}
diff --git a/display.h b/display.h
index 7a203e3..b062aa7 100644
--- a/display.h
+++ b/display.h
@@ -44,23 +44,29 @@ public:
protected:
- cRpiDisplay(int id, int width, int height, int frameRate, bool interlaced,
- bool fixedMode);
+ cRpiDisplay(int id, int width, int height, int frameRate, int aspectRatio,
+ bool interlaced, bool fixedMode);
virtual ~cRpiDisplay();
int Update(const cVideoFrameFormat *videoFormat);
- virtual int SetMode(int width, int height, int frameRate,
+ virtual int SetMode(int width, int height, int frameRate, int aspectRatio,
cScanMode::eMode scanMode) {
return 0;
}
static int SetHvsSyncUpdate(cScanMode::eMode scanMode);
+ static void GetModeFormat(const cVideoFrameFormat *format,
+ int &modeX, int &modeY, int &aspectRatio);
+
+ static const char* AspectRatioStr(int aspectRatio);
+
int m_id;
int m_width;
int m_height;
int m_frameRate;
+ int m_aspectRatio;
bool m_interlaced;
bool m_fixedMode;
@@ -78,13 +84,13 @@ class cRpiHDMIDisplay : public cRpiDisplay
public:
- cRpiHDMIDisplay(int id, int width, int height, int frameRate, bool interlaced,
- int group, int mode);
+ cRpiHDMIDisplay(int id, int width, int height, int frameRate,
+ int aspectRatio, bool interlaced, int group, int mode);
virtual ~cRpiHDMIDisplay();
private:
- virtual int SetMode(int width, int height, int frameRate,
+ virtual int SetMode(int width, int height, int frameRate, int aspectRatio,
cScanMode::eMode scanMode);
int SetMode(int group, int mode);
@@ -107,7 +113,7 @@ class cRpiDefaultDisplay : public cRpiDisplay
public:
- cRpiDefaultDisplay(int id, int width, int height);
+ cRpiDefaultDisplay(int id, int width, int height, int aspectRatio);
};
diff --git a/omx.c b/omx.c
index 3881c14..a1361bd 100644
--- a/omx.c
+++ b/omx.c
@@ -21,6 +21,7 @@
#include "omx.h"
#include "display.h"
+#include "setup.h"
#include <vdr/tools.h>
#include <vdr/thread.h>
@@ -31,8 +32,6 @@ extern "C" {
#include "bcm_host.h"
-#define OMX_PRE_ROLL 0
-
// default: 20x 81920 bytes, now 128x 64k (8M)
#define OMX_VIDEO_BUFFERS 128
#define OMX_VIDEO_BUFFERSIZE KILOBYTE(64);
@@ -206,9 +205,19 @@ void cOmx::Action(void)
break;
case cOmxEvents::eConfigChanged:
- if (event->data == OMX_IndexConfigBufferStall)
+ switch (event->data)
+ {
+ case OMX_IndexParamBrcmPixelAspectRatio:
+ if (m_handlePortEvents)
+ HandlePortSettingsChanged(131);
+ break;
+ case OMX_IndexConfigBufferStall:
if (IsBufferStall() && !IsClockFreezed() && m_onBufferStall)
m_onBufferStall(m_onBufferStallData);
+ break;
+ default:
+ break;
+ }
break;
case cOmxEvents::eEndOfStream:
@@ -362,8 +371,11 @@ void cOmx::HandlePortSettingsChanged(unsigned int portId)
if (cRpiDisplay::IsProgressive() && m_videoFrameFormat.Interlaced())
{
- bool fastDeinterlace = portdef.format.video.nFrameWidth *
- portdef.format.video.nFrameHeight > 576 * 720;
+ bool fastDeinterlace = !cRpiSetup::UseAdvancedDeinterlacer(
+ portdef.format.video.nFrameWidth,
+ portdef.format.video.nFrameHeight);
+
+ DBG("using %s deinterlacer", fastDeinterlace ? "fast" : "advanced");
filterparam.nNumParams = 4;
filterparam.nParams[0] = 3;
@@ -551,6 +563,7 @@ int cOmx::Init(int display, int layer)
SetDisplay(display, layer);
SetClockLatencyTarget();
+ SetPARChangeCallback(true);
SetBufferStallThreshold(20000);
SetClockReference(cOmx::eClockRefVideo);
@@ -662,7 +675,7 @@ bool cOmx::IsClockRunning(void)
return false;
}
-void cOmx::StartClock(bool waitForVideo, bool waitForAudio)
+void cOmx::StartClock(bool waitForVideo, bool waitForAudio, int preRollMs)
{
DBG("StartClock(%svideo, %saudio)",
waitForVideo ? "" : "no ",
@@ -672,7 +685,7 @@ void cOmx::StartClock(bool waitForVideo, bool waitForAudio)
OMX_INIT_STRUCT(cstate);
cstate.eState = OMX_TIME_ClockStateRunning;
- cstate.nOffset = ToOmxTicks(-1000LL * OMX_PRE_ROLL);
+ cstate.nOffset = ToOmxTicks(-1000LL * preRollMs);
if (waitForVideo)
{
@@ -698,7 +711,6 @@ void cOmx::StopClock(void)
OMX_INIT_STRUCT(cstate);
cstate.eState = OMX_TIME_ClockStateStopped;
- cstate.nOffset = ToOmxTicks(-1000LL * OMX_PRE_ROLL);
if (OMX_SetConfig(ILC_GET_HANDLE(m_comp[eClock]),
OMX_IndexConfigTimeClockState, &cstate) != OMX_ErrorNone)
@@ -821,6 +833,18 @@ void cOmx::SetClockLatencyTarget(void)
ELOG("failed set video render latency target!");
}
+void cOmx::SetPARChangeCallback(bool enable)
+{
+ OMX_CONFIG_REQUESTCALLBACKTYPE reqCallback;
+ OMX_INIT_STRUCT(reqCallback);
+ reqCallback.nPortIndex = 131;
+ reqCallback.bEnable = enable ? OMX_TRUE : OMX_FALSE;
+ reqCallback.nIndex = OMX_IndexParamBrcmPixelAspectRatio;
+ if (OMX_SetConfig(ILC_GET_HANDLE(m_comp[eVideoDecoder]),
+ OMX_IndexConfigRequestCallback, &reqCallback) != OMX_ErrorNone)
+ ELOG("failed to set video aspect ratio change call back!");
+}
+
void cOmx::SetBufferStallThreshold(int delayMs)
{
if (delayMs > 0)
diff --git a/omx.h b/omx.h
index c0daffa..e633746 100644
--- a/omx.h
+++ b/omx.h
@@ -62,7 +62,8 @@ public:
eClockStateWaitForAudioVideo
};
- void StartClock(bool waitForVideo = false, bool waitForAudio = false);
+ void StartClock(bool waitForVideo = false, bool waitForAudio = false,
+ int preRollMs = 0);
void StopClock(void);
void ResetClock(void);
@@ -178,6 +179,7 @@ private:
void HandlePortBufferEmptied(eOmxComponent component);
void HandlePortSettingsChanged(unsigned int portId);
+ void SetPARChangeCallback(bool enable);
void SetBufferStallThreshold(int delayMs);
bool IsBufferStall(void);
diff --git a/omxdevice.c b/omxdevice.c
index 684f68d..c646f90 100644
--- a/omxdevice.c
+++ b/omxdevice.c
@@ -22,6 +22,7 @@
#include "audio.h"
#include "display.h"
#include "setup.h"
+#include "tools.h"
#include <vdr/thread.h>
#include <vdr/remux.h>
@@ -33,6 +34,9 @@
#define S(x) ((int)(floor(x * pow(2, 16))))
#define PTS_START_OFFSET (32 * (MAX33BIT + 1))
+#define PRE_ROLL_LIVE 250
+#define PRE_ROLL_PLAYBACK 0
+
// trick speeds as defined in vdr/dvbplayer.c
const int cOmxDevice::s_playbackSpeeds[eNumDirections][eNumPlaybackSpeeds] = {
{ S(0.0f), S( 0.125f), S( 0.25f), S( 0.5f), S( 1.0f), S( 2.0f), S( 4.0f), S( 12.0f) },
@@ -289,7 +293,8 @@ int cOmxDevice::PlayAudio(const uchar *Data, int Length, uchar Id)
DBG("audio first");
m_omx->SetClockScale(
s_playbackSpeeds[m_direction][m_playbackSpeed]);
- m_omx->StartClock(m_hasVideo, m_hasAudio);
+ m_omx->StartClock(m_hasVideo, m_hasAudio,
+ Transferring() ? PRE_ROLL_LIVE : PRE_ROLL_PLAYBACK);
m_audioPts = PTS_START_OFFSET + pts;
m_playMode = pmAudioOnly;
}
@@ -382,7 +387,8 @@ int cOmxDevice::PlayVideo(const uchar *Data, int Length, bool EndOfFrame)
DBG("video first");
m_omx->SetClockReference(cOmx::eClockRefVideo);
m_omx->SetClockScale(s_playbackSpeeds[m_direction][m_playbackSpeed]);
- m_omx->StartClock(m_hasVideo, m_hasAudio);
+ m_omx->StartClock(m_hasVideo, m_hasAudio,
+ Transferring() ? PRE_ROLL_LIVE : PRE_ROLL_PLAYBACK);
m_videoPts = PTS_START_OFFSET + pts;
m_playMode = pmVideoOnly;
}
@@ -686,7 +692,8 @@ void cOmxDevice::HandleEndOfStream()
// flush pipes and restart clock after still image
FlushStreams();
m_omx->SetClockScale(s_playbackSpeeds[m_direction][m_playbackSpeed]);
- m_omx->StartClock(m_hasVideo, m_hasAudio);
+ m_omx->StartClock(m_hasVideo, m_hasAudio,
+ Transferring() ? PRE_ROLL_LIVE : PRE_ROLL_PLAYBACK);
m_mutex->Unlock();
}
@@ -696,18 +703,17 @@ void cOmxDevice::HandleStreamStart()
DBG("HandleStreamStart()");
const cVideoFrameFormat *format = m_omx->GetVideoFrameFormat();
- DLOG("video stream started %dx%d@%d%s PAR(%d:%d)",
+ 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);
+ HandleVideoSetupChanged();
}
void cOmxDevice::HandleVideoSetupChanged()
{
- DBG("HandleVideoSetupChanged()");
-
+ // apply framing parameters
switch (cRpiSetup::GetVideoFraming())
{
default:
@@ -724,7 +730,24 @@ void cOmxDevice::HandleVideoSetupChanged()
break;
}
- cRpiDisplay::SetVideoFormat(m_omx->GetVideoFrameFormat());
+ const cVideoFrameFormat *format = m_omx->GetVideoFrameFormat();
+ double videoPAR = format->pixelHeight ?
+ (double)format->pixelWidth / format->pixelHeight : 1.0f;
+
+ // update display format according current video stream
+ cRpiDisplay::SetVideoFormat(format);
+
+ // get updated display format ...
+ int width, height;
+ double displayPAR;
+ cRpiDisplay::GetSize(width, height, displayPAR);
+
+ // ... and set video render format accordingly
+ cRational renderPAR = cRational(videoPAR / displayPAR);
+ renderPAR.Reduce(100);
+ m_omx->SetPixelAspectRatio(renderPAR.num, renderPAR.den);
+ DLOG("display PAR=%0.3f, setting video render PAR=%d/%d",
+ displayPAR, renderPAR.num, renderPAR.den);
}
void cOmxDevice::FlushStreams(bool flushVideoRender)
diff --git a/ovgosd.c b/ovgosd.c
index 685dadb..4c2652c 100644
--- a/ovgosd.c
+++ b/ovgosd.c
@@ -757,6 +757,7 @@ public:
virtual bool Execute(cEgl *egl) = 0;
virtual const char* Description(void) = 0;
+ virtual bool IsFlush(void) { return false; };
protected:
@@ -776,6 +777,7 @@ public:
cOvgCmd(target) { }
virtual const char* Description(void) { return "Flush"; }
+ virtual bool IsFlush(void) { return true; };
virtual bool Execute(cEgl *egl)
{
@@ -1207,14 +1209,14 @@ public:
if (m_alignment & taLeft)
{
if (m_alignment & taBorder)
- offsetX += max(height / TEXT_ALIGN_BORDER, 1.0f);
+ offsetX += std::max(height / TEXT_ALIGN_BORDER, 1.0f);
}
else if (m_alignment & taRight)
{
if (width < m_w)
offsetX += m_w - width;
if (m_alignment & taBorder)
- offsetX -= max(height / TEXT_ALIGN_BORDER, 1.0f);
+ offsetX -= std::max(height / TEXT_ALIGN_BORDER, 1.0f);
}
else
{
@@ -1240,12 +1242,9 @@ public:
vgSeti(VG_BLEND_MODE, VG_BLEND_SRC);
vgSeti(VG_MATRIX_MODE, VG_MATRIX_GLYPH_USER_TO_SURFACE);
- // some magic offset to conform with VDR's text rendering
- offsetY -= 0.06f * m_fontSize;
-
vgLoadIdentity();
vgTranslate(m_x + offsetX,
- m_target->height - m_y - m_fontSize - offsetY + 1);
+ m_target->height - m_y - height + descender - offsetY + 1);
vgScale(m_fontSize, m_fontSize);
VGfloat origin[2] = { 0.0f, 0.0f };
@@ -1253,10 +1252,11 @@ public:
cOvgPaintBox::SetScissoring(
m_w ? m_x : m_x + floor(offsetX),
- m_h ? m_target->height - m_y - m_h : m_target->height - m_y -
- m_fontSize - floor(descender) + 1,
- m_w ? m_w : floor(width) + 1,
- m_h ? m_h : m_fontSize + floor(descender) - 1);
+ m_h ? m_target->height - m_y - m_h :
+ m_target->height - m_y - floor(height),
+ m_w ? m_w : floor(width),
+ m_h ? m_h : floor(height));
+
if (m_colorBg != clrTransparent)
{
@@ -1592,8 +1592,8 @@ public:
virtual bool Execute(cEgl *egl)
{
- int w = min(m_w, vgGeti(VG_MAX_IMAGE_WIDTH));
- int h = min(m_h, vgGeti(VG_MAX_IMAGE_HEIGHT));
+ int w = std::min(m_w, vgGeti(VG_MAX_IMAGE_WIDTH));
+ int h = std::min(m_h, vgGeti(VG_MAX_IMAGE_HEIGHT));
if (w <= 0 || h <= 0)
return true;
@@ -1866,6 +1866,11 @@ protected:
vgSetfv(VG_CLEAR_COLOR, 4, color);
vgClear(0, 0, egl.window.width, egl.window.height);
+#ifdef DEBUG_OVGSTAT
+ cTimeMs timer;
+ int commands = 0, flushes = 0;
+#endif
+
bool reset = false;
while (!reset)
{
@@ -1878,6 +1883,22 @@ protected:
m_commands.pop();
Unlock();
+#ifdef DEBUG_OVGSTAT
+ if (timer.TimedOut())
+ {
+ if (commands || flushes)
+ {
+ DLOG("[OpenVG] commands executed: %d, flushes: %d",
+ commands, flushes);
+ commands = 0;
+ flushes = 0;
+ }
+ timer.Set(1000);
+ }
+ commands++;
+ if (cmd->IsFlush())
+ flushes++;
+#endif
reset = cmd ? !cmd->Execute(&egl) : true;
VGErrorCode err = vgGetError();
@@ -2354,11 +2375,11 @@ public:
{
ELOG("[OpenVG] cannot allocate pixmap of %dpx x %dpx, "
"clipped to %dpx x %dpx!", width, height,
- min(width, m_ovg->MaxImageSize().Width()),
- min(height, m_ovg->MaxImageSize().Height()));
+ std::min(width, m_ovg->MaxImageSize().Width()),
+ std::min(height, m_ovg->MaxImageSize().Height()));
- width = min(width, m_ovg->MaxImageSize().Width());
- height = min(height, m_ovg->MaxImageSize().Height());
+ width = std::min(width, m_ovg->MaxImageSize().Width());
+ height = std::min(height, m_ovg->MaxImageSize().Height());
}
#endif
// create pixel buffer and wait until command has been completed
diff --git a/po/de_DE.po b/po/de_DE.po
index 3c37270..a221585 100644
--- a/po/de_DE.po
+++ b/po/de_DE.po
@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: vdr-rpihddevice 1.0.0\n"
"Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2015-03-14 19:22+0100\n"
-"PO-Revision-Date: 2015-10-12 09:33+0100\n"
+"POT-Creation-Date: 2016-04-27 15:09+0200\n"
+"PO-Revision-Date: 2016-04-27 15:11+0100\n"
"Last-Translator: Thomas Reufer <thomas at reufer.ch>\n"
"Language-Team: German\n"
"Language: de\n"
@@ -54,12 +54,21 @@ msgstr "Voreinstellung"
msgid "follow video"
msgstr "wie Video"
+msgid "for SD video only"
+msgstr "nur für SD-Video"
+
+msgid "always"
+msgstr "immer"
+
msgid "Resolution"
msgstr "Auflösung"
msgid "Frame Rate"
msgstr "Bildwiederholrate"
+msgid "Use Advanced Deinterlacer"
+msgstr "Benutze erweiterten Deinterlacer"
+
msgid "Video Framing"
msgstr "Seitenverhältnis-Anpassung"
diff --git a/po/fi_FI.po b/po/fi_FI.po
index 2b2258f..2dcff96 100644
--- a/po/fi_FI.po
+++ b/po/fi_FI.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: vdr-rpihddevice 0.0.8\n"
"Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2015-03-14 19:22+0100\n"
+"POT-Creation-Date: 2016-04-27 15:09+0200\n"
"PO-Revision-Date: 2014-03-22 03:22+0200\n"
"Last-Translator: Rolf Ahrenberg\n"
"Language-Team: Finnish <vdr at linuxtv.org>\n"
@@ -52,12 +52,21 @@ msgstr "oletus"
msgid "follow video"
msgstr "lähetteen mukaan"
+msgid "for SD video only"
+msgstr ""
+
+msgid "always"
+msgstr ""
+
msgid "Resolution"
msgstr "Resoluutio"
msgid "Frame Rate"
msgstr "Ruudunpäivitys"
+msgid "Use Advanced Deinterlacer"
+msgstr ""
+
msgid "Video Framing"
msgstr "Kuvan rajaustapa"
diff --git a/po/fr_FR.po b/po/fr_FR.po
index dfb92b9..a0dd2cd 100644
--- a/po/fr_FR.po
+++ b/po/fr_FR.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: vdr-rpihddevice 1.0.0\n"
"Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2015-10-14 17:58+0200\n"
+"POT-Creation-Date: 2016-04-27 15:09+0200\n"
"PO-Revision-Date: 2015-10-15 06:56+0100\n"
"Last-Translator: Cyril Jaquier <cyril.jaquier at jaqpot.net>\n"
"Language-Team: French\n"
@@ -53,12 +53,21 @@ msgstr "par défaut"
msgid "follow video"
msgstr "comme l'original"
+msgid "for SD video only"
+msgstr ""
+
+msgid "always"
+msgstr ""
+
msgid "Resolution"
msgstr "Résolution"
msgid "Frame Rate"
msgstr "Cadence d'images"
+msgid "Use Advanced Deinterlacer"
+msgstr ""
+
msgid "Video Framing"
msgstr "Aspect de l'image"
diff --git a/po/hu_HU.po b/po/hu_HU.po
index 7206b02..fa8130e 100644
--- a/po/hu_HU.po
+++ b/po/hu_HU.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: vdr-rpihddevice 1.0.0\n"
"Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2015-03-14 19:22+0100\n"
+"POT-Creation-Date: 2016-04-27 15:09+0200\n"
"PO-Revision-Date: 2015-10-16 13:49+0200\n"
"Last-Translator: Füley István <ifuley at tigercomp dot ro>\n"
"Language-Team: Hungarian\n"
@@ -54,12 +54,21 @@ msgstr "alapértelmezett"
msgid "follow video"
msgstr "video szerinti"
+msgid "for SD video only"
+msgstr "csak SD videónál"
+
+msgid "always"
+msgstr "mindig"
+
msgid "Resolution"
msgstr "Felbontás"
msgid "Frame Rate"
msgstr "Képfrissítés"
+msgid "Use Advanced Deinterlacer"
+msgstr "Fejlett deinterlacer használata"
+
msgid "Video Framing"
msgstr "Video képarány"
diff --git a/po/it_IT.po b/po/it_IT.po
index c21fd2e..3b35087 100644
--- a/po/it_IT.po
+++ b/po/it_IT.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: vdr-rpihddevice 1.0.0\n"
"Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2015-10-14 17:58+0200\n"
+"POT-Creation-Date: 2016-04-27 15:09+0200\n"
"PO-Revision-Date: 2015-10-15 07:01+0100\n"
"Last-Translator: Gerlando Falauto <gerlando.falauto at gmail.com>\n"
"Language-Team: Italian\n"
@@ -53,12 +53,21 @@ msgstr "default"
msgid "follow video"
msgstr "come nel video"
+msgid "for SD video only"
+msgstr ""
+
+msgid "always"
+msgstr ""
+
msgid "Resolution"
msgstr "Risoluzione"
msgid "Frame Rate"
msgstr "Frequenza fotogrammi"
+msgid "Use Advanced Deinterlacer"
+msgstr ""
+
msgid "Video Framing"
msgstr "Rapporto d'aspetto"
diff --git a/setup.c b/setup.c
index 99b90d6..1ad488b 100644
--- a/setup.c
+++ b/setup.c
@@ -59,10 +59,12 @@ public:
m_videoResolution[0] = tr("default");
m_videoResolution[1] = tr("follow video");
- m_videoResolution[2] = "720x480";
- m_videoResolution[3] = "720x576";
- m_videoResolution[4] = "1280x720";
- m_videoResolution[5] = "1920x1080";
+ m_videoResolution[2] = "720x480 (4:3)";
+ m_videoResolution[3] = "720x480 (16:9)";
+ m_videoResolution[4] = "720x576 (4:3)";
+ m_videoResolution[5] = "720x576 (16:9)";
+ m_videoResolution[6] = "1280x720";
+ m_videoResolution[7] = "1920x1080";
m_videoFrameRate[0] = tr("default");
m_videoFrameRate[1] = tr("follow video");
@@ -74,6 +76,10 @@ public:
m_videoFrameRate[7] = "60i";
m_videoFrameRate[8] = "60p";
+ m_useAdvancedDeinterlacer[0] = trVDR("no");
+ m_useAdvancedDeinterlacer[1] = tr("for SD video only");
+ m_useAdvancedDeinterlacer[2] = tr("always");
+
Setup();
}
@@ -101,6 +107,7 @@ protected:
SetupStore("VideoFraming", m_video.framing);
SetupStore("Resolution", m_video.resolution);
SetupStore("FrameRate", m_video.frameRate);
+ SetupStore("AdvancedDeinterlacer", m_video.advancedDeinterlacer);
SetupStore("AcceleratedOsd", m_osd.accelerated);
@@ -117,11 +124,16 @@ private:
if (!cRpiDisplay::IsFixedMode())
{
Add(new cMenuEditStraItem(
- tr("Resolution"), &m_video.resolution, 6, m_videoResolution));
+ tr("Resolution"), &m_video.resolution, 8, m_videoResolution));
Add(new cMenuEditStraItem(
tr("Frame Rate"), &m_video.frameRate, 9, m_videoFrameRate));
}
+ if (cRpiDisplay::IsProgressive())
+ Add(new cMenuEditStraItem(
+ tr("Use Advanced Deinterlacer"),
+ &m_video.advancedDeinterlacer, 3,
+ m_useAdvancedDeinterlacer));
Add(new cMenuEditStraItem(
tr("Video Framing"), &m_video.framing, 3, m_videoFraming));
@@ -149,8 +161,9 @@ private:
const char *m_audioPort[2];
const char *m_audioFormat[3];
const char *m_videoFraming[3];
- const char *m_videoResolution[6];
+ const char *m_videoResolution[8];
const char *m_videoFrameRate[9];
+ const char *m_useAdvancedDeinterlacer[3];
};
/* ------------------------------------------------------------------------- */
@@ -222,6 +235,9 @@ bool cRpiSetup::IsAudioFormatSupported(cAudioCodec::eCodec codec,
if (codec == cAudioCodec::eMPG || codec == cAudioCodec::eAAC)
return false;
+ if (channels < 2 || channels > 6)
+ return false;
+
switch (GetAudioFormat())
{
case cAudioFormat::ePassThrough:
@@ -310,6 +326,8 @@ bool cRpiSetup::Parse(const char *name, const char *value)
m_video.resolution = atoi(value);
else if (!strcasecmp(name, "FrameRate"))
m_video.frameRate = atoi(value);
+ else if (!strcasecmp(name, "AdvancedDeinterlacer"))
+ m_video.advancedDeinterlacer = atoi(value);
else if (!strcasecmp(name, "AcceleratedOsd"))
m_osd.accelerated = atoi(value);
else return false;
diff --git a/setup.h b/setup.h
index a91b8e1..f33d5ea 100644
--- a/setup.h
+++ b/setup.h
@@ -52,15 +52,18 @@ public:
VideoParameters() :
framing(0),
resolution(0),
- frameRate(0) { }
+ frameRate(0),
+ advancedDeinterlacer(1){ }
int framing;
int resolution;
int frameRate;
+ int advancedDeinterlacer;
bool operator!=(const VideoParameters& a) {
return (a.framing != framing) || (a.resolution != resolution) ||
- (a.frameRate != frameRate);
+ (a.frameRate != frameRate) ||
+ (a.advancedDeinterlacer != advancedDeinterlacer);
}
};
@@ -108,9 +111,11 @@ public:
static cVideoResolution::eResolution GetVideoResolution(void) {
return GetInstance()->m_video.resolution == 1 ? cVideoResolution::eFollowVideo :
GetInstance()->m_video.resolution == 2 ? cVideoResolution::e480 :
- GetInstance()->m_video.resolution == 3 ? cVideoResolution::e576 :
- GetInstance()->m_video.resolution == 4 ? cVideoResolution::e720 :
- GetInstance()->m_video.resolution == 5 ? cVideoResolution::e1080 :
+ GetInstance()->m_video.resolution == 3 ? cVideoResolution::e480w :
+ GetInstance()->m_video.resolution == 4 ? cVideoResolution::e576 :
+ GetInstance()->m_video.resolution == 5 ? cVideoResolution::e576w :
+ GetInstance()->m_video.resolution == 6 ? cVideoResolution::e720 :
+ GetInstance()->m_video.resolution == 7 ? cVideoResolution::e1080 :
cVideoResolution::eDontChange;
}
@@ -126,6 +131,12 @@ public:
cVideoFrameRate::eDontChange;
}
+ static bool UseAdvancedDeinterlacer(int width, int height) {
+ return GetInstance()->m_video.advancedDeinterlacer == 0 ? false :
+ GetInstance()->m_video.advancedDeinterlacer == 1 ?
+ (width * height <= 576 * 720 ? true : false) : true;
+ }
+
static bool IsAudioFormatSupported(cAudioCodec::eCodec codec,
int channels, int samplingRate);
diff --git a/tools.c b/tools.c
new file mode 100644
index 0000000..e807045
--- /dev/null
+++ b/tools.c
@@ -0,0 +1,111 @@
+/*
+ * rpihddevice - VDR HD output device for Raspberry Pi
+ * Copyright (C) 2014, 2015, 2016 Thomas Reufer
+ *
+ * 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 <limits.h>
+#include <vdr/tools.h>
+#include "tools.h"
+#include <algorithm>
+
+/*
+ * ffmpeg's implementation for rational numbers:
+ * https://github.com/FFmpeg/FFmpeg/blob/master/libavutil/rational.c
+ */
+
+cRational::cRational(double d) :
+ num(0), den(0)
+{
+ int exp;
+ frexp(d, &exp);
+
+ den = 1LL << (29 - std::max(exp - 1, 0));
+ num = floor(d * den + 0.5);
+
+ Reduce(INT_MAX);
+}
+
+bool cRational::Reduce(int max)
+{
+ cRational a0 = cRational(0, 1), a1 = cRational(1, 0);
+ int sign = (num < 0) ^ (den < 0);
+ if (int div = Gcd(abs(num), abs(den)))
+ {
+ num = abs(num) / div;
+ den = abs(den) / div;
+ }
+ if (num <= max && den <= max)
+ {
+ a1 = cRational(num, den);
+ den = 0;
+ }
+ while (den)
+ {
+ int x = num / den;
+ int nextDen = num - den * x;
+ cRational a2 = cRational(x * a1.num + a0.num, x * a1.den + a0.den);
+ if (a2.num > max || a2.den > max)
+ {
+ if (a1.num)
+ x = (max - a0.num) / a1.num;
+ if (a1.den)
+ x = std::min(x, (max - a0.den) / a1.den);
+ if (den * (2 * x * a1.den + a0.den) > num * a1.den)
+ a1 = cRational(x * a1.num + a0.num, x * a1.den + a0.den);
+ break;
+ }
+ a0 = a1;
+ a1 = a2;
+ num = den;
+ den = nextDen;
+ }
+ num = sign ? -a1.num : a1.num;
+ den = a1.den;
+ return den == 0;
+}
+
+/*
+ * Stein's binary GCD algorithm:
+ * https://en.wikipedia.org/wiki/Binary_GCD_algorithm
+ */
+
+int cRational::Gcd(int u, int v)
+{
+ if (u == v || v == 0)
+ return u;
+
+ if (u == 0)
+ return v;
+
+ // look for factors of 2
+ if (~u & 1) // u is even
+ {
+ if (v & 1) // v is odd
+ return Gcd(u >> 1, v);
+ else // both u and v are even
+ return Gcd(u >> 1, v >> 1) << 1;
+ }
+
+ if (~v & 1) // u is odd, v is even
+ return Gcd(u, v >> 1);
+
+ // reduce larger argument
+ if (u > v)
+ return Gcd((u - v) >> 1, v);
+
+ return Gcd((v - u) >> 1, u);
+}
diff --git a/tools.h b/tools.h
index c6d198f..4a1a6c5 100644
--- a/tools.h
+++ b/tools.h
@@ -38,7 +38,9 @@ public:
eDontChange = 0,
eFollowVideo,
e480,
+ e480w,
e576,
+ e576w,
e720,
e1080
};
@@ -47,7 +49,9 @@ public:
return (resolution == eDontChange) ? "don't change" :
(resolution == eFollowVideo) ? "follow video" :
(resolution == e480) ? "480" :
+ (resolution == e480w) ? "480w" :
(resolution == e576) ? "576" :
+ (resolution == e576w) ? "576w" :
(resolution == e720) ? "720" :
(resolution == e1080) ? "1080" : "unknown";
}
@@ -215,4 +219,22 @@ public:
}
};
+class cRational
+{
+public:
+
+ cRational(double d);
+ cRational(int _num, int _den) : num(_num), den(_den) { }
+
+ bool Reduce(int max);
+
+ int num;
+ int den;
+
+private:
+
+ cRational();
+ static int Gcd(int u, int v);
+};
+
#endif
--
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