00001
00002
00003 #include <unistd.h>
00004
00005
00006 #include "mpegstreamdata.h"
00007 #include "iptvchannel.h"
00008 #include "iptvfeederwrapper.h"
00009 #include "iptvsignalmonitor.h"
00010 #include "mythlogging.h"
00011
00012 #undef DBG_SM
00013 #define DBG_SM(FUNC, MSG) LOG(VB_CHANNEL, LOG_DEBUG, \
00014 QString("IPTVSM(%1)::%2: %3").arg(channel->GetDevice()).arg(FUNC).arg(MSG))
00015
00016 #define LOC QString("IPTVSM(%1): ").arg(channel->GetDevice())
00017
00018 void IPTVTableMonitorThread::run(void)
00019 {
00020 RunProlog();
00021 m_parent->RunTableMonitor();
00022 RunEpilog();
00023 }
00024
00039 IPTVSignalMonitor::IPTVSignalMonitor(int db_cardnum,
00040 IPTVChannel *_channel,
00041 uint64_t _flags) :
00042 DTVSignalMonitor(db_cardnum, _channel, _flags),
00043 dtvMonitorRunning(false), tableMonitorThread(NULL)
00044 {
00045 bool isLocked = false;
00046 IPTVChannelInfo chaninfo = GetChannel()->GetCurrentChanInfo();
00047 if (chaninfo.isValid())
00048 {
00049 isLocked = GetChannel()->GetFeeder()->Open(chaninfo.m_url);
00050 }
00051
00052 QMutexLocker locker(&statusLock);
00053 signalLock.SetValue((isLocked) ? 1 : 0);
00054 signalStrength.SetValue((isLocked) ? 100 : 0);
00055 m_gotlock = false;
00056 }
00057
00061 IPTVSignalMonitor::~IPTVSignalMonitor()
00062 {
00063 GetChannel()->GetFeeder()->RemoveListener(this);
00064 Stop();
00065 if (!m_gotlock)
00066 {
00067 DBG_SM("~IPTVSignalMonitor", "Didn't get a lock earlier, closing feed");
00068 GetChannel()->GetFeeder()->Close();
00069 }
00070 }
00071
00072 IPTVChannel *IPTVSignalMonitor::GetChannel(void)
00073 {
00074 return dynamic_cast<IPTVChannel*>(channel);
00075 }
00076
00080 void IPTVSignalMonitor::Stop(void)
00081 {
00082 DBG_SM("Stop", "begin");
00083 GetChannel()->GetFeeder()->RemoveListener(this);
00084 SignalMonitor::Stop();
00085 if (tableMonitorThread)
00086 {
00087 GetChannel()->GetFeeder()->Stop();
00088 dtvMonitorRunning = false;
00089 tableMonitorThread->wait();
00090 delete tableMonitorThread;
00091 tableMonitorThread = NULL;
00092 }
00093 DBG_SM("Stop", "end");
00094 }
00095
00098 void IPTVSignalMonitor::RunTableMonitor(void)
00099 {
00100 DBG_SM("Run", "begin");
00101 dtvMonitorRunning = true;
00102
00103 GetStreamData()->AddListeningPID(0);
00104
00105 GetChannel()->GetFeeder()->AddListener(this);
00106 GetChannel()->GetFeeder()->Run();
00107 GetChannel()->GetFeeder()->RemoveListener(this);
00108
00109 while (dtvMonitorRunning)
00110 usleep(10000);
00111
00112 DBG_SM("Run", "end");
00113 }
00114
00115 void IPTVSignalMonitor::AddData(
00116 const unsigned char *data, unsigned int dataSize)
00117 {
00118 GetStreamData()->ProcessData((unsigned char*)data, dataSize);
00119 }
00120
00121 bool IPTVSignalMonitor::IsAllGood(void) const
00122 {
00123 QMutexLocker locker(&statusLock);
00124
00125 bool ret = DTVSignalMonitor::IsAllGood();
00126 if (ret)
00127 {
00128 m_gotlock = true;
00129 }
00130 return ret;
00131 }
00132
00133
00140 void IPTVSignalMonitor::UpdateValues(void)
00141 {
00142 if (!running || exit)
00143 return;
00144
00145 if (dtvMonitorRunning)
00146 {
00147 EmitStatus();
00148 if (IsAllGood())
00149 SendMessageAllGood();
00150
00151
00152 update_done = true;
00153 return;
00154 }
00155
00156 bool isLocked = false;
00157 {
00158 QMutexLocker locker(&statusLock);
00159 isLocked = signalLock.IsGood();
00160 }
00161
00162 EmitStatus();
00163 if (IsAllGood())
00164 SendMessageAllGood();
00165
00166
00167
00168 if (isLocked && GetStreamData() &&
00169 HasAnyFlag(kDTVSigMon_WaitForPAT | kDTVSigMon_WaitForPMT |
00170 kDTVSigMon_WaitForMGT | kDTVSigMon_WaitForVCT |
00171 kDTVSigMon_WaitForNIT | kDTVSigMon_WaitForSDT))
00172 {
00173 tableMonitorThread = new IPTVTableMonitorThread(this);
00174 DBG_SM("UpdateValues", "Waiting for table monitor to start");
00175 while (!dtvMonitorRunning)
00176 usleep(5000);
00177 DBG_SM("UpdateValues", "Table monitor started");
00178 }
00179
00180 update_done = true;
00181 }