diff -Nru mythtv-29.1+fixes.20180220.9b7b962/debian/changelog mythtv-29.1+fixes.20180414.329c235/debian/changelog --- mythtv-29.1+fixes.20180220.9b7b962/debian/changelog 2018-03-09 06:38:18.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/debian/changelog 2018-04-14 17:05:25.000000000 +0000 @@ -1,16 +1,10 @@ -mythtv (2:29.1+fixes.20180220.9b7b962-0ubuntu3) bionic; urgency=medium +mythtv (2:29.1+fixes.20180414.329c235-0ubuntu3) bionic; urgency=medium - * mytharchive: Depend on python-pil instead of python-imaging. + * Scripted Build from fixes git packaging [45c4c70] + * Packaging changes between and 20180414: + * New upstream checkout (329c235) - -- Matthias Klose Fri, 09 Mar 2018 13:38:18 +0700 - -mythtv (2:29.1+fixes.20180220.9b7b962-0ubuntu2) bionic; urgency=medium - - * Scripted Build from fixes git packaging [923bb99] - * Packaging changes between and 20180220: - * New upstream checkout (9b7b962) - - -- Thomas Mashos Tue, 20 Feb 2018 03:32:59 +0000 + -- Thomas Mashos Sat, 14 Apr 2018 17:05:11 +0000 mythtv (2:29.1~master-manualbuildubuntu1) zesty; urgency=medium diff -Nru mythtv-29.1+fixes.20180220.9b7b962/debian/control mythtv-29.1+fixes.20180414.329c235/debian/control --- mythtv-29.1+fixes.20180220.9b7b962/debian/control 2018-03-09 06:37:29.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/debian/control 2018-04-14 17:05:25.000000000 +0000 @@ -90,6 +90,7 @@ uuid-dev, libxml-xpath-perl, git, + libsystemd-dev, dh-systemd, libraspberrypi-dev [armhf] | hello, @@ -224,7 +225,7 @@ Package: mythtv-backend Architecture: any -Depends: mythtv-common, mythtv-transcode-utils, ${shlibs:Depends}, cron, wget, zenity | kdebase-bin, gksu | kdebase-bin, xterm, python, libjs-jquery, libxml-simple-perl, ${misc:Depends} +Depends: mythtv-common, mythtv-transcode-utils, ${shlibs:Depends}, cron, wget, zenity | kdebase-bin, xterm, python, libjs-jquery, libxml-simple-perl, ${misc:Depends} Conflicts: mythtv (<< 0.8-1) Replaces: mythtv (<< 0.8-1), mythtv-frontend (<= 0.20-0.4) Recommends: ntp | time-daemon | ntp-simple, logrotate, libmyth-python, libmythtv-perl @@ -263,7 +264,6 @@ libnotify-bin, adduser, zenity | kdebase-bin, - gksu | kdebase-bin, wmctrl, libxml-simple-perl, libwww-perl, diff -Nru mythtv-29.1+fixes.20180220.9b7b962/debian/control.in mythtv-29.1+fixes.20180414.329c235/debian/control.in --- mythtv-29.1+fixes.20180220.9b7b962/debian/control.in 2018-03-09 06:37:20.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/debian/control.in 2018-04-14 17:05:06.000000000 +0000 @@ -90,6 +90,7 @@ uuid-dev, libxml-xpath-perl, git, + libsystemd-dev, dh-systemd, libraspberrypi-dev [armhf] | hello, @@ -224,7 +225,7 @@ Package: mythtv-backend Architecture: any -Depends: mythtv-common, mythtv-transcode-utils, ${shlibs:Depends}, cron, wget, zenity | kdebase-bin, gksu | kdebase-bin, xterm, python, libjs-jquery, libxml-simple-perl, ${misc:Depends} +Depends: mythtv-common, mythtv-transcode-utils, ${shlibs:Depends}, cron, wget, zenity | kdebase-bin, xterm, python, libjs-jquery, libxml-simple-perl, ${misc:Depends} Conflicts: mythtv (<< 0.8-1) Replaces: mythtv (<< 0.8-1), mythtv-frontend (<= 0.20-0.4) Recommends: ntp | time-daemon | ntp-simple, logrotate, libmyth-python, libmythtv-perl @@ -263,7 +264,6 @@ libnotify-bin, adduser, zenity | kdebase-bin, - gksu | kdebase-bin, wmctrl, libxml-simple-perl, libwww-perl, diff -Nru mythtv-29.1+fixes.20180220.9b7b962/debian/DESCRIBE mythtv-29.1+fixes.20180414.329c235/debian/DESCRIBE --- mythtv-29.1+fixes.20180220.9b7b962/debian/DESCRIBE 2018-02-20 03:32:59.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/debian/DESCRIBE 2018-04-14 17:05:11.000000000 +0000 @@ -1,2 +1,2 @@ BRANCH="fixes/29" -SOURCE_VERSION="v29.1" +SOURCE_VERSION="v29.1-13-g329c235" diff -Nru mythtv-29.1+fixes.20180220.9b7b962/debian/dialog_functions.sh mythtv-29.1+fixes.20180414.329c235/debian/dialog_functions.sh --- mythtv-29.1+fixes.20180220.9b7b962/debian/dialog_functions.sh 2018-02-20 03:32:55.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/debian/dialog_functions.sh 2018-04-14 17:05:06.000000000 +0000 @@ -29,19 +29,19 @@ find_session() { - if [ x"$KDE_FULL_SESSION" = x"true" ]; then + if [ x"$KDE_FULL_SESSION" = x"true" ]; then DE=kde; DIALOG=`which kdialog`; DIALOG_TYPE=kdialog; SU=`which kdesudo` SU_TYPE=kdesudo - elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then + elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome; DIALOG=`which zenity`; DIALOG_TYPE=zenity; SU=`which gksu` SU_TYPE=gksu - elif xprop -root _DT_SAVE_MODE | grep ' = \"xfce4\"$' >/dev/null 2>&1; then + elif xprop -root _DT_SAVE_MODE | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce; DIALOG=`which zenity`; DIALOG_TYPE=zenity; @@ -76,6 +76,13 @@ fi fi + if [ -z "$SU" ]; then + SU=`which sudo` + + if [ -z "$SU_TYPE" ]; then + SU_TYPE=sudo + fi + fi if [ -z "$SU_TYPE" ]; then failure "You need gksu or kdesu installed to run mythfrontend" @@ -134,7 +141,7 @@ if [ -e ~/.mythtv/ignoregroup ] then IGNORE_NOT=0 - else + else dialog_question "Incorrect Group Membership" "You must be a member of the \"mythtv\" group before starting any mythtv applications.\nWould you like to automatically be added to the group?\n(Note: sudo access required)" ADD_NOT=$? # 0 means that they do want in @@ -170,8 +177,8 @@ fi #exit in case they hit cancel here exit 2 - else - exit 3 + else + exit 3 fi fi fi @@ -181,4 +188,3 @@ } ################################################################### - diff -Nru mythtv-29.1+fixes.20180220.9b7b962/debian/.gitignore mythtv-29.1+fixes.20180414.329c235/debian/.gitignore --- mythtv-29.1+fixes.20180220.9b7b962/debian/.gitignore 1970-01-01 00:00:00.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/debian/.gitignore 2018-04-14 17:05:06.000000000 +0000 @@ -0,0 +1 @@ +libmyth-0.*-0.install diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmyth/audio/audiooutput_omx.cpp mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmyth/audio/audiooutput_omx.cpp --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmyth/audio/audiooutput_omx.cpp 2018-02-20 03:04:13.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmyth/audio/audiooutput_omx.cpp 2018-04-12 14:28:57.000000000 +0000 @@ -438,6 +438,55 @@ m_audiorender.Shutdown(); } +// HDMI uses a different channel order from WAV and others +// See CEA spec: Table 20, Audio InfoFrame + +#define REORD_NUMCHAN 6 // Min Num of channels for reorder to be done +#define REORD_A 2 // First channel to switch +#define REORD_B 3 // Second channel to switch + +void AudioOutputOMX::reorderChannels(int *aubuf, int size) +{ + int t_size = size; + int *sample = aubuf; + while (t_size >= REORD_NUMCHAN*4) + { + int savefirst = sample[REORD_A]; + sample[REORD_A] = sample[REORD_B]; + sample[REORD_B] = savefirst; + sample += channels; + t_size -= output_bytes_per_frame; + } +} + +void AudioOutputOMX::reorderChannels(short *aubuf, int size) +{ + int t_size = size; + short *sample = aubuf; + while (t_size >= REORD_NUMCHAN*2) + { + short savefirst = sample[REORD_A]; + sample[REORD_A] = sample[REORD_B]; + sample[REORD_B] = savefirst; + sample += channels; + t_size -= output_bytes_per_frame; + } +} + +void AudioOutputOMX::reorderChannels(uchar *aubuf, int size) +{ + int t_size = size; + uchar *sample = aubuf; + while (t_size >= REORD_NUMCHAN) + { + uchar savefirst = sample[REORD_A]; + sample[REORD_A] = sample[REORD_B]; + sample[REORD_B] = savefirst; + sample += channels; + t_size -= output_bytes_per_frame; + } +} + // virtual void AudioOutputOMX::WriteAudio(uchar *aubuf, int size) { @@ -447,6 +496,25 @@ return; } + // Reorder channels for CEA format + // See CEA spec: Table 20, Audio InfoFrame + if (!enc && !reenc && channels >= REORD_NUMCHAN) + { + int samplesize = output_bytes_per_frame / channels; + switch (samplesize) + { + case 1: + reorderChannels(aubuf, size); + break; + case 2: + reorderChannels((short*)aubuf, size); + break; + case 4: + reorderChannels((int*)aubuf, size); + break; + } + } + while (size > 0) { if (!m_ibufs_sema.tryAcquire(1, 3000)) diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmyth/audio/audiooutput_omx.h mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmyth/audio/audiooutput_omx.h --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmyth/audio/audiooutput_omx.h 2018-02-20 03:04:11.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmyth/audio/audiooutput_omx.h 2018-04-12 14:28:57.000000000 +0000 @@ -49,6 +49,10 @@ typedef OMX_ERRORTYPE ComponentCB(); ComponentCB FreeBuffersCB, AllocBuffersCB; + void reorderChannels(int *aubuf, int size); + void reorderChannels(short *aubuf, int size); + void reorderChannels(uchar *aubuf, int size); + private: OMXComponent m_audiorender; diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythbase/mythstorage.cpp mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythbase/mythstorage.cpp --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythbase/mythstorage.cpp 2018-02-20 03:04:11.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythbase/mythstorage.cpp 2018-04-12 14:28:57.000000000 +0000 @@ -3,6 +3,7 @@ // Myth headers #include "mythstorage.h" #include "mythdb.h" +#include "mythcorecontext.h" void SimpleDBStorage::Load(void) { @@ -167,6 +168,12 @@ return clause; } +void HostDBStorage::Save(void) +{ + SimpleDBStorage::Save(); + gCoreContext->ClearSettingsCache(settingname); +} + ////////////////////////////////////////////////////////////////////// GlobalDBStorage::GlobalDBStorage( @@ -197,3 +204,9 @@ return clause; } + +void GlobalDBStorage::Save(void) +{ + SimpleDBStorage::Save(); + gCoreContext->ClearSettingsCache(settingname); +} diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythbase/mythstorage.h mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythbase/mythstorage.h --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythbase/mythstorage.h 2018-02-20 03:04:13.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythbase/mythstorage.h 2018-04-12 14:28:57.000000000 +0000 @@ -107,6 +107,8 @@ { public: HostDBStorage(StorageUser *_user, const QString &name); + using SimpleDBStorage::Save; // prevent compiler warning + virtual void Save(void); protected: virtual QString GetWhereClause(MSqlBindings &bindings) const; @@ -120,6 +122,8 @@ { public: GlobalDBStorage(StorageUser *_user, const QString &name); + using SimpleDBStorage::Save; // prevent compiler warning + virtual void Save(void); protected: virtual QString GetWhereClause(MSqlBindings &bindings) const; diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythbase/mythversion.h mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythbase/mythversion.h --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythbase/mythversion.h 2018-02-20 03:04:13.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythbase/mythversion.h 2018-04-12 14:28:57.000000000 +0000 @@ -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 "29.20180131-3" +#define MYTH_BINARY_VERSION "29.20180316-1" /** \brief Increment this whenever the MythTV network protocol changes. * Note that the token currently cannot contain spaces. diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/channelscan/channelscan_sm.cpp mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/channelscan/channelscan_sm.cpp --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/channelscan/channelscan_sm.cpp 2018-02-20 03:04:13.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/channelscan/channelscan_sm.cpp 2018-04-12 14:28:57.000000000 +0000 @@ -144,7 +144,7 @@ : // Set in constructor m_scanMonitor(_scan_monitor), m_channel(_channel), - m_signalMonitor(SignalMonitor::Init(_cardtype, -1, _channel)), + m_signalMonitor(SignalMonitor::Init(_cardtype, -1, _channel, true)), m_sourceID(_sourceID), m_signalTimeout(signal_timeout), m_channelTimeout(channel_timeout), diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/fileringbuffer.cpp mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/fileringbuffer.cpp --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/fileringbuffer.cpp 2018-02-20 03:04:13.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/fileringbuffer.cpp 2018-04-12 14:28:57.000000000 +0000 @@ -352,7 +352,9 @@ if (suffixPos > 0) { baseName = tmpSubName.left(suffixPos); - extension = tmpSubName.right(suffixPos-1); + int extnleng = tmpSubName.size() - baseName.size() - 1; + extension = tmpSubName.right(extnleng); + if (is_subtitle_possible(extension)) { QMutexLocker locker(&subExtLock); diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/privatedecoder_omx.cpp mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/privatedecoder_omx.cpp --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/privatedecoder_omx.cpp 2018-02-20 03:04:13.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/privatedecoder_omx.cpp 2018-04-12 14:28:57.000000000 +0000 @@ -478,21 +478,6 @@ return false; } - // Test the filter - static const uint8_t test[] = { 0U,0U,0U,2U,0U,0U }; - int outbuf_size = 0; - uint8_t *outbuf = NULL; - int res = av_bitstream_filter_filter(m_filter, avctx, NULL, &outbuf, - &outbuf_size, test, sizeof test, 0); - if (res < 0) - { - LOG(VB_PLAYBACK, LOG_ERR, LOC + "h264_mp4toannexb filter test failed"); - av_bitstream_filter_close(m_filter); - m_filter = NULL; - return false; - } - - av_freep(&outbuf); LOG(VB_GENERAL, LOG_INFO, LOC + "Installed h264_mp4toannexb filter"); return true; } diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/analogsignalmonitor.cpp mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/analogsignalmonitor.cpp --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/analogsignalmonitor.cpp 2018-02-20 03:04:11.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/analogsignalmonitor.cpp 2018-04-12 14:28:57.000000000 +0000 @@ -17,11 +17,13 @@ #define LOC QString("AnalogSigMon[%1](%2): ") \ .arg(capturecardnum).arg(channel->GetDevice()) -AnalogSignalMonitor::AnalogSignalMonitor( - int db_cardnum, V4LChannel *_channel, uint64_t _flags) : - SignalMonitor(db_cardnum, _channel, _flags), - m_usingv4l2(false), m_version(0), m_width(0), m_stable_time(2000), - m_lock_cnt(0), m_log_idx(40) +AnalogSignalMonitor::AnalogSignalMonitor(int db_cardnum, + V4LChannel *_channel, + bool _release_stream, + uint64_t _flags) + : SignalMonitor(db_cardnum, _channel, _release_stream, _flags), + m_usingv4l2(false), m_version(0), m_width(0), m_stable_time(2000), + m_lock_cnt(0), m_log_idx(40) { int videofd = channel->GetFd(); if (videofd >= 0) diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/analogsignalmonitor.h mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/analogsignalmonitor.h --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/analogsignalmonitor.h 2018-02-20 03:04:11.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/analogsignalmonitor.h 2018-04-12 14:28:57.000000000 +0000 @@ -12,9 +12,9 @@ class AnalogSignalMonitor : public SignalMonitor { public: - AnalogSignalMonitor( - int db_cardnum, V4LChannel *_channel, - uint64_t _flags = kSigMon_WaitForSig); + AnalogSignalMonitor(int db_cardnum, V4LChannel *_channel, + bool _release_stream, + uint64_t _flags = kSigMon_WaitForSig); virtual void UpdateValues(void); diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/asisignalmonitor.cpp mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/asisignalmonitor.cpp --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/asisignalmonitor.cpp 2018-02-20 03:04:11.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/asisignalmonitor.cpp 2018-04-12 14:28:57.000000000 +0000 @@ -38,10 +38,12 @@ * \param _channel ASIChannel for card * \param _flags Flags to start with */ -ASISignalMonitor::ASISignalMonitor( - int db_cardnum, ASIChannel *_channel, uint64_t _flags) : - DTVSignalMonitor(db_cardnum, _channel, _flags), - streamHandlerStarted(false), streamHandler(NULL) +ASISignalMonitor::ASISignalMonitor(int db_cardnum, + ASIChannel *_channel, + bool _release_stream, + uint64_t _flags) + : DTVSignalMonitor(db_cardnum, _channel, _release_stream, _flags), + streamHandlerStarted(false), streamHandler(NULL) { LOG(VB_CHANNEL, LOG_INFO, LOC + "ctor"); streamHandler = ASIStreamHandler::Get(_channel->GetDevice()); diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/asisignalmonitor.h mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/asisignalmonitor.h --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/asisignalmonitor.h 2018-02-20 03:04:11.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/asisignalmonitor.h 2018-04-12 14:28:57.000000000 +0000 @@ -14,7 +14,7 @@ { public: ASISignalMonitor(int db_cardnum, ASIChannel *_channel, - uint64_t _flags = 0); + bool _release_stream = true, uint64_t _flags = 0); virtual ~ASISignalMonitor(); void Stop(void); diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/asistreamhandler.cpp mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/asistreamhandler.cpp --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/asistreamhandler.cpp 2018-02-20 03:04:13.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/asistreamhandler.cpp 2018-04-12 14:28:57.000000000 +0000 @@ -65,7 +65,7 @@ return _handlers[devkey]; } -void ASIStreamHandler::Return(ASIStreamHandler * & ref) +void ASIStreamHandler::Return(ASIStreamHandler * & ref, int recorder_id) { QMutexLocker locker(&_handlers_lock); diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/cetonsignalmonitor.cpp mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/cetonsignalmonitor.cpp --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/cetonsignalmonitor.cpp 2018-02-20 03:04:11.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/cetonsignalmonitor.cpp 2018-04-12 14:28:57.000000000 +0000 @@ -30,10 +30,12 @@ * \param _channel CetonChannel for card * \param _flags Flags to start with */ -CetonSignalMonitor::CetonSignalMonitor( - int db_cardnum, CetonChannel* _channel, uint64_t _flags) : - DTVSignalMonitor(db_cardnum, _channel, _flags), - streamHandlerStarted(false), streamHandler(NULL) +CetonSignalMonitor::CetonSignalMonitor(int db_cardnum, + CetonChannel* _channel, + bool _release_stream, + uint64_t _flags) + : DTVSignalMonitor(db_cardnum, _channel, _release_stream, _flags), + streamHandlerStarted(false), streamHandler(NULL) { LOG(VB_CHANNEL, LOG_INFO, LOC + "ctor"); diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/cetonsignalmonitor.h mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/cetonsignalmonitor.h --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/cetonsignalmonitor.h 2018-02-20 03:04:11.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/cetonsignalmonitor.h 2018-04-12 14:28:57.000000000 +0000 @@ -19,7 +19,7 @@ { public: CetonSignalMonitor(int db_cardnum, CetonChannel* _channel, - uint64_t _flags = 0); + bool _release_stream, uint64_t _flags = 0); virtual ~CetonSignalMonitor(); void Stop(void); diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/dtvsignalmonitor.cpp mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/dtvsignalmonitor.cpp --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/dtvsignalmonitor.cpp 2018-02-20 03:04:11.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/dtvsignalmonitor.cpp 2018-04-12 14:28:57.000000000 +0000 @@ -43,8 +43,9 @@ DTVSignalMonitor::DTVSignalMonitor(int db_cardnum, DTVChannel *_channel, + bool _release_stream, uint64_t wait_for_mask) - : SignalMonitor(db_cardnum, _channel, wait_for_mask), + : SignalMonitor(db_cardnum, _channel, _release_stream, wait_for_mask), stream_data(NULL), seenPAT(QObject::tr("Seen")+" PAT", "seen_pat", 1, true, 0, 1, 0), seenPMT(QObject::tr("Seen")+" PMT", "seen_pmt", 1, true, 0, 1, 0), diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/dtvsignalmonitor.h mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/dtvsignalmonitor.h --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/dtvsignalmonitor.h 2018-02-20 03:04:11.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/dtvsignalmonitor.h 2018-04-12 14:28:57.000000000 +0000 @@ -21,6 +21,7 @@ public: DTVSignalMonitor(int db_cardnum, DTVChannel *_channel, + bool _release_stream, uint64_t wait_for_mask); virtual ~DTVSignalMonitor(); diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/dvbsignalmonitor.cpp mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/dvbsignalmonitor.cpp --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/dvbsignalmonitor.cpp 2018-02-20 03:04:11.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/dvbsignalmonitor.cpp 2018-04-12 14:28:57.000000000 +0000 @@ -43,8 +43,9 @@ * \param _flags Flags to start with */ DVBSignalMonitor::DVBSignalMonitor(int db_cardnum, DVBChannel* _channel, + bool _release_stream, uint64_t _flags) - : DTVSignalMonitor(db_cardnum, _channel, _flags), + : DTVSignalMonitor(db_cardnum, _channel, _release_stream, _flags), // This snr setup is incorrect for API 3.x but works better // than int16_t range in practice, however this is correct // for the 4.0 DVB API which uses a uint16_t for the snr diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/dvbsignalmonitor.h mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/dvbsignalmonitor.h --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/dvbsignalmonitor.h 2018-02-20 03:04:13.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/dvbsignalmonitor.h 2018-04-12 14:28:57.000000000 +0000 @@ -20,6 +20,7 @@ public: DVBSignalMonitor(int db_cardnum, DVBChannel* _channel, + bool _release_stream, uint64_t _flags = kSigMon_WaitForSig | kDVBSigMon_WaitForSNR | kDVBSigMon_WaitForBER | kDVBSigMon_WaitForUB); diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/ExternalChannel.h mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/ExternalChannel.h --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/ExternalChannel.h 2018-02-20 03:04:11.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/ExternalChannel.h 2018-04-12 14:28:57.000000000 +0000 @@ -38,6 +38,9 @@ virtual QString GetDevice(void) const { return m_device; } virtual bool IsPIDTuningSupported(void) const { return true; } + protected: + virtual bool IsExternalChannelChangeSupported(void) { return true; } + private: QString m_device; QStringList m_args; diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/ExternalRecorder.cpp mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/ExternalRecorder.cpp --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/ExternalRecorder.cpp 2018-02-20 03:04:11.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/ExternalRecorder.cpp 2018-04-12 14:28:57.000000000 +0000 @@ -81,11 +81,19 @@ StartNewFile(); + m_stream_handler->LockReplay(); + + m_h264_parser.Reset(); + _wait_for_keyframe_option = true; + _seen_sps = false; + _stream_data->AddAVListener(this); _stream_data->AddWritingListener(this); m_stream_handler->AddListener(_stream_data, false, true); - StartStreaming(); + m_stream_handler->ReplayStream(); + m_stream_handler->UnlockReplay(); + while (IsRecordingRequested() && !IsErrored()) { @@ -189,7 +197,8 @@ else if (IsPaused(true)) { LOG(VB_RECORD, LOG_INFO, LOC + "PauseAndWait unpause"); - StartStreaming(); + + // The SignalMonitor will StartStreaming if (_stream_data) _stream_data->Reset(_stream_data->DesiredProgram()); @@ -205,12 +214,8 @@ bool ExternalRecorder::StartStreaming(void) { - m_h264_parser.Reset(); - _wait_for_keyframe_option = true; - _seen_sps = false; - LOG(VB_RECORD, LOG_INFO, LOC + "StartStreaming"); - if (m_stream_handler && m_stream_handler->StartStreaming(true)) + if (m_stream_handler && m_stream_handler->StartStreaming()) return true; return false; diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/ExternalSignalMonitor.cpp mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/ExternalSignalMonitor.cpp --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/ExternalSignalMonitor.cpp 2018-02-20 03:04:11.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/ExternalSignalMonitor.cpp 2018-04-12 14:28:57.000000000 +0000 @@ -36,10 +36,12 @@ * \param _channel ExternalChannel for card * \param _flags Flags to start with */ -ExternalSignalMonitor::ExternalSignalMonitor( - int db_cardnum, ExternalChannel *_channel, uint64_t _flags) : - DTVSignalMonitor(db_cardnum, _channel, _flags), - m_stream_handler(NULL), m_stream_handler_started(false), m_lock_timeout(0) +ExternalSignalMonitor::ExternalSignalMonitor(int db_cardnum, + ExternalChannel *_channel, + bool _release_stream, + uint64_t _flags) + : DTVSignalMonitor(db_cardnum, _channel, _flags, _release_stream), + m_stream_handler(NULL), m_stream_handler_started(false), m_lock_timeout(0) { QString result; @@ -69,11 +71,13 @@ QString result; LOG(VB_CHANNEL, LOG_INFO, LOC + "Stop() -- begin"); - m_stream_handler->StopStreaming(); SignalMonitor::Stop(); - if (GetStreamData()) + if (release_stream && GetStreamData()) + { + m_stream_handler->StopStreaming(); m_stream_handler->RemoveListener(GetStreamData()); + } m_stream_handler_started = false; LOG(VB_CHANNEL, LOG_INFO, LOC + "Stop() -- end"); @@ -90,6 +94,15 @@ if (!running || exit) return; + if (GetExternalChannel()->IsExternalChannelChangeInUse()) + { + SignalMonitor::UpdateValues(); + + QMutexLocker locker(&statusLock); + if (!scriptStatus.IsGood()) + return; + } + if (m_stream_handler_started) { if (!m_stream_handler->IsRunning()) @@ -134,7 +147,7 @@ if (!m_stream_handler_started) { m_stream_handler->AddListener(GetStreamData()); - m_stream_handler->StartStreaming(false); + m_stream_handler->StartStreaming(); m_stream_handler_started = true; } } diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/ExternalSignalMonitor.h mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/ExternalSignalMonitor.h --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/ExternalSignalMonitor.h 2018-02-20 03:04:11.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/ExternalSignalMonitor.h 2018-04-12 14:28:57.000000000 +0000 @@ -16,7 +16,7 @@ { public: ExternalSignalMonitor(int db_cardnum, ExternalChannel *_channel, - uint64_t _flags = 0); + bool _release_stream, uint64_t _flags = 0); virtual ~ExternalSignalMonitor(); void Stop(void); diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/ExternalStreamHandler.cpp mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/ExternalStreamHandler.cpp --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/ExternalStreamHandler.cpp 2018-02-20 03:04:13.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/ExternalStreamHandler.cpp 2018-04-12 14:28:57.000000000 +0000 @@ -237,11 +237,6 @@ return true; } -void ExternIO::Term(bool /*force*/) -{ - LOG(VB_RECORD, LOG_INFO, QString("ExternIO::Term()")); -} - /* Return true if the process is not, or is no longer running */ bool ExternIO::KillIfRunning(const QString & cmd) { @@ -268,7 +263,7 @@ .arg(cmd)); res_kil = system(kil.toUtf8().constData()); if (WEXITSTATUS(res_kil) == 1) - LOG(VB_GENERAL, LOG_WARNING, QString("'%1' failed") + LOG(VB_GENERAL, LOG_WARNING, QString("'%1' failed: %2") .arg(kil).arg(ENO)); res_grp = system(grp.toUtf8().constData()); @@ -307,6 +302,7 @@ } QString full_command = QString("%1").arg(m_args.join(" ")); + if (!KillIfRunning(full_command)) { // Give it one more chance. @@ -637,8 +633,8 @@ m_notify = false; } - while (read_len = 0, buffer.size() > 188*50 || - (read_len = m_IO->Read(buffer, PACKET_SIZE, 100)) > 0) + while (read_len = 0, buffer.size() == PACKET_SIZE || + (read_len = m_IO->Read(buffer, PACKET_SIZE - remainder, 100)) > 0) { if (m_IO->Error()) { @@ -655,12 +651,6 @@ if (read_len > 0) empty_cnt = 0; - if (_stream_data_list.empty()) - { - LOG(VB_GENERAL, LOG_ERR, LOC + "_stream_data_list is empty"); - continue; - } - if (xon) { if (timer.elapsed() >= 2000) @@ -697,6 +687,11 @@ } } + len = remainder = buffer.size(); + + if (!m_stream_lock.tryLock()) + continue; + if (!_listener_lock.tryLock()) continue; @@ -708,8 +703,6 @@ _listener_lock.unlock(); - len = buffer.size(); - if (m_replay) { m_replay_buffer += buffer.left(len - remainder); @@ -722,11 +715,14 @@ } } - if (remainder > 0 && (len > remainder)) // leftover bytes - buffer.remove(0, len - remainder); - else + m_stream_lock.unlock(); + + if (remainder == 0) buffer.clear(); + else if (len > remainder) // leftover bytes + buffer.remove(0, len - remainder); } + if (m_IO->Error()) { LOG(VB_GENERAL, LOG_ERR, LOC + @@ -737,7 +733,8 @@ break; } } - LOG(VB_RECORD, LOG_INFO, LOC + "run(): " + "shutdown"); + LOG(VB_RECORD, LOG_INFO, LOC + "run(): " + + QString("%1 shutdown").arg(_error ? "Error" : "Normal")); RemoveAllPIDFilters(); SetRunning(false, true, false); @@ -873,9 +870,21 @@ { LOG(VB_RECORD, LOG_INFO, LOC + "CloseRecorder failed, sending kill."); - m_IO->Term(); - sleep(5); - m_IO->Term(true); + + QString full_command = QString("%1").arg(m_args.join(" ")); + + if (!m_IO->KillIfRunning(full_command)) + { + // Give it one more chance. + usleep(50000); + if (!m_IO->KillIfRunning(full_command)) + { + LOG(VB_GENERAL, LOG_ERR, + QString("Unable to kill existing '%1'.") + .arg(full_command)); + return; + } + } } delete m_IO; m_IO = 0; @@ -899,30 +908,22 @@ if (streaming) { - return StartStreaming(false); + return StartStreaming(); } return true; } -bool ExternalStreamHandler::StartStreaming(bool flush_buffer) +void ExternalStreamHandler::ReplayStream(void) { - QString result; - - QMutexLocker locker(&m_stream_lock); - - LOG(VB_RECORD, LOG_INFO, LOC + - QString("StartStreaming with %1 current listeners") - .arg(StreamingCount())); - - if (!IsAppOpen()) + if (m_replay) { - LOG(VB_GENERAL, LOG_ERR, LOC + "External Recorder not started."); - return false; - } + QString result; + + // Let the external app know that we could be busy for a little while + if (!m_poll_mode) + ProcessCommand(QString("XOFF"), 50, result); - if (flush_buffer && m_replay) - { /* If the input is not a 'broadcast' it may only have one * copy of the SPS right at the beginning of the stream, * so make sure we don't miss it! @@ -941,6 +942,27 @@ .arg(m_replay_buffer.size())); m_replay_buffer.clear(); m_replay = false; + + // Let the external app know that we are ready + if (!m_poll_mode) + ProcessCommand(QString("XON"), 50, result); + } +} + +bool ExternalStreamHandler::StartStreaming(void) +{ + QString result; + + QMutexLocker locker(&m_stream_lock); + + LOG(VB_RECORD, LOG_INFO, LOC + + QString("StartStreaming with %1 current listeners") + .arg(StreamingCount())); + + if (!IsAppOpen()) + { + LOG(VB_GENERAL, LOG_ERR, LOC + "External Recorder not started."); + return false; } if (StreamingCount() == 0) @@ -1018,7 +1040,7 @@ .arg(result)); if (!result.startsWith("Warn")) { - LOG(VB_RECORD, LOG_WARNING, LOC + + LOG(VB_RECORD, LOG_ERR, LOC + QString("StopStreaming failed: '%1'").arg(result)); _error = true; } @@ -1062,7 +1084,7 @@ if (m_IO->Error()) { - LOG(VB_GENERAL, LOG_ERR, "External Recorder in bad state: " + + LOG(VB_GENERAL, LOG_ERR, LOC + "External Recorder in bad state: " + m_IO->ErrorString()); return false; } @@ -1079,7 +1101,7 @@ result = m_IO->GetStatus(timeout); if (m_IO->Error()) { - LOG(VB_GENERAL, LOG_ERR, + LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to read from External Recorder: " + m_IO->ErrorString()); _error = true; @@ -1118,7 +1140,11 @@ } if (++m_io_errcnt > 10) + { + LOG(VB_GENERAL, LOG_ERR, LOC + "Too many I/O errors."); _error = true; + break; + } usleep(timeout); } diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/ExternalStreamHandler.h mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/ExternalStreamHandler.h --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/ExternalStreamHandler.h 2018-02-20 03:04:11.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/ExternalStreamHandler.h 2018-04-12 14:28:57.000000000 +0000 @@ -30,13 +30,13 @@ QString GetStatus(int timeout = 2500); int Write(const QByteArray & buffer); bool Run(void); - void Term(bool force = false); bool Error(void) const { return !m_error.isEmpty(); } QString ErrorString(void) const { return m_error; } void ClearError(void) { m_error.clear(); } - private: bool KillIfRunning(const QString & cmd); + + private: void Fork(void); QFileInfo m_app; @@ -80,7 +80,11 @@ bool RestartStream(void); - bool StartStreaming(bool flush_buffer); + void LockReplay(void) { m_replay_lock.lock(); } + void UnlockReplay(bool enable_replay = false) + { m_replay = enable_replay; m_replay_lock.unlock(); } + void ReplayStream(void); + bool StartStreaming(void); bool StopStreaming(void); bool CheckForError(void); @@ -117,6 +121,7 @@ QAtomicInt m_streaming_cnt; QMutex m_stream_lock; + QMutex m_replay_lock; }; #endif // _ExternalSTREAMHANDLER_H_ diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/firewiresignalmonitor.cpp mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/firewiresignalmonitor.cpp --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/firewiresignalmonitor.cpp 2018-02-20 03:04:11.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/firewiresignalmonitor.cpp 2018-04-12 14:28:57.000000000 +0000 @@ -44,16 +44,16 @@ * \param _channel FirewireChannel for card * \param _flags Flags to start with */ -FirewireSignalMonitor::FirewireSignalMonitor( - int db_cardnum, - FirewireChannel *_channel, - uint64_t _flags) : - DTVSignalMonitor(db_cardnum, _channel, _flags), - dtvMonitorRunning(false), - tableMonitorThread(NULL), - stb_needs_retune(true), - stb_needs_to_wait_for_pat(false), - stb_needs_to_wait_for_power(false) +FirewireSignalMonitor::FirewireSignalMonitor(int db_cardnum, + FirewireChannel *_channel, + bool _release_stream, + uint64_t _flags) + : DTVSignalMonitor(db_cardnum, _channel, _release_stream, _flags), + dtvMonitorRunning(false), + tableMonitorThread(NULL), + stb_needs_retune(true), + stb_needs_to_wait_for_pat(false), + stb_needs_to_wait_for_power(false) { LOG(VB_CHANNEL, LOG_INFO, LOC + "ctor"); diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/firewiresignalmonitor.h mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/firewiresignalmonitor.h --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/firewiresignalmonitor.h 2018-02-20 03:04:11.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/firewiresignalmonitor.h 2018-04-12 14:28:57.000000000 +0000 @@ -36,6 +36,7 @@ friend class FirewireTableMonitorThread; public: FirewireSignalMonitor(int db_cardnum, FirewireChannel *_channel, + bool _release_stream, uint64_t _flags = kFWSigMon_WaitForPower); virtual void HandlePAT(const ProgramAssociationTable*); diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/hdhrsignalmonitor.cpp mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/hdhrsignalmonitor.cpp --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/hdhrsignalmonitor.cpp 2018-02-20 03:04:11.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/hdhrsignalmonitor.cpp 2018-04-12 14:28:57.000000000 +0000 @@ -38,10 +38,12 @@ * \param _channel HDHRChannel for card * \param _flags Flags to start with */ -HDHRSignalMonitor::HDHRSignalMonitor( - int db_cardnum, HDHRChannel* _channel, uint64_t _flags) : - DTVSignalMonitor(db_cardnum, _channel, _flags), - streamHandlerStarted(false), streamHandler(NULL) +HDHRSignalMonitor::HDHRSignalMonitor(int db_cardnum, + HDHRChannel* _channel, + bool _release_stream, + uint64_t _flags) + : DTVSignalMonitor(db_cardnum, _channel, _release_stream, _flags), + streamHandlerStarted(false), streamHandler(NULL) { LOG(VB_CHANNEL, LOG_INFO, LOC + "ctor"); diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/hdhrsignalmonitor.h mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/hdhrsignalmonitor.h --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/hdhrsignalmonitor.h 2018-02-20 03:04:11.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/hdhrsignalmonitor.h 2018-04-12 14:28:57.000000000 +0000 @@ -14,7 +14,7 @@ { public: HDHRSignalMonitor(int db_cardnum, HDHRChannel* _channel, - uint64_t _flags = 0); + bool _release_stream, uint64_t _flags = 0); virtual ~HDHRSignalMonitor(); void Stop(void); diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/iptvsignalmonitor.cpp mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/iptvsignalmonitor.cpp --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/iptvsignalmonitor.cpp 2018-02-20 03:04:11.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/iptvsignalmonitor.cpp 2018-04-12 14:28:57.000000000 +0000 @@ -24,9 +24,10 @@ */ IPTVSignalMonitor::IPTVSignalMonitor(int db_cardnum, IPTVChannel *_channel, - uint64_t _flags) : - DTVSignalMonitor(db_cardnum, _channel, _flags), - m_streamHandlerStarted(false), m_locked(false) + bool _release_stream, + uint64_t _flags) + : DTVSignalMonitor(db_cardnum, _channel, _release_stream, _flags), + m_streamHandlerStarted(false), m_locked(false) { LOG(VB_CHANNEL, LOG_INFO, LOC + "ctor"); signalLock.SetValue(0); diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/iptvsignalmonitor.h mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/iptvsignalmonitor.h --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/iptvsignalmonitor.h 2018-02-20 03:04:11.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/iptvsignalmonitor.h 2018-04-12 14:28:57.000000000 +0000 @@ -13,7 +13,7 @@ friend class IPTVTableMonitorThread; public: IPTVSignalMonitor(int db_cardnum, IPTVChannel *_channel, - uint64_t _flags = 0); + bool _release_stream, uint64_t _flags = 0); virtual ~IPTVSignalMonitor(); void Stop(void); diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/scriptsignalmonitor.h mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/scriptsignalmonitor.h --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/scriptsignalmonitor.h 2018-02-20 03:04:11.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/scriptsignalmonitor.h 2018-04-12 14:28:57.000000000 +0000 @@ -10,8 +10,9 @@ { public: ScriptSignalMonitor(int db_cardnum, ChannelBase *_channel, + bool _release_stream, uint64_t _flags = 0) : - SignalMonitor(db_cardnum, _channel, _flags) + SignalMonitor(db_cardnum, _channel, _release_stream, _flags) { signalLock.SetValue(true); signalStrength.SetValue(100); @@ -20,7 +21,7 @@ virtual void UpdateValues(void) { SignalMonitor::UpdateValues(); - + EmitStatus(); if (IsAllGood()) SendMessageAllGood(); diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/signalmonitor.cpp mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/signalmonitor.cpp --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/signalmonitor.cpp 2018-02-20 03:04:13.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/signalmonitor.cpp 2018-04-12 14:28:57.000000000 +0000 @@ -83,7 +83,8 @@ */ SignalMonitor *SignalMonitor::Init(QString cardtype, int db_cardnum, - ChannelBase *channel) + ChannelBase *channel, + bool release_stream) { (void) cardtype; (void) db_cardnum; @@ -103,7 +104,8 @@ { DVBChannel *dvbc = dynamic_cast(channel); if (dvbc) - signalMonitor = new DVBSignalMonitor(db_cardnum, dvbc); + signalMonitor = new DVBSignalMonitor(db_cardnum, dvbc, + release_stream); } #endif @@ -112,13 +114,15 @@ { V4LChannel *chan = dynamic_cast(channel); if (chan) - signalMonitor = new AnalogSignalMonitor(db_cardnum, chan); + signalMonitor = new AnalogSignalMonitor(db_cardnum, chan, + release_stream); } else if (cardtype.toUpper() == "V4L2ENC") { V4LChannel *chan = dynamic_cast(channel); if (chan) - signalMonitor = new V4L2encSignalMonitor(db_cardnum, chan); + signalMonitor = new V4L2encSignalMonitor(db_cardnum, chan, + release_stream); } #endif @@ -127,7 +131,8 @@ { HDHRChannel *hdhrc = dynamic_cast(channel); if (hdhrc) - signalMonitor = new HDHRSignalMonitor(db_cardnum, hdhrc); + signalMonitor = new HDHRSignalMonitor(db_cardnum, hdhrc, + release_stream); } #endif @@ -136,7 +141,8 @@ { CetonChannel *cetonchan = dynamic_cast(channel); if (cetonchan) - signalMonitor = new CetonSignalMonitor(db_cardnum, cetonchan); + signalMonitor = new CetonSignalMonitor(db_cardnum, cetonchan, + release_stream); } #endif @@ -145,7 +151,8 @@ { IPTVChannel *fbc = dynamic_cast(channel); if (fbc) - signalMonitor = new IPTVSignalMonitor(db_cardnum, fbc); + signalMonitor = new IPTVSignalMonitor(db_cardnum, fbc, + release_stream); } #endif @@ -154,7 +161,8 @@ { IPTVChannel *fbc = dynamic_cast(channel); if (fbc) - signalMonitor = new IPTVSignalMonitor(db_cardnum, fbc); + signalMonitor = new IPTVSignalMonitor(db_cardnum, fbc, + release_stream); } #endif @@ -163,7 +171,8 @@ { FirewireChannel *fc = dynamic_cast(channel); if (fc) - signalMonitor = new FirewireSignalMonitor(db_cardnum, fc); + signalMonitor = new FirewireSignalMonitor(db_cardnum, fc, + release_stream); } #endif @@ -172,7 +181,8 @@ { ASIChannel *fc = dynamic_cast(channel); if (fc) - signalMonitor = new ASISignalMonitor(db_cardnum, fc); + signalMonitor = new ASISignalMonitor(db_cardnum, fc, + release_stream); } #endif @@ -180,12 +190,14 @@ { ExternalChannel *fc = dynamic_cast(channel); if (fc) - signalMonitor = new ExternalSignalMonitor(db_cardnum, fc); + signalMonitor = new ExternalSignalMonitor(db_cardnum, fc, + release_stream); } if (!signalMonitor && channel) { - signalMonitor = new ScriptSignalMonitor(db_cardnum, channel); + signalMonitor = new ScriptSignalMonitor(db_cardnum, channel, + release_stream); } if (!signalMonitor) @@ -212,10 +224,11 @@ * \param wait_for_mask SignalMonitorFlags to start with. */ SignalMonitor::SignalMonitor(int _capturecardnum, ChannelBase *_channel, - uint64_t wait_for_mask) + uint64_t wait_for_mask, bool _release_stream) : MThread("SignalMonitor"), channel(_channel), pParent(NULL), capturecardnum(_capturecardnum), flags(wait_for_mask), + release_stream(_release_stream), update_rate(25), minimum_update_rate(5), update_done(false), notify_frontend(true), tablemon(false), eit_scan(false), diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/signalmonitor.h mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/signalmonitor.h --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/signalmonitor.h 2018-02-20 03:04:13.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/signalmonitor.h 2018-04-12 14:28:57.000000000 +0000 @@ -38,7 +38,8 @@ static inline bool IsRequired(const QString &cardtype); static inline bool IsSupported(const QString &cardtype); static SignalMonitor *Init(QString cardtype, int db_cardnum, - ChannelBase *channel); + ChannelBase *channel, + bool release_stream); virtual ~SignalMonitor(); // // // // // // // // // // // // // // // // // // // // // // // // @@ -115,7 +116,7 @@ protected: SignalMonitor(int db_cardnum, ChannelBase *_channel, - uint64_t wait_for_mask); + uint64_t wait_for_mask, bool _release_stream); virtual void run(void); @@ -197,6 +198,7 @@ TVRec *pParent; int capturecardnum; volatile uint64_t flags; + bool release_stream; int update_rate; uint minimum_update_rate; bool update_done; diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/streamhandler.cpp mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/streamhandler.cpp --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/streamhandler.cpp 2018-02-20 03:04:11.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/streamhandler.cpp 2018-04-12 14:28:57.000000000 +0000 @@ -105,16 +105,7 @@ _needs_buffering |= needs_buffering; } - StreamDataList::iterator it = _stream_data_list.find(data); - if (it != _stream_data_list.end()) - { - LOG(VB_GENERAL, LOG_ERR, LOC + "Programmer Error, attempted " - "to add a listener which is already being listened to."); - } - else - { - _stream_data_list[data] = output_file; - } + _stream_data_list[data] = output_file; _listener_lock.unlock(); diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/v4l2encsignalmonitor.cpp mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/v4l2encsignalmonitor.cpp --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/v4l2encsignalmonitor.cpp 2018-02-20 03:04:13.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/v4l2encsignalmonitor.cpp 2018-04-12 14:28:57.000000000 +0000 @@ -35,11 +35,13 @@ * \param _channel V4lChannel for card * \param _flags Flags to start with */ -V4L2encSignalMonitor::V4L2encSignalMonitor(int db_cardnum, V4LChannel *_channel, - uint64_t _flags) : - DTVSignalMonitor(db_cardnum, _channel, _flags), - m_stream_handler(nullptr), m_isTS(false), - m_strength(0), m_stable_time(1500), m_width(0), m_height(0), m_lock_cnt(0) +V4L2encSignalMonitor::V4L2encSignalMonitor(int db_cardnum, + V4LChannel *_channel, + bool _release_stream, + uint64_t _flags) + : DTVSignalMonitor(db_cardnum, _channel, _release_stream, _flags), + m_stream_handler(nullptr), m_isTS(false), + m_strength(0), m_stable_time(1500), m_width(0), m_height(0), m_lock_cnt(0) { LOG(VB_CHANNEL, LOG_INFO, LOC + "ctor"); diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/v4l2encsignalmonitor.h mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/v4l2encsignalmonitor.h --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/v4l2encsignalmonitor.h 2018-02-20 03:04:11.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/v4l2encsignalmonitor.h 2018-04-12 14:28:57.000000000 +0000 @@ -17,7 +17,7 @@ { public: V4L2encSignalMonitor(int db_cardnum, V4LChannel *_channel, - uint64_t _flags = 0); + bool _release_stream, uint64_t _flags = 0); virtual ~V4L2encSignalMonitor(); void Stop(void); diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/v4lchannel.cpp mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/v4lchannel.cpp --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/v4lchannel.cpp 2018-02-20 03:04:13.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/v4lchannel.cpp 2018-04-12 14:28:57.000000000 +0000 @@ -40,7 +40,6 @@ audio_device(audiodevice), videofd(-1), device_name(), driver_name(), curList(NULL), totalChannels(0), - currentFormat(), has_stream_io(false), has_std_io(false), has_async_io(false), has_tuner(false), has_sliced_vbi(false), @@ -301,10 +300,9 @@ LOG(VB_CHANNEL, LOG_INFO, LOC + QString("SetFormat(%1) fmt(%2) input(%3)") .arg(format).arg(fmt).arg(inputNum)); - if ((fmt == currentFormat) || SetInputAndFormat(inputNum, fmt)) - { - currentFormat = fmt; - } + if (!SetInputAndFormat(inputNum, fmt)) + LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to set format." + ENO); + } int V4LChannel::SetDefaultFreqTable(const QString &name) diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/v4lchannel.h mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/v4lchannel.h --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/recorders/v4lchannel.h 2018-02-20 03:04:11.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/recorders/v4lchannel.h 2018-04-12 14:28:57.000000000 +0000 @@ -94,7 +94,6 @@ struct CHANLIST *curList; int totalChannels; - QString currentFormat; bool has_stream_io; bool has_std_io; bool has_async_io; diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/tv_rec.cpp mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/tv_rec.cpp --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/tv_rec.cpp 2018-02-20 03:04:13.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/tv_rec.cpp 2018-04-12 14:28:57.000000000 +0000 @@ -2052,7 +2052,8 @@ SignalMonitorValue::Init(); if (SignalMonitor::IsSupported(genOpt.inputtype) && channel->Open()) - signalMonitor = SignalMonitor::Init(genOpt.inputtype, inputid, channel); + signalMonitor = SignalMonitor::Init(genOpt.inputtype, inputid, + channel, false); if (signalMonitor) { @@ -3550,48 +3551,6 @@ } } -/** \fn TVRec::TuningCheckForHWChange(const TuningRequest&,QString&,QString&) - * \brief Returns inputid for device info row in capturecard if it changes. - */ -uint TVRec::TuningCheckForHWChange(const TuningRequest &request, - QString &channum, - QString &inputname) -{ - LOG(VB_RECORD, LOG_INFO, LOC + QString("request (%1) channum (%2) inputname (%3)") - .arg(request.toString()).arg(channum).arg(inputname)); - if (!channel) - return 0; - - uint curInputID = 0, newInputID = 0; - channum = request.channel; - inputname = request.input; - - if (request.program) - request.program->QueryTuningInfo(channum, inputname); - - if (!channum.isEmpty() && inputname.isEmpty()) - channel->CheckChannel(channum); - - if (!inputname.isEmpty()) - { - curInputID = channel->GetInputID(); - newInputID = channel->GetInputID(); - LOG(VB_GENERAL, LOG_INFO, LOC + QString("HW Tuner: %1->%2") - .arg(curInputID).arg(newInputID)); - } - - if (curInputID != newInputID || !CardUtil::IsChannelReusable(genOpt.inputtype)) - { - LOG(VB_RECORD, LOG_INFO, LOC + QString("Inputtype HW Tuner newinputid channum curinputid: %1->%2 %3") - .arg(curInputID).arg(newInputID).arg(channum)); - if (channum.isEmpty()) - channum = GetStartChannel(newInputID); - return newInputID; - } - - return 0; -} - /** \fn TVRec::TuningShutdowns(const TuningRequest&) * \brief This shuts down anything that needs to be shut down * before handling the passed in tuning request. @@ -3602,7 +3561,6 @@ .arg(request.toString())); QString channum, inputname; - uint newInputID = TuningCheckForHWChange(request, channum, inputname); if (scanner && !(request.flags & kFlagEITScan) && HasFlags(kFlagEITScannerRunning)) @@ -3634,7 +3592,7 @@ // At this point any waits are canceled. - if (newInputID || (request.flags & kFlagNoRec)) + if (request.flags & kFlagNoRec) { if (HasFlags(kFlagDummyRecorderRunning)) { @@ -3658,19 +3616,6 @@ // At this point the channel is shut down } - // handle HW change for digital/analog inputs - if (newInputID) - { - LOG(VB_CHANNEL, LOG_INFO, LOC + - "TuningShutdowns: Recreating channel..."); - channel->Close(); - delete channel; - channel = NULL; - - GetDevices(newInputID, genOpt, dvbOpt, fwOpt); - CreateChannel(channum, false); - } - if (ringBuffer && (request.flags & kFlagKillRingBuffer)) { LOG(VB_RECORD, LOG_INFO, LOC + "Tearing down RingBuffer"); diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/tv_rec.h mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/tv_rec.h --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/tv_rec.h 2018-02-20 03:04:13.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/tv_rec.h 2018-04-12 14:28:57.000000000 +0000 @@ -299,9 +299,6 @@ void TuningNewRecorder(MPEGStreamData*); void TuningRestartRecorder(void); QString TuningGetChanNum(const TuningRequest&, QString &input) const; - uint TuningCheckForHWChange(const TuningRequest&, - QString &channum, - QString &inputname); bool TuningOnSameMultiplex(TuningRequest &request); void HandleStateChange(void); diff -Nru mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/videosource.cpp mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/videosource.cpp --- mythtv-29.1+fixes.20180220.9b7b962/mythtv/libs/libmythtv/videosource.cpp 2018-02-20 03:04:13.000000000 +0000 +++ mythtv-29.1+fixes.20180414.329c235/mythtv/libs/libmythtv/videosource.cpp 2018-04-12 14:28:57.000000000 +0000 @@ -957,15 +957,18 @@ } }; -class ArgumentString : public LineEditSetting, public CaptureCardDBStorage +class CommandPath : public MythUITextEditSetting { public: - explicit ArgumentString(const CaptureCard &parent) : - LineEditSetting(this, true), - CaptureCardDBStorage(this, parent, "audiodevice") // change to arguments + explicit CommandPath(const CaptureCard &parent) : + MythUITextEditSetting(new CaptureCardDBStorage(this, parent, + "videodevice")) { - setLabel(QObject::tr("Arguments")); - } + setLabel(QObject::tr("")); + setValue(""); + setHelpText(QObject::tr("Specify the command to run, with any " + "needed arguments.")); + }; }; class FileDevice : public MythUIFileBrowserSetting @@ -2553,7 +2556,8 @@ info(new TransTextEditSetting()) { setVisible(false); - FileDevice *device = new FileDevice(parent); + CommandPath *device = new CommandPath(parent); + device->setLabel(tr("Command path")); device->setHelpText(tr("A 'black box' application controlled via " "stdin, status on stderr and TransportStream " "read from stdout")); @@ -2563,6 +2567,9 @@ info->setEnabled(false); a_cardtype.addTargetedChild("EXTERNAL", info); + a_cardtype.addTargetedChild("EXTERNAL", + new ChannelTimeout(parent, 20000, 1750)); + connect(device, SIGNAL(valueChanged(const QString&)), this, SLOT( probeApp( const QString&))); @@ -2581,13 +2588,16 @@ { ci = tr("'%1' is valid.").arg(fileInfo.absoluteFilePath()); if (!fileInfo.isReadable() || !fileInfo.isFile()) - ci = tr("'%1' is not readable.").arg(fileInfo.absoluteFilePath()); + ci = tr("WARNING: '%1' is not readable.") + .arg(fileInfo.absoluteFilePath()); if (!fileInfo.isExecutable()) - ci = tr("'%1' is not executable.").arg(fileInfo.absoluteFilePath()); + ci = tr("WARNING: '%1' is not executable.") + .arg(fileInfo.absoluteFilePath()); } else { - ci = tr("'%1' does not exist.").arg(fileInfo.absoluteFilePath()); + ci = tr("WARNING: '%1' does not exist.") + .arg(fileInfo.absoluteFilePath()); } info->setValue(ci); @@ -4190,4 +4200,3 @@ DiSEqCDev trees; trees.InvalidateTrees(); } -