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...
jyavenard committed May 25, 2012
1 parent 00a4727 commit d83672529ac1d851d67ca0c06b0b11b64e141119
@@ -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*);
@@ -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;
@@ -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);
@@ -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();
@@ -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);
@@ -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.
*
@@ -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.