Ticket #6719: channel-thread-v1.2.patch
File channel-thread-v1.2.patch, 45.4 KB (added by , 15 years ago) |
---|
-
libs/libmythtv/analogsignalmonitor.cpp
old new void AnalogSignalMonitor::UpdateValues(v 32 32 if (videofd < 0) 33 33 return; 34 34 35 if (!IsChannelTuned()) 36 return; 37 35 38 bool isLocked = false; 36 39 if (usingv4l2) 37 40 { -
libs/libmythtv/channelbase.cpp
old new using namespace std; 35 35 #define LOC_WARN QString("ChannelBase(%1) Warning: ").arg(GetCardID()) 36 36 #define LOC_ERR QString("ChannelBase(%1) Error: ").arg(GetCardID()) 37 37 38 /* 39 * Run the channel change thread, and report the status when done 40 */ 41 void ChannelThread::run(void) 42 { 43 bool result = tuner->SetChannelByString(channel); 44 tuner->setStatus(result ? 45 ChannelBase::changeSuccess : ChannelBase::changeFailed); 46 } 47 38 48 ChannelBase::ChannelBase(TVRec *parent) 39 49 : 40 50 pParent(parent), curchannelname(""), 41 currentInputID(-1), commfree(false), cardid(0) 51 currentInputID(-1), commfree(false), cardid(0), 52 abort_change(false) 42 53 { 54 tuneStatus = changeUnknown; 55 tuneThread.tuner = this; 43 56 } 44 57 45 58 ChannelBase::~ChannelBase(void) 46 59 { 60 TeardownAll(); 61 } 62 63 void ChannelBase::TeardownAll(void) 64 { 65 if (tuneThread.isRunning()) 66 { 67 thread_lock.lock(); 68 abort_change = true; 69 tuneCond.wakeAll(); 70 thread_lock.unlock(); 71 tuneThread.wait(); 72 } 73 } 74 75 void ChannelBase::SelectChannel(const QString & chan) 76 { 77 VERBOSE(VB_CHANNEL, LOC + "SelectChannel " + chan); 78 TeardownAll(); 79 80 thread_lock.lock(); 81 abort_change = false; 82 tuneStatus = changePending; 83 thread_lock.unlock(); 84 85 curchannelname = tuneThread.channel = chan; 86 tuneThread.start(); 87 } 88 89 /* 90 * Returns true of the channel change thread should abort 91 */ 92 bool ChannelBase::Aborted(void) 93 { 94 bool result; 95 96 thread_lock.lock(); 97 result = abort_change; 98 thread_lock.unlock(); 99 100 return result; 101 } 102 103 ChannelBase::Status ChannelBase::GetStatus(void) 104 { 105 Status status; 106 107 thread_lock.lock(); 108 status = tuneStatus; 109 thread_lock.unlock(); 110 111 return status; 112 } 113 114 ChannelBase::Status ChannelBase::Wait(void) 115 { 116 tuneThread.wait(); 117 return tuneStatus; 118 } 119 120 void ChannelBase::setStatus(ChannelBase::Status status) 121 { 122 thread_lock.lock(); 123 tuneStatus = status; 124 thread_lock.unlock(); 47 125 } 48 126 49 127 bool ChannelBase::Init(QString &inputname, QString &startchannel, bool setchan) 50 128 { 51 129 bool ok; 52 130 131 VERBOSE(VB_CHANNEL, LOC + QString("Init(%1, %2, %3)") 132 .arg(inputname).arg(startchannel).arg(setchan)); 133 53 134 if (!setchan) 54 135 ok = inputname.isEmpty() ? false : IsTunable(inputname, startchannel); 55 136 else if (inputname.isEmpty()) 56 ok = SetChannelByString(startchannel); 137 { 138 SelectChannel(startchannel); 139 ok = Wait(); 140 } 57 141 else 58 142 ok = SwitchToInput(inputname, startchannel); 59 143 … … bool ChannelBase::Init(QString &inputnam 124 208 if (chanid && cit != channels.end()) 125 209 { 126 210 if (!setchan) 127 {128 211 ok = IsTunable(*it, (mplexid_restriction) ? 129 212 (*cit).channum : startchannel); 130 }131 213 else 132 214 ok = SwitchToInput(*it, (*cit).channum); 133 215 … … int ChannelBase::GetInputByName(const QS 329 411 return -1; 330 412 } 331 413 414 #if 0 // Not used? 332 415 bool ChannelBase::SwitchToInput(const QString &inputname) 333 416 { 334 417 int input = GetInputByName(inputname); … … bool ChannelBase::SwitchToInput(const QS 340 423 "%1 on card\n").arg(inputname)); 341 424 return false; 342 425 } 426 #endif 427 428 bool ChannelBase::SelectInput(const QString &inputname, const QString &chan) 429 { 430 int input = GetInputByName(inputname); 431 432 VERBOSE(VB_CHANNEL, LOC + QString("SelectInput(%1, %2) %3") 433 .arg(inputname).arg(chan).arg(input)); 434 435 if (input >= 0) 436 { 437 if (!SwitchToInput(input, false)) 438 return false; 439 SelectChannel(chan); 440 } 441 else 442 { 443 VERBOSE(VB_IMPORTANT, 444 QString("ChannelBase: Could not find input: %1 on card when " 445 "setting channel %2\n").arg(inputname).arg(chan)); 446 return false; 447 } 448 449 return true; 450 } 343 451 344 452 bool ChannelBase::SwitchToInput(const QString &inputname, const QString &chan) 345 453 { 346 454 int input = GetInputByName(inputname); 347 455 348 bool ok = false; 456 VERBOSE(VB_CHANNEL, LOC + QString("SwitchToInput(%1, %2), %3") 457 .arg(inputname).arg(chan).arg(input)); 458 349 459 if (input >= 0) 350 460 { 351 ok = SwitchToInput(input, false);352 if (ok)353 ok =SetChannelByString(chan);461 if (!SwitchToInput(input, false)) 462 return false; 463 return SetChannelByString(chan); 354 464 } 355 465 else 356 466 { 357 467 VERBOSE(VB_IMPORTANT, 358 468 QString("ChannelBase: Could not find input: %1 on card when " 359 469 "setting channel %2\n").arg(inputname).arg(chan)); 470 return false; 360 471 } 361 return ok; 472 473 return true; 362 474 } 363 475 364 476 bool ChannelBase::SwitchToInput(int newInputNum, bool setstarting) 365 477 { 478 VERBOSE(VB_CHANNEL, LOC + QString("SwitchToInput(%1, %2)") 479 .arg(newInputNum).arg(setstarting)); 480 366 481 InputMap::const_iterator it = inputs.find(newInputNum); 367 482 if (it == inputs.end() || (*it)->startChanNum.isEmpty()) 368 483 return false; … … bool ChannelBase::SwitchToInput(int newI 374 489 // input switching code would go here 375 490 376 491 if (setstarting) 377 return SetChannelByString((*it)->startChanNum);492 SelectChannel((*it)->startChanNum); 378 493 379 494 return true; 380 495 } … … static bool is_input_busy( 485 600 return is_busy; 486 601 } 487 602 488 bool ChannelBase::IsInputAvailable( 489 int inputid, uint &mplexid_restriction) const 603 bool ChannelBase::IsInputAvailable(int inputid, uint &mplexid_restriction) const 490 604 { 491 605 if (inputid < 0) 492 606 return false; … … bool ChannelBase::ChangeExternalChannel( 651 765 } 652 766 else 653 767 { // child contains the pid of the new process 654 int status = 0, pid = 0; 768 QMutex lock; 769 int status = 0, pid = 0; 770 655 771 VERBOSE(VB_CHANNEL, "Waiting for External Tuning program to exit"); 656 772 657 773 bool timed_out = false; 658 774 uint timeout = 30; // how long to wait in seconds 659 775 time_t start_time = time(0); 660 while (-1 != pid && !timed_out )776 while (-1 != pid && !timed_out && !Aborted()) 661 777 { 662 sleep(1); 778 lock.lock(); 779 tuneCond.wait(&lock, 500); // sleep up to 0.5 seconds 663 780 pid = waitpid(child, &status, WUNTRACED|WNOHANG); 664 781 VERBOSE(VB_IMPORTANT, QString("ret_pid(%1) child(%2) status(0x%3)") 665 782 .arg(pid).arg(child).arg(status,0,16)); … … bool ChannelBase::ChangeExternalChannel( 667 784 break; 668 785 else if (time(0) > (time_t)(start_time + timeout)) 669 786 timed_out = true; 787 lock.unlock(); 670 788 } 671 if (timed_out) 789 790 if (timed_out || Aborted()) 672 791 { 673 VERBOSE(VB_IMPORTANT, "External Tuning program timed out, killing"); 792 if (Aborted()) 793 VERBOSE(VB_IMPORTANT, "Aborting External Tuning program"); 794 else 795 VERBOSE(VB_IMPORTANT, "External Tuning program timed out, " 796 "killing"); 674 797 kill(child, SIGTERM); 675 798 usleep(500); 676 799 kill(child, SIGKILL); -
libs/libmythtv/channelbase.h
old new 6 6 // Qt headers 7 7 #include <qmap.h> 8 8 #include <qstringlist.h> 9 #include <qwaitcondition.h> 10 #include <qmutex.h> 11 #include <qthread.h> 9 12 10 13 // MythTV headers 11 14 #include "channelutil.h" … … 13 16 #include "tv.h" 14 17 15 18 class TVRec; 19 class ChannelBase; 20 21 /* 22 * Thread to run tunning process in 23 */ 24 class ChannelThread : public QThread 25 { 26 public: 27 virtual void run(void); 28 29 QString channel; 30 ChannelBase *tuner; 31 }; 16 32 17 33 /** \class ChannelBase 18 34 * \brief Abstract class providing a generic interface to tuning hardware. … … class TVRec; 24 40 25 41 class ChannelBase 26 42 { 27 public: 43 friend class ChannelThread; 44 45 public: 46 enum Status { changeUnknown = 'U', changePending = 'P', 47 changeFailed = 'F', changeSuccess = 'S' }; 48 28 49 ChannelBase(TVRec *parent); 29 virtual ~ChannelBase( );50 virtual ~ChannelBase(void); 30 51 31 52 virtual bool Init(QString &inputname, QString &startchannel, bool setchan); 32 53 virtual bool IsTunable(const QString &input, const QString &channum) const; 33 54 55 virtual void SelectChannel(const QString & chan); 56 57 Status GetStatus(void); 58 Status Wait(void); 59 34 60 // Methods that must be implemented. 35 61 /// \brief Opens the channel changing hardware for use. 36 62 virtual bool Open(void) = 0; 37 63 /// \brief Closes the channel changing hardware to use. 38 64 virtual void Close(void) = 0; 39 virtual bool SetChannelByString(const QString &chan) = 0;40 65 /// \brief Reports whether channel is already open 41 66 virtual bool IsOpen(void) const = 0; 42 67 … … class ChannelBase 83 108 const QString &newChanNum); 84 109 85 110 // Input toggling convenience methods 86 virtual bool SwitchToInput(const QString &input); 87 virtual bool SwitchToInput(const QString &input, const QString &chan); 111 112 // virtual bool SwitchToInput(const QString &input); // not used? 113 virtual bool SelectInput(const QString &input, const QString &chan); 88 114 89 115 virtual bool InitializeInputs(void); 90 116 … … class ChannelBase 109 135 110 136 virtual int GetCardID(void) const; 111 137 protected: 138 virtual bool SetChannelByString(const QString &chan) = 0; 139 112 140 /// \brief Switches to another input on hardware, 113 141 /// and sets the channel is setstarting is true. 142 virtual bool SwitchToInput(const QString &input, const QString &chan); 114 143 virtual bool SwitchToInput(int inputNum, bool setstarting); 115 144 virtual bool IsInputAvailable( 116 145 int inputNum, uint &mplexid_restriction) const; … … class ChannelBase 119 148 static void StoreInputChannels(const InputMap&); 120 149 static void StoreDefaultInput(uint cardid, const QString &input); 121 150 151 bool Aborted(); 152 void setStatus(Status status); 153 void TeardownAll(void); 154 122 155 TVRec *pParent; 123 156 QString curchannelname; 124 157 int currentInputID; … … class ChannelBase 126 159 uint cardid; 127 160 InputMap inputs; 128 161 DBChanList allchannels; ///< channels across all inputs 162 163 QWaitCondition tuneCond; 164 165 private: 166 mutable ChannelThread tuneThread; 167 Status tuneStatus; 168 QMutex thread_lock; 169 bool abort_change; 129 170 }; 130 171 131 172 #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 "videodev_myth.h" 8 #include "mythcontext.h" 9 #include "channelchangemonitor.h" 10 #include "v4lchannel.h" 11 12 #define LOC QString("ChannelChangeM: ").arg(channel->GetDevice()) 13 #define LOC_ERR QString("ChannelChangeM, Error: ").arg(channel->GetDevice()) 14 15 ChannelChangeMonitor::ChannelChangeMonitor( 16 int db_cardnum, V4LChannel *_channel, uint64_t _flags) : 17 SignalMonitor(db_cardnum, _channel, _flags) 18 { 19 } 20 21 void ChannelChangeMonitor::UpdateValues(void) 22 { 23 if (!running || exit) 24 return; 25 26 if (!IsChannelTuned()) 27 return; 28 29 { 30 QMutexLocker locker(&statusLock); 31 signalLock.SetValue(true); 32 signalStrength.SetValue(100); 33 } 34 35 EmitStatus(); 36 SendMessageAllGood(); 37 } 38 -
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 1330 1330 } 1331 1331 1332 1332 // Start signal monitor for this channel 1333 signalMonitor->Start( );1333 signalMonitor->Start(false); 1334 1334 1335 1335 timer.start(); 1336 1336 waitingForTables = true; -
libs/libmythtv/channelscan/channelscan_sm.h
old new class AnalogSignalHandler : public Signa 71 71 72 72 public slots: 73 73 virtual inline void AllGood(void); 74 virtual void StatusChannelTuned(const SignalMonitorValue&) { } 74 75 virtual void StatusSignalLock(const SignalMonitorValue&) { } 75 76 virtual void StatusSignalStrength(const SignalMonitorValue&) { } 76 77 -
libs/libmythtv/channelscan/channelscanner_cli.cpp
old new void ChannelScannerCLI::HandleEvent(cons 92 92 break; 93 93 case ScannerEvent::SetStatusRotorPosition: 94 94 break; 95 case ScannerEvent::SetStatusChannelTuned: 96 break; 95 97 case ScannerEvent::SetStatusSignalLock: 96 98 status_lock = scanEvent->intValue(); 97 99 break; -
libs/libmythtv/channelscan/channelscanner_gui.cpp
old new void ChannelScannerGUI::HandleEvent(cons 151 151 case ScannerEvent::SetStatusRotorPosition: 152 152 popupProgress->SetStatusRotorPosition(scanEvent->intValue()); 153 153 break; 154 case ScannerEvent::SetStatusChannelTuned: 155 break; 154 156 case ScannerEvent::SetStatusSignalLock: 155 157 popupProgress->SetStatusLock(scanEvent->intValue()); 156 158 break; -
libs/libmythtv/channelscan/scanmonitor.cpp
old new void ScanMonitor::StatusRotorPosition(co 107 107 val.GetNormalizedValue(0, 65535)); 108 108 } 109 109 110 void ScanMonitor::StatusChannelTuned(const SignalMonitorValue &val) 111 { 112 post_event(this, ScannerEvent::SetStatusChannelTuned, val.GetValue()); 113 } 114 110 115 void ScanMonitor::StatusSignalLock(const SignalMonitorValue &val) 111 116 { 112 117 post_event(this, ScannerEvent::SetStatusSignalLock, val.GetValue()); -
libs/libmythtv/channelscan/scanmonitor.h
old new class ScanMonitor : 64 64 65 65 // SignalMonitorListener 66 66 virtual void AllGood(void) { } 67 virtual void StatusChannelTuned(const SignalMonitorValue&); 67 68 virtual void StatusSignalLock(const SignalMonitorValue&); 68 69 virtual void StatusSignalStrength(const SignalMonitorValue&); 69 70 … … class ScannerEvent : public QEvent 98 99 SetStatusSignalToNoise, 99 100 SetStatusSignalStrength, 100 101 SetStatusSignalLock, 102 SetStatusChannelTuned 101 103 }; 102 104 103 105 ScannerEvent(TYPE t) : -
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/dvbsignalmonitor.cpp
old new void DVBSignalMonitor::UpdateValues(void 230 230 return; 231 231 } 232 232 233 if (!IsChannelTuned()) 234 return; 235 233 236 AddFlags(kSigMon_WaitForSig); 234 237 235 238 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 140 140 if (!IsInputAvailable(currentInputID, mplexid_restriction)) 141 141 return false; 142 142 143 if (Aborted()) 144 return false; 145 143 146 // Fetch tuning data from the database. 144 147 QString tvformat, modulation, freqtable, freqid, si_std; 145 148 int finetune; -
libs/libmythtv/hdhrsignalmonitor.cpp
old new void HDHRSignalMonitor::UpdateValues(voi 103 103 return; 104 104 } 105 105 106 if (!IsChannelTuned()) 107 return; 108 106 109 QString msg = streamHandler->GetTunerStatus(); 107 110 //ss = signal strength, [0,100] 108 111 //snq = signal to noise quality [0,100] -
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 { 450 450 HEADERS += NuppelVideoRecorder.h fifowriter.h 451 451 SOURCES += NuppelVideoRecorder.cpp fifowriter.cpp 452 452 453 HEADERS += channelchangemonitor.h 454 SOURCES += channelchangemonitor.cpp 455 453 456 # Support for Video4Linux devices 454 457 using_v4l { 455 458 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), 174 is_tuned(false), tablemon(false), 163 175 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::MonitorLoop() 306 324 QStringList slist = GetStatusList(false); 307 325 MythEvent me(QString("SIGNAL %1").arg(capturecardnum), slist); 308 326 gContext->dispatch(me); 309 //cerr<<"sent SIGNAL"<<endl;310 327 } 311 328 312 329 usleep(update_rate * 1000); … … void SignalMonitor::SendMessage( 441 458 case kStatusSignalStrength: 442 459 listener->StatusSignalStrength(val); 443 460 break; 461 case kStatusChannelTuned: 462 listener->StatusChannelTuned(val); 463 break; 444 464 case kStatusSignalToNoise: 445 465 if (dvblistener) 446 466 dvblistener->StatusSignalToNoise(val); … … void SignalMonitor::SendMessage( 461 481 } 462 482 } 463 483 484 bool SignalMonitor::IsChannelTuned(void) 485 { 486 if (is_tuned) 487 return true; 488 489 ChannelBase::Status status = channel->GetStatus(); 490 QMutexLocker locker(&statusLock); 491 492 switch (status) { 493 case ChannelBase::changePending: 494 channelTuned.SetValue(1); 495 break; 496 case ChannelBase::changeFailed: 497 channelTuned.SetValue(2); 498 break; 499 case ChannelBase::changeSuccess: 500 channelTuned.SetValue(3); 501 break; 502 } 503 504 EmitStatus(); 505 506 if (status == ChannelBase::changeSuccess) 507 { 508 if (tablemon) 509 pParent->SetupDTVSignalMonitor(); 510 511 is_tuned = true; 512 return true; 513 } 514 515 return false; 516 } 517 464 518 void SignalMonitor::SendMessageAllGood(void) 465 519 { 466 520 QMutexLocker locker(&listenerLock); … … void SignalMonitor::SendMessageAllGood(v 470 524 471 525 void SignalMonitor::EmitStatus(void) 472 526 { 527 SendMessage(kStatusChannelTuned, channelTuned); 473 528 SendMessage(kStatusSignalLock, signalLock); 474 529 if (HasFlags(kSigMon_WaitForSig)) 475 530 SendMessage(kStatusSignalStrength, signalStrength); -
libs/libmythtv/signalmonitor.h
old new using namespace std; 27 27 28 28 inline QString sm_flags_to_string(uint64_t); 29 29 30 class TVRec; 31 30 32 class SignalMonitor 31 33 { 32 34 public: … … class SignalMonitor 40 42 // // // // // // // // // // // // // // // // // // // // // // // // 41 43 // Control // // // // // // // // // // // // // // // // // // // // 42 44 43 virtual void Start( );45 virtual void Start(bool waitfor_tune); 44 46 virtual void Stop(); 45 47 virtual void Kick(); 46 48 virtual bool WaitForLock(int timeout = -1); … … class SignalMonitor 84 86 */ 85 87 void SetNotifyFrontend(bool notify) { notify_frontend = notify; } 86 88 89 /** \brief Indicate if table monitoring is needed 90 * \param monitor if true parent->SetupDTVSignalMonitor is called 91 * after the channel is tuned. 92 */ 93 void SetMonitoring(TVRec * parent, bool monitor) 94 { pParent = parent; tablemon = monitor; } 95 87 96 /** \brief Sets the number of milliseconds between signal monitoring 88 97 * attempts in the signal monitoring thread. 89 98 * … … class SignalMonitor 97 106 // Listeners // // // // // // // // // // // // // // // // // // // 98 107 void AddListener(SignalMonitorListener *listener); 99 108 void RemoveListener(SignalMonitorListener *listener); 109 100 110 void SendMessage(SignalMonitorMessageType type, 101 111 const SignalMonitorValue &val); 102 112 void SendMessageAllGood(void); … … class SignalMonitor 109 119 static void* SpawnMonitorLoop(void*); 110 120 virtual void MonitorLoop(); 111 121 122 bool IsChannelTuned(void); 123 112 124 /// \brief This should be overridden to actually do signal monitoring. 113 125 virtual void UpdateValues() { ; } 114 126 … … class SignalMonitor 140 152 /// We've seen something indicating whether the data stream is encrypted 141 153 static const uint64_t kDTVSigMon_CryptSeen = 0x0000000200ULL; 142 154 155 static const uint64_t kSigMon_Tuned = 0x0000000400ULL; 156 143 157 /// We've seen a PAT matching our requirements 144 158 static const uint64_t kDTVSigMon_PATMatch = 0x0000001000ULL; 145 159 /// We've seen a PMT matching our requirements … … class SignalMonitor 185 199 protected: 186 200 pthread_t monitor_thread; 187 201 ChannelBase *channel; 202 TVRec *pParent; 188 203 int capturecardnum; 189 204 uint64_t flags; 190 205 int update_rate; … … class SignalMonitor 193 208 bool exit; 194 209 bool update_done; 195 210 bool notify_frontend; 211 bool is_tuned; 212 bool tablemon; 196 213 QString error; 197 214 198 215 SignalMonitorValue signalLock; 199 216 SignalMonitorValue signalStrength; 217 SignalMonitorValue channelTuned; 200 218 201 219 vector<SignalMonitorListener*> listeners; 202 220 -
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 Singal 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 7145 7145 float snr = 0.0f; 7146 7146 uint ber = 0xffffffff; 7147 7147 int pos = -1; 7148 int tuned = -1; 7148 7149 QString pat(""), pmt(""), mgt(""), vct(""), nit(""), sdt(""), crypt(""); 7149 7150 QString err = QString::null, msg = QString::null; 7150 7151 for (it = slist.begin(); it != slist.end(); ++it) … … void TV::UpdateOSDSignal(const PlayerCon 7171 7172 ber = it->GetValue(); 7172 7173 else if ("pos" == it->GetShortName()) 7173 7174 pos = it->GetValue(); 7175 else if ("tuned" == it->GetShortName()) 7176 tuned = it->GetValue(); 7174 7177 else if ("seen_pat" == it->GetShortName()) 7175 7178 pat = it->IsGood() ? "a" : "_"; 7176 7179 else if ("matching_pat" == it->GetShortName()) … … void TV::UpdateOSDSignal(const PlayerCon 7204 7207 infoMap["signal"] = QString::number(sig); // use normalized value 7205 7208 7206 7209 bool allGood = SignalMonitorValue::AllGood(slist); 7210 char tuneCode; 7207 7211 QString slock = ("1" == infoMap["slock"]) ? "L" : "l"; 7208 7212 QString lockMsg = (slock=="L") ? tr("Partial Lock") : tr("No Lock"); 7209 7213 QString sigMsg = allGood ? tr("Lock") : lockMsg; … … void TV::UpdateOSDSignal(const PlayerCon 7216 7220 if ((pos >= 0) && (pos < 100)) 7217 7221 sigDesc += " | " + tr("Rotor %1\%").arg(pos,2); 7218 7222 7219 sigDesc = sigDesc + QString(" | (%1%2%3%4%5%6%7%8) %9") 7220 .arg(slock).arg(pat).arg(pmt).arg(mgt).arg(vct) 7221 .arg(nit).arg(sdt).arg(crypt).arg(sigMsg); 7223 if (tuned == 1) 7224 tuneCode = 't'; 7225 else if (tuned == 2) 7226 tuneCode = 'F'; 7227 else if (tuned == 3) 7228 tuneCode = 'T'; 7229 else 7230 tuneCode = '_'; 7231 7232 sigDesc = sigDesc + QString(" | (%1%2%3%4%5%6%7%8%9) %10") 7233 .arg(tuneCode).arg(slock).arg(pat).arg(pmt).arg(mgt).arg(vct) 7234 .arg(nit).arg(sdt).arg(crypt).arg(sigMsg); 7222 7235 7223 7236 if (!err.isEmpty()) 7224 7237 sigDesc = err; -
libs/libmythtv/tv_rec.cpp
old new ProgramInfo *TVRec::GetRecording(void) 366 366 void TVRec::RecordPending(const ProgramInfo *rcinfo, int secsleft, 367 367 bool hasLater) 368 368 { 369 QMutexLocker lock(&stateChangeLock); 369 QMutexLocker statelock(&stateChangeLock); 370 QMutexLocker pendlock(&pendingRecLock); 370 371 371 372 if (secsleft < 0) 372 373 { … … void TVRec::RecordPending(const ProgramI 404 405 405 406 pendingRecordings[rcinfo->cardid].possibleConflicts = cardids; 406 407 407 state ChangeLock.unlock();408 statelock.unlock(); 408 409 for (uint i = 0; i < cardids.size(); i++) 409 410 RemoteRecordPending(cardids[i], rcinfo, secsleft, hasLater); 410 state ChangeLock.lock();411 statelock.relock(); 411 412 } 412 413 413 414 /** \fn TVRec::SetPseudoLiveTVRecording(ProgramInfo*) … … QDateTime TVRec::GetRecordEndTime(const 439 440 */ 440 441 void TVRec::CancelNextRecording(bool cancel) 441 442 { 443 QMutexLocker pendlock(&pendingRecLock); 442 444 VERBOSE(VB_RECORD, LOC + "CancelNextRecording("<<cancel<<") -- begin"); 443 445 444 446 PendingMap::iterator it = pendingRecordings.find(cardid); … … RecStatusType TVRec::StartRecording(cons 523 525 return retval; 524 526 } 525 527 526 PendingMap::iterator it = pendingRecordings.find(cardid);527 528 bool cancelNext = false; 529 bool has_pending; 530 531 pendingRecLock.lock(); 532 PendingMap::iterator it = pendingRecordings.find(cardid); 528 533 if (it != pendingRecordings.end()) 529 534 { 530 535 (*it).ask = (*it).doNotAsk = false; 531 536 cancelNext = (*it).canceled; 537 has_pending = true; 532 538 } 539 else 540 has_pending = false; 541 542 PendingInfo pendinfo = *it; 543 pendingRecLock.unlock(); 533 544 534 545 // Flush out events... 535 546 WaitForEventThreadSleep(); 536 547 537 548 // If the needed input is in a shared input group, and we are 538 549 // not canceling the recording anyway, check other recorders 539 if (!cancelNext && 540 (it != pendingRecordings.end()) && (*it).possibleConflicts.size()) 550 if (!cancelNext && has_pending && pendinfo.possibleConflicts.size()) 541 551 { 542 552 VERBOSE(VB_RECORD, LOC + "Checking input group recorders - begin"); 543 vector<uint> &cardids = (*it).possibleConflicts;553 vector<uint> &cardids = pendinfo.possibleConflicts; 544 554 545 555 uint mplexid = 0, sourceid = 0; 546 556 vector<uint> cardids2; … … RecStatusType TVRec::StartRecording(cons 563 573 564 574 if (is_busy && !sourceid) 565 575 { 566 mplexid = (*it).info->GetMplexID();567 sourceid = (*it).info->sourceid;576 mplexid = pendinfo.info->GetMplexID(); 577 sourceid = pendinfo.info->sourceid; 568 578 } 569 579 570 580 if (is_busy && … … void TVRec::HandleStateChange(void) 950 960 void TVRec::ChangeState(TVState nextState) 951 961 { 952 962 QMutexLocker lock(&stateChangeLock); 953 954 963 desiredNextState = nextState; 955 964 changeState = true; 956 965 triggerEventLoop.wakeAll(); … … void TVRec::RunTV(void) 1440 1449 QDateTime now = QDateTime::currentDateTime(); 1441 1450 bool has_finish = HasFlags(kFlagFinishRecording); 1442 1451 bool has_rec = pseudoLiveTVRecording; 1452 bool enable_ui = true; 1453 1454 pendingRecLock.lock(); 1443 1455 bool rec_soon = 1444 1456 pendingRecordings.find(cardid) != pendingRecordings.end(); 1445 bool enable_ui = true;1457 pendingRecLock.unlock(); 1446 1458 1447 1459 if (has_rec && (has_finish || (now > recordEndTime))) 1448 1460 { … … bool TVRec::WaitForEventThreadSleep(bool 1589 1601 1590 1602 void TVRec::HandlePendingRecordings(void) 1591 1603 { 1604 QMutexLocker pendlock(&pendingRecLock); 1605 1592 1606 if (pendingRecordings.empty()) 1593 1607 return; 1594 1608 … … bool TVRec::SetupSignalMonitor(bool tabl 2061 2075 // make sure statics are initialized 2062 2076 SignalMonitorValue::Init(); 2063 2077 2064 if (SignalMonitor::IsSupported(genOpt.cardtype) && channel->Open()) 2065 signalMonitor = SignalMonitor::Init(genOpt.cardtype, cardid, channel); 2078 if (channel->Open()) 2079 signalMonitor = SignalMonitor::Init(genOpt.cardtype, cardid, 2080 channel); 2066 2081 2067 2082 if (signalMonitor) 2068 2083 { 2069 2084 VERBOSE(VB_RECORD, LOC + "Signal monitor successfully created"); 2070 // If this is a monitor for Digital TV, initialize table monitors2071 if (GetDTVSignalMonitor() && tablemon && !SetupDTVSignalMonitor())2072 {2073 VERBOSE(VB_IMPORTANT, LOC_ERR +2074 "Failed to setup digital signal monitoring");2075 2076 return false;2077 }2078 2085 2086 signalMonitor->SetMonitoring(this, GetDTVSignalMonitor() && tablemon); 2079 2087 signalMonitor->AddListener(this); 2080 2088 signalMonitor->SetUpdateRate(kSignalMonitoringRate); 2081 2089 signalMonitor->SetNotifyFrontend(notify); 2082 2090 2083 2091 // Start the monitoring thread 2084 signalMonitor->Start( );2092 signalMonitor->Start(true); 2085 2093 } 2086 2094 2087 2095 return true; … … bool TVRec::CheckChannelPrefix(const QSt 2353 2361 { 2354 2362 for (uint j = 0; j < kSpacerListSize; j++) 2355 2363 { 2356 2364 QString qprefix = add_spacer( 2357 2365 prefix, (QString(spacers[j]) == "_") ? "\\_" : spacers[j]); 2358 2366 query.prepare(basequery.arg(qprefix) + cardquery[i]); 2359 2367 … … bool TVRec::IsReallyRecording(void) 2486 2494 */ 2487 2495 bool TVRec::IsBusy(TunedInputInfo *busy_input, int time_buffer) const 2488 2496 { 2489 QMutexLocker lock(&stateChangeLock);2490 2491 2497 TunedInputInfo dummy; 2492 2498 if (!busy_input) 2493 2499 busy_input = &dummy; … … bool TVRec::IsBusy(TunedInputInfo *busy_ 2509 2515 chanid = channel->GetChanID(); 2510 2516 } 2511 2517 2518 QMutexLocker pendlock(&pendingRecLock); 2512 2519 PendingMap::const_iterator it = pendingRecordings.find(cardid); 2513 2520 if (!busy_input->inputid && (it != pendingRecordings.end())) 2514 2521 { … … void TVRec::GetNextProgram(int direction 3194 3201 } 3195 3202 else if (BROWSE_RIGHT == direction) 3196 3203 { 3197 3204 chanid = channel->GetNextChannel(channum, CHANNEL_DIRECTION_SAME); 3198 3205 compare = ">"; 3199 3206 sortorder = "asc"; 3200 3207 } … … void TVRec::TuningShutdowns(const Tuning 3684 3691 void TVRec::TuningFrequency(const TuningRequest &request) 3685 3692 { 3686 3693 DTVChannel *dtvchan = GetDTVChannel(); 3694 3695 bool livetv = request.flags & kFlagLiveTV; 3696 bool antadj = request.flags & kFlagAntennaAdjust; 3697 bool has_dummy = false; 3698 3687 3699 if (dtvchan) 3688 3700 { 3689 3701 MPEGStreamData *mpeg = NULL; … … void TVRec::TuningFrequency(const Tuning 3700 3712 3701 3713 if (request.minorChan && (tuningmode == "atsc")) 3702 3714 { 3703 channel->SetChannelByString(request.channel); 3704 3715 channel->SelectChannel(request.channel); 3705 3716 ATSCStreamData *atsc = dynamic_cast<ATSCStreamData*>(mpeg); 3706 3717 if (atsc) 3707 3718 atsc->SetDesiredChannel(request.majorChan, request.minorChan); 3708 3719 } 3709 3720 else if (request.progNum >= 0) 3710 3721 { 3711 channel->SetChannelByString(request.channel); 3712 3722 channel->SelectChannel(request.channel); 3713 3723 if (mpeg) 3714 3724 mpeg->SetDesiredProgram(request.progNum); 3715 3725 } … … void TVRec::TuningFrequency(const Tuning 3738 3748 if (channel && !channum.isEmpty()) 3739 3749 { 3740 3750 if (!input.isEmpty()) 3741 ok = channel->SwitchToInput(input, channum);3751 channel->SelectInput(input, channum); 3742 3752 else 3743 ok = channel->SetChannelByString(channum); 3753 channel->SelectChannel(channum); 3754 3755 ok = true; 3744 3756 } 3745 3757 3746 3758 if (!ok) … … void TVRec::TuningFrequency(const Tuning 3767 3779 } 3768 3780 } 3769 3781 3770 bool livetv = request.flags & kFlagLiveTV; 3771 bool antadj = request.flags & kFlagAntennaAdjust; 3772 bool use_sm = SignalMonitor::IsRequired(genOpt.cardtype); 3773 bool use_dr = use_sm && (livetv || antadj); 3774 bool has_dummy = false; 3775 3776 if (use_dr) 3782 if (livetv || antadj) 3777 3783 { 3778 3784 // We need there to be a ringbuffer for these modes 3779 3785 bool ok; … … void TVRec::TuningFrequency(const Tuning 3799 3805 has_dummy = true; 3800 3806 } 3801 3807 3802 // Start signal monitoring for devices capable of monitoring 3803 if (use_sm) 3808 // Start signal (or channel change) monitoring 3809 VERBOSE(VB_RECORD, LOC + "Starting Signal Monitor"); 3810 bool error = false; 3811 if (!SetupSignalMonitor(!antadj, livetv | antadj)) 3804 3812 { 3805 VERBOSE(VB_RECORD, LOC + "Starting Signal Monitor"); 3806 bool error = false; 3807 if (!SetupSignalMonitor(!antadj, livetv | antadj)) 3813 VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to setup signal monitor"); 3814 if (signalMonitor) 3808 3815 { 3809 VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to setup signal monitor"); 3810 if (signalMonitor) 3811 { 3812 delete signalMonitor; 3813 signalMonitor = NULL; 3814 } 3815 3816 // pretend the signal monitor is running to prevent segfault 3817 SetFlags(kFlagSignalMonitorRunning); 3818 ClearFlags(kFlagWaitingForSignal); 3819 error = true; 3816 delete signalMonitor; 3817 signalMonitor = NULL; 3820 3818 } 3821 3819 3822 if (signalMonitor) 3823 { 3824 if (request.flags & kFlagEITScan) 3825 { 3826 GetDTVSignalMonitor()->GetStreamData()-> 3827 SetVideoStreamsRequired(0); 3828 GetDTVSignalMonitor()->IgnoreEncrypted(true); 3829 } 3820 // pretend the signal monitor is running to prevent segfault 3821 SetFlags(kFlagSignalMonitorRunning); 3822 ClearFlags(kFlagWaitingForSignal); 3823 error = true; 3824 } 3830 3825 3831 SetFlags(kFlagSignalMonitorRunning); 3832 ClearFlags(kFlagWaitingForSignal); 3833 if (!antadj) 3834 SetFlags(kFlagWaitingForSignal); 3826 if (signalMonitor) 3827 { 3828 if (request.flags & kFlagEITScan) 3829 { 3830 GetDTVSignalMonitor()->GetStreamData()-> 3831 SetVideoStreamsRequired(0); 3832 GetDTVSignalMonitor()->IgnoreEncrypted(true); 3835 3833 } 3836 3834 3837 if (has_dummy && ringBuffer) 3838 { 3839 // Make sure recorder doesn't point to bogus ringbuffer before 3840 // it is potentially restarted without a new ringbuffer, if 3841 // the next channel won't tune and the user exits LiveTV. 3842 if (recorder) 3843 recorder->SetRingBuffer(NULL); 3835 SetFlags(kFlagSignalMonitorRunning); 3836 ClearFlags(kFlagWaitingForSignal); 3837 if (!antadj) 3838 SetFlags(kFlagWaitingForSignal); 3839 } 3844 3840 3845 SetFlags(kFlagDummyRecorderRunning); 3846 VERBOSE(VB_RECORD, "DummyDTVRecorder -- started"); 3847 SetFlags(kFlagRingBufferReady); 3848 } 3841 if (has_dummy && ringBuffer) 3842 { 3843 // Make sure recorder doesn't point to bogus ringbuffer before 3844 // it is potentially restarted without a new ringbuffer, if 3845 // the next channel won't tune and the user exits LiveTV. 3846 if (recorder) 3847 recorder->SetRingBuffer(NULL); 3849 3848 3850 // if we had problems starting the signal monitor, 3851 // we don't want to start the recorder... 3852 if (error) 3853 return; 3849 SetFlags(kFlagDummyRecorderRunning); 3850 VERBOSE(VB_RECORD, "DummyDTVRecorder -- started"); 3851 SetFlags(kFlagRingBufferReady); 3854 3852 } 3855 3853 3854 // if we had problems starting the signal monitor, 3855 // we don't want to start the recorder... 3856 if (error) 3857 return; 3858 3856 3859 // Request a recorder, if the command is a recording command 3857 3860 ClearFlags(kFlagNeedToStartRecorder); 3858 3861 if (request.flags & kFlagRec && !antadj) -
libs/libmythtv/tv_rec.h
old new typedef QMap<uint,PendingInfo> PendingMa 158 158 class MPUBLIC TVRec : public SignalMonitorListener 159 159 { 160 160 friend class TuningRequest; 161 friend class SignalMonitor; 161 162 162 163 public: 163 164 TVRec(int capturecardnum); … … class MPUBLIC TVRec : public SignalMonit 252 253 static TVRec *GetTVRec(uint cardid); 253 254 254 255 virtual void AllGood(void) { triggerEventLoop.wakeAll(); } 256 virtual void StatusChannelTuned(const SignalMonitorValue&) { } 255 257 virtual void StatusSignalLock(const SignalMonitorValue&) { } 256 258 virtual void StatusSignalStrength(const SignalMonitorValue&) { } 257 259 … … class MPUBLIC TVRec : public SignalMonit 260 262 bool WaitForEventThreadSleep(bool wake = true, ulong time = ULONG_MAX); 261 263 static void *EventThread(void *param); 262 264 static void *RecorderThread(void *param); 265 bool SetupDTVSignalMonitor(void); 263 266 264 267 private: 265 268 void SetRingBuffer(RingBuffer *); … … class MPUBLIC TVRec : public SignalMonit 291 294 V4LChannel *GetV4LChannel(void); 292 295 293 296 bool SetupSignalMonitor(bool enable_table_monitoring, bool notify); 294 bool SetupDTVSignalMonitor(void);295 297 void TeardownSignalMonitor(void); 296 298 DTVSignalMonitor *GetDTVSignalMonitor(void); 297 299 … … class MPUBLIC TVRec : public SignalMonit 370 372 371 373 // State variables 372 374 mutable QMutex stateChangeLock; 375 mutable QMutex pendingRecLock; 373 376 TVState internalState; 374 377 TVState desiredNextState; 375 378 bool changeState; -
libs/libmythtv/v4lchannel.h
old new class V4LChannel : public DTVChannel 49 49 QString GetSIStandard(void) const { return "atsc"; } 50 50 51 51 // Commands 52 bool SwitchToInput(int newcapchannel, bool setstarting);53 52 bool Retune(void); 54 53 55 54 // Picture attributes. … … class V4LChannel : public DTVChannel 69 68 bool Tune(uint frequency, QString inputname, 70 69 QString modulation, QString si_std); 71 70 71 protected: 72 bool SwitchToInput(int newcapchannel, bool setstarting); 73 72 74 private: 73 75 // Helper Sets 74 76 void SetFreqTable(const int index);