403 changes: 226 additions & 177 deletions mythplugins/mytharchive/mythburn/scripts/mythburn.py

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion mythplugins/settings.pro
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ CONFIG += $$CCONFIG
# enable C++11 support, QT5.7 will be based on C++11 anyway
CONFIG += c++11

LIBVERSION = 31
LIBVERSION = 32

MY_INSTALL_INCLUDE = $${SYSROOT}$${PREFIX}/include
!contains(MY_INSTALL_INCLUDE, /usr/include$) {
Expand Down
2 changes: 1 addition & 1 deletion mythtv/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
SOURCE_VERSION="v31-Pre"
SOURCE_VERSION="v32-Pre"
2 changes: 1 addition & 1 deletion mythtv/bindings/python/MythTV/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -1167,7 +1167,7 @@ def __init__(self, db, log, host):
self._db = db
self._host = host
self._log = log
if host is 'NULL':
if host == 'NULL':
self._insert = """INSERT INTO settings
(value, data, hostname)
VALUES (?, ?, NULL)"""
Expand Down
2 changes: 1 addition & 1 deletion mythtv/bindings/python/MythTV/services_api/send.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
# an HTTP POST is potentially dangerous. #
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #

MYTHTV_VERSION_LIST = ('0.27', '0.28', '29', '30', '31')
MYTHTV_VERSION_LIST = ('0.27', '0.28', '29', '30', '31', '32')


class Send(object):
Expand Down
2 changes: 1 addition & 1 deletion mythtv/bindings/python/MythTV/static.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
Contains any static and global variables for MythTV Python Bindings
"""

OWN_VERSION = (30,0,-1,0)
OWN_VERSION = (32,0,-1,0)
SCHEMA_VERSION = 1360
NVSCHEMA_VERSION = 1007
MUSICSCHEMA_VERSION = 1024
Expand Down
6 changes: 3 additions & 3 deletions mythtv/bindings/python/MythTV/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def command(self, *args):
stderr will be available in the exception and this object
as attributes 'returncode' and 'stderr'.
"""
if self.path is '':
if self.path == '':
return ''
cmd = '%s %s' % (self.path, ' '.join(['%s' % a for a in args]))
return self._runcmd(cmd)
Expand Down Expand Up @@ -165,7 +165,7 @@ def append(self, *args):
self.path += ' '+' '.join(['%s' % a for a in args])

def _runasync(self, *args):
if self.path is '':
if self.path == '':
return ''
cmd = '%s %s' % (self.path, ' '.join(['%s' % a for a in args]))
return self.Process(cmd, self.useshell, self.log)
Expand Down Expand Up @@ -441,7 +441,7 @@ def command(self, eventdata):
stderr will be available in the exception and this object
as attributes 'returncode' and 'stderr'.
"""
if self.path is '':
if self.path == '':
return
cmd = self.path
if 'program' in eventdata:
Expand Down
2 changes: 1 addition & 1 deletion mythtv/bindings/python/MythTV/utility/other.py
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ def _buildlist(self, ms, me):
if len(start) > len(stop):
# endpoint missing, no known better option
stop.append(9999999)
return zip(start, stop)
return list(zip(start, stop))

def levenshtein(s1, s2):
"""Compute the Levenshtein distance of two strings."""
Expand Down
2 changes: 1 addition & 1 deletion mythtv/bindings/python/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ def run(self):

setup(
name='MythTV',
version='31.0.-1',
version='32.0.-1',
description='MythTV Python bindings.',
long_description='Provides canned database and protocol access to the MythTV database, mythproto, mythxml, services_api and frontend remote control.',
packages=['MythTV', 'MythTV/tmdb3', 'MythTV/ttvdb',
Expand Down
91 changes: 56 additions & 35 deletions mythtv/configure
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ Advanced options (experts only):
directory with frontend.h [$dvb_path_default]
--disable-asi disable support for DVEO ASI recorder
--disable-x11 disable X11 support
--enable-opengles link to OpenGL ES (auto)
--x11-path=X11LOC location of X11 include files [$x11_path_default]
--disable-xrandr disable X11 resolution switching
--disable-vdpau disable NVidia VDPAU hardware acceleration.
Expand Down Expand Up @@ -2768,7 +2769,6 @@ enable mheg
enable mmal
enable mythtranscode
enable opengl
enable opengles
enable egl
enable symbol_visibility
enable deprecation_warnings
Expand Down Expand Up @@ -3000,6 +3000,8 @@ for opt do
;;
--enable-mac-bundle) enable mac_bundle
;;
--enable-opengles) enable opengles && disable opengl
;;
--previous|--prev)
echo "No history of previous configure parameters."
;;
Expand Down Expand Up @@ -3328,7 +3330,6 @@ if enabled set_cc_default; then
cc="$cc_default"
cxx="$cxx_default"
fi
echo "cc_default $cc_default , ${cross_prefix_cc}"
nm_default="${cross_prefix}${nm_default}"
pkg_config_default="${cross_prefix}${pkg_config_default}"
if ${cross_prefix}${ranlib_default} 2>&1 | grep -q "\-D "; then
Expand Down Expand Up @@ -5983,27 +5984,6 @@ enabled libx264 && { use_pkg_config libx264 x264 "stdint.h x264.h" x26
{ check_cpp_condition x264.h "X264_MPEG2" &&
enable libx262; }
enabled libxml2 && require_pkg_config libxml2 libxml-2.0 libxml/xmlversion.h xmlCheckVersion
enabled opengl && { check_lib opengl GL/glx.h glXGetProcAddress "-lGL" ||
check_lib opengl windows.h wglGetProcAddress "-lopengl32 -lgdi32" ||
check_lib opengl OpenGL/gl3.h glGetError "-Wl,-framework,OpenGL" ||
check_lib opengl ES2/gl.h glGetError "-isysroot=${sysroot} -Wl,-framework,OpenGLES" ||
check_lib opengl GLES/gl.h glGetError "-Wl,-framework,OpenGLES" ||
{ check_pkg_config GLESv2 glesv2 GLES2/gl2.h glGetError &&
check_pkg_config EGL egl EGL/egl.h eglGetProcAddress &&
enable opengl
} ||
{ check_lib GLESv2 GLES2/gl2.h glGetError "-lGLESv2" &&
check_lib EGL EGL/egl.h eglGetProcAddress "-lEGL" &&
enable opengl
} ||
die "ERROR: opengl not found."
}

enabled egl && { check_lib EGL EGL/egl.h eglGetProcAddress "-lEGL" ||
{
check_pkg_config EGL egl EGL/egl.h eglGetProcAddress && enable egl
}
}

enabled drm && use_pkg_config libdrm libdrm xf86drm.h drmGetVersion || disable drm
enabled drm && check_cpp_condition drm_fourcc.h 'defined(DRM_FORMAT_MOD_LINEAR)' || disable drm
Expand Down Expand Up @@ -6440,12 +6420,9 @@ if test $target_os = mingw32 ; then
elif test $target_os = darwin ; then
qt_inc="-I`cd $(${qmake} -query QT_INSTALL_HEADERS); pwd` -F`cd $(${qmake} -query QT_INSTALL_LIBS); pwd`"
qt_libs="-L`cd $(${qmake} -query QT_INSTALL_LIBS) ; pwd`"
elif test $target_os = android ; then
else
qt_inc="-I$(${qmake} -query QT_INSTALL_HEADERS)"
qt_libs="-L$(${qmake} -query QT_INSTALL_LIBS)"
else
qt_inc="-I${sysroot}/$(${qmake} -query QT_INSTALL_HEADERS)"
qt_libs="-L${sysroot}/$(${qmake} -query QT_INSTALL_LIBS)"
fi

qt_compiler_check() {
Expand Down Expand Up @@ -6492,6 +6469,57 @@ case "$cc_type" in
;;
esac

# we need either OpenGL or OpenGL ES and 'ideally' the same version that Qt was
# configured with. Linking to both can cause problems on some systems.
# opengl is enabled by default (and hence opengles is disabled by default)

qt_opengles_check() {
log "qt_opengles_check $@"
"qt_opengles_check $@" >> $logfile 2>&1
check_ecxx ${qt_inc} <<EOF
#include <QtCore/QtCore>
#if QT_VERSION >= QT_VERSION_CHECK(5,8,0)
#include <QtGui/qtguiglobal.h>
#endif
#if !defined(QT_OPENGL_ES_2)
No OpenGL ES here!
#endif
int x;
EOF
}

qt_opengles_check && enable opengles && disable opengl && echo Qt built for OpenGL ES

enabled opengl && { check_lib opengl GL/glx.h glXGetProcAddress "-lGL" ||
check_lib opengl windows.h wglGetProcAddress "-lopengl32 -lgdi32" ||
check_lib opengl OpenGL/gl3.h glGetError "-Wl,-framework,OpenGL" || disable opengl
}

disabled opengl || enabled opengles && {
check_lib opengl ES2/gl.h glGetError "-isysroot=${sysroot} -Wl,-framework,OpenGLES" ||
check_lib opengl GLES/gl.h glGetError "-Wl,-framework,OpenGLES" ||
{ check_pkg_config GLESv2 glesv2 GLES2/gl2.h glGetError &&
check_pkg_config EGL egl EGL/egl.h eglGetProcAddress &&
enable opengles
} ||
{ check_lib GLESv2 GLES2/gl2.h glGetError "-lGLESv2" &&
check_lib EGL EGL/egl.h eglGetProcAddress "-lEGL" &&
enable opengles
} ||
disable opengles
}

enabled opengles && enable opengl
if disabled opengl; then
die "Neither OpenGL or OpenGLES found!"
fi

enabled egl && { check_lib EGL EGL/egl.h eglGetProcAddress "-lEGL" ||
{
check_pkg_config EGL egl EGL/egl.h eglGetProcAddress && enable egl
}
}

enable enforce_wshadow
case $target_os in
android)
Expand Down Expand Up @@ -6624,12 +6652,6 @@ if enabled taglib; then
taglib_libs=`taglib-config --libs`
fi

if enabled x11; then
if enabled opengles; then
check_libx gl_lib GLES2/gl2.h glClear -lGLESv2 || disable opengles
fi
fi

enabled x11 && check_lib X11 "X11/Xdefs.h X11/Xlib.h" XQueryExtension -lX11 || disable x11
enabled xrandr && check_lib Xrandr "X11/Xdefs.h X11/Xlib.h X11/extensions/Xrandr.h" XRRSelectInput -lXrandr || disable xrandr

Expand Down Expand Up @@ -7390,8 +7412,7 @@ fi
echo "DRM support ${drm-no}"
echo "Video4Linux codecs ${v4l2-no} (DRM ${v4l2prime-no})"
echo "MMAL decoder support ${mmal-no}"
echo "OpenGL support ${opengl-no}"
echo "OpenGL ES 2.0 ${opengles-no}"
echo "OpenGL ${opengl-no} (OpenGLES ${opengles-no})"
echo "EGL support ${egl-no}"
if test x"$target_os" = x"mingw32" ; then
echo "Windows (Direct3D) yes"
Expand Down
1 change: 1 addition & 0 deletions mythtv/database/mc.sql
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
CREATE DATABASE IF NOT EXISTS mythconverg;
CREATE USER IF NOT EXISTS 'mythtv'@'localhost' IDENTIFIED BY 'mythtv';
ALTER USER 'mythtv'@'localhost' IDENTIFIED WITH mysql_native_password;
GRANT ALL ON mythconverg.* TO mythtv@localhost;
FLUSH PRIVILEGES;
GRANT CREATE TEMPORARY TABLES ON mythconverg.* TO mythtv@localhost;
Expand Down
8 changes: 4 additions & 4 deletions mythtv/external/FFmpeg/libavcodec/v4l2_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ static inline V4L2m2mContext *ctx_to_m2mctx(V4L2Context *ctx)

static inline AVClass *logger(V4L2Context *ctx)
{
return ctx_to_m2mctx(ctx)->priv;
return ctx_to_m2mctx(ctx)->avctx;
}

static inline unsigned int v4l2_get_width(struct v4l2_format *fmt)
Expand Down Expand Up @@ -278,7 +278,7 @@ static V4L2Buffer* v4l2_dequeue_v4l2buf(V4L2Context *ctx, int timeout)
{
struct v4l2_plane planes[VIDEO_MAX_PLANES];
struct v4l2_buffer buf = { 0 };
V4L2Buffer* avbuf = NULL;
V4L2Buffer *avbuf;
struct pollfd pfd = {
.events = POLLIN | POLLRDNORM | POLLPRI | POLLOUT | POLLWRNORM, /* default blocking capture */
.fd = ctx_to_m2mctx(ctx)->fd,
Expand Down Expand Up @@ -635,7 +635,7 @@ int ff_v4l2_context_enqueue_packet(V4L2Context* ctx, const AVPacket* pkt)

int ff_v4l2_context_dequeue_frame(V4L2Context* ctx, AVFrame* frame, int timeout)
{
V4L2Buffer* avbuf = NULL;
V4L2Buffer *avbuf;

/*
* timeout=-1 blocks until:
Expand All @@ -655,7 +655,7 @@ int ff_v4l2_context_dequeue_frame(V4L2Context* ctx, AVFrame* frame, int timeout)

int ff_v4l2_context_dequeue_packet(V4L2Context* ctx, AVPacket* pkt)
{
V4L2Buffer* avbuf = NULL;
V4L2Buffer *avbuf;

/*
* blocks until:
Expand Down
32 changes: 16 additions & 16 deletions mythtv/external/FFmpeg/libavcodec/v4l2_m2m.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@ static inline int v4l2_mplane_video(struct v4l2_capability *cap)
return 0;
}

static int v4l2_prepare_contexts(V4L2m2mContext* s, int probe)
static int v4l2_prepare_contexts(V4L2m2mContext *s, int probe)
{
struct v4l2_capability cap;
void *log_ctx = s->priv;
void *log_ctx = s->avctx;
int ret;

s->capture.done = s->output.done = 0;
Expand Down Expand Up @@ -97,9 +97,9 @@ static int v4l2_prepare_contexts(V4L2m2mContext* s, int probe)
return AVERROR(EINVAL);
}

static int v4l2_probe_driver(V4L2m2mContext* s)
static int v4l2_probe_driver(V4L2m2mContext *s)
{
void *log_ctx = s->priv;
void *log_ctx = s->avctx;
int ret;

s->fd = open(s->devname, O_RDWR | O_NONBLOCK, 0);
Expand Down Expand Up @@ -133,9 +133,9 @@ static int v4l2_probe_driver(V4L2m2mContext* s)
return ret;
}

static int v4l2_configure_contexts(V4L2m2mContext* s)
static int v4l2_configure_contexts(V4L2m2mContext *s)
{
void *log_ctx = s->priv;
void *log_ctx = s->avctx;
int ret;
struct v4l2_format ofmt, cfmt;

Expand Down Expand Up @@ -176,7 +176,7 @@ static int v4l2_configure_contexts(V4L2m2mContext* s)
}

/* decoder's buffers need to be updated at a later stage */
if (!s->avctx || !av_codec_is_decoder(s->avctx->codec)) {
if (s->avctx && !av_codec_is_decoder(s->avctx->codec)) {
ret = ff_v4l2_context_init(&s->capture);
if (ret) {
av_log(log_ctx, AV_LOG_ERROR, "no v4l2 capture context's buffers\n");
Expand All @@ -202,9 +202,9 @@ static int v4l2_configure_contexts(V4L2m2mContext* s)
* V4L2 M2M Interface
*
******************************************************************************/
int ff_v4l2_m2m_codec_reinit(V4L2m2mContext* s)
int ff_v4l2_m2m_codec_reinit(V4L2m2mContext *s)
{
void *log_ctx = s->priv;
void *log_ctx = s->avctx;
int ret;

av_log(log_ctx, AV_LOG_DEBUG, "reinit context\n");
Expand Down Expand Up @@ -307,7 +307,7 @@ int ff_v4l2_m2m_codec_full_reinit(V4L2m2mContext *s)
}

/* decoder's buffers need to be updated at a later stage */
if (!s->avctx || !av_codec_is_decoder(s->avctx->codec)) {
if (s->avctx && !av_codec_is_decoder(s->avctx->codec)) {
ret = ff_v4l2_context_init(&s->capture);
if (ret) {
av_log(log_ctx, AV_LOG_ERROR, "no v4l2 capture context's buffers\n");
Expand Down Expand Up @@ -335,16 +335,16 @@ static void v4l2_m2m_destroy_context(void *opaque, uint8_t *context)

int ff_v4l2_m2m_codec_end(V4L2m2mPriv *priv)
{
V4L2m2mContext* s = priv->context;
V4L2m2mContext *s = priv->context;
int ret;

ret = ff_v4l2_context_set_status(&s->output, VIDIOC_STREAMOFF);
if (ret)
av_log(priv, AV_LOG_ERROR, "VIDIOC_STREAMOFF %s\n", s->output.name);
av_log(s->avctx, AV_LOG_ERROR, "VIDIOC_STREAMOFF %s\n", s->output.name);

ret = ff_v4l2_context_set_status(&s->capture, VIDIOC_STREAMOFF);
if (ret)
av_log(priv, AV_LOG_ERROR, "VIDIOC_STREAMOFF %s\n", s->capture.name);
av_log(s->avctx, AV_LOG_ERROR, "VIDIOC_STREAMOFF %s\n", s->capture.name);

ff_v4l2_context_release(&s->output);

Expand Down Expand Up @@ -373,7 +373,7 @@ int ff_v4l2_m2m_codec_init(V4L2m2mPriv *priv)
continue;

snprintf(node, sizeof(node), "/dev/%s", entry->d_name);
av_log(priv, AV_LOG_DEBUG, "probing device %s\n", node);
av_log(s->avctx, AV_LOG_DEBUG, "probing device %s\n", node);
strncpy(s->devname, node, strlen(node) + 1);
ret = v4l2_probe_driver(s);
if (!ret)
Expand All @@ -383,13 +383,13 @@ int ff_v4l2_m2m_codec_init(V4L2m2mPriv *priv)
closedir(dirp);

if (ret) {
av_log(priv, AV_LOG_ERROR, "Could not find a valid device\n");
av_log(s->avctx, AV_LOG_ERROR, "Could not find a valid device\n");
memset(s->devname, 0, sizeof(s->devname));

return ret;
}

av_log(priv, AV_LOG_INFO, "Using device %s\n", node);
av_log(s->avctx, AV_LOG_INFO, "Using device %s\n", node);

return v4l2_configure_contexts(s);
}
Expand Down
2 changes: 1 addition & 1 deletion mythtv/external/FFmpeg/libavcodec/v4l2_m2m_dec.c
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ static av_cold int v4l2_decode_init(AVCodecContext *avctx)
static av_cold int v4l2_decode_close(AVCodecContext *avctx)
{
V4L2m2mPriv *priv = avctx->priv_data;
V4L2m2mContext* s = priv->context;
V4L2m2mContext *s = priv->context;
av_packet_unref(&s->buf_pkt);
return ff_v4l2_m2m_codec_end(priv);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
#define CU_CTX_SCHED_BLOCKING_SYNC 4

typedef int CUdevice;
#if defined(__x86_64) || defined(AMD64) || defined(_M_AMD64)
#if defined(__x86_64) || defined(AMD64) || defined(_M_AMD64) || defined(__LP64__)
typedef unsigned long long CUdeviceptr;
#else
typedef unsigned int CUdeviceptr;
Expand Down
2 changes: 1 addition & 1 deletion mythtv/libs/libmythbase/mythversion.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
/// Update this whenever the plug-in ABI changes.
/// Including changes in the libmythbase, libmyth, libmythtv, libmythav* and
/// libmythui class methods in exported headers.
#define MYTH_BINARY_VERSION "31.20200101-1"
#define MYTH_BINARY_VERSION "32.20200101-1"

/** \brief Increment this whenever the MythTV network protocol changes.
* Note that the token currently cannot contain spaces.
Expand Down
3 changes: 3 additions & 0 deletions mythtv/libs/libmythtv/channelscan/paneatsc.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ class PaneATSC : public GroupSetting
}
}

void SetFrequencyTable(const QString &atsc_table)
{ m_atsc_table->setValue(atsc_table); }

QString GetFrequencyTable(void) const
{ return m_atsc_table->getValue(); }
QString GetModulation(void) const
Expand Down
43 changes: 39 additions & 4 deletions mythtv/libs/libmythtv/channelscan/scanwizardconfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,26 +114,49 @@ void ScanWizard::SetPaneDefaults(const QString &cardid_inputname)
{
const int sourceid = m_videoSource->getValue().toInt();
uint scanfrequency = 0;
QString freqtable;

MSqlQuery query(MSqlQuery::InitCon());
query.prepare(
"SELECT scanfrequency "
"SELECT scanfrequency, freqtable "
"FROM videosource "
"WHERE videosource.sourceid = :SOURCEID ;");
query.bindValue(":SOURCEID", sourceid);
if (!query.exec() || !query.isActive())
{
MythDB::DBError("ScanOptionalConfig::SetPaneDefaults", query);
return;
}
else if (query.next())
{
scanfrequency = query.value(0).toUInt();
freqtable = query.value(1).toString();
LOG(VB_CHANSCAN, LOG_DEBUG,
QString("SetPaneDefaults cardid_inputname:%1 sourceid:%2 frequency:%3")
.arg(cardid_inputname).arg(sourceid).arg(scanfrequency));
QString("SetPaneDefaults cardid_inputname:%1 sourceid:%2 scanfrequency:%3 freqtable:%4")
.arg(cardid_inputname).arg(sourceid).arg(scanfrequency).arg(freqtable));
}

// Channel Frequency Table for ATSC
// Use general setting if not defined in the videosource
{
if (freqtable == "default")
{
freqtable = gCoreContext->GetSetting("FreqTable");
}
QString table;
table = (freqtable == "us-bcast" ) ? "us" : table;
table = (freqtable == "us-cable" ) ? "uscable" : table;
table = (freqtable == "us-cable-hrc") ? "ushrc" : table;
table = (freqtable == "us-cable-irc") ? "usirc" : table;
if (!table.isEmpty())
{
LOG(VB_CHANSCAN, LOG_DEBUG,
QString("SetPaneDefaults ATSC frequency table:'%1'").arg(table));
m_scanConfig->SetTuningPaneValuesATSC(table);
}
}

// Set defaults only when a frequency has been entered.
// Set "Full Scan (Tuned)" defaults only when a frequency has been entered.
if (scanfrequency == 0)
return;

Expand Down Expand Up @@ -636,3 +659,15 @@ void ScanOptionalConfig::SetTuningPaneValues(uint frequency, const DTVMultiplex
}
}
}

void ScanOptionalConfig::SetTuningPaneValuesATSC(const QString &freqtable)
{
const int st = m_scanType->getValue().toInt();

if (st == ScanTypeSetting::FullScan_ATSC)
{
PaneATSC *pane = m_paneATSC;

pane->SetFrequencyTable(freqtable);
}
}
1 change: 1 addition & 0 deletions mythtv/libs/libmythtv/channelscan/scanwizardconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ class ScanOptionalConfig : public GroupSetting
QMap<QString,QString> GetStartChan(void) const;
uint GetScanID(void) const;
void SetTuningPaneValues(uint frequency, const DTVMultiplex &mpx);
void SetTuningPaneValuesATSC(const QString &freqtable);

public slots:
void SetSourceID(const QString &sourceid);
Expand Down
26 changes: 23 additions & 3 deletions mythtv/libs/libmythtv/decoders/avformatdecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,7 @@ __inline AVRational GetAVTimeBaseQ()
// Maximum number of sequential invalid data packet errors before we try
// switching to software decoder. Packet errors are often seen when using
// hardware contexts and, for example, seeking. Hence this needs to be high and
// is probably best removed as it is treating the symptoms and not the cause
// (e.g. VAAPI2 does not currently do any hardware support checks).
// is probably best removed as it is treating the symptoms and not the cause.
// See also comment in MythCodecMap::freeCodecContext re trying to free an
// active hardware context when it is errored.
#define SEQ_PKT_ERR_MAX 50
Expand Down Expand Up @@ -1569,6 +1568,8 @@ void AvFormatDecoder::InitVideoCodec(AVStream *stream, AVCodecContext *enc,

if (selectedStream)
{
// m_fps is now set 'correctly' in ScanStreams so this additional call
// to GetVideoFrameRate may now be redundant
m_fps = GetVideoFrameRate(stream, enc, true);
QSize dim = get_video_dim(*enc);
int width = m_currentWidth = dim.width();
Expand Down Expand Up @@ -2335,10 +2336,14 @@ int AvFormatDecoder::ScanStreams(bool novideo)
QString codecName;
if (enc->codec)
codecName = enc->codec->name;
// framerate appears to never be set - which is probably why
// GetVideoFrameRate never uses it:)
// So fallback to the GetVideoFrameRate call which should then ensure
// the video display profile gets an accurate frame rate - instead of 0
if (enc->framerate.den && enc->framerate.num)
m_fps = float(enc->framerate.num) / float(enc->framerate.den);
else
m_fps = 0;
m_fps = GetVideoFrameRate(stream, enc, true);
if (!m_isDbIgnored)
{
m_videoDisplayProfile.SetInput(QSize(width, height), m_fps, codecName);
Expand Down Expand Up @@ -3172,6 +3177,10 @@ void AvFormatDecoder::MpegPreProcessPkt(AVStream *stream, AVPacket *pkt)
forceaspectchange, 2,
decoderdeint ? kScan_Progressive : kScan_Ignore);

if (context->hw_frames_ctx)
if (context->internal)
avcodec_flush_buffers(context);

m_currentWidth = width;
m_currentHeight = height;
m_fps = seqFPS;
Expand Down Expand Up @@ -3279,6 +3288,17 @@ int AvFormatDecoder::H264PreProcessPkt(AVStream *stream, AVPacket *pkt)
static_cast<int>(m_h264Parser->getRefFrames()),
decoderdeint ? kScan_Progressive : kScan_Ignore);

// the SetVideoParams call above will have released all held frames
// when using a hardware frames context - but for H264 (as opposed to mpeg2)
// the codec will still hold references for reference frames (decoded picture buffer).
// Flushing the context will release these references and the old
// hardware context is released correctly before a new one is created.
// TODO check what is needed here when a device context is used
// TODO check whether any codecs need to be flushed for a frame rate change (e.g. mediacodec?)
if (context->hw_frames_ctx && (forcechange || res_changed))
if (context->internal)
avcodec_flush_buffers(context);

m_currentWidth = width;
m_currentHeight = height;

Expand Down
14 changes: 10 additions & 4 deletions mythtv/libs/libmythtv/decoders/mythcodeccontext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ QStringList MythCodecContext::GetDecoderDescription(void)
#endif
#ifdef USING_V4L2
MythV4L2M2MContext::GetDecoderList(decoders);
#endif
#ifdef USING_VTB
MythVTBContext::GetDecoderList(decoders);
#endif
return decoders;
}
Expand Down Expand Up @@ -183,10 +186,13 @@ void MythCodecContext::GetDecoders(RenderOptions &Opts)
}
#endif
#ifdef USING_VTB
Opts.decoders->append("vtb");
Opts.decoders->append("vtb-dec");
(*Opts.equiv_decoders)["vtb"].append("dummy");
(*Opts.equiv_decoders)["vtb-dec"].append("dummy");
if (MythVTBContext::HaveVTB())
{
Opts.decoders->append("vtb");
Opts.decoders->append("vtb-dec");
(*Opts.equiv_decoders)["vtb"].append("dummy");
(*Opts.equiv_decoders)["vtb-dec"].append("dummy");
}
#endif
#ifdef USING_V4L2
if (MythV4L2M2MContext::HaveV4L2Codecs())
Expand Down
2 changes: 1 addition & 1 deletion mythtv/libs/libmythtv/decoders/mythdrmprimecontext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ MythDRMPRIMEContext::MythDRMPRIMEContext(DecoderBase *Parent, MythCodecID CodecI
MythDRMPRIMEContext::~MythDRMPRIMEContext()
{
if (m_interop)
m_interop->DecrRef();
DestroyInterop(m_interop);
}

MythCodecID MythDRMPRIMEContext::GetPrimeCodec(AVCodecContext **Context,
Expand Down
2 changes: 1 addition & 1 deletion mythtv/libs/libmythtv/decoders/mythmmalcontext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ MythMMALContext::MythMMALContext(DecoderBase *Parent, MythCodecID Codec)
MythMMALContext::~MythMMALContext()
{
if (m_interop)
m_interop->DecrRef();
DestroyInterop(m_interop);
}

MythCodecID MythMMALContext::GetSupportedCodec(AVCodecContext **Context,
Expand Down
64 changes: 63 additions & 1 deletion mythtv/libs/libmythtv/decoders/mythnvdeccontext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ MythNVDECContext::MythNVDECContext(DecoderBase *Parent, MythCodecID CodecID)
{
}

MythNVDECContext::~MythNVDECContext()
{
av_buffer_unref(&m_framesContext);
}

/*! \brief Determine whether NVDEC decoding is supported for this codec.
*
* The objective here is, as for other decoders, to fail fast so that we can fallback
Expand Down Expand Up @@ -338,6 +343,11 @@ void MythNVDECContext::PostProcessFrame(AVCodecContext* /*Context*/, VideoFrame
}
}

bool MythNVDECContext::DecoderWillResetOnFlush(void)
{
return codec_is_nvdec(m_codecID);
}

bool MythNVDECContext::IsDeinterlacing(bool &DoubleRate, bool /*unused*/)
{
if (m_deinterlacer != DEINT_NONE)
Expand All @@ -349,12 +359,21 @@ bool MythNVDECContext::IsDeinterlacing(bool &DoubleRate, bool /*unused*/)
return false;
}

enum AVPixelFormat MythNVDECContext::GetFormat(AVCodecContext* /*Contextconst*/, const AVPixelFormat *PixFmt)
enum AVPixelFormat MythNVDECContext::GetFormat(AVCodecContext* Context, const AVPixelFormat *PixFmt)
{
while (*PixFmt != AV_PIX_FMT_NONE)
{
if (*PixFmt == AV_PIX_FMT_CUDA)
{
AvFormatDecoder* decoder = reinterpret_cast<AvFormatDecoder*>(Context->opaque);
if (decoder)
{
MythNVDECContext* me = dynamic_cast<MythNVDECContext*>(decoder->GetMythCodecContext());
if (me)
me->InitFramesContext(Context);
}
return AV_PIX_FMT_CUDA;
}
PixFmt++;
}
return AV_PIX_FMT_NONE;
Expand Down Expand Up @@ -604,3 +623,46 @@ const std::vector<MythNVDECContext::MythNVDECCaps> &MythNVDECContext::GetProfile

return s_profiles;
}

void MythNVDECContext::InitFramesContext(AVCodecContext *Context)
{
if (!Context)
return;

if (m_framesContext)
{
AVHWFramesContext *frames = reinterpret_cast<AVHWFramesContext*>(m_framesContext->data);
if ((frames->sw_format == Context->sw_pix_fmt) && (frames->width == Context->coded_width) &&
(frames->height == Context->coded_height))
{
Context->hw_frames_ctx = av_buffer_ref(m_framesContext);
return;
}
}

// If this is a 'spontaneous' callback from FFmpeg (i.e. not on a stream change)
// then we must release any direct render buffers.
if (codec_is_nvdec(m_codecID) && m_parent->GetPlayer())
m_parent->GetPlayer()->DiscardVideoFrames(true, true);

av_buffer_unref(&m_framesContext);

AVBufferRef* framesref = av_hwframe_ctx_alloc(Context->hw_device_ctx);
AVHWFramesContext *frames = reinterpret_cast<AVHWFramesContext*>(framesref->data);
frames->free = MythCodecContext::FramesContextFinished;
frames->user_opaque = nullptr;
frames->sw_format = Context->sw_pix_fmt;
frames->format = AV_PIX_FMT_CUDA;
frames->width = Context->coded_width;
frames->height = Context->coded_height;
if (av_hwframe_ctx_init(framesref) < 0)
{
av_buffer_unref(&framesref);
}
else
{
Context->hw_frames_ctx = framesref;
m_framesContext = av_buffer_ref(framesref);
NewHardwareFramesContext();
}
}
7 changes: 6 additions & 1 deletion mythtv/libs/libmythtv/decoders/mythnvdeccontext.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,21 @@ class MythNVDECContext : public MythCodecContext
{
public:
MythNVDECContext(DecoderBase *Parent, MythCodecID CodecID);
~MythNVDECContext() override;
void InitVideoCodec (AVCodecContext *Context, bool SelectedStream, bool &DirectRendering) override;
int HwDecoderInit (AVCodecContext *Context) override;
bool RetrieveFrame (AVCodecContext *Context, VideoFrame *Frame, AVFrame *AvFrame) override;
void SetDeinterlacing (AVCodecContext *Context,
VideoDisplayProfile *Profile, bool DoubleRate) override;
void PostProcessFrame (AVCodecContext *Context, VideoFrame *Frame) override;
bool IsDeinterlacing (bool &DoubleRate, bool StreamChange = false) override;
bool DecoderWillResetOnFlush (void) override;
static MythCodecID GetSupportedCodec (AVCodecContext **CodecContext,
AVCodec **Codec,
const QString &Decoder,
AVStream *Stream,
uint StreamType);
static enum AVPixelFormat GetFormat (AVCodecContext *Contextconst, const AVPixelFormat *PixFmt);
static enum AVPixelFormat GetFormat (AVCodecContext *Context, const AVPixelFormat *PixFmt);
static bool GetBuffer (AVCodecContext *Context, VideoFrame *Frame,
AVFrame *AvFrame, int Flags);
static int InitialiseDecoder (AVCodecContext *Context);
Expand All @@ -64,6 +66,9 @@ class MythNVDECContext : public MythCodecContext
};

private:
void InitFramesContext(AVCodecContext *Context);
AVBufferRef* m_framesContext { nullptr };

static const std::vector<MythNVDECCaps>& GetProfiles(void);
MythDeintType m_deinterlacer { DEINT_NONE };
bool m_deinterlacer2x { false };
Expand Down
2 changes: 2 additions & 0 deletions mythtv/libs/libmythtv/decoders/mythvaapicontext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -627,11 +627,13 @@ void MythVAAPIContext::InitVideoCodec(AVCodecContext *Context, bool SelectedStre
{
Context->get_buffer2 = MythCodecContext::GetBuffer;
Context->get_format = MythVAAPIContext::GetFormat;
Context->slice_flags = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD;
return;
}
if (codec_is_vaapi_dec(m_codecID))
{
Context->get_format = MythVAAPIContext::GetFormat2;
Context->slice_flags = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD;
DirectRendering = false;
return;
}
Expand Down
159 changes: 109 additions & 50 deletions mythtv/libs/libmythtv/decoders/mythvtbcontext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,56 +64,8 @@ int MythVTBContext::HwDecoderInit(AVCodecContext *Context)
return -1;
}

bool MythVTBContext::CheckDecoderSupport(AVCodecContext **Context, uint StreamType)
{
static bool initialised = false;
static QVector<uint> supported;
if (!initialised)
{
initialised = true;
if (__builtin_available(macOS 10.13, *))
{
QStringList debug;
if (VTIsHardwareDecodeSupported(kCMVideoCodecType_MPEG1Video)) { supported.append(1); debug << "MPEG1"; }
if (VTIsHardwareDecodeSupported(kCMVideoCodecType_MPEG2Video)) { supported.append(2); debug << "MPEG2"; }
if (VTIsHardwareDecodeSupported(kCMVideoCodecType_H263)) { supported.append(3); debug << "H.263"; }
if (VTIsHardwareDecodeSupported(kCMVideoCodecType_MPEG4Video)) { supported.append(4); debug << "MPEG4"; }
if (VTIsHardwareDecodeSupported(kCMVideoCodecType_H264)) { supported.append(5); debug << "H.264"; }
if (VTIsHardwareDecodeSupported(kCMVideoCodecType_HEVC)) { supported.append(10); debug << "HEVC"; }
LOG(VB_GENERAL, LOG_INFO, LOC + QString("Supported VideoToolBox codecs: %1").arg(debug.join(",")));
}
else
{
LOG(VB_GENERAL, LOG_INFO, LOC + "Unable to check hardware decode support. Assuming all.");
supported.append(1); supported.append(2); supported.append(3);
supported.append(4); supported.append(5); supported.append(10);
}
}

QString codec = ff_codec_id_string((*Context)->codec_id);
QString profile = avcodec_profile_name((*Context)->codec_id, (*Context)->profile);
QString pixfmt = av_get_pix_fmt_name((*Context)->pix_fmt);

if (!supported.contains(StreamType))
{
LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("HW device type '%1' does not support decoding '%2 %3 %4'")
.arg(av_hwdevice_get_type_name(AV_HWDEVICE_TYPE_VIDEOTOOLBOX))
.arg(codec).arg(profile).arg(pixfmt));
return false;
}

// There is no guarantee (and no obvious way to check) whether the given H264 or HEVC
// profile is actually supported.
bool maybe = (StreamType == 5) || (StreamType == 10);
LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("HW device type '%1' %2 decoding '%3 %4 %5'")
.arg(av_hwdevice_get_type_name(AV_HWDEVICE_TYPE_VIDEOTOOLBOX))
.arg(maybe ? "MAY support" : "supports")
.arg(codec).arg(profile).arg(pixfmt));
return true;
}

MythCodecID MythVTBContext::GetSupportedCodec(AVCodecContext **Context,
AVCodec **,
AVCodec ** Codec,
const QString &Decoder,
uint StreamType)
{
Expand All @@ -125,9 +77,40 @@ MythCodecID MythVTBContext::GetSupportedCodec(AVCodecContext **Context,
return failure;

// Check decoder support
if (!CheckDecoderSupport(Context, StreamType))
MythCodecContext::CodecProfile mythprofile = MythCodecContext::NoProfile;
switch ((*Codec)->id)
{
case AV_CODEC_ID_MPEG1VIDEO: mythprofile = MythCodecContext::MPEG1; break;
case AV_CODEC_ID_MPEG2VIDEO: mythprofile = MythCodecContext::MPEG2; break;
case AV_CODEC_ID_MPEG4: mythprofile = MythCodecContext::MPEG4; break;
case AV_CODEC_ID_H263: mythprofile = MythCodecContext::H263; break;
case AV_CODEC_ID_H264: mythprofile = MythCodecContext::H264; break;
case AV_CODEC_ID_VC1: mythprofile = MythCodecContext::VC1; break;
case AV_CODEC_ID_VP8: mythprofile = MythCodecContext::VP8; break;
case AV_CODEC_ID_VP9: mythprofile = MythCodecContext::VP9; break;
case AV_CODEC_ID_HEVC: mythprofile = MythCodecContext::HEVC; break;
default: break;
}

if (mythprofile == MythCodecContext::NoProfile)
return failure;

QString codec = ff_codec_id_string((*Context)->codec_id);
QString profile = avcodec_profile_name((*Context)->codec_id, (*Context)->profile);
QString pixfmt = av_get_pix_fmt_name((*Context)->pix_fmt);

const VTBProfiles& profiles = MythVTBContext::GetProfiles();
if (!profiles.contains(mythprofile))
{
LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("VideoToolbox does not support decoding '%1 %2 %3'")
.arg(codec).arg(profile).arg(pixfmt));
return failure;
}

// There is no guarantee (and no obvious way to check) whether the given
// profile is actually supported.
LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("VideoToolbox MAY support decoding '%1 %2 %3'")
.arg(codec).arg(profile).arg(pixfmt));
(*Context)->pix_fmt = AV_PIX_FMT_VIDEOTOOLBOX;
return success;
}
Expand Down Expand Up @@ -203,3 +186,79 @@ enum AVPixelFormat MythVTBContext::GetFormat(struct AVCodecContext*, const enum
}
return ret;
}

const VTBProfiles& MythVTBContext::GetProfiles(void)
{
static QMutex lock(QMutex::Recursive);
static bool s_initialised = false;
static VTBProfiles s_profiles;

QMutexLocker locker(&lock);
if (s_initialised)
return s_profiles;
s_initialised = true;

if (__builtin_available(macOS 10.13, *))
{
if (VTIsHardwareDecodeSupported(kCMVideoCodecType_MPEG1Video)) { s_profiles.append(MythCodecContext::MPEG1); }
if (VTIsHardwareDecodeSupported(kCMVideoCodecType_MPEG2Video)) { s_profiles.append(MythCodecContext::MPEG2); }
if (VTIsHardwareDecodeSupported(kCMVideoCodecType_H263)) { s_profiles.append(MythCodecContext::H263); }
if (VTIsHardwareDecodeSupported(kCMVideoCodecType_MPEG4Video)) { s_profiles.append(MythCodecContext::MPEG4); }
if (VTIsHardwareDecodeSupported(kCMVideoCodecType_H264)) { s_profiles.append(MythCodecContext::H264); }
if (VTIsHardwareDecodeSupported(kCMVideoCodecType_HEVC)) { s_profiles.append(MythCodecContext::HEVC); }
}
else
{
LOG(VB_GENERAL, LOG_INFO, LOC + "Unable to check hardware decode support. Assuming all.");
s_profiles.append(MythCodecContext::MPEG1);
s_profiles.append(MythCodecContext::MPEG2);
s_profiles.append(MythCodecContext::H263);
s_profiles.append(MythCodecContext::MPEG4);
s_profiles.append(MythCodecContext::H264);
s_profiles.append(MythCodecContext::HEVC);
}

return s_profiles;
}

bool MythVTBContext::HaveVTB(void)
{
static QMutex lock(QMutex::Recursive);
QMutexLocker locker(&lock);
static bool s_checked = false;
static bool s_available = false;
if (!s_checked)
{
const VTBProfiles& profiles = MythVTBContext::GetProfiles();
if (profiles.empty())
{
LOG(VB_GENERAL, LOG_INFO, LOC + "No VideoToolbox decoders found");
}
else
{
s_available = true;
LOG(VB_GENERAL, LOG_INFO, LOC + "Supported/available VideoToolbox decoders:");
QSize size{0, 0};
for (auto profile : profiles)
{
LOG(VB_GENERAL, LOG_INFO, LOC +
MythCodecContext::GetProfileDescription(profile, size));
}
}
}
s_checked = true;
return s_available;
}

void MythVTBContext::GetDecoderList(QStringList &Decoders)
{
const VTBProfiles& profiles = MythVTBContext::GetProfiles();
if (profiles.isEmpty())
return;

QSize size(0, 0);
Decoders.append("VideoToolbox:");
for (MythCodecContext::CodecProfile profile : profiles)
Decoders.append(MythCodecContext::GetProfileDescription(profile, size));
}

6 changes: 5 additions & 1 deletion mythtv/libs/libmythtv/decoders/mythvtbcontext.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ extern "C" {
#include "libavcodec/avcodec.h"
}

using VTBProfiles = QList<MythCodecContext::CodecProfile>;

class MythVTBContext : public MythCodecContext
{
public:
Expand All @@ -29,9 +31,11 @@ class MythVTBContext : public MythCodecContext
uint StreamType);
static enum AVPixelFormat GetFormat (AVCodecContext *Context,
const enum AVPixelFormat *PixFmt);
static bool HaveVTB (void);
static void GetDecoderList (QStringList &Decoders);

private:
static bool CheckDecoderSupport (AVCodecContext **Context, uint StreamType);
static const VTBProfiles& GetProfiles(void);
static int InitialiseDecoder (AVCodecContext *Context);
};

Expand Down
8 changes: 4 additions & 4 deletions mythtv/libs/libmythtv/decoders/nuppeldecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -278,12 +278,12 @@ int NuppelDecoder::OpenFile(RingBuffer *rbuffer, bool novideo,
{
m_ringBuffer->Read(&m_extraData, frameheader.packetlength);
#if HAVE_BIGENDIAN
struct extendeddata *ed = &m_extradata;
struct extendeddata *ed = &m_extraData;
ed->version = bswap_32(ed->version);
ed->video_fourcc = bswap_32(ed->video_fourcc);
ed->audio_fourcc = bswap_32(ed->audio_fourcc);
ed->audio_sample_rate = bswap_32(ed->audio_sample_rate);
ed->audio_bitsPerSample = bswap_32(ed->audio_BitsPerSample);
ed->audio_bits_per_sample = bswap_32(ed->audio_bits_per_sample);
ed->audio_channels = bswap_32(ed->audio_channels);
ed->audio_compression_ratio = bswap_32(ed->audio_compression_ratio);
ed->audio_quality = bswap_32(ed->audio_quality);
Expand Down Expand Up @@ -493,7 +493,7 @@ int NuppelDecoder::OpenFile(RingBuffer *rbuffer, bool novideo,
m_audioSamplerate = m_extraData.audio_sample_rate;
#if HAVE_BIGENDIAN
// Why only if using extradata?
m_audio_bits_per_sample = m_extraData.audio_bits_per_sample;
m_audioBitsPerSample = m_extraData.audio_bits_per_sample;
#endif
AudioFormat format = FORMAT_NONE;
switch (m_extraData.audio_bits_per_sample)
Expand Down Expand Up @@ -1270,7 +1270,7 @@ bool NuppelDecoder::GetFrame(DecodeType decodetype, bool& /*Retry*/)
#if HAVE_BIGENDIAN
// Why endian correct the audio buffer here?
// Don't big-endian clients have to do it in audiooutBlah.cpp?
if (m_audio_bits_per_sample == 16) {
if (m_audioBitsPerSample == 16) {
// swap bytes
for (int i = 0; i < (m_frameHeader.packetlength & ~1); i+=2) {
char tmp;
Expand Down
2 changes: 0 additions & 2 deletions mythtv/libs/libmythtv/libmythtv.pro
Original file line number Diff line number Diff line change
Expand Up @@ -460,8 +460,6 @@ using_frontend {

using_opengl {
DEFINES += USING_OPENGL
using_opengles: DEFINES += USING_OPENGLES

HEADERS += opengl/mythopenglvideo.h
HEADERS += opengl/mythvideooutopengl.h
HEADERS += opengl/mythopenglvideoshaders.h
Expand Down
2 changes: 1 addition & 1 deletion mythtv/libs/libmythtv/mythframe.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ static inline bool format_is_hw(VideoFrameType Type)

static inline bool format_is_hwframes(VideoFrameType Type)
{
return (Type == FMT_VDPAU) || (Type == FMT_VAAPI);
return (Type == FMT_VDPAU) || (Type == FMT_VAAPI) || (Type == FMT_NVDEC);
}

static inline bool format_is_420(VideoFrameType Type)
Expand Down
24 changes: 9 additions & 15 deletions mythtv/libs/libmythtv/mythplayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ bool MythPlayer::Pause(void)
if (FlagIsSet(kVideoIsNull) && m_decoder)
m_decoder->UpdateFramesPlayed();
else if (m_videoOutput && !FlagIsSet(kVideoIsNull))
m_framesPlayed = m_videoOutput->GetFramesPlayed() + m_framesPlayedExtra;
m_framesPlayed = m_videoOutput->GetFramesPlayed();
}
m_pauseLock.unlock();
return already_paused;
Expand Down Expand Up @@ -860,7 +860,6 @@ int MythPlayer::OpenFile(int Retries)
void MythPlayer::SetFramesPlayed(uint64_t played)
{
m_framesPlayed = played;
m_framesPlayedExtra = 0;
if (m_videoOutput)
m_videoOutput->SetFramesPlayed(played);
}
Expand Down Expand Up @@ -1628,9 +1627,11 @@ void MythPlayer::AVSync(VideoFrame *buffer)
else
framedue = unow + m_frameInterval / 2;

// This code is disabled as it appears to cause multiple issues. It is
// retained for future reference...
// recalculate m_framesPlayed to conform to actual time code.
m_framesPlayed = TranslatePositionMsToFrame(static_cast<uint64_t>(videotimecode + m_timeOffsetBase), false);
m_decoder->SetFramesPlayed(static_cast<long long>(m_framesPlayed));
//m_framesPlayed = TranslatePositionMsToFrame(static_cast<uint64_t>(videotimecode + m_timeOffsetBase), false);
//m_decoder->SetFramesPlayed(static_cast<long long>(m_framesPlayed));

lateness = unow - framedue;
dropframe = false;
Expand Down Expand Up @@ -1723,8 +1724,8 @@ void MythPlayer::AVSync(VideoFrame *buffer)
if (dropframe)
{
LOG(VB_PLAYBACK, LOG_INFO, LOC +
QString("dropping frame to catch up, lateness=%1 usec")
.arg(lateness));
QString("Dropping frame: Video is behind by %1ms").arg(lateness / 1000));
m_videoOutput->SetFramesPlayed(static_cast<long long>(++m_framesPlayed));
}
else if (!FlagIsSet(kVideoIsNull) && buffer)
{
Expand Down Expand Up @@ -1875,11 +1876,6 @@ bool MythPlayer::PrebufferEnoughFrames(int min_buffers)
{
uint64_t frameCount = GetCurrentFrameCount();
uint64_t framesLeft = frameCount - m_framesPlayed;
// Sometimes m_framesPlayed > frameCount. Until that can
// be fixed, set framesLeft = 0 so the forced pause below
// is performed.
if (m_framesPlayed > frameCount)
framesLeft = 0;
auto margin = (uint64_t) (m_videoFrameRate * 3);
if (framesLeft < margin)
{
Expand Down Expand Up @@ -2197,7 +2193,7 @@ bool MythPlayer::VideoLoop(void)
else if (m_decoder && m_decoder->GetEof() != kEofStateNone)
++m_framesPlayed;
else
m_framesPlayed = m_videoOutput->GetFramesPlayed() + m_framesPlayedExtra;
m_framesPlayed = m_videoOutput->GetFramesPlayed();
return !IsErrored();
}

Expand Down Expand Up @@ -2292,7 +2288,7 @@ void MythPlayer::ResetPlaying(bool resetframes)
ClearAfterSeek();
m_ffrewSkip = 1;
if (resetframes)
m_framesPlayed = m_framesPlayedExtra = 0;
m_framesPlayed = 0;
if (m_decoder)
{
m_decoder->Reset(true, true, true);
Expand Down Expand Up @@ -2605,7 +2601,6 @@ bool MythPlayer::StartPlaying(void)
}

m_framesPlayed = 0;
m_framesPlayedExtra = 0;
m_rewindTime = m_ffTime = 0;
m_nextPlaySpeed = m_audio.GetStretchFactor();
m_jumpChapter = 0;
Expand Down Expand Up @@ -4597,7 +4592,6 @@ void MythPlayer::InitForTranscode(bool copyaudio, bool copyvideo)
}

m_framesPlayed = 0;
m_framesPlayedExtra = 0;
ClearAfterSeek();

if (copyvideo && m_decoder)
Expand Down
3 changes: 0 additions & 3 deletions mythtv/libs/libmythtv/mythplayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -733,9 +733,6 @@ class MTV_PUBLIC MythPlayer
/// How often we have tried to wait for a video output buffer and failed
int m_videobufRetries {0};
uint64_t m_framesPlayed {0};
// "Fake" frame counter for when the container frame rate doesn't
// match the stream frame rate.
uint64_t m_framesPlayedExtra {0};
uint64_t m_totalFrames {0};
long long m_totalLength {0};
int64_t m_totalDuration {0};
Expand Down
21 changes: 20 additions & 1 deletion mythtv/libs/libmythtv/mythvideoout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ MythVideoOutput *MythVideoOutput::Create(const QString &Decoder, MythCodecID
#endif // USING_OPENGL
}

LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Allowed renderers: %1").arg(renderers.join(",")));
LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Allowed renderers for %1 %2 (Decoder: %3): '%4'")
.arg(get_encoding_type(CodecID)).arg(get_decoder_name(CodecID))
.arg(Decoder).arg(renderers.join(",")));
renderers = VideoDisplayProfile::GetFilteredRenderers(Decoder, renderers);
LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Allowed renderers (filt: %1): %2")
.arg(Decoder).arg(renderers.join(",")));
Expand All @@ -87,11 +89,28 @@ MythVideoOutput *MythVideoOutput::Create(const QString &Decoder, MythCodecID
renderer = tmp;
LOG(VB_PLAYBACK, LOG_INFO, LOC + "Preferred renderer: " + renderer);
}
else
{
LOG(VB_PLAYBACK, LOG_INFO, LOC +
QString("No preferred renderer for decoder '%1' - profile renderer: '%2'")
.arg(Decoder).arg(tmp));
}
}

if (renderer.isEmpty())
renderer = VideoDisplayProfile::GetBestVideoRenderer(renderers);

if (renderer.isEmpty() && !(PlayerFlags & kVideoIsNull))
{
QString fallback;
#ifdef USING_OPENGL
fallback = "opengl";
#endif
LOG(VB_GENERAL, LOG_WARNING, LOC + "No renderer found. This should not happen!.");
LOG(VB_GENERAL, LOG_WARNING, LOC + QString("Falling back to '%1'").arg(fallback));
renderer = fallback;
}

while (!renderers.empty())
{
LOG(VB_PLAYBACK, LOG_INFO, LOC +
Expand Down
2 changes: 1 addition & 1 deletion mythtv/libs/libmythtv/opengl/mythopenglvideo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,7 @@ void MythOpenGLVideo::PrepareFrame(VideoFrame *Frame, bool TopFieldFirst, FrameS
bool hwframes = false;
bool useframebufferimage = false;

// We lose the pause frame when seeking and using VDPAU or VAAPI direct rendering.
// We lose the pause frame when seeking and using VDPAU/VAAPI/NVDEC direct rendering.
// As a workaround, we always use the resize stage so the last displayed frame
// should be retained in the Framebuffer used for resizing. If there is
// nothing to display, then fallback to this framebuffer.
Expand Down
286 changes: 0 additions & 286 deletions mythtv/libs/libmythtv/vaapi2context.cpp

This file was deleted.

64 changes: 0 additions & 64 deletions mythtv/libs/libmythtv/vaapi2context.h

This file was deleted.

8 changes: 5 additions & 3 deletions mythtv/libs/libmythtv/videobuffers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,9 @@ uint VideoBuffers::GetNumBuffers(int PixelFormat, int MaxReferenceFrames, bool D
switch (PixelFormat)
{
case FMT_DXVA2: return 30;
case FMT_VTB: return 24;
// It is currrently unclear whether VTB just happy with a smaller buffer size
// or needs reference frames plus headroom - use the latter for now.
case FMT_VTB: return refs + 8;
// Max 16 ref frames, 12 headroom and allocate 2 extra in the VAAPI frames
// context for additional references held by the VPP deinterlacer (i.e.
// prevent buffer starvation in the decoder)
Expand Down Expand Up @@ -284,7 +286,7 @@ void VideoBuffers::ReleaseDecoderResources(VideoFrame *Frame)
av_buffer_unref(&ref);
Frame->buf = Frame->priv[0] = nullptr;

if (format_is_hwframes(Frame->codec) || (Frame->codec == FMT_NVDEC))
if (format_is_hwframes(Frame->codec))
{
ref = reinterpret_cast<AVBufferRef*>(Frame->priv[1]);
if (ref != nullptr)
Expand Down Expand Up @@ -841,7 +843,7 @@ bool VideoBuffers::CreateBuffers(VideoFrameType Type, int Width, int Height)
{
for (uint i = 0; i < Size(); i++)
success &= CreateBuffer(Width, Height, i, nullptr, Type);
LOG(VB_PLAYBACK, LOG_INFO, QString("Created %1 %2 (%3x%4) video buffers")
LOG(VB_PLAYBACK, LOG_INFO, QString("Created %1 empty %2 (%3x%4) video buffers")
.arg(Size()).arg(format_description(Type)).arg(Width).arg(Height));
return success;
}
Expand Down
6 changes: 6 additions & 0 deletions mythtv/libs/libmythtv/videocolourspace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ VideoColourSpace::VideoColourSpace(VideoColourSpace *Parent)
SetSaturation(m_dbSettings[kPictureAttribute_Colour]);
SetHue(m_dbSettings[kPictureAttribute_Hue]);
SetFullRange(m_dbSettings[kPictureAttribute_Range] != 0);

// This isn't working as intended (most notable on OSX internal display).
// Presumably the driver is expecting sRGB/Rec709 and handles any final
// conversion to the display's colourspace.
/*
if (HasMythMainWindow())
{
MythDisplay* display = MythDisplay::AcquireRelease();
Expand All @@ -110,6 +115,7 @@ VideoColourSpace::VideoColourSpace(VideoColourSpace *Parent)
}
MythDisplay::AcquireRelease(false);
}
*/
m_updatesDisabled = false;
Update();
}
Expand Down
2 changes: 2 additions & 0 deletions mythtv/libs/libmythtv/videodisplayprofile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1296,6 +1296,8 @@ bool VideoDisplayProfile::IsFilterAllowed(const QString &VideoRenderer)
QStringList VideoDisplayProfile::GetFilteredRenderers(const QString &Decoder, const QStringList &Renderers)
{
const QStringList dec_list = GetVideoRenderers(Decoder);
LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Safe renderers for '%1': %2")
.arg(Decoder).arg(dec_list.join(",")));
QStringList new_list;

foreach (const auto & dec, dec_list)
Expand Down
4 changes: 0 additions & 4 deletions mythtv/libs/libmythui/libmythui.pro
Original file line number Diff line number Diff line change
Expand Up @@ -199,10 +199,6 @@ using_opengl {
HEADERS += opengl/mythegl.h
SOURCES += opengl/mythegl.cpp

using_opengles {
DEFINES += USING_OPENGLES
}

using_egl {
LIBS += -lEGL
DEFINES += USING_EGL
Expand Down
4 changes: 4 additions & 0 deletions mythtv/libs/libmythui/mythdisplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -735,6 +735,8 @@ int MythDisplay::GetRefreshInterval(int Fallback) const
{
if (m_refreshRate > 20.0 && m_refreshRate < 200.0)
return static_cast<int>(lround(1000000.0 / m_refreshRate));
if (Fallback > 33000) // ~30Hz
Fallback /= 2;
return Fallback;
}

Expand Down Expand Up @@ -1029,6 +1031,8 @@ void MythDisplay::DebugModes(void) const
QStringList rateslist;
for (auto it2 = rates.crbegin(); it2 != rates.crend(); ++it2)
rateslist.append(QString("%1").arg(*it2, 2, 'f', 2, '0'));
if (rateslist.empty())
rateslist.append("Variable rate?");
LOG(VB_PLAYBACK, LOG_INFO, QString("%1x%2\t%3")
.arg((*it).Width()).arg((*it).Height()).arg(rateslist.join("\t")));
}
Expand Down
11 changes: 7 additions & 4 deletions mythtv/libs/libmythui/mythmainwindow_internal.h
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
#ifndef MYTHMAINWINDOW_INT
#define MYTHMAINWINDOW_INT

// Qt
#include <QWidget>
class MythRender;

// MythTV
#include "mythrender_base.h"

class MythMainWindow;
class MythMainWindowPrivate;

#ifdef USING_OPENGL
#include "mythrenderopengl.h"

class MythPainterWindow : public QWidget
{
public:
Expand All @@ -20,6 +21,8 @@ class MythPainterWindow : public QWidget
MythRender* m_render { nullptr };
};

#ifdef USING_OPENGL
#include "mythrenderopengl.h"
class MythPainterWindowGL : public MythPainterWindow
{
Q_OBJECT
Expand Down
21 changes: 20 additions & 1 deletion mythtv/libs/libmythui/mythuiwebbrowser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -872,6 +872,10 @@ void MythUIWebBrowser::Finalize(void)
*/
void MythUIWebBrowser::Init(void)
{
// only do the initialisation for widgets not being stored in the global object store
if (parent() == GetGlobalObjectStore())
return;

if (m_initialized)
return;

Expand Down Expand Up @@ -1127,6 +1131,9 @@ void MythUIWebBrowser::SetBackgroundColor(QColor color)
*/
void MythUIWebBrowser::SetActive(bool active)
{
if (!m_browser)
return;

if (m_active == active)
return;

Expand Down Expand Up @@ -1325,6 +1332,9 @@ QVariant MythUIWebBrowser::evaluateJavaScript(const QString &scriptSource)

void MythUIWebBrowser::Scroll(int dx, int dy)
{
if (!m_browser)
return;

QPoint startPos = m_browser->page()->currentFrame()->scrollPosition();
QPoint endPos = startPos + QPoint(dx, dy);

Expand Down Expand Up @@ -1434,6 +1444,9 @@ bool MythUIWebBrowser::IsOnTopScreen(void)

void MythUIWebBrowser::UpdateScrollBars(void)
{
if (!m_browser)
return;

QPoint position = m_browser->page()->currentFrame()->scrollPosition();
if (m_verticalScrollbar)
{
Expand All @@ -1460,7 +1473,7 @@ void MythUIWebBrowser::UpdateBuffer(void)
{
UpdateScrollBars();

if (!m_image)
if (!m_image || !m_browser)
return;

if (!m_active || (m_active && !m_browser->hasFocus()))
Expand All @@ -1479,6 +1492,9 @@ void MythUIWebBrowser::UpdateBuffer(void)
*/
void MythUIWebBrowser::Pulse(void)
{
if (!m_browser)
return;

if (m_scrollAnimation.IsActive() &&
m_destinationScrollPos !=
m_browser->page()->currentFrame()->scrollPosition())
Expand Down Expand Up @@ -1521,6 +1537,9 @@ void MythUIWebBrowser::DrawSelf(MythPainter *p, int xoffset, int yoffset,
*/
bool MythUIWebBrowser::keyPressEvent(QKeyEvent *event)
{
if (!m_browser)
return false;

QStringList actions;
bool handled = false;
handled = GetMythMainWindow()->TranslateKeyPress("Browser", event, actions);
Expand Down
14 changes: 11 additions & 3 deletions mythtv/libs/libmythui/opengl/mythrenderopengl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -738,7 +738,7 @@ QOpenGLFramebufferObject* MythRenderOpenGL::CreateFramebuffer(QSize &Size, GLenu
{
if (framebuffer->isBound())
{
m_activeFramebuffer = framebuffer;
m_activeFramebuffer = framebuffer->handle();
BindFramebuffer(nullptr);
}
Flush();
Expand Down Expand Up @@ -773,16 +773,22 @@ void MythRenderOpenGL::DeleteFramebuffer(QOpenGLFramebufferObject *Framebuffer)

void MythRenderOpenGL::BindFramebuffer(QOpenGLFramebufferObject *Framebuffer)
{
if (Framebuffer == m_activeFramebuffer)
if ((Framebuffer && Framebuffer->handle() == m_activeFramebuffer) ||
(!Framebuffer && defaultFramebufferObject() == m_activeFramebuffer))
return;

makeCurrent();
if (Framebuffer == nullptr)
{
QOpenGLFramebufferObject::bindDefault();
m_activeFramebuffer = defaultFramebufferObject();
}
else
{
Framebuffer->bind();
m_activeFramebuffer = Framebuffer->handle();
}
doneCurrent();
m_activeFramebuffer = Framebuffer;
}

void MythRenderOpenGL::ClearFramebuffer(void)
Expand Down Expand Up @@ -1177,6 +1183,8 @@ void MythRenderOpenGL::Init2DState(void)
glDisable(GL_CULL_FACE);
glClearColor(0.0F, 0.0F, 0.0F, 0.0F);
glClear(GL_COLOR_BUFFER_BIT);
QOpenGLFramebufferObject::bindDefault();
m_activeFramebuffer = defaultFramebufferObject();
Flush();
}

Expand Down
2 changes: 1 addition & 1 deletion mythtv/libs/libmythui/opengl/mythrenderopengl.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ class MUI_PUBLIC MythRenderOpenGL : public QOpenGLContext, public QOpenGLFunctio
bool m_ready { false };

// Framebuffers
QOpenGLFramebufferObject *m_activeFramebuffer { nullptr };
GLuint m_activeFramebuffer { 0 };

// Synchronisation
GLuint m_fence { 0 };
Expand Down
65 changes: 40 additions & 25 deletions mythtv/libs/libmythui/platforms/mythdrmdevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,11 @@ bool MythDRMDevice::Initialise(void)
#endif
if (serial.isEmpty())
{
LOG(VB_GENERAL, m_verbose, LOC + "QScreen has no serial number");
return false;
// No serial number either means an older version of Qt or the EDID
// is not available for some reason - in which case there is no point
// in trying to use it anyway.
LOG(VB_GENERAL, m_verbose, LOC + "QScreen has no serial number.");
LOG(VB_GENERAL, m_verbose, LOC + "Will use first suitable connected device");
}

// Retrieve full details for the device
Expand All @@ -171,33 +174,41 @@ bool MythDRMDevice::Initialise(void)
continue;
if (connector->connection == DRM_MODE_CONNECTED)
{
// Does the connected display have the serial number we are looking for?
drmModePropertyBlobPtr edidblob = GetBlobProperty(connector, "EDID");
if (edidblob)
if (serial.isEmpty())
{
MythEDID edid(reinterpret_cast<const char *>(edidblob->data),
static_cast<int>(edidblob->length));
drmModeFreePropertyBlob(edidblob);
if (edid.Valid() && edid.SerialNumbers().contains(serial))
{
LOG(VB_GENERAL, LOG_DEBUG, LOC + QString("Matched connector with serial '%1'")
.arg(serial));
m_connector = connector;
m_physicalSize = QSize(static_cast<int>(connector->mmWidth),
static_cast<int>(connector->mmHeight));
m_serialNumber = serial;
m_edid = edid;
break;
}
if (!edid.Valid())
LOG(VB_GENERAL, m_verbose, LOC + "Connected device has invalid EDID");

if (m_connector && !m_serialNumber.isEmpty())
break;
m_connector = connector;
break;
}
else
{
LOG(VB_GENERAL, m_verbose, LOC + "Connected device has no EDID");
// Does the connected display have the serial number we are looking for?
drmModePropertyBlobPtr edidblob = GetBlobProperty(connector, "EDID");
if (edidblob)
{
MythEDID edid(reinterpret_cast<const char *>(edidblob->data),
static_cast<int>(edidblob->length));
drmModeFreePropertyBlob(edidblob);
if (edid.Valid() && edid.SerialNumbers().contains(serial))
{
LOG(VB_GENERAL, LOG_DEBUG, LOC + QString("Matched connector with serial '%1'")
.arg(serial));
m_connector = connector;
m_physicalSize = QSize(static_cast<int>(connector->mmWidth),
static_cast<int>(connector->mmHeight));
m_serialNumber = serial;
m_edid = edid;
break;
}
if (!edid.Valid())
LOG(VB_GENERAL, m_verbose, LOC + "Connected device has invalid EDID");

if (m_connector && !m_serialNumber.isEmpty())
break;
}
else
{
LOG(VB_GENERAL, m_verbose, LOC + "Connected device has no EDID");
}
}
}
LOG(VB_GENERAL, LOG_DEBUG, LOC + QString("Ignoring disconnected connector %1")
Expand Down Expand Up @@ -300,6 +311,10 @@ QString MythDRMDevice::FindBestDevice(void)
return QString();
}

// Only one device - return it
if (devices.size() == 1)
return root + devices.first();

// Use the serial number from the current QScreen to select a suitable device
auto serial = QString();
#if QT_VERSION >= QT_VERSION_CHECK(5,9,0)
Expand Down
12 changes: 6 additions & 6 deletions mythtv/programs/mythbackend/autoexpire.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,15 +134,15 @@ void AutoExpire::CalcParams()
// without handling that issue too. It is done this way
// because the scheduler thread can't afford to be blocked by
// an unresponsive, remote filesystem and the autoexpirer
// thrad can.
// thread can.
m_mainServer->GetFilesystemInfos(fsInfos, false);
}
m_instanceLock.unlock();

if (fsInfos.empty())
{
LOG(VB_GENERAL, LOG_ERR, LOC + "Filesystem Info cache is empty, unable " "to calculate necessary parameters.");

LOG(VB_GENERAL, LOG_ERR, LOC + "Filesystem Info cache is empty, unable "
"to calculate necessary parameters.");
return;
}

Expand All @@ -154,9 +154,9 @@ void AutoExpire::CalcParams()
QMap<int, uint64_t> fsMap;
QMap<int, vector<int> > fsEncoderMap;

// we use this copying on purpose. The used_encoders map ensures
// We use this copying on purpose. The used_encoders map ensures
// that every encoder writes only to one fs.
// Copying the data minimizes the time the lock is held
// Copying the data minimizes the time the lock is held.
m_instanceLock.lock();
QMap<int, int>::const_iterator ueit = m_usedEncoders.begin();
while (ueit != m_usedEncoders.end())
Expand Down Expand Up @@ -196,7 +196,7 @@ void AutoExpire::CalcParams()
{
// remove encoder since it can't write to any file system
LOG(VB_FILE, LOG_INFO, LOC +
QString("Cardid %1: is not recoding, removing it "
QString("Cardid %1: is not recording, removing it "
"from used list.").arg(cardid));
m_instanceLock.lock();
m_usedEncoders.remove(cardid);
Expand Down
4 changes: 2 additions & 2 deletions mythtv/programs/mythbackend/mainserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3318,9 +3318,9 @@ bool MainServer::HandleAddChildInput(uint inputid)
TVRec::s_inputsLock.unlock();
m_addChildInputLock.unlock();

LOG(VB_GENERAL, LOG_ERR, LOC +
LOG(VB_GENERAL, LOG_INFO, LOC +
QString("HandleAddChildInput: "
"Succesffuly handled input %1").arg(inputid));
"Successfully handled input %1").arg(inputid));

return true;
}
Expand Down
11 changes: 10 additions & 1 deletion mythtv/programs/mythbackend/scheduler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3068,7 +3068,12 @@ void Scheduler::HandleIdleShutdown(
// the frontend may have connected then gone idle between scheduler runs
if (blockShutdown)
{
if (m_mainServer->isClientConnected())
m_schedLock.unlock();
bool b = m_mainServer->isClientConnected();
m_schedLock.lock();
if (m_recListChanged)
return;
if (b)
{
LOG(VB_GENERAL, LOG_NOTICE, "Client is connected, removing startup block on shutdown");
blockShutdown = false;
Expand All @@ -3083,6 +3088,7 @@ void Scheduler::HandleIdleShutdown(

// find out, if we are currently recording (or LiveTV)
bool recording = false;
m_schedLock.unlock();
TVRec::s_inputsLock.lockForRead();
QMap<int, EncoderLink *>::Iterator it;
for (it = m_tvList->begin(); (it != m_tvList->end()) &&
Expand All @@ -3095,6 +3101,9 @@ void Scheduler::HandleIdleShutdown(

// If there are BLOCKING clients, then we're not idle
bool blocking = m_mainServer->isClientConnected(true);
m_schedLock.lock();
if (m_recListChanged)
return;

// If there are active jobs, then we're not idle
bool activeJobs = JobQueue::HasRunningOrPendingJobs(0);
Expand Down
4 changes: 2 additions & 2 deletions mythtv/programs/mythfrontend/globalsettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ static HostComboBoxSetting *ColourPrimaries()
gc->setHelpText(PlaybackSettings::tr(
"Converting between different primary colourspaces incurs a small "
"performance penalty but in some situations the difference in output is "
"barely noticeable. The default ('Auto') behavour is to only enforce "
"this converion when there is a significant difference between source "
"negligible. The default ('Auto') behaviour is to only enforce "
"this conversion when there is a significant difference between source "
"colourspace primaries and the display."));
return gc;
}
Expand Down
53 changes: 0 additions & 53 deletions mythtv/programs/scripts/build_commdb.py

This file was deleted.

8 changes: 6 additions & 2 deletions mythtv/settings.pro
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ isEmpty( LIBDIR ) {
LIBDIR = $${RUNPREFIX}/$${LIBDIRNAME}
}

LIBVERSION = 31
VERSION = 31.0
LIBVERSION = 32
VERSION = 32.0

# Die on the (common) case where OS X users inadvertently use Fink's
# Qt/X11 install instead of Qt/Mac. '
Expand Down Expand Up @@ -220,6 +220,10 @@ win32 {

EXTRA_LIBS += $$LOCAL_LIBDIR_OGL
EXTRA_LIBS += $$LOCAL_LIBDIR_X11
# FIXME MK Jan/20 I'm not sure this is necessary or necessarily accurate.
# FFmpeg OpenGL is an option that we do not (and should not imho) enable -
# and we should in that case be stripping out GLES etc as well.
# and CONFIG_OPENGL_LIBS is always empty as we never set gl_lib anymore
!isEmpty( CONFIG_OPENGL_LIBS ) {
# Replace FFmpeg's OpenGL with OpenGLES
EXTRA_LIBS -= -lGL
Expand Down