diff options
author | Frank Schmirler <vdr@schmirler.de> | 2010-12-02 08:59:14 +0100 |
---|---|---|
committer | Frank Schmirler <vdr@schmirler.de> | 2010-12-02 08:59:14 +0100 |
commit | 5a270cc3ab659a98b4bb674acb77982f7e1ecb14 (patch) | |
tree | 5f2f51c096f192a9b32af9ffd8244eeb6637ad06 /client/device.c | |
parent | e6249bf957a943920b11abbd9efac1efa18b1d00 (diff) | |
download | vdr-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.c | 155 |
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; } |