summaryrefslogtreecommitdiff
path: root/client/device.c
diff options
context:
space:
mode:
authorFrank Schmirler <vdr@schmirler.de>2010-12-02 08:59:14 +0100
committerFrank Schmirler <vdr@schmirler.de>2010-12-02 08:59:14 +0100
commit5a270cc3ab659a98b4bb674acb77982f7e1ecb14 (patch)
tree5f2f51c096f192a9b32af9ffd8244eeb6637ad06 /client/device.c
parente6249bf957a943920b11abbd9efac1efa18b1d00 (diff)
downloadvdr-plugin-streamdev-5a270cc3ab659a98b4bb674acb77982f7e1ecb14.tar.gz
vdr-plugin-streamdev-5a270cc3ab659a98b4bb674acb77982f7e1ecb14.tar.bz2
Snapshot 2007-05-09
Diffstat (limited to 'client/device.c')
-rw-r--r--client/device.c155
1 files changed, 133 insertions, 22 deletions
diff --git a/client/device.c b/client/device.c
index a2e4580..be79bb9 100644
--- a/client/device.c
+++ b/client/device.c
@@ -1,5 +1,5 @@
/*
- * $Id: device.c,v 1.8 2007/01/15 12:15:12 schmirl Exp $
+ * $Id: device.c,v 1.13 2007/05/07 12:18:18 schmirl Exp $
*/
#include "client/device.h"
@@ -42,6 +42,8 @@ cStreamdevDevice::cStreamdevDevice(void) {
#endif
m_Device = this;
+ m_Pids = 0;
+ m_DvrClosed = true;
if (StreamdevClientSetup.SyncEPG)
ClientSocket.SynchronizeEPG();
@@ -59,13 +61,22 @@ cStreamdevDevice::~cStreamdevDevice() {
bool cStreamdevDevice::ProvidesSource(int Source) const {
Dprintf("ProvidesSource, Source=%d\n", Source);
- return false;
+ return true;
}
bool cStreamdevDevice::ProvidesTransponder(const cChannel *Channel) const
{
Dprintf("ProvidesTransponder\n");
- return false;
+ return true;
+}
+
+bool cStreamdevDevice::IsTunedToTransponder(const cChannel *Channel)
+{
+ bool res = false;
+ if (ClientSocket.DataSocket(siLive) != NULL
+ && TRANSPONDER(Channel, m_Channel))
+ res = true;
+ return res;
}
bool cStreamdevDevice::ProvidesChannel(const cChannel *Channel, int Priority,
@@ -123,37 +134,118 @@ bool cStreamdevDevice::SetChannelDevice(const cChannel *Channel,
bool cStreamdevDevice::SetPid(cPidHandle *Handle, int Type, bool On) {
Dprintf("SetPid, Pid=%d, Type=%d, On=%d, used=%d\n", Handle->pid, Type, On,
Handle->used);
- if (Handle->pid && (On || !Handle->used))
- return ClientSocket.SetPid(Handle->pid, On);
- return true;
+ LOCK_THREAD;
+
+ if (On && !m_TSBuffer) {
+ Dprintf("SetPid: no data connection -> OpenDvr()");
+ OpenDvrInt();
+ }
+
+ bool res = true;
+ if (Handle->pid && (On || !Handle->used)) {
+ res = ClientSocket.SetPid(Handle->pid, On);
+
+ m_Pids += (!res) ? 0 : On ? 1 : -1;
+ if (m_Pids < 0)
+ m_Pids = 0;
+
+ if(m_Pids < 1 && m_DvrClosed) {
+ Dprintf("SetPid: 0 pids left -> CloseDvr()");
+ CloseDvrInt();
+ }
+ }
+
+ return res;
}
-bool cStreamdevDevice::OpenDvr(void) {
- Dprintf("OpenDvr\n");
- CloseDvr();
+bool cStreamdevDevice::OpenDvrInt(void) {
+ Dprintf("OpenDvrInt\n");
+ LOCK_THREAD;
+
+ CloseDvrInt();
+ if (m_TSBuffer) {
+ Dprintf("cStreamdevDevice::OpenDvrInt(): DVR connection already open\n");
+ return true;
+ }
+
+ Dprintf("cStreamdevDevice::OpenDvrInt(): Connecting ...\n");
if (ClientSocket.CreateDataConnection(siLive)) {
- //m_Assembler = new cStreamdevAssembler(ClientSocket.DataSocket(siLive));
- //m_TSBuffer = new cTSBuffer(m_Assembler->ReadPipe(), MEGABYTE(2), CardIndex() + 1);
m_TSBuffer = new cTSBuffer(*ClientSocket.DataSocket(siLive), MEGABYTE(2), CardIndex() + 1);
- Dprintf("waiting\n");
- //m_Assembler->WaitForFill();
- Dprintf("resuming\n");
return true;
}
+ esyslog("cStreamdevDevice::OpenDvrInt(): DVR connection FAILED");
return false;
}
-void cStreamdevDevice::CloseDvr(void) {
- Dprintf("CloseDvr\n");
+bool cStreamdevDevice::OpenDvr(void) {
+ Dprintf("OpenDvr\n");
+ LOCK_THREAD;
+
+ m_DvrClosed = false;
+ return OpenDvrInt();
+}
- //DELETENULL(m_Assembler);
+void cStreamdevDevice::CloseDvrInt(void) {
+ Dprintf("CloseDvrInt\n");
+ LOCK_THREAD;
+
+ if (ClientSocket.CheckConnection()) {
+ if (!m_DvrClosed) {
+ Dprintf("cStreamdevDevice::CloseDvrInt(): m_DvrClosed=false -> not closing yet\n");
+ return;
+ }
+ if (m_Pids > 0) {
+ Dprintf("cStreamdevDevice::CloseDvrInt(): %d active pids -> not closing yet\n", m_Pids);
+ return;
+ }
+ } else {
+ Dprintf("cStreamdevDevice::CloseDvrInt(): Control connection gone !\n");
+ }
+
+ Dprintf("cStreamdevDevice::CloseDvrInt(): Closing DVR connection\n");
DELETENULL(m_TSBuffer);
ClientSocket.CloseDvr();
}
+void cStreamdevDevice::CloseDvr(void) {
+ Dprintf("CloseDvr\n");
+ LOCK_THREAD;
+
+ m_DvrClosed = true;
+ CloseDvrInt();
+}
+
bool cStreamdevDevice::GetTSPacket(uchar *&Data) {
if (m_TSBuffer) {
Data = m_TSBuffer->Get();
+#if 1 // TODO: this should be fixed in vdr cTSBuffer
+ // simple disconnect detection
+ static int m_TSFails = 0;
+ if (!Data) {
+ LOCK_THREAD;
+ if(!ClientSocket.DataSocket(siLive)) {
+ return false; // triggers CloseDvr() + OpenDvr() in cDevice
+ }
+ cPoller Poller(*ClientSocket.DataSocket(siLive));
+ errno = 0;
+ if (Poller.Poll() && !errno) {
+ char tmp[1];
+ if (recv(*ClientSocket.DataSocket(siLive), tmp, 1, MSG_PEEK) == 0 && !errno) {
+esyslog("cStreamDevice::GetTSPacket: GetChecked: NOTHING (%d)", m_TSFails);
+ m_TSFails++;
+ if (m_TSFails > 10) {
+ isyslog("cStreamdevDevice::GetTSPacket(): disconnected");
+ m_Pids = 0;
+ CloseDvrInt();
+ m_TSFails = 0;
+ return false;
+ }
+ return true;
+ }
+ }
+ m_TSFails = 0;
+ }
+#endif
return true;
}
return false;
@@ -162,11 +254,24 @@ bool cStreamdevDevice::GetTSPacket(uchar *&Data) {
#if VDRVERSNUM >= 10300
int cStreamdevDevice::OpenFilter(u_short Pid, u_char Tid, u_char Mask) {
Dprintf("OpenFilter\n");
- if (StreamdevClientSetup.StreamFilters
- && ClientSocket.SetFilter(Pid, Tid, Mask, true)) {
- return m_Filters->OpenFilter(Pid, Tid, Mask);
- } else
+
+ if (!StreamdevClientSetup.StreamFilters)
return -1;
+
+
+ if (!ClientSocket.DataSocket(siLiveFilter)) {
+ if (ClientSocket.CreateDataConnection(siLiveFilter)) {
+ m_Filters->SetConnection(*ClientSocket.DataSocket(siLiveFilter));
+ } else {
+ isyslog("cStreamdevDevice::OpenFilter: connect failed: %m");
+ return -1;
+ }
+ }
+
+ if (ClientSocket.SetFilter(Pid, Tid, Mask, true))
+ return m_Filters->OpenFilter(Pid, Tid, Mask);
+
+ return -1;
}
#endif
@@ -177,11 +282,17 @@ bool cStreamdevDevice::Init(void) {
}
bool cStreamdevDevice::ReInit(void) {
+ if(m_Device) {
+ m_Device->Lock();
+ m_Device->m_Filters->SetConnection(-1);
+ m_Device->m_Pids = 0;
+ }
ClientSocket.Quit();
ClientSocket.Reset();
if (m_Device != NULL) {
- DELETENULL(m_Device->m_TSBuffer);
+ //DELETENULL(m_Device->m_TSBuffer);
DELETENULL(m_Device->m_Assembler);
+ m_Device->Unlock();
}
return StreamdevClientSetup.StartClient ? Init() : true;
}