Permalink
Browse files

Set up IPTVStreamHandler only when we have a StreamData.

With other recorders the StreamHandler lives as long as the device does, but for IPTV we
need to create a new IPTVStreamHandler for every channel we tune to. So instead of creating
one whenever Tune is called we now only create it when the MPEGStreamData is set.

This means we need to unset the MPEGStreamData to pause the IPTVRecorder and set it
when unpausing the IPTVRecorder so RecorderBase::PauseAndWait() has been overridden
to do that.
  • Loading branch information...
daniel-kristjansson committed Mar 9, 2012
1 parent 473c4ec commit 527c910999d4053c7c1935df4c67c10c5a38ed76
@@ -53,7 +53,7 @@ class DTVSignalMonitor : public SignalMonitor,
/// Sets the MPEG stream data for DTVSignalMonitor to use,
/// and connects the table signals to the monitor.
void SetStreamData(MPEGStreamData* data);
virtual void SetStreamData(MPEGStreamData* data);
/// Returns the MPEG stream data if it exists
MPEGStreamData *GetStreamData() { return stream_data; }
@@ -27,13 +27,13 @@ IPTVChannel::IPTVChannel(TVRec *rec, const QString&) :
IPTVChannel::~IPTVChannel()
{
LOG(VB_GENERAL, LOG_INFO, LOC + "dtor");
LOG(VB_CHANNEL, LOG_INFO, LOC + "dtor");
m_stream_data = NULL;
}
bool IPTVChannel::Open(void)
{
LOG(VB_GENERAL, LOG_INFO, LOC + "Open()");
LOG(VB_CHANNEL, LOG_INFO, LOC + "Open()");
if (IsOpen())
return true;
@@ -46,29 +46,67 @@ bool IPTVChannel::Open(void)
return false;
}
m_open = true;
if (m_last_tuning.IsValid())
m_stream_handler = IPTVStreamHandler::Get(m_last_tuning);
if (m_stream_data)
SetStreamDataInternal(m_stream_data);
return m_open;
return true;
}
void IPTVChannel::SetStreamData(MPEGStreamData *sd)
{
QMutexLocker locker(&m_lock);
if (m_stream_data && m_stream_handler)
m_stream_handler->RemoveListener(m_stream_data);
SetStreamDataInternal(sd);
}
void IPTVChannel::SetStreamDataInternal(MPEGStreamData *sd)
{
LOG(VB_CHANNEL, LOG_INFO, LOC + QString("SetStreamData(0x%1)")
.arg((intptr_t)sd,0,16));
if (m_stream_data == sd)
return;
if (m_stream_data)
{
if (sd)
{
m_stream_handler->RemoveListener(m_stream_data);
m_stream_handler->AddListener(sd);
}
else
{
m_stream_handler->RemoveListener(m_stream_data);
IPTVStreamHandler::Return(m_stream_handler);
}
}
else
{
assert(m_stream_handler == NULL);
if (m_stream_handler)
IPTVStreamHandler::Return(m_stream_handler);
if (sd)
{
if (m_last_tuning.IsValid())
m_stream_handler = IPTVStreamHandler::Get(m_last_tuning);
if (m_stream_handler)
m_stream_handler->AddListener(sd);
}
}
m_stream_data = sd;
if (m_stream_data && m_stream_handler)
m_stream_handler->AddListener(m_stream_data);
}
void IPTVChannel::Close(void)
{
LOG(VB_GENERAL, LOG_INFO, LOC + "Close()");
LOG(VB_CHANNEL, LOG_INFO, LOC + "Close()");
QMutexLocker locker(&m_lock);
if (m_stream_handler)
{
if (m_stream_data)
m_stream_handler->RemoveListener(m_stream_data);
IPTVStreamHandler::Return(m_stream_handler);
}
}
bool IPTVChannel::IsOpen(void) const
@@ -81,31 +119,33 @@ bool IPTVChannel::Tune(const IPTVTuningData &tuning)
{
QMutexLocker locker(&m_lock);
LOG(VB_CHANNEL, LOG_INFO, LOC + QString("Tune(%1)")
.arg(tuning.GetDeviceName()));
if (tuning.GetDataURL().scheme().toUpper() == "RTSP")
{
// TODO get RTP info using RTSP
}
if (!tuning.IsValid())
{
LOG(VB_GENERAL, LOG_ERR, LOC + QString("Invalid tuning info %1")
LOG(VB_CHANNEL, LOG_ERR, LOC + QString("Invalid tuning info %1")
.arg(tuning.GetDeviceName()));
return false;
}
if (m_stream_handler)
{
if (m_stream_data)
m_stream_handler->RemoveListener(m_stream_data);
IPTVStreamHandler::Return(m_stream_handler);
}
m_stream_handler = IPTVStreamHandler::Get(tuning);
if (m_stream_data)
m_stream_handler->AddListener(m_stream_data);
if (m_last_tuning == tuning)
return true;
m_last_tuning = tuning;
if (m_stream_data)
{
MPEGStreamData *tmp = m_stream_data;
SetStreamDataInternal(NULL);
SetStreamDataInternal(tmp);
}
return true;
}
@@ -40,6 +40,9 @@ class IPTVChannel : public DTVChannel
bool IsOpen(void) const;
virtual bool IsIPTV(void) const { return true; } // DTVChannel
private:
void SetStreamDataInternal(MPEGStreamData*);
private:
mutable QMutex m_lock;
volatile bool m_open;
@@ -10,6 +10,7 @@
#include "mpegstreamdata.h"
#include "iptvrecorder.h"
#include "iptvchannel.h"
#include "tv_rec.h"
#define LOC QString("IPTVRec: ")
@@ -59,10 +60,37 @@ void IPTVRecorder::Close(void)
void IPTVRecorder::SetStreamData(MPEGStreamData *data)
{
DTVRecorder::SetStreamData(data);
if (m_open)
if (m_open && !IsPaused())
m_channel->SetStreamData(_stream_data);
}
bool IPTVRecorder::PauseAndWait(int timeout)
{
QMutexLocker locker(&pauseLock);
if (request_pause)
{
if (!IsPaused(true))
{
m_channel->SetStreamData(NULL);
paused = true;
pauseWait.wakeAll();
if (tvrec)
tvrec->RecorderPaused();
}
unpauseWait.wait(&pauseLock, timeout);
}
if (!request_pause && IsPaused(true))
{
m_channel->SetStreamData(_stream_data);
paused = false;
unpauseWait.wakeAll();
}
return IsPaused(true);
}
void IPTVRecorder::run(void)
{
LOG(VB_RECORD, LOG_INFO, LOC + "run -- begin");
@@ -26,6 +26,7 @@ class IPTVRecorder : public DTVRecorder
bool IsOpen(void) const;
virtual void SetStreamData(MPEGStreamData*); // DTVRecorder
virtual bool PauseAndWait(int timeout = 100); // RecorderBase
virtual void run(void); // QRunnable
@@ -57,12 +57,17 @@ void IPTVSignalMonitor::Stop(void)
{
LOG(VB_CHANNEL, LOG_INFO, LOC + "Stop() -- begin");
SignalMonitor::Stop();
if (GetStreamData())
GetChannel()->SetStreamData(GetStreamData());
GetChannel()->SetStreamData(NULL);
m_streamHandlerStarted = false;
LOG(VB_CHANNEL, LOG_INFO, LOC + "Stop() -- end");
}
void IPTVSignalMonitor::SetStreamData(MPEGStreamData *data)
{
DTVSignalMonitor::SetStreamData(data);
GetChannel()->SetStreamData(GetStreamData());
}
void IPTVSignalMonitor::HandlePAT(const ProgramAssociationTable *pat)
{
LOG(VB_CHANNEL, LOG_INFO, LOC + QString("HandlePAT pn: %1")
@@ -18,8 +18,11 @@ class IPTVSignalMonitor : public DTVSignalMonitor
void Stop(void);
// DTVSignalMonitor
virtual void SetStreamData(MPEGStreamData *data);
// MPEG
void HandlePAT(const ProgramAssociationTable*);
virtual void HandlePAT(const ProgramAssociationTable*);
protected:
IPTVSignalMonitor(void);
@@ -138,6 +138,8 @@ void IPTVStreamHandler::run(void)
// can set some socket options
int fd = socket(AF_INET, SOCK_DGRAM, 0); // create IPv4 socket
int buf_size = 2 * 1024 * max(m_tuning.GetBitrate(i)/1000, 500U);
if (!m_tuning.GetBitrate(i))
buf_size = 2 * 1024 * 1024;
int ok = setsockopt(fd, SOL_SOCKET, SO_RCVBUF,
(char *)&buf_size, sizeof(buf_size));
if (ok)
@@ -87,6 +87,16 @@ class MTV_PUBLIC IPTVTuningData
.arg(GetFECURL1().toString());
}
bool operator==(const IPTVTuningData &other) const
{
return GetDeviceName() == other.GetDeviceName();
}
bool operator!=(const IPTVTuningData &other) const
{
return GetDeviceName() != other.GetDeviceName();
}
QUrl GetDataURL(void) const { return m_data_url; }
QUrl GetFECURL0(void) const { return m_fec_url0; }
QUrl GetFECURL1(void) const { return m_fec_url1; }

0 comments on commit 527c910

Please sign in to comment.