Proper fix for "client sends ABRT after TUNE". Obsoletes many hacks in client

This commit is contained in:
Frank Schmirler 2012-05-21 00:42:08 +02:00
parent 6389c5fd90
commit fffd5aef4f
4 changed files with 15 additions and 67 deletions

View File

@ -1,6 +1,7 @@
VDR Plugin 'streamdev' Revision History VDR Plugin 'streamdev' Revision History
--------------------------------------- ---------------------------------------
- Proper fix for "client sends ABRT after TUNE". Obsoletes many hacks in client
- Added CLOCK_MONOTONIC timestamp and thread id to Dprintf - Added CLOCK_MONOTONIC timestamp and thread id to Dprintf
- Silenced warning (thanks to Rolf Ahrenberg) - Silenced warning (thanks to Rolf Ahrenberg)
- Updated Finnish translation (thanks to Rolf Ahrenberg) - Updated Finnish translation (thanks to Rolf Ahrenberg)

View File

@ -43,7 +43,6 @@ cStreamdevDevice::cStreamdevDevice(void) {
m_Device = this; m_Device = this;
m_Pids = 0; m_Pids = 0;
m_Priority = -100; m_Priority = -100;
m_DvrClosed = true;
} }
cStreamdevDevice::~cStreamdevDevice() { cStreamdevDevice::~cStreamdevDevice() {
@ -178,17 +177,11 @@ bool cStreamdevDevice::SetChannelDevice(const cChannel *Channel,
} }
bool cStreamdevDevice::SetPid(cPidHandle *Handle, int Type, bool On) { bool cStreamdevDevice::SetPid(cPidHandle *Handle, int Type, bool On) {
Dprintf("SetPid, Pid=%d, Type=%d, On=%d, used=%d\n", Handle->pid, Type, On, Dprintf("SetPid, Pid=%d, Type=%d, On=%d, used=%d\n", Handle->pid, Type, On, Handle->used);
Handle->used);
LOCK_THREAD; LOCK_THREAD;
m_UpdatePriority = ClientSocket.SupportsPrio(); m_UpdatePriority = ClientSocket.SupportsPrio();
if (On && !m_TSBuffer) {
Dprintf("SetPid: no data connection -> OpenDvr()");
OpenDvrInt();
}
bool res = true; bool res = true;
if (Handle->pid && (On || !Handle->used)) { if (Handle->pid && (On || !Handle->used)) {
res = ClientSocket.SetPid(Handle->pid, On); res = ClientSocket.SetPid(Handle->pid, On);
@ -196,74 +189,31 @@ bool cStreamdevDevice::SetPid(cPidHandle *Handle, int Type, bool On) {
m_Pids += (!res) ? 0 : On ? 1 : -1; m_Pids += (!res) ? 0 : On ? 1 : -1;
if (m_Pids < 0) if (m_Pids < 0)
m_Pids = 0; m_Pids = 0;
if(m_Pids < 1 && m_DvrClosed) {
Dprintf("SetPid: 0 pids left -> CloseDvr()");
CloseDvrInt();
} }
}
return res; return res;
} }
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_TSBuffer = new cTSBuffer(*ClientSocket.DataSocket(siLive), MEGABYTE(2), CardIndex() + 1);
return true;
}
esyslog("cStreamdevDevice::OpenDvrInt(): DVR connection FAILED");
return false;
}
bool cStreamdevDevice::OpenDvr(void) { bool cStreamdevDevice::OpenDvr(void) {
Dprintf("OpenDvr\n"); Dprintf("OpenDvr\n");
LOCK_THREAD; LOCK_THREAD;
m_DvrClosed = false; CloseDvr();
return OpenDvrInt(); if (ClientSocket.CreateDataConnection(siLive)) {
m_TSBuffer = new cTSBuffer(*ClientSocket.DataSocket(siLive), MEGABYTE(2), CardIndex() + 1);
}
else {
esyslog("cStreamdevDevice::OpenDvr(): DVR connection FAILED");
}
return m_TSBuffer != NULL;
} }
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");
// Hack for VDR 1.5.x clients (sometimes sending ABRT after TUNE)
// TODO: Find a clean solution to fix this
ClientSocket.SetChannelDevice(m_Channel);
ClientSocket.CloseDvr();
DELETENULL(m_TSBuffer);
}
void cStreamdevDevice::CloseDvr(void) { void cStreamdevDevice::CloseDvr(void) {
Dprintf("CloseDvr\n"); Dprintf("CloseDvr\n");
LOCK_THREAD; LOCK_THREAD;
m_DvrClosed = true; ClientSocket.CloseDvr();
CloseDvrInt(); DELETENULL(m_TSBuffer);
} }
bool cStreamdevDevice::GetTSPacket(uchar *&Data) { bool cStreamdevDevice::GetTSPacket(uchar *&Data) {
@ -287,7 +237,7 @@ esyslog("cStreamDevice::GetTSPacket: GetChecked: NOTHING (%d)", m_TSFails);
if (m_TSFails > 10) { if (m_TSFails > 10) {
isyslog("cStreamdevDevice::GetTSPacket(): disconnected"); isyslog("cStreamdevDevice::GetTSPacket(): disconnected");
m_Pids = 0; m_Pids = 0;
CloseDvrInt(); CloseDvr();
m_TSFails = 0; m_TSFails = 0;
return false; return false;
} }

View File

@ -23,14 +23,10 @@ private:
int m_Pids; int m_Pids;
int m_Priority; int m_Priority;
bool m_UpdatePriority; bool m_UpdatePriority;
bool m_DvrClosed;
static cStreamdevDevice *m_Device; static cStreamdevDevice *m_Device;
static const cChannel *m_DenyChannel; static const cChannel *m_DenyChannel;
bool OpenDvrInt(void);
void CloseDvrInt(void);
protected: protected:
virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView); virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView);
virtual bool HasLock(int TimeoutMs) virtual bool HasLock(int TimeoutMs)

View File

@ -1282,7 +1282,8 @@ bool cConnectionVTP::CmdABRT(char *Opts)
switch (id) { switch (id) {
case siLive: case siLive:
DELETENULL(m_LiveStreamer); if (m_LiveStreamer)
m_LiveStreamer->Stop();
DELETENULL(m_LiveSocket); DELETENULL(m_LiveSocket);
break; break;
case siLiveFilter: case siLiveFilter: