Permalink
Browse files

Attempt to fix most issues in IPTV recorder.

IPTV recording is broken, this commit make things better, but it doesn't solve all issues.
- Tuning wasn't working, it was searching for a freqid on a recorder that doesn't have any, only a channel number
- When playback startup was interrupted (like the frontend exiting) or an error occurs during SignalMonitor, the IPTV stream wasn't killed, resulting in a recorder being stuck forever in "in-use" mode (ref: #10493)
- When recording was going, it would have been impossible to stop the recorder, and TVRec would have just waited forever.

Also add some logging.
  • Loading branch information...
1 parent 00a4727 commit d83672529ac1d851d67ca0c06b0b11b64e141119 @jyavenard jyavenard committed May 25, 2012
View
2 mythtv/libs/libmythtv/dtvsignalmonitor.h
@@ -73,7 +73,7 @@ class DTVSignalMonitor : public SignalMonitor,
/// Returns the scan stream data if it exists
const ScanStreamData *GetScanStreamData() const;
- bool IsAllGood(void) const;
+ virtual bool IsAllGood(void) const;
// MPEG
void HandlePAT(const ProgramAssociationTable*);
View
11 mythtv/libs/libmythtv/iptv/iptvchannelinfo.h
@@ -8,6 +8,7 @@
#include <QString>
#include <QMap>
+#include "mythlogging.h"
class IPTVChannelInfo
{
@@ -20,12 +21,20 @@ class IPTVChannelInfo
IPTVChannelInfo(const QString &name,
const QString &url,
const QString &xmltvid) :
- m_name(name), m_url(url), m_xmltvid(xmltvid) {}
+ m_name(name), m_url(url), m_xmltvid(xmltvid)
+ {
+ }
bool isValid(void) const
{
return !m_name.isEmpty() && !m_url.isEmpty();
}
+
+ QString toString(void) const
+ {
+ return QString("IPTVChannelInfo: Name(%1) Url(%2) xmltvid(%3")
+ .arg(m_name).arg(m_url).arg(m_xmltvid);
+ }
public:
QString m_name;
View
26 mythtv/libs/libmythtv/iptvchannel.cpp
@@ -81,7 +81,8 @@ bool IPTVChannel::IsOpen(void) const
bool IPTVChannel::SetChannelByString(const QString &channum)
{
- LOG(VB_CHANNEL, LOG_INFO, LOC + "SetChannelByString() -- begin");
+ LOG(VB_CHANNEL, LOG_INFO, LOC + QString("SetChannelByString(%1) -- begin")
+ .arg(channum));
QMutexLocker locker(&m_lock);
LOG(VB_CHANNEL, LOG_INFO, LOC + "SetChannelByString() -- locked");
@@ -113,7 +114,8 @@ bool IPTVChannel::SetChannelByString(const QString &channum)
HandleScript(channum /* HACK treat channum as freqid */);
- LOG(VB_CHANNEL, LOG_INFO, LOC + "SetChannelByString() -- end");
+ LOG(VB_CHANNEL, LOG_INFO, LOC + QString("SetChannelByString(%1) = %2 -- end")
+ .arg(channum).arg(m_curchannelname));
return true;
}
@@ -146,7 +148,7 @@ IPTVChannelInfo IPTVChannel::GetChanInfo(
MSqlQuery query(MSqlQuery::InitCon());
query.prepare(
- "SELECT freqid, name "
+ "SELECT name "
"FROM channel "
"WHERE channum = :CHANNUM AND "
" sourceid = :SOURCEID");
@@ -163,24 +165,28 @@ IPTVChannelInfo IPTVChannel::GetChanInfo(
while (query.next())
{
- // Try to map freqid or name to a channel in the map
- const QString freqid = query.value(0).toString();
fbox_chan_map_t::const_iterator it;
- if (!freqid.isEmpty())
+ it = m_freeboxchannels.find(channum);
+ if (it != m_freeboxchannels.end())
{
- it = m_freeboxchannels.find(freqid);
- if (it != m_freeboxchannels.end())
- return *it;
+ LOG(VB_CHANNEL, LOG_DEBUG, LOC +
+ QString("Found: %1").arg((*it).toString()));
+ return *it;
}
// Try to map name to a channel in the map
- const QString name = query.value(1).toString();
+ const QString name = query.value(0).toString();
for (it = m_freeboxchannels.begin();
it != m_freeboxchannels.end(); ++it)
{
if ((*it).m_name == name)
+ {
+ LOG(VB_CHANNEL, LOG_DEBUG, LOC +
+ QString("Found: %1").arg((*it).toString()));
return *it;
+ }
}
+ LOG(VB_CHANNEL, LOG_DEBUG, LOC + QString("Not Found"));
}
LOG(VB_GENERAL, LOG_ERR, msg);
View
63 mythtv/libs/libmythtv/iptvrecorder.cpp
@@ -39,7 +39,7 @@ bool IPTVRecorder::Open(void)
LOG(VB_RECORD, LOG_INFO, LOC + "Open() -- begin");
if (_channel->GetFeeder()->IsOpen())
- _channel->GetFeeder()->Close();
+ return true; // already open
IPTVChannelInfo chaninfo = _channel->GetCurrentChanInfo();
@@ -63,39 +63,15 @@ void IPTVRecorder::Close(void)
LOG(VB_RECORD, LOG_INFO, LOC + "Close() -- end");
}
-bool IPTVRecorder::PauseAndWait(int timeout)
+void IPTVRecorder::StopRecording(void)
{
- QMutexLocker locker(&pauseLock);
- if (request_pause)
- {
- if (!IsPaused(true))
- {
- _channel->GetFeeder()->Stop();
- _channel->GetFeeder()->Close();
-
- paused = true;
- pauseWait.wakeAll();
- if (tvrec)
- tvrec->RecorderPaused();
- }
-
- unpauseWait.wait(&pauseLock, timeout);
- }
-
- if (!request_pause && IsPaused(true))
- {
- paused = false;
-
- if (recording && !_channel->GetFeeder()->IsOpen())
- Open();
-
- if (_stream_data)
- _stream_data->Reset(_stream_data->DesiredProgram());
-
- unpauseWait.wakeAll();
- }
-
- return IsPaused(true);
+ pauseLock.lock();
+ request_recording = false;
+ unpauseWait.wakeAll();
+ pauseLock.unlock();
+
+ // we can't hold the pause lock while we wait for the IPTV feeder to stop
+ _channel->GetFeeder()->Stop();
}
void IPTVRecorder::run(void)
@@ -115,28 +91,13 @@ void IPTVRecorder::run(void)
recordingWait.wakeAll();
}
- while (IsRecordingRequested() && !IsErrored())
- {
- if (PauseAndWait())
- continue;
-
- if (!IsRecordingRequested())
- break;
-
- if (!_channel->GetFeeder()->IsOpen())
- {
- usleep(5000);
- continue;
- }
+ // Go into main RTSP loop, feeding data to AddData
+ _channel->GetFeeder()->Run();
- // Go into main RTSP loop, feeding data to AddData
- _channel->GetFeeder()->Run();
- }
+ Close();
// Finish up...
FinishRecording();
- Close();
-
QMutexLocker locker(&pauseLock);
recording = false;
recordingWait.wakeAll();
View
2 mythtv/libs/libmythtv/iptvrecorder.h
@@ -28,6 +28,7 @@ class IPTVRecorder : public DTVRecorder, public TSDataListener
bool Open(void);
void Close(void);
+ void StopRecording(void);
virtual void run(void);
@@ -40,7 +41,6 @@ class IPTVRecorder : public DTVRecorder, public TSDataListener
private:
bool ProcessTSPacket(const TSPacket &tspacket);
- virtual bool PauseAndWait(int timeout = 100);
// implements TSDataListener
void AddData(const unsigned char *data, unsigned int dataSize);
View
19 mythtv/libs/libmythtv/iptvsignalmonitor.cpp
@@ -52,6 +52,7 @@ IPTVSignalMonitor::IPTVSignalMonitor(int db_cardnum,
QMutexLocker locker(&statusLock);
signalLock.SetValue((isLocked) ? 1 : 0);
signalStrength.SetValue((isLocked) ? 100 : 0);
+ m_gotlock = false;
}
/** \fn IPTVSignalMonitor::~IPTVSignalMonitor()
@@ -61,6 +62,11 @@ IPTVSignalMonitor::~IPTVSignalMonitor()
{
GetChannel()->GetFeeder()->RemoveListener(this);
Stop();
+ if (!m_gotlock)
+ {
+ DBG_SM("~IPTVSignalMonitor", "Didn't get a lock earlier, closing feed");
+ GetChannel()->GetFeeder()->Close();
+ }
}
IPTVChannel *IPTVSignalMonitor::GetChannel(void)
@@ -112,6 +118,19 @@ void IPTVSignalMonitor::AddData(
GetStreamData()->ProcessData((unsigned char*)data, dataSize);
}
+bool IPTVSignalMonitor::IsAllGood(void) const
+{
+ QMutexLocker locker(&statusLock);
+
+ bool ret = DTVSignalMonitor::IsAllGood();
+ if (ret)
+ {
+ m_gotlock = true;
+ }
+ return ret;
+}
+
+
/** \fn IPTVSignalMonitor::UpdateValues(void)
* \brief Fills in frontend stats and emits status Qt signals.
*
View
5 mythtv/libs/libmythtv/iptvsignalmonitor.h
@@ -29,6 +29,8 @@ class IPTVSignalMonitor : public DTVSignalMonitor, public TSDataListener
virtual ~IPTVSignalMonitor();
void Stop(void);
+ bool HasExtraSlowTuning(void) const { return true; }
+ bool IsAllGood(void) const;
// implements TSDataListener
void AddData(const unsigned char *data, unsigned int dataSize);
@@ -46,6 +48,9 @@ class IPTVSignalMonitor : public DTVSignalMonitor, public TSDataListener
protected:
volatile bool dtvMonitorRunning;
IPTVTableMonitorThread *tableMonitorThread;
+
+ private:
+ mutable bool m_gotlock;
};
#endif // _IPTVSIGNALMONITOR_H_

0 comments on commit d836725

Please sign in to comment.