Ticket #6719: channel-thread-trunk-25379.patch
| File channel-thread-trunk-25379.patch, 48.1 KB (added by , 16 years ago) |
|---|
-
libs/libmythtv/analogsignalmonitor.cpp
old new void AnalogSignalMonitor::UpdateValues(v 33 33 if (videofd < 0) 34 34 return; 35 35 36 if (!IsChannelTuned()) 37 return; 38 36 39 bool isLocked = false; 37 40 if (usingv4l2) 38 41 { -
libs/libmythtv/channelbase.cpp
old new using namespace std; 34 34 #define LOC_WARN QString("ChannelBase(%1) Warning: ").arg(GetCardID()) 35 35 #define LOC_ERR QString("ChannelBase(%1) Error: ").arg(GetCardID()) 36 36 37 /* 38 * Run the channel change thread, and report the status when done 39 */ 40 void ChannelThread::run(void) 41 { 42 VERBOSE(VB_CHANNEL, "ChannelThread::run"); 43 bool result = tuner->SetChannelByString(channel); 44 tuner->setStatus(result ? 45 ChannelBase::changeSuccess : ChannelBase::changeFailed); 46 } 47 37 48 ChannelBase::ChannelBase(TVRec *parent) 38 49 : 39 50 m_pParent(parent), m_curchannelname(""), 40 m_currentInputID(-1), m_commfree(false), m_cardid(0) 51 m_currentInputID(-1), m_commfree(false), m_cardid(0), 52 m_abort_change(false) 41 53 { 54 m_tuneStatus = changeUnknown; 55 m_tuneThread.tuner = this; 42 56 } 43 57 44 58 ChannelBase::~ChannelBase(void) 45 59 { 46 60 ClearInputMap(); 61 TeardownAll(); 62 } 63 64 void ChannelBase::TeardownAll(void) 65 { 66 if (m_tuneThread.isRunning()) 67 { 68 m_thread_lock.lock(); 69 m_abort_change = true; 70 m_tuneCond.wakeAll(); 71 m_thread_lock.unlock(); 72 m_tuneThread.wait(); 73 } 74 } 75 76 void ChannelBase::SelectChannel(const QString & chan) 77 { 78 VERBOSE(VB_CHANNEL, LOC + "SelectChannel " + chan); 79 TeardownAll(); 80 81 m_thread_lock.lock(); 82 m_abort_change = false; 83 m_tuneStatus = changePending; 84 m_thread_lock.unlock(); 85 86 m_curchannelname = m_tuneThread.channel = chan; 87 m_tuneThread.start(); 88 } 89 90 /* 91 * Returns true of the channel change thread should abort 92 */ 93 bool ChannelBase::Aborted(void) 94 { 95 bool result; 96 97 m_thread_lock.lock(); 98 result = m_abort_change; 99 m_thread_lock.unlock(); 100 101 return result; 102 } 103 104 ChannelBase::Status ChannelBase::GetStatus(void) 105 { 106 Status status; 107 108 m_thread_lock.lock(); 109 status = m_tuneStatus; 110 m_thread_lock.unlock(); 111 112 return status; 113 } 114 115 ChannelBase::Status ChannelBase::Wait(void) 116 { 117 m_tuneThread.wait(); 118 return m_tuneStatus; 119 } 120 121 void ChannelBase::setStatus(ChannelBase::Status status) 122 { 123 m_thread_lock.lock(); 124 m_tuneStatus = status; 125 m_thread_lock.unlock(); 47 126 } 48 127 49 128 bool ChannelBase::Init(QString &inputname, QString &startchannel, bool setchan) … … bool ChannelBase::Init(QString &inputnam 53 132 if (!setchan) 54 133 ok = inputname.isEmpty() ? false : IsTunable(inputname, startchannel); 55 134 else if (inputname.isEmpty()) 56 ok = SetChannelByString(startchannel); 135 { 136 SelectChannel(startchannel); 137 ok = Wait(); 138 } 57 139 else 58 ok = S witchToInput(inputname, startchannel);140 ok = SelectInput(inputname, startchannel, false); 59 141 60 142 if (ok) 61 143 return true; … … bool ChannelBase::Init(QString &inputnam 124 206 if (chanid && cit != channels.end()) 125 207 { 126 208 if (!setchan) 127 {128 209 ok = IsTunable(*it, (mplexid_restriction) ? 129 210 (*cit).channum : startchannel); 130 }131 211 else 132 ok = S witchToInput(*it, (*cit).channum);212 ok = SelectInput(*it, (*cit).channum, false); 133 213 134 214 if (ok) 135 215 { … … int ChannelBase::GetInputByName(const QS 329 409 return -1; 330 410 } 331 411 412 #if 0 // Not used? 332 413 bool ChannelBase::SwitchToInput(const QString &inputname) 333 414 { 334 415 int input = GetInputByName(inputname); … … bool ChannelBase::SwitchToInput(const QS 340 421 "%1 on card\n").arg(inputname)); 341 422 return false; 342 423 } 424 #endif 343 425 344 bool ChannelBase::SwitchToInput(const QString &inputname, const QString &chan) 426 bool ChannelBase::SelectInput(const QString &inputname, const QString &chan, 427 bool use_sm) 345 428 { 346 429 int input = GetInputByName(inputname); 347 430 348 bool ok = false;349 431 if (input >= 0) 350 432 { 351 ok = SwitchToInput(input, false); 352 if (ok) 353 ok = SetChannelByString(chan); 433 if (!SwitchToInput(input, false)) 434 return false; 435 if (use_sm) 436 SelectChannel(chan); 437 else 438 return SetChannelByString(chan); 354 439 } 355 440 else 356 441 { 357 442 VERBOSE(VB_IMPORTANT, 358 443 QString("ChannelBase: Could not find input: %1 on card when " 359 444 "setting channel %2\n").arg(inputname).arg(chan)); 445 return false; 360 446 } 361 return ok;447 return true; 362 448 } 363 449 364 450 bool ChannelBase::SwitchToInput(int newInputNum, bool setstarting) … … bool ChannelBase::SwitchToInput(int newI 374 460 // input switching code would go here 375 461 376 462 if (setstarting) 377 return SetChannelByString((*it)->startChanNum);463 SelectChannel((*it)->startChanNum); 378 464 379 465 return true; 380 466 } … … static bool is_input_busy( 485 571 return is_busy; 486 572 } 487 573 488 bool ChannelBase::IsInputAvailable( 489 int inputid, uint &mplexid_restriction) const 574 bool ChannelBase::IsInputAvailable(int inputid, uint &mplexid_restriction) const 490 575 { 491 576 if (inputid < 0) 492 577 return false; … … bool ChannelBase::ChangeExternalChannel( 651 736 } 652 737 else 653 738 { // child contains the pid of the new process 654 int status = 0, pid = 0; 739 QMutex lock; 740 int status = 0, pid = 0; 741 655 742 VERBOSE(VB_CHANNEL, "Waiting for External Tuning program to exit"); 656 743 657 744 bool timed_out = false; 658 745 uint timeout = 30; // how long to wait in seconds 659 746 time_t start_time = time(0); 660 while (-1 != pid && !timed_out )747 while (-1 != pid && !timed_out && !Aborted()) 661 748 { 662 sleep(1); 749 lock.lock(); 750 m_tuneCond.wait(&lock, 500); // sleep up to 0.5 seconds 663 751 pid = waitpid(child, &status, WUNTRACED|WNOHANG); 664 752 VERBOSE(VB_IMPORTANT, QString("ret_pid(%1) child(%2) status(0x%3)") 665 753 .arg(pid).arg(child).arg(status,0,16)); 666 754 if (pid==child) 755 { 756 lock.unlock(); 667 757 break; 758 } 668 759 else if (time(0) > (time_t)(start_time + timeout)) 669 760 timed_out = true; 761 lock.unlock(); 670 762 } 671 if (timed_out) 763 764 if (timed_out || Aborted()) 672 765 { 673 VERBOSE(VB_IMPORTANT, "External Tuning program timed out, killing"); 766 if (Aborted()) 767 VERBOSE(VB_IMPORTANT, "Aborting External Tuning program"); 768 else 769 VERBOSE(VB_IMPORTANT, "External Tuning program timed out, " 770 "killing"); 674 771 kill(child, SIGTERM); 675 772 usleep(500); 676 773 kill(child, SIGKILL); … … int ChannelBase::GetChanID() const 752 849 return -1; 753 850 754 851 query.next(); 852 853 VERBOSE(VB_CHANNEL, LOC + QString(" ChannelBase::GetChanID %1") 854 .arg(query.value(0).toInt()));; 855 755 856 return query.value(0).toInt(); 756 857 } 757 858 -
libs/libmythtv/channelbase.h
old new 5 5 6 6 // Qt headers 7 7 #include <QStringList> 8 #include <qwaitcondition.h> 9 #include <qmutex.h> 10 #include <qthread.h> 8 11 9 12 // MythTV headers 10 13 #include "channelutil.h" … … 12 15 #include "tv.h" 13 16 14 17 class TVRec; 18 class ChannelBase; 19 20 /* 21 * Thread to run tunning process in 22 */ 23 class ChannelThread : public QThread 24 { 25 public: 26 virtual void run(void); 27 28 QString channel; 29 ChannelBase *tuner; 30 }; 15 31 16 32 /** \class ChannelBase 17 33 * \brief Abstract class providing a generic interface to tuning hardware. … … class TVRec; 23 39 24 40 class ChannelBase 25 41 { 26 public: 42 friend class ChannelThread; 43 44 public: 45 enum Status { changeUnknown = 'U', changePending = 'P', 46 changeFailed = 'F', changeSuccess = 'S' }; 47 27 48 ChannelBase(TVRec *parent); 28 virtual ~ChannelBase( );49 virtual ~ChannelBase(void); 29 50 30 51 virtual bool Init(QString &inputname, QString &startchannel, bool setchan); 31 52 virtual bool IsTunable(const QString &input, const QString &channum) const; 32 53 54 virtual void SelectChannel(const QString & chan); 55 56 Status GetStatus(void); 57 Status Wait(void); 58 33 59 // Methods that must be implemented. 34 60 /// \brief Opens the channel changing hardware for use. 35 61 virtual bool Open(void) = 0; 36 62 /// \brief Closes the channel changing hardware to use. 37 63 virtual void Close(void) = 0; 38 virtual bool SetChannelByString(const QString &chan) = 0;39 64 /// \brief Reports whether channel is already open 40 65 virtual bool IsOpen(void) const = 0; 41 66 … … class ChannelBase 82 107 const QString &newChanNum); 83 108 84 109 // Input toggling convenience methods 85 virtual bool SwitchToInput(const QString &input); 86 virtual bool SwitchToInput(const QString &input, const QString &chan); 110 // virtual bool SwitchToInput(const QString &input); // not used? 111 virtual bool SelectInput(const QString &input, const QString &chan, 112 bool use_sm); 87 113 88 114 virtual bool InitializeInputs(void); 89 115 … … class ChannelBase 108 134 109 135 virtual int GetCardID(void) const; 110 136 protected: 137 virtual bool SetChannelByString(const QString &chan) = 0; 138 111 139 /// \brief Switches to another input on hardware, 112 140 /// and sets the channel is setstarting is true. 113 141 virtual bool SwitchToInput(int inputNum, bool setstarting); … … class ChannelBase 119 147 static void StoreDefaultInput(uint cardid, const QString &input); 120 148 void ClearInputMap(void); 121 149 150 bool Aborted(); 151 void setStatus(Status status); 152 void TeardownAll(void); 153 122 154 TVRec *m_pParent; 123 155 QString m_curchannelname; 124 156 int m_currentInputID; … … class ChannelBase 126 158 uint m_cardid; 127 159 InputMap m_inputs; 128 160 DBChanList m_allchannels; ///< channels across all inputs 161 162 QWaitCondition m_tuneCond; 163 164 private: 165 mutable ChannelThread m_tuneThread; 166 Status m_tuneStatus; 167 QMutex m_thread_lock; 168 bool m_abort_change; 129 169 }; 130 170 131 171 #endif -
new file libs/libmythtv/channelchangemonitor.cpp
- + 1 // -*- Mode: c++ -*- 2 3 #include <cerrno> 4 #include <unistd.h> 5 #include <sys/ioctl.h> 6 7 #include "mythcontext.h" 8 #include "channelchangemonitor.h" 9 #include "v4lchannel.h" 10 11 #define LOC QString("ChannelChangeM: ").arg(channel->GetDevice()) 12 #define LOC_ERR QString("ChannelChangeM, Error: ").arg(channel->GetDevice()) 13 14 ChannelChangeMonitor::ChannelChangeMonitor( 15 int db_cardnum, V4LChannel *_channel, uint64_t _flags) : 16 SignalMonitor(db_cardnum, _channel, _flags) 17 { 18 } 19 20 void ChannelChangeMonitor::UpdateValues(void) 21 { 22 if (!running || exit) 23 return; 24 25 if (!IsChannelTuned()) 26 return; 27 28 { 29 QMutexLocker locker(&statusLock); 30 signalLock.SetValue(true); 31 signalStrength.SetValue(100); 32 } 33 34 EmitStatus(); 35 SendMessageAllGood(); 36 } 37 -
new file libs/libmythtv/channelchangemonitor.h
- + 1 // -*- Mode: c++ -*- 2 // Copyright (c) 2005, Daniel Thor Kristjansson 3 4 #ifndef _CHANNEL_CHANGE_MONITOR_H_ 5 #define _CHANNEL_CHANGE_MONITOR_H_ 6 7 // MythTV headers 8 #include "signalmonitor.h" 9 10 class V4LChannel; 11 12 class ChannelChangeMonitor : public SignalMonitor 13 { 14 public: 15 ChannelChangeMonitor( 16 int db_cardnum, V4LChannel *_channel, 17 uint64_t _flags = kSigMon_WaitForSig); 18 19 virtual void UpdateValues(void); 20 }; 21 22 #endif // _CHANNEL_CHANGE_MONITOR_H_ -
libs/libmythtv/channelscan/channelscan_sm.cpp
old new void ChannelScanSM::ScanTransport(const 1627 1627 } 1628 1628 1629 1629 // Start signal monitor for this channel 1630 signalMonitor->Start( );1630 signalMonitor->Start(false); 1631 1631 1632 1632 timer.start(); 1633 1633 waitingForTables = (item.tuning.sistandard != "analog"); -
libs/libmythtv/channelscan/channelscan_sm.h
old new class AnalogSignalHandler : public Signa 73 73 public slots: 74 74 virtual inline void AllGood(void); 75 75 virtual void StatusSignalLock(const SignalMonitorValue&) { } 76 virtual void StatusChannelTuned(const SignalMonitorValue&) { } 76 77 virtual void StatusSignalStrength(const SignalMonitorValue&) { } 77 78 78 79 private: -
libs/libmythtv/channelscan/scanmonitor.cpp
old new QEvent::Type ScannerEvent::SetStatusSign 55 55 (QEvent::Type) QEvent::registerEventType(); 56 56 QEvent::Type ScannerEvent::SetStatusSignalLock = 57 57 (QEvent::Type) QEvent::registerEventType(); 58 QEvent::Type ScannerEvent::SetStatusChannelTuned = 59 (QEvent::Type) QEvent::registerEventType(); 58 60 59 61 /// Percentage to set to after the transports have been scanned 60 62 #define TRANSPORT_PCT 6 … … void ScanMonitor::StatusSignalLock(const 133 135 post_event(this, ScannerEvent::SetStatusSignalLock, val.GetValue()); 134 136 } 135 137 138 void ScanMonitor::StatusChannelTuned(const SignalMonitorValue &val) 139 { 140 post_event(this, ScannerEvent::SetStatusChannelTuned, val.GetValue()); 141 } 142 136 143 void ScanMonitor::StatusSignalToNoise(const SignalMonitorValue &val) 137 144 { 138 145 post_event(this, ScannerEvent::SetStatusSignalToNoise, -
libs/libmythtv/channelscan/scanmonitor.h
old new class ScanMonitor : 65 65 // SignalMonitorListener 66 66 virtual void AllGood(void) { } 67 67 virtual void StatusSignalLock(const SignalMonitorValue&); 68 virtual void StatusChannelTuned(const SignalMonitorValue&); 68 69 virtual void StatusSignalStrength(const SignalMonitorValue&); 69 70 70 71 // DVBSignalMonitorListener … … class ScannerEvent : public QEvent 110 111 static Type SetStatusSignalToNoise; 111 112 static Type SetStatusSignalStrength; 112 113 static Type SetStatusSignalLock; 114 static Type SetStatusChannelTuned; 113 115 114 116 private: 115 117 ~ScannerEvent() { } -
libs/libmythtv/dtvsignalmonitor.cpp
old new DTVSignalMonitor::DTVSignalMonitor(int d 25 25 uint64_t wait_for_mask) 26 26 : SignalMonitor(db_cardnum, _channel, wait_for_mask), 27 27 stream_data(NULL), 28 channelTuned(QObject::tr("Channel Tuned"), "tuned", 3, true, 0, 3, 0), 28 29 seenPAT(QObject::tr("Seen")+" PAT", "seen_pat", 1, true, 0, 1, 0), 29 30 seenPMT(QObject::tr("Seen")+" PMT", "seen_pmt", 1, true, 0, 1, 0), 30 31 seenMGT(QObject::tr("Seen")+" MGT", "seen_mgt", 1, true, 0, 1, 0), … … QStringList DTVSignalMonitor::GetStatusL 63 64 { 64 65 QStringList list = SignalMonitor::GetStatusList(kick); 65 66 QMutexLocker locker(&statusLock); 67 68 // tuned? 69 if (flags & kSigMon_Tuned) 70 { 71 list<<channelTuned.GetName()<<channelTuned.GetStatus(); 72 } 73 66 74 // mpeg tables 67 75 if (flags & kDTVSigMon_WaitForPAT) 68 76 { … … void DTVSignalMonitor::RemoveFlags(uint6 138 146 void DTVSignalMonitor::UpdateMonitorValues(void) 139 147 { 140 148 QMutexLocker locker(&statusLock); 149 channelTuned.SetValue((flags & kSigMon_Tuned) ? 3 : 1); 141 150 seenPAT.SetValue( (flags & kDTVSigMon_PATSeen) ? 1 : 0); 142 151 seenPMT.SetValue( (flags & kDTVSigMon_PMTSeen) ? 1 : 0); 143 152 seenMGT.SetValue( (flags & kDTVSigMon_MGTSeen) ? 1 : 0); -
libs/libmythtv/dtvsignalmonitor.h
old new class DTVSignalMonitor : public SignalMo 111 111 protected: 112 112 MPEGStreamData *stream_data; 113 113 vector<uint> eit_pids; 114 SignalMonitorValue channelTuned; 114 115 SignalMonitorValue seenPAT; 115 116 SignalMonitorValue seenPMT; 116 117 SignalMonitorValue seenMGT; -
libs/libmythtv/dvbchannel.cpp
old new bool DVBChannel::SetChannelByString(cons 394 394 return true; 395 395 } 396 396 397 bool DVBChannel::SwitchToInput(const QString &inputname, const QString &chan) 397 bool DVBChannel::SelectInput(const QString &inputname, const QString &chan, 398 bool use_sm) 398 399 { 399 400 int input = GetInputByName(inputname); 400 401 401 bool ok = false;402 402 if (input >= 0) 403 403 { 404 404 nextInputID = input; 405 ok = SetChannelByString(chan); 405 if (use_sm) 406 SelectChannel(chan); 407 else 408 return SetChannelByString(chan); 406 409 } 407 410 else 408 411 { 409 412 VERBOSE(VB_IMPORTANT, 410 413 QString("DVBChannel: Could not find input: %1 on card when " 411 414 "setting channel %2\n").arg(inputname).arg(chan)); 415 return false; 412 416 } 413 return ok;417 return true; 414 418 } 415 419 416 420 bool DVBChannel::SwitchToInput(int newInputNum, bool setstarting) -
libs/libmythtv/dvbchannel.h
old new class DVBChannel : public DTVChannel 78 78 double GetUncorrectedBlockCount(bool *ok = NULL) const; 79 79 80 80 // Commands 81 #if 0 81 82 bool SwitchToInput(const QString &inputname, const QString &chan); 83 #else 84 bool SelectInput(const QString &inputname, const QString &chan, 85 bool use_sm); 86 #endif 82 87 bool SwitchToInput(int newcapchannel, bool setstarting); 83 88 bool SetChannelByString(const QString &chan); 84 89 bool Tune(const DTVMultiplex &tuning, QString inputname); -
libs/libmythtv/dvbsignalmonitor.cpp
old new void DVBSignalMonitor::UpdateValues(void 232 232 return; 233 233 } 234 234 235 if (!IsChannelTuned()) 236 return; 237 235 238 AddFlags(kSigMon_WaitForSig); 236 239 237 240 DVBChannel *dvbchannel = GetDVBChannel(); -
libs/libmythtv/firewiresignalmonitor.cpp
old new void FirewireSignalMonitor::UpdateValues 190 190 if (!running || exit) 191 191 return; 192 192 193 if (!IsChannelTuned()) 194 return; 195 193 196 if (dtvMonitorRunning) 194 197 { 195 198 EmitStatus(); -
libs/libmythtv/hdhrchannel.cpp
old new bool HDHRChannel::SetChannelByString(con 130 130 // change inputs and return, since the act of changing 131 131 // inputs will change the channel as well. 132 132 if (!inputName.isEmpty()) 133 return S witchToInput(inputName, channum);133 return SelectInput(inputName, channum, false); 134 134 135 135 ClearDTVInfo(); 136 136 … … bool HDHRChannel::SetChannelByString(con 142 142 if (!IsInputAvailable(m_currentInputID, mplexid_restriction)) 143 143 return false; 144 144 145 if (Aborted()) 146 return false; 147 145 148 // Fetch tuning data from the database. 146 149 QString tvformat, modulation, freqtable, freqid, si_std; 147 150 int finetune; -
libs/libmythtv/hdhrsignalmonitor.cpp
old new void HDHRSignalMonitor::UpdateValues(voi 105 105 return; 106 106 } 107 107 108 if (!IsChannelTuned()) 109 return; 110 108 111 struct hdhomerun_tuner_status_t status; 109 112 streamHandler->GetTunerStatus(&status); 110 113 -
libs/libmythtv/iptvsignalmonitor.cpp
old new void IPTVSignalMonitor::UpdateValues(voi 119 119 if (!running || exit) 120 120 return; 121 121 122 if (!IsChannelTuned()) 123 return; 124 122 125 if (dtvMonitorRunning) 123 126 { 124 127 EmitStatus(); -
libs/libmythtv/libmythtv.pro
old new using_backend { 454 454 DEFINES += USING_OSS 455 455 } 456 456 457 HEADERS += channelchangemonitor.h 458 SOURCES += channelchangemonitor.cpp 459 457 460 # Support for Video4Linux devices 458 461 using_v4l { 459 462 HEADERS += v4lchannel.h analogsignalmonitor.h -
libs/libmythtv/signalmonitor.cpp
old new 8 8 9 9 // MythTV headers 10 10 #include "mythcontext.h" 11 #include "tv_rec.h" 11 12 #include "signalmonitor.h" 12 13 #include "compat.h" 13 14 #include "mythverbose.h" … … extern "C" { 42 43 # include "firewirechannel.h" 43 44 #endif 44 45 46 #include "channelchangemonitor.h" 47 45 48 #undef DBG_SM 46 49 #define DBG_SM(FUNC, MSG) VERBOSE(VB_CHANNEL, \ 47 50 "SM("<<channel->GetDevice()<<")::"<<FUNC<<": "<<MSG); … … SignalMonitor *SignalMonitor::Init(QStri 93 96 #endif 94 97 95 98 #ifdef USING_V4L 99 #if 0 // Just use ChannelChangeMonitor for these types 96 100 if ((cardtype.toUpper() == "V4L") || 97 (cardtype.toUpper() == "MPEG") || 98 (cardtype.toUpper() == "HDPVR")) 101 (cardtype.toUpper() == "MPEG")) 99 102 { 100 103 V4LChannel *chan = dynamic_cast<V4LChannel*>(channel); 101 104 if (chan) 102 105 signalMonitor = new AnalogSignalMonitor(db_cardnum, chan); 103 106 } 104 107 #endif 108 #endif 105 109 106 110 #ifdef USING_HDHOMERUN 107 111 if (cardtype.toUpper() == "HDHOMERUN") … … SignalMonitor *SignalMonitor::Init(QStri 132 136 133 137 if (!signalMonitor) 134 138 { 139 V4LChannel *chan = dynamic_cast<V4LChannel*>(channel); 140 if (chan) 141 signalMonitor = new ChannelChangeMonitor(db_cardnum, chan); 142 } 143 144 if (!signalMonitor) 145 { 135 146 VERBOSE(VB_IMPORTANT, 136 147 QString("Failed to create signal monitor in Init(%1, %2, 0x%3)") 137 148 .arg(cardtype).arg(db_cardnum).arg((long)channel,0,16)); … … SignalMonitor::SignalMonitor(int _captur 160 171 update_rate(25), minimum_update_rate(5), 161 172 running(false), exit(false), 162 173 update_done(false), notify_frontend(true), 163 error(""), 174 is_tuned(false), tablemon(false), 175 eit_scan(false), error(""), 164 176 signalLock (QObject::tr("Signal Lock"), "slock", 165 177 1, true, 0, 1, 0), 166 178 signalStrength(QObject::tr("Signal Power"), "signal", 167 179 0, true, 0, 100, 0), 180 channelTuned("Channel Tuned", "tuned", 3, true, 0, 3, 0), 168 181 statusLock(QMutex::Recursive) 169 182 { 170 183 } … … bool SignalMonitor::HasAnyFlag(uint64_t 202 215 /** \fn SignalMonitor::Start() 203 216 * \brief Start signal monitoring thread. 204 217 */ 205 void SignalMonitor::Start( )218 void SignalMonitor::Start(bool waitfor_tune) 206 219 { 207 220 DBG_SM("Start", "begin"); 208 221 { 209 222 QMutexLocker locker(&startStopLock); 223 224 // When used for scanning, don't wait for the tuning thread 225 is_tuned = !waitfor_tune; 226 210 227 if (!running) 211 228 { 212 229 int rval = pthread_create( … … QStringList SignalMonitor::GetStatusList 279 296 280 297 QStringList list; 281 298 statusLock.lock(); 299 list<<channelTuned.GetName()<<channelTuned.GetStatus(); 282 300 list<<signalLock.GetName()<<signalLock.GetStatus(); 283 301 if (HasFlags(kSigMon_WaitForSig)) 284 302 list<<signalStrength.GetName()<<signalStrength.GetStatus(); … … void SignalMonitor::SendMessage( 441 459 case kStatusSignalStrength: 442 460 listener->StatusSignalStrength(val); 443 461 break; 462 case kStatusChannelTuned: 463 listener->StatusChannelTuned(val); 464 break; 444 465 case kStatusSignalToNoise: 445 466 if (dvblistener) 446 467 dvblistener->StatusSignalToNoise(val); … … void SignalMonitor::SendMessage( 461 482 } 462 483 } 463 484 485 bool SignalMonitor::IsChannelTuned(void) 486 { 487 if (is_tuned) 488 return true; 489 490 ChannelBase::Status status = channel->GetStatus(); 491 QMutexLocker locker(&statusLock); 492 493 switch (status) { 494 case ChannelBase::changePending: 495 channelTuned.SetValue(1); 496 break; 497 case ChannelBase::changeFailed: 498 channelTuned.SetValue(2); 499 break; 500 case ChannelBase::changeSuccess: 501 channelTuned.SetValue(3); 502 break; 503 } 504 505 EmitStatus(); 506 507 if (status == ChannelBase::changeSuccess) 508 { 509 if (tablemon) 510 pParent->SetupDTVSignalMonitor(eit_scan); 511 512 is_tuned = true; 513 return true; 514 } 515 516 return false; 517 } 518 464 519 void SignalMonitor::SendMessageAllGood(void) 465 520 { 466 521 QMutexLocker locker(&listenerLock); … … void SignalMonitor::SendMessageAllGood(v 470 525 471 526 void SignalMonitor::EmitStatus(void) 472 527 { 528 SendMessage(kStatusChannelTuned, channelTuned); 473 529 SendMessage(kStatusSignalLock, signalLock); 474 530 if (HasFlags(kSigMon_WaitForSig)) 475 531 SendMessage(kStatusSignalStrength, signalStrength); -
libs/libmythtv/signalmonitor.h
old new using namespace std; 26 26 27 27 inline QString sm_flags_to_string(uint64_t); 28 28 29 class TVRec; 30 29 31 class SignalMonitor 30 32 { 31 33 public: … … class SignalMonitor 39 41 // // // // // // // // // // // // // // // // // // // // // // // // 40 42 // Control // // // // // // // // // // // // // // // // // // // // 41 43 42 virtual void Start( );44 virtual void Start(bool waitfor_tune); 43 45 virtual void Stop(); 44 46 virtual void Kick(); 45 47 virtual bool WaitForLock(int timeout = -1); … … class SignalMonitor 83 85 */ 84 86 void SetNotifyFrontend(bool notify) { notify_frontend = notify; } 85 87 88 /** \brief Indicate if table monitoring is needed 89 * \param monitor if true parent->SetupDTVSignalMonitor is called 90 * after the channel is tuned. 91 */ 92 void SetMonitoring(TVRec * parent, bool EITscan, bool monitor) 93 { pParent = parent; eit_scan = EITscan, tablemon = monitor; } 94 86 95 /** \brief Sets the number of milliseconds between signal monitoring 87 96 * attempts in the signal monitoring thread. 88 97 * … … class SignalMonitor 108 117 static void* SpawnMonitorLoop(void*); 109 118 virtual void MonitorLoop(); 110 119 120 bool IsChannelTuned(void); 121 111 122 /// \brief This should be overridden to actually do signal monitoring. 112 123 virtual void UpdateValues() { ; } 113 124 … … class SignalMonitor 139 150 /// We've seen something indicating whether the data stream is encrypted 140 151 static const uint64_t kDTVSigMon_CryptSeen = 0x0000000200ULL; 141 152 153 static const uint64_t kSigMon_Tuned = 0x0000000400ULL; 154 142 155 /// We've seen a PAT matching our requirements 143 156 static const uint64_t kDTVSigMon_PATMatch = 0x0000001000ULL; 144 157 /// We've seen a PMT matching our requirements … … class SignalMonitor 184 197 protected: 185 198 pthread_t monitor_thread; 186 199 ChannelBase *channel; 200 TVRec *pParent; 187 201 int capturecardnum; 188 202 uint64_t flags; 189 203 int update_rate; … … class SignalMonitor 192 206 bool exit; 193 207 bool update_done; 194 208 bool notify_frontend; 209 bool is_tuned; 210 bool tablemon; 211 bool eit_scan; 195 212 QString error; 196 213 197 214 SignalMonitorValue signalLock; 198 215 SignalMonitorValue signalStrength; 216 SignalMonitorValue channelTuned; 199 217 200 218 vector<SignalMonitorListener*> listeners; 201 219 -
libs/libmythtv/signalmonitorlistener.h
old new 9 9 10 10 typedef enum { 11 11 kAllGood, 12 kStatusChannelTuned, 12 13 kStatusSignalLock, 13 14 kStatusSignalStrength, 14 15 kStatusSignalToNoise, … … class MPUBLIC SignalMonitorListener 30 31 */ 31 32 virtual void AllGood(void) = 0; 32 33 34 /** \brief Signal to be sent with change change status. 35 * 36 * Note: Signals are only sent once the monitoring thread 37 * has been started. 38 */ 39 virtual void StatusChannelTuned(const SignalMonitorValue&) = 0; 40 33 41 /** \brief Signal to be sent as true when it is safe to begin 34 42 * or continue recording, and false if it may not be safe. 35 43 * -
libs/libmythtv/tv_play.cpp
old new void TV::UpdateOSDSignal(const PlayerCon 7143 7143 float snr = 0.0f; 7144 7144 uint ber = 0xffffffff; 7145 7145 int pos = -1; 7146 int tuned = -1; 7146 7147 QString pat(""), pmt(""), mgt(""), vct(""), nit(""), sdt(""), crypt(""); 7147 7148 QString err = QString::null, msg = QString::null; 7148 7149 for (it = slist.begin(); it != slist.end(); ++it) … … void TV::UpdateOSDSignal(const PlayerCon 7169 7170 ber = it->GetValue(); 7170 7171 else if ("pos" == it->GetShortName()) 7171 7172 pos = it->GetValue(); 7173 else if ("tuned" == it->GetShortName()) 7174 tuned = it->GetValue(); 7172 7175 else if ("seen_pat" == it->GetShortName()) 7173 7176 pat = it->IsGood() ? "a" : "_"; 7174 7177 else if ("matching_pat" == it->GetShortName()) … … void TV::UpdateOSDSignal(const PlayerCon 7202 7205 infoMap["signal"] = QString::number(sig); // use normalized value 7203 7206 7204 7207 bool allGood = SignalMonitorValue::AllGood(slist); 7208 char tuneCode; 7205 7209 QString slock = ("1" == infoMap["slock"]) ? "L" : "l"; 7206 7210 QString lockMsg = (slock=="L") ? tr("Partial Lock") : tr("No Lock"); 7207 7211 QString sigMsg = allGood ? tr("Lock") : lockMsg; … … void TV::UpdateOSDSignal(const PlayerCon 7214 7218 if ((pos >= 0) && (pos < 100)) 7215 7219 sigDesc += " | " + tr("Rotor %1\%").arg(pos,2); 7216 7220 7217 sigDesc = sigDesc + QString(" | (%1%2%3%4%5%6%7%8) %9") 7218 .arg(slock).arg(pat).arg(pmt).arg(mgt).arg(vct) 7219 .arg(nit).arg(sdt).arg(crypt).arg(sigMsg); 7221 if (tuned == 1) 7222 tuneCode = 't'; 7223 else if (tuned == 2) 7224 tuneCode = 'F'; 7225 else if (tuned == 3) 7226 tuneCode = 'T'; 7227 else 7228 tuneCode = '_'; 7229 7230 sigDesc = sigDesc + QString(" | (%1%2%3%4%5%6%7%8%9) %10") 7231 .arg(tuneCode).arg(slock).arg(pat).arg(pmt).arg(mgt).arg(vct) 7232 .arg(nit).arg(sdt).arg(crypt).arg(sigMsg); 7220 7233 7221 7234 if (!err.isEmpty()) 7222 7235 sigDesc = err; -
libs/libmythtv/tv_rec.cpp
old new ProgramInfo *TVRec::GetRecording(void) 368 368 void TVRec::RecordPending(const ProgramInfo *rcinfo, int secsleft, 369 369 bool hasLater) 370 370 { 371 QMutexLocker lock(&stateChangeLock); 371 QMutexLocker statelock(&stateChangeLock); 372 QMutexLocker pendlock(&pendingRecLock); 372 373 373 374 if (secsleft < 0) 374 375 { … … void TVRec::RecordPending(const ProgramI 406 407 407 408 pendingRecordings[rcinfo->GetCardID()].possibleConflicts = cardids; 408 409 409 stateChangeLock.unlock(); 410 pendlock.unlock(); 411 statelock.unlock(); 410 412 for (uint i = 0; i < cardids.size(); i++) 411 413 RemoteRecordPending(cardids[i], rcinfo, secsleft, hasLater); 412 stateChangeLock.lock(); 414 statelock.relock(); 415 pendlock.relock(); 413 416 } 414 417 415 418 /** \fn TVRec::SetPseudoLiveTVRecording(ProgramInfo*) … … QDateTime TVRec::GetRecordEndTime(const 441 444 */ 442 445 void TVRec::CancelNextRecording(bool cancel) 443 446 { 447 QMutexLocker pendlock(&pendingRecLock); 444 448 VERBOSE(VB_RECORD, LOC + "CancelNextRecording("<<cancel<<") -- begin"); 445 449 446 450 PendingMap::iterator it = pendingRecordings.find(cardid); … … RecStatusType TVRec::StartRecording(cons 524 528 return retval; 525 529 } 526 530 527 PendingMap::iterator it = pendingRecordings.find(cardid);528 531 bool cancelNext = false; 529 if (it != pendingRecordings.end()) 532 PendingInfo pendinfo; 533 PendingMap::iterator it; 534 bool has_pending; 535 536 pendingRecLock.lock(); 537 if ((it = pendingRecordings.find(cardid)) != pendingRecordings.end()) 530 538 { 531 539 (*it).ask = (*it).doNotAsk = false; 532 540 cancelNext = (*it).canceled; 533 541 } 542 pendingRecLock.unlock(); 534 543 535 544 // Flush out events... 536 545 WaitForEventThreadSleep(); … … RecStatusType TVRec::StartRecording(cons 538 547 // Rescan pending recordings since the event loop may have deleted 539 548 // a stale entry. If this happens the info pointer will not be valid 540 549 // since the HandlePendingRecordings loop will have deleted it. 550 pendingRecLock.lock(); 541 551 it = pendingRecordings.find(cardid); 552 has_pending = (it != pendingRecordings.end()); 553 if (has_pending) 554 pendinfo = *it; 555 pendingRecLock.unlock(); 542 556 543 557 // If the needed input is in a shared input group, and we are 544 558 // not canceling the recording anyway, check other recorders 545 if (!cancelNext && 546 (it != pendingRecordings.end()) && (*it).possibleConflicts.size()) 559 if (!cancelNext && has_pending && pendinfo.possibleConflicts.size()) 547 560 { 548 561 VERBOSE(VB_RECORD, LOC + "Checking input group recorders - begin"); 549 vector<uint> &cardids = (*it).possibleConflicts;562 vector<uint> &cardids = pendinfo.possibleConflicts; 550 563 551 564 uint mplexid = 0, sourceid = 0; 552 565 vector<uint> cardids2; … … RecStatusType TVRec::StartRecording(cons 569 582 570 583 if (is_busy && !sourceid) 571 584 { 572 mplexid = (*it).info->QueryMplexID();573 sourceid = (*it).info->GetSourceID();585 mplexid = pendinfo.info->QueryMplexID(); 586 sourceid = pendinfo.info->GetSourceID(); 574 587 } 575 588 576 589 if (is_busy && … … void TVRec::HandleStateChange(void) 954 967 void TVRec::ChangeState(TVState nextState) 955 968 { 956 969 QMutexLocker lock(&stateChangeLock); 957 958 970 desiredNextState = nextState; 959 971 changeState = true; 960 972 WakeEventLoop(); … … void TVRec::RunTV(void) 1428 1440 QDateTime now = QDateTime::currentDateTime(); 1429 1441 bool has_finish = HasFlags(kFlagFinishRecording); 1430 1442 bool has_rec = pseudoLiveTVRecording; 1443 bool enable_ui = true; 1444 1445 pendingRecLock.lock(); 1431 1446 bool rec_soon = 1432 1447 pendingRecordings.find(cardid) != pendingRecordings.end(); 1433 bool enable_ui = true;1448 pendingRecLock.unlock(); 1434 1449 1435 1450 if (has_rec && (has_finish || (now > recordEndTime))) 1436 1451 { … … bool TVRec::WaitForEventThreadSleep(bool 1603 1618 1604 1619 void TVRec::HandlePendingRecordings(void) 1605 1620 { 1621 QMutexLocker pendlock(&pendingRecLock); 1622 1606 1623 if (pendingRecordings.empty()) 1607 1624 return; 1608 1625 … … bool ApplyCachedPids(DTVSignalMonitor *d 1892 1909 * This method also grabs the ATSCStreamData() from the recorder 1893 1910 * if possible, or creates one if needed. 1894 1911 */ 1895 bool TVRec::SetupDTVSignalMonitor( void)1912 bool TVRec::SetupDTVSignalMonitor(bool EITscan) 1896 1913 { 1897 1914 VERBOSE(VB_RECORD, LOC + "Setting up table monitoring."); 1898 1915 … … bool TVRec::SetupDTVSignalMonitor(void) 2026 2043 SignalMonitor::kDVBSigMon_WaitForPos); 2027 2044 sm->SetRotorTarget(1.0f); 2028 2045 2046 if (EITscan) 2047 { 2048 sm->GetStreamData()->SetVideoStreamsRequired(0); 2049 sm->IgnoreEncrypted(true); 2050 } 2051 2029 2052 VERBOSE(VB_RECORD, LOC + "Successfully set up MPEG table monitoring."); 2030 2053 return true; 2031 2054 } … … bool TVRec::SetupDTVSignalMonitor(void) 2047 2070 * \param notify If set we notify the frontend of the signal values 2048 2071 * \return true on success, false on failure 2049 2072 */ 2050 bool TVRec::SetupSignalMonitor(bool tablemon, bool notify)2073 bool TVRec::SetupSignalMonitor(bool tablemon, bool EITscan, bool notify) 2051 2074 { 2052 2075 VERBOSE(VB_RECORD, LOC + "SetupSignalMonitor(" 2053 2076 <<tablemon<<", "<<notify<<")"); … … bool TVRec::SetupSignalMonitor(bool tabl 2063 2086 // make sure statics are initialized 2064 2087 SignalMonitorValue::Init(); 2065 2088 2066 if (SignalMonitor::IsSupported(genOpt.cardtype) && channel->Open()) 2067 signalMonitor = SignalMonitor::Init(genOpt.cardtype, cardid, channel); 2089 if (channel->Open()) 2090 signalMonitor = SignalMonitor::Init(genOpt.cardtype, cardid, 2091 channel); 2068 2092 2069 2093 if (signalMonitor) 2070 2094 { 2071 2095 VERBOSE(VB_RECORD, LOC + "Signal monitor successfully created"); 2072 // If this is a monitor for Digital TV, initialize table monitors2073 if (GetDTVSignalMonitor() && tablemon && !SetupDTVSignalMonitor())2074 {2075 VERBOSE(VB_IMPORTANT, LOC_ERR +2076 "Failed to setup digital signal monitoring");2077 2078 return false;2079 }2080 2096 2097 signalMonitor->SetMonitoring(this, EITscan, 2098 GetDTVSignalMonitor() && tablemon); 2081 2099 signalMonitor->AddListener(this); 2082 2100 signalMonitor->SetUpdateRate(kSignalMonitoringRate); 2083 2101 signalMonitor->SetNotifyFrontend(notify); 2084 2102 2085 2103 // Start the monitoring thread 2086 signalMonitor->Start( );2104 signalMonitor->Start(true); 2087 2105 } 2088 2106 2089 2107 return true; … … bool TVRec::IsReallyRecording(void) 2488 2506 */ 2489 2507 bool TVRec::IsBusy(TunedInputInfo *busy_input, int time_buffer) const 2490 2508 { 2491 QMutexLocker lock(&stateChangeLock);2492 2493 2509 TunedInputInfo dummy; 2494 2510 if (!busy_input) 2495 2511 busy_input = &dummy; … … bool TVRec::IsBusy(TunedInputInfo *busy_ 2511 2527 chanid = channel->GetChanID(); 2512 2528 } 2513 2529 2514 PendingMap::const_iterator it = pendingRecordings.find(cardid); 2515 if (!busy_input->inputid && (it != pendingRecordings.end())) 2530 PendingInfo pendinfo; 2531 bool has_pending; 2532 { 2533 pendingRecLock.lock(); 2534 PendingMap::const_iterator it = pendingRecordings.find(cardid); 2535 has_pending = (it != pendingRecordings.end()); 2536 if (has_pending) 2537 pendinfo = *it; 2538 pendingRecLock.unlock(); 2539 } 2540 2541 if (!busy_input->inputid && has_pending) 2516 2542 { 2517 2543 int timeLeft = QDateTime::currentDateTime() 2518 .secsTo( (*it).recordingStart);2544 .secsTo(pendinfo.recordingStart); 2519 2545 2520 2546 if (timeLeft <= time_buffer) 2521 2547 { 2522 2548 QString channum = QString::null, input = QString::null; 2523 if ( (*it).info->QueryTuningInfo(channum, input))2549 if (pendinfo.info->QueryTuningInfo(channum, input)) 2524 2550 { 2525 2551 busy_input->inputid = channel->GetInputByName(input); 2526 chanid = (*it).info->GetChanID();2552 chanid = pendinfo.info->GetChanID(); 2527 2553 } 2528 2554 } 2529 2555 } … … void TVRec::TuningShutdowns(const Tuning 3667 3693 void TVRec::TuningFrequency(const TuningRequest &request) 3668 3694 { 3669 3695 DTVChannel *dtvchan = GetDTVChannel(); 3696 3697 bool livetv = request.flags & kFlagLiveTV; 3698 bool antadj = request.flags & kFlagAntennaAdjust; 3699 bool has_dummy = false; 3700 3670 3701 if (dtvchan) 3671 3702 { 3672 3703 MPEGStreamData *mpeg = NULL; … … void TVRec::TuningFrequency(const Tuning 3683 3714 3684 3715 if (request.minorChan && (tuningmode == "atsc")) 3685 3716 { 3686 channel->SetChannelByString(request.channel); 3687 3717 channel->SelectChannel(request.channel); 3688 3718 ATSCStreamData *atsc = dynamic_cast<ATSCStreamData*>(mpeg); 3689 3719 if (atsc) 3690 3720 atsc->SetDesiredChannel(request.majorChan, request.minorChan); 3691 3721 } 3692 3722 else if (request.progNum >= 0) 3693 3723 { 3694 channel->SetChannelByString(request.channel); 3695 3724 channel->SelectChannel(request.channel); 3696 3725 if (mpeg) 3697 3726 mpeg->SetDesiredProgram(request.progNum); 3698 3727 } … … void TVRec::TuningFrequency(const Tuning 3721 3750 if (channel && !channum.isEmpty()) 3722 3751 { 3723 3752 if (!input.isEmpty()) 3724 ok = channel->S witchToInput(input, channum);3753 ok = channel->SelectInput(input, channum, true); 3725 3754 else 3726 ok = channel->SetChannelByString(channum); 3755 { 3756 channel->SelectChannel(channum); 3757 ok = true; 3758 } 3727 3759 } 3728 3760 3729 3761 if (!ok) … … void TVRec::TuningFrequency(const Tuning 3750 3782 } 3751 3783 } 3752 3784 3753 bool livetv = request.flags & kFlagLiveTV; 3754 bool antadj = request.flags & kFlagAntennaAdjust; 3755 bool use_sm = SignalMonitor::IsRequired(genOpt.cardtype); 3756 bool use_dr = use_sm && (livetv || antadj); 3757 bool has_dummy = false; 3758 3759 if (use_dr) 3785 if (livetv || antadj) 3760 3786 { 3761 3787 // We need there to be a ringbuffer for these modes 3762 3788 bool ok; … … void TVRec::TuningFrequency(const Tuning 3782 3808 has_dummy = true; 3783 3809 } 3784 3810 3785 // Start signal monitoring for devices capable of monitoring 3786 if (use_sm) 3811 // Start signal (or channel change) monitoring 3812 VERBOSE(VB_RECORD, LOC + "Starting Signal Monitor"); 3813 bool error = false; 3814 if (!SetupSignalMonitor(!antadj, request.flags & kFlagEITScan, 3815 livetv | antadj)) 3787 3816 { 3788 VERBOSE(VB_RECORD, LOC + "Starting Signal Monitor"); 3789 bool error = false; 3790 if (!SetupSignalMonitor(!antadj, livetv | antadj)) 3791 { 3792 VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to setup signal monitor"); 3793 if (signalMonitor) 3794 { 3795 delete signalMonitor; 3796 signalMonitor = NULL; 3797 } 3798 3799 // pretend the signal monitor is running to prevent segfault 3800 SetFlags(kFlagSignalMonitorRunning); 3801 ClearFlags(kFlagWaitingForSignal); 3802 error = true; 3803 } 3804 3817 VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to setup signal monitor"); 3805 3818 if (signalMonitor) 3806 3819 { 3807 if (request.flags & kFlagEITScan) 3808 { 3809 GetDTVSignalMonitor()->GetStreamData()-> 3810 SetVideoStreamsRequired(0); 3811 GetDTVSignalMonitor()->IgnoreEncrypted(true); 3812 } 3813 3814 SetFlags(kFlagSignalMonitorRunning); 3815 ClearFlags(kFlagWaitingForSignal); 3816 if (!antadj) 3817 SetFlags(kFlagWaitingForSignal); 3820 delete signalMonitor; 3821 signalMonitor = NULL; 3818 3822 } 3819 3823 3820 if (has_dummy && ringBuffer) 3821 { 3822 // Make sure recorder doesn't point to bogus ringbuffer before 3823 // it is potentially restarted without a new ringbuffer, if 3824 // the next channel won't tune and the user exits LiveTV. 3825 if (recorder) 3826 recorder->SetRingBuffer(NULL); 3824 // pretend the signal monitor is running to prevent segfault 3825 SetFlags(kFlagSignalMonitorRunning); 3826 ClearFlags(kFlagWaitingForSignal); 3827 error = true; 3828 } 3827 3829 3828 SetFlags(kFlagDummyRecorderRunning); 3829 VERBOSE(VB_RECORD, "DummyDTVRecorder -- started"); 3830 SetFlags(kFlagRingBufferReady); 3831 } 3830 if (signalMonitor) 3831 { 3832 SetFlags(kFlagSignalMonitorRunning); 3833 ClearFlags(kFlagWaitingForSignal); 3834 if (!antadj) 3835 SetFlags(kFlagWaitingForSignal); 3836 } 3832 3837 3833 // if we had problems starting the signal monitor, 3834 // we don't want to start the recorder... 3835 if (error) 3836 return; 3838 if (has_dummy && ringBuffer) 3839 { 3840 // Make sure recorder doesn't point to bogus ringbuffer before 3841 // it is potentially restarted without a new ringbuffer, if 3842 // the next channel won't tune and the user exits LiveTV. 3843 if (recorder) 3844 recorder->SetRingBuffer(NULL); 3845 3846 SetFlags(kFlagDummyRecorderRunning); 3847 VERBOSE(VB_RECORD, "DummyDTVRecorder -- started"); 3848 SetFlags(kFlagRingBufferReady); 3837 3849 } 3838 3850 3851 // if we had problems starting the signal monitor, 3852 // we don't want to start the recorder... 3853 if (error) 3854 return; 3855 3839 3856 // Request a recorder, if the command is a recording command 3840 3857 ClearFlags(kFlagNeedToStartRecorder); 3841 3858 if (request.flags & kFlagRec && !antadj) -
libs/libmythtv/tv_rec.h
old new typedef QMap<uint,PendingInfo> PendingMa 137 137 class MPUBLIC TVRec : public SignalMonitorListener 138 138 { 139 139 friend class TuningRequest; 140 friend class SignalMonitor; 140 141 141 142 public: 142 143 TVRec(int capturecardnum); … … class MPUBLIC TVRec : public SignalMonit 231 232 static TVRec *GetTVRec(uint cardid); 232 233 233 234 virtual void AllGood(void) { WakeEventLoop(); } 235 virtual void StatusChannelTuned(const SignalMonitorValue&) { } 234 236 virtual void StatusSignalLock(const SignalMonitorValue&) { } 235 237 virtual void StatusSignalStrength(const SignalMonitorValue&) { } 236 238 … … class MPUBLIC TVRec : public SignalMonit 239 241 bool WaitForEventThreadSleep(bool wake = true, ulong time = ULONG_MAX); 240 242 static void *EventThread(void *param); 241 243 static void *RecorderThread(void *param); 244 bool SetupDTVSignalMonitor(bool EITscan); 242 245 243 246 private: 244 247 void SetRingBuffer(RingBuffer *); … … class MPUBLIC TVRec : public SignalMonit 268 271 FirewireChannel *GetFirewireChannel(void); 269 272 V4LChannel *GetV4LChannel(void); 270 273 271 bool SetupSignalMonitor(bool enable_table_monitoring, bool notify);272 bool SetupDTVSignalMonitor(void);274 bool SetupSignalMonitor(bool enable_table_monitoring, 275 bool EITscan, bool notify); 273 276 void TeardownSignalMonitor(void); 274 277 DTVSignalMonitor *GetDTVSignalMonitor(void); 275 278 … … class MPUBLIC TVRec : public SignalMonit 347 350 348 351 // State variables 349 352 mutable QMutex stateChangeLock; 353 mutable QMutex pendingRecLock; 350 354 TVState internalState; 351 355 TVState desiredNextState; 352 356 bool changeState; -
libs/libmythtv/v4lchannel.cpp
old new bool V4LChannel::SetChannelByString(cons 441 441 // change inputs and return, since the act of changing 442 442 // inputs will change the channel as well. 443 443 if (!inputName.isEmpty()) 444 return ChannelBase::S witchToInput(inputName, channum);444 return ChannelBase::SelectInput(inputName, channum, false); 445 445 446 446 ClearDTVInfo(); 447 447 -
libs/libmythtv/v4lchannel.h
old new class V4LChannel : public DTVChannel 53 53 QString GetSIStandard(void) const { return "atsc"; } 54 54 55 55 // Commands 56 bool SwitchToInput(int newcapchannel, bool setstarting);57 56 bool Retune(void); 58 57 59 58 // Picture attributes. … … class V4LChannel : public DTVChannel 73 72 bool Tune(uint frequency, QString inputname, 74 73 QString modulation, QString si_std); 75 74 75 protected: 76 bool SwitchToInput(int newcapchannel, bool setstarting); 77 76 78 private: 77 79 // Helper Sets 78 80 void SetFreqTable(const int index);
