mirror of
https://github.com/rofafor/vdr-plugin-satip.git
synced 2023-10-10 13:37:42 +02:00
Refactored the section filtering.
This commit is contained in:
parent
80fc28d8cf
commit
5b1af5ba29
5
HISTORY
5
HISTORY
@ -33,3 +33,8 @@ VDR Plugin 'satip' Revision History
|
|||||||
- Added a check to write new sections only if there
|
- Added a check to write new sections only if there
|
||||||
is no data in the read socket.
|
is no data in the read socket.
|
||||||
- Fixed keepalive heartbeat again.
|
- Fixed keepalive heartbeat again.
|
||||||
|
|
||||||
|
2014-04-05: Version 0.2.2
|
||||||
|
|
||||||
|
- Fixed the default keepalive interval.
|
||||||
|
- Refactored the section filtering.
|
||||||
|
24
common.c
24
common.c
@ -57,30 +57,6 @@ char *StripTags(char *strP)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int select_single_desc(int descriptorP, const int msP, const bool selectWriteP)
|
|
||||||
{
|
|
||||||
// Wait for data
|
|
||||||
struct timeval tv;
|
|
||||||
tv.tv_sec = 0;
|
|
||||||
tv.tv_usec = msP * 1000L;
|
|
||||||
// Use select
|
|
||||||
fd_set infd;
|
|
||||||
fd_set outfd;
|
|
||||||
fd_set errfd;
|
|
||||||
FD_ZERO(&infd);
|
|
||||||
FD_ZERO(&outfd);
|
|
||||||
FD_ZERO(&errfd);
|
|
||||||
FD_SET(descriptorP, &errfd);
|
|
||||||
if (selectWriteP)
|
|
||||||
FD_SET(descriptorP, &outfd);
|
|
||||||
else
|
|
||||||
FD_SET(descriptorP, &infd);
|
|
||||||
int retval = select(descriptorP + 1, &infd, &outfd, &errfd, &tv);
|
|
||||||
// Check if error
|
|
||||||
ERROR_IF_RET(retval < 0, "select()", return retval);
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
cString ChangeCase(const cString &strP, bool upperP)
|
cString ChangeCase(const cString &strP, bool upperP)
|
||||||
{
|
{
|
||||||
cString res(strP);
|
cString res(strP);
|
||||||
|
1
common.h
1
common.h
@ -93,7 +93,6 @@ uint16_t ts_pid(const uint8_t *bufP);
|
|||||||
uint8_t payload(const uint8_t *bufP);
|
uint8_t payload(const uint8_t *bufP);
|
||||||
const char *id_pid(const u_short pidP);
|
const char *id_pid(const u_short pidP);
|
||||||
char *StripTags(char *strP);
|
char *StripTags(char *strP);
|
||||||
int select_single_desc(int descriptorP, const int msP, const bool selectWriteP);
|
|
||||||
cString ChangeCase(const cString &strP, bool upperP);
|
cString ChangeCase(const cString &strP, bool upperP);
|
||||||
|
|
||||||
struct section_filter_table_type {
|
struct section_filter_table_type {
|
||||||
|
@ -5,10 +5,10 @@
|
|||||||
#
|
#
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: vdr-satip 0.2.1\n"
|
"Project-Id-Version: vdr-satip 0.2.2\n"
|
||||||
"Report-Msgid-Bugs-To: <see README>\n"
|
"Report-Msgid-Bugs-To: <see README>\n"
|
||||||
"POT-Creation-Date: 2014-04-01 04:01+0200\n"
|
"POT-Creation-Date: 2014-04-05 04:05+0200\n"
|
||||||
"PO-Revision-Date: 2014-04-01 04:01+0200\n"
|
"PO-Revision-Date: 2014-04-05 04:05+0200\n"
|
||||||
"Last-Translator: Frank Neumann <fnu@yavdr.org>\n"
|
"Last-Translator: Frank Neumann <fnu@yavdr.org>\n"
|
||||||
"Language-Team: German <vdr@linuxtv.org>\n"
|
"Language-Team: German <vdr@linuxtv.org>\n"
|
||||||
"Language: de\n"
|
"Language: de\n"
|
||||||
|
@ -5,10 +5,10 @@
|
|||||||
#
|
#
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: vdr-satip 0.2.1\n"
|
"Project-Id-Version: vdr-satip 0.2.2\n"
|
||||||
"Report-Msgid-Bugs-To: <see README>\n"
|
"Report-Msgid-Bugs-To: <see README>\n"
|
||||||
"POT-Creation-Date: 2014-04-01 04:01+0200\n"
|
"POT-Creation-Date: 2014-04-05 04:05+0200\n"
|
||||||
"PO-Revision-Date: 2014-04-01 04:01+0200\n"
|
"PO-Revision-Date: 2014-04-05 04:05+0200\n"
|
||||||
"Last-Translator: Rolf Ahrenberg\n"
|
"Last-Translator: Rolf Ahrenberg\n"
|
||||||
"Language-Team: Finnish <vdr@linuxtv.org>\n"
|
"Language-Team: Finnish <vdr@linuxtv.org>\n"
|
||||||
"Language: fi\n"
|
"Language: fi\n"
|
||||||
|
2
satip.c
2
satip.c
@ -21,7 +21,7 @@
|
|||||||
#define GITVERSION ""
|
#define GITVERSION ""
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const char VERSION[] = "0.2.1" GITVERSION;
|
const char VERSION[] = "0.2.2" GITVERSION;
|
||||||
static const char DESCRIPTION[] = trNOOP("SAT>IP Devices");
|
static const char DESCRIPTION[] = trNOOP("SAT>IP Devices");
|
||||||
|
|
||||||
class cPluginSatip : public cPlugin {
|
class cPluginSatip : public cPlugin {
|
||||||
|
@ -17,6 +17,7 @@ cSatipSectionFilter::cSatipSectionFilter(int deviceIndexP, uint16_t pidP, uint8_
|
|||||||
secLenM(0),
|
secLenM(0),
|
||||||
tsFeedpM(0),
|
tsFeedpM(0),
|
||||||
pidM(pidP),
|
pidM(pidP),
|
||||||
|
ringBufferM(new cRingBufferFrame(eDmxMaxSectionCount * eDmxMaxSectionSize)),
|
||||||
deviceIndexM(deviceIndexP)
|
deviceIndexM(deviceIndexP)
|
||||||
{
|
{
|
||||||
//debug("cSatipSectionFilter::%s(%d, %d)", __FUNCTION__, deviceIndexM, pidM);
|
//debug("cSatipSectionFilter::%s(%d, %d)", __FUNCTION__, deviceIndexM, pidM);
|
||||||
@ -48,7 +49,7 @@ cSatipSectionFilter::cSatipSectionFilter(int deviceIndexP, uint16_t pidP, uint8_
|
|||||||
|
|
||||||
// Create sockets
|
// Create sockets
|
||||||
socketM[0] = socketM[1] = -1;
|
socketM[0] = socketM[1] = -1;
|
||||||
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, socketM) != 0) {
|
if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, socketM) != 0) {
|
||||||
char tmp[64];
|
char tmp[64];
|
||||||
error("Opening section filter sockets failed (device=%d pid=%d): %s", deviceIndexM, pidM, strerror_r(errno, tmp, sizeof(tmp)));
|
error("Opening section filter sockets failed (device=%d pid=%d): %s", deviceIndexM, pidM, strerror_r(errno, tmp, sizeof(tmp)));
|
||||||
}
|
}
|
||||||
@ -70,6 +71,7 @@ cSatipSectionFilter::~cSatipSectionFilter()
|
|||||||
if (tmp >= 0)
|
if (tmp >= 0)
|
||||||
close(tmp);
|
close(tmp);
|
||||||
secBufM = NULL;
|
secBufM = NULL;
|
||||||
|
DELETENULL(ringBufferM);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint16_t cSatipSectionFilter::GetLength(const uint8_t *dataP)
|
inline uint16_t cSatipSectionFilter::GetLength(const uint8_t *dataP)
|
||||||
@ -99,21 +101,8 @@ int cSatipSectionFilter::Filter(void)
|
|||||||
if (doneqM && !neq)
|
if (doneqM && !neq)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// There is no data in the read socket, more can be written
|
if (ringBufferM && (secLenM > 0))
|
||||||
if ((secLenM > 0) && (socketM[1] >= 0) && (socketM[0] >= 0)) {
|
ringBufferM->Put(new cFrame(secBufM, secLenM));
|
||||||
for (i = 0; i < eWriteMaxRetries; ++i) {
|
|
||||||
if (select_single_desc(socketM[0], 10, false))
|
|
||||||
continue;
|
|
||||||
ssize_t len = write(socketM[1], secBufM, secLenM);
|
|
||||||
ERROR_IF(len < 0, "write()");
|
|
||||||
// Update statistics
|
|
||||||
if (len >= 0)
|
|
||||||
AddSectionStatistic(len, 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (i >= eWriteMaxRetries)
|
|
||||||
debug("Skipped section write (%d bytes)", secLenM);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -219,13 +208,31 @@ void cSatipSectionFilter::Process(const uint8_t* dataP)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool cSatipSectionFilter::Send(void)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
cFrame *section = ringBufferM->Get();
|
||||||
|
if (section) {
|
||||||
|
uchar *data = section->Data();
|
||||||
|
int count = section->Count();
|
||||||
|
if (data && (count > 0) && (socketM[1] >= 0) && (socketM[0] >= 0)) {
|
||||||
|
ssize_t len = send(socketM[1], data, count, MSG_EOR);
|
||||||
|
ERROR_IF(len < 0 && errno != EAGAIN, "send()");
|
||||||
|
if (len > 0) {
|
||||||
|
ringBufferM->Drop(section);
|
||||||
|
// Update statistics
|
||||||
|
AddSectionStatistic(len, 1);
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
cSatipSectionFilterHandler::cSatipSectionFilterHandler(int deviceIndexP, unsigned int bufferLenP)
|
cSatipSectionFilterHandler::cSatipSectionFilterHandler(int deviceIndexP, unsigned int bufferLenP)
|
||||||
:
|
: cThread("SAT>IP section handler"),
|
||||||
#ifdef USE_THREADED_SECTIONFILTER
|
|
||||||
cThread("SAT>IP section handler", true),
|
|
||||||
ringBufferM(new cRingBufferLinear(bufferLenP, TS_SIZE, false, *cString::sprintf("SAT>IP SECTION HANDLER %d", deviceIndexP))),
|
ringBufferM(new cRingBufferLinear(bufferLenP, TS_SIZE, false, *cString::sprintf("SAT>IP SECTION HANDLER %d", deviceIndexP))),
|
||||||
#endif
|
|
||||||
mutexM(),
|
mutexM(),
|
||||||
deviceIndexM(deviceIndexP)
|
deviceIndexM(deviceIndexP)
|
||||||
{
|
{
|
||||||
@ -234,7 +241,6 @@ cSatipSectionFilterHandler::cSatipSectionFilterHandler(int deviceIndexP, unsigne
|
|||||||
// Initialize filter pointers
|
// Initialize filter pointers
|
||||||
memset(filtersM, 0, sizeof(filtersM));
|
memset(filtersM, 0, sizeof(filtersM));
|
||||||
|
|
||||||
#ifdef USE_THREADED_SECTIONFILTER
|
|
||||||
// Create input buffer
|
// Create input buffer
|
||||||
if (ringBufferM) {
|
if (ringBufferM) {
|
||||||
ringBufferM->SetTimeouts(100, 100);
|
ringBufferM->SetTimeouts(100, 100);
|
||||||
@ -242,19 +248,17 @@ cSatipSectionFilterHandler::cSatipSectionFilterHandler(int deviceIndexP, unsigne
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
error("Failed to allocate buffer for section filter handler (device=%d): ", deviceIndexM);
|
error("Failed to allocate buffer for section filter handler (device=%d): ", deviceIndexM);
|
||||||
|
|
||||||
Start();
|
Start();
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cSatipSectionFilterHandler::~cSatipSectionFilterHandler()
|
cSatipSectionFilterHandler::~cSatipSectionFilterHandler()
|
||||||
{
|
{
|
||||||
debug("cSatipSectionFilterHandler::%s(%d)", __FUNCTION__, deviceIndexM);
|
debug("cSatipSectionFilterHandler::%s(%d)", __FUNCTION__, deviceIndexM);
|
||||||
#ifdef USE_THREADED_SECTIONFILTER
|
|
||||||
// Stop thread
|
// Stop thread
|
||||||
if (Running())
|
if (Running())
|
||||||
Cancel(3);
|
Cancel(3);
|
||||||
DELETE_POINTER(ringBufferM);
|
DELETE_POINTER(ringBufferM);
|
||||||
#endif
|
|
||||||
|
|
||||||
// Destroy all filters
|
// Destroy all filters
|
||||||
cMutexLock MutexLock(&mutexM);
|
cMutexLock MutexLock(&mutexM);
|
||||||
@ -262,13 +266,22 @@ cSatipSectionFilterHandler::~cSatipSectionFilterHandler()
|
|||||||
Delete(i);
|
Delete(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_THREADED_SECTIONFILTER
|
|
||||||
void cSatipSectionFilterHandler::Action(void)
|
void cSatipSectionFilterHandler::Action(void)
|
||||||
{
|
{
|
||||||
debug("cSatipSectionFilterHandler::%s(%d): entering", __FUNCTION__, deviceIndexM);
|
debug("cSatipSectionFilterHandler::%s(%d): entering", __FUNCTION__, deviceIndexM);
|
||||||
bool processed = false;
|
bool processed = false;
|
||||||
// Do the thread loop
|
// Do the thread loop
|
||||||
while (Running()) {
|
while (Running()) {
|
||||||
|
// Send demuxed section packets through all filters
|
||||||
|
bool retry = false;
|
||||||
|
mutexM.Lock();
|
||||||
|
for (unsigned int i = 0; i < eMaxSecFilterCount; ++i) {
|
||||||
|
if (filtersM[i] && filtersM[i]->Send())
|
||||||
|
retry = true;
|
||||||
|
}
|
||||||
|
mutexM.Unlock();
|
||||||
|
if (retry)
|
||||||
|
continue;
|
||||||
// Read one TS packet
|
// Read one TS packet
|
||||||
if (ringBufferM) {
|
if (ringBufferM) {
|
||||||
int len = 0;
|
int len = 0;
|
||||||
@ -304,7 +317,6 @@ void cSatipSectionFilterHandler::Action(void)
|
|||||||
}
|
}
|
||||||
debug("cSatipSectionFilterHandler::%s(%d): exiting", __FUNCTION__, deviceIndexM);
|
debug("cSatipSectionFilterHandler::%s(%d): exiting", __FUNCTION__, deviceIndexM);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
cString cSatipSectionFilterHandler::GetInformation(void)
|
cString cSatipSectionFilterHandler::GetInformation(void)
|
||||||
{
|
{
|
||||||
@ -405,35 +417,10 @@ int cSatipSectionFilterHandler::GetPid(int handleP)
|
|||||||
void cSatipSectionFilterHandler::Write(uchar *bufferP, int lengthP)
|
void cSatipSectionFilterHandler::Write(uchar *bufferP, int lengthP)
|
||||||
{
|
{
|
||||||
//debug("cSatipSectionFilterHandler::%s(%d): length=%d", __FUNCTION__, deviceIndexM, lengthP);
|
//debug("cSatipSectionFilterHandler::%s(%d): length=%d", __FUNCTION__, deviceIndexM, lengthP);
|
||||||
#ifdef USE_THREADED_SECTIONFILTER
|
|
||||||
// Fill up the buffer
|
// Fill up the buffer
|
||||||
if (ringBufferM) {
|
if (ringBufferM) {
|
||||||
int len = ringBufferM->Put(bufferP, lengthP);
|
int len = ringBufferM->Put(bufferP, lengthP);
|
||||||
if (len != lengthP)
|
if (len != lengthP)
|
||||||
ringBufferM->ReportOverflow(lengthP - len);
|
ringBufferM->ReportOverflow(lengthP - len);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
// Lock
|
|
||||||
cMutexLock MutexLock(&mutexM);
|
|
||||||
uchar *p = bufferP;
|
|
||||||
int len = lengthP;
|
|
||||||
// Process TS packets through all filters
|
|
||||||
while (p && (len >= TS_SIZE)) {
|
|
||||||
if (*p != TS_SYNC_BYTE) {
|
|
||||||
for (int i = 1; i < len; ++i) {
|
|
||||||
if (p[i] == TS_SYNC_BYTE) {
|
|
||||||
p += i;
|
|
||||||
len -= i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (unsigned int i = 0; i < eMaxSecFilterCount; ++i) {
|
|
||||||
if (filtersM[i])
|
|
||||||
filtersM[i]->Process(p);
|
|
||||||
}
|
|
||||||
p += TS_SIZE;
|
|
||||||
len -= TS_SIZE;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
@ -8,21 +8,16 @@
|
|||||||
#ifndef __SATIP_SECTIONFILTER_H
|
#ifndef __SATIP_SECTIONFILTER_H
|
||||||
#define __SATIP_SECTIONFILTER_H
|
#define __SATIP_SECTIONFILTER_H
|
||||||
|
|
||||||
#ifdef __FreeBSD__
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#endif // __FreeBSD__
|
|
||||||
#include <vdr/device.h>
|
#include <vdr/device.h>
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "statistics.h"
|
#include "statistics.h"
|
||||||
|
|
||||||
#define USE_THREADED_SECTIONFILTER
|
|
||||||
|
|
||||||
class cSatipSectionFilter : public cSatipSectionStatistics {
|
class cSatipSectionFilter : public cSatipSectionStatistics {
|
||||||
private:
|
private:
|
||||||
enum {
|
enum {
|
||||||
eWriteMaxRetries = 20,
|
|
||||||
eDmxMaxFilterSize = 18,
|
eDmxMaxFilterSize = 18,
|
||||||
|
eDmxMaxSectionCount = 64,
|
||||||
eDmxMaxSectionSize = 4096,
|
eDmxMaxSectionSize = 4096,
|
||||||
eDmxMaxSectionFeedSize = (eDmxMaxSectionSize + TS_SIZE)
|
eDmxMaxSectionFeedSize = (eDmxMaxSectionSize + TS_SIZE)
|
||||||
};
|
};
|
||||||
@ -38,6 +33,7 @@ private:
|
|||||||
uint16_t tsFeedpM;
|
uint16_t tsFeedpM;
|
||||||
uint16_t pidM;
|
uint16_t pidM;
|
||||||
|
|
||||||
|
cRingBufferFrame *ringBufferM;
|
||||||
int deviceIndexM;
|
int deviceIndexM;
|
||||||
int socketM[2];
|
int socketM[2];
|
||||||
|
|
||||||
@ -59,23 +55,17 @@ public:
|
|||||||
cSatipSectionFilter(int deviceIndexP, uint16_t pidP, uint8_t tidP, uint8_t maskP);
|
cSatipSectionFilter(int deviceIndexP, uint16_t pidP, uint8_t tidP, uint8_t maskP);
|
||||||
virtual ~cSatipSectionFilter();
|
virtual ~cSatipSectionFilter();
|
||||||
void Process(const uint8_t* dataP);
|
void Process(const uint8_t* dataP);
|
||||||
|
bool Send(void);
|
||||||
int GetFd(void) { return socketM[0]; }
|
int GetFd(void) { return socketM[0]; }
|
||||||
uint16_t GetPid(void) const { return pidM; }
|
uint16_t GetPid(void) const { return pidM; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef USE_THREADED_SECTIONFILTER
|
|
||||||
class cSatipSectionFilterHandler : public cThread {
|
class cSatipSectionFilterHandler : public cThread {
|
||||||
protected:
|
|
||||||
virtual void Action(void);
|
|
||||||
private:
|
|
||||||
cRingBufferLinear *ringBufferM;
|
|
||||||
#else
|
|
||||||
class cSatipSectionFilterHandler {
|
|
||||||
#endif
|
|
||||||
private:
|
private:
|
||||||
enum {
|
enum {
|
||||||
eMaxSecFilterCount = 32
|
eMaxSecFilterCount = 32
|
||||||
};
|
};
|
||||||
|
cRingBufferLinear *ringBufferM;
|
||||||
cMutex mutexM;
|
cMutex mutexM;
|
||||||
int deviceIndexM;
|
int deviceIndexM;
|
||||||
cSatipSectionFilter *filtersM[eMaxSecFilterCount];
|
cSatipSectionFilter *filtersM[eMaxSecFilterCount];
|
||||||
@ -83,6 +73,9 @@ private:
|
|||||||
bool Delete(unsigned int indexP);
|
bool Delete(unsigned int indexP);
|
||||||
bool IsBlackListed(u_short pidP, u_char tidP, u_char maskP) const;
|
bool IsBlackListed(u_short pidP, u_char tidP, u_char maskP) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void Action(void);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cSatipSectionFilterHandler(int deviceIndexP, unsigned int bufferLenP);
|
cSatipSectionFilterHandler(int deviceIndexP, unsigned int bufferLenP);
|
||||||
virtual ~cSatipSectionFilterHandler();
|
virtual ~cSatipSectionFilterHandler();
|
||||||
|
Loading…
Reference in New Issue
Block a user