Added some filtering tweaks.

This commit is contained in:
Rolf Ahrenberg 2007-09-20 21:15:08 +00:00
parent a16c31c276
commit e85dc10fea
3 changed files with 61 additions and 40 deletions

View File

@ -3,13 +3,15 @@
* *
* See the README file for copyright information and how to reach the author. * See the README file for copyright information and how to reach the author.
* *
* $Id: device.c,v 1.27 2007/09/19 19:43:29 rahrenbe Exp $ * $Id: device.c,v 1.28 2007/09/20 21:15:08 rahrenbe Exp $
*/ */
#include "common.h" #include "common.h"
#include "config.h" #include "config.h"
#include "device.h" #include "device.h"
#define IPTV_FILTER_FILENAME "/tmp/vdr-iptv%d.filter%d"
#define IPTV_MAX_DEVICES 8 #define IPTV_MAX_DEVICES 8
cIptvDevice * IptvDevices[IPTV_MAX_DEVICES]; cIptvDevice * IptvDevices[IPTV_MAX_DEVICES];
@ -25,8 +27,6 @@ cIptvDevice::cIptvDevice(unsigned int Index)
debug("cIptvDevice::cIptvDevice(%d)\n", deviceIndex); debug("cIptvDevice::cIptvDevice(%d)\n", deviceIndex);
tsBuffer = new cRingBufferLinear(MEGABYTE(IptvConfig.GetTsBufferSize()), tsBuffer = new cRingBufferLinear(MEGABYTE(IptvConfig.GetTsBufferSize()),
(TS_SIZE * 2), false, "IPTV"); (TS_SIZE * 2), false, "IPTV");
memset(&filter, '\0', sizeof(filter));
init_trans(&filter);
tsBuffer->SetTimeouts(100, 100); tsBuffer->SetTimeouts(100, 100);
// pad prefill to multiple of TS_SIZE // pad prefill to multiple of TS_SIZE
tsBufferPrefill = MEGABYTE(IptvConfig.GetTsBufferSize()) * tsBufferPrefill = MEGABYTE(IptvConfig.GetTsBufferSize()) *
@ -37,12 +37,20 @@ cIptvDevice::cIptvDevice(unsigned int Index)
pHttpProtocol = new cIptvProtocolHttp(); pHttpProtocol = new cIptvProtocolHttp();
pFileProtocol = new cIptvProtocolFile(); pFileProtocol = new cIptvProtocolFile();
pIptvStreamer = new cIptvStreamer(tsBuffer, &mutex); pIptvStreamer = new cIptvStreamer(tsBuffer, &mutex);
StartSectionHandler();
// Initialize filters // Initialize filters
memset(&filter, '\0', sizeof(filter));
init_trans(&filter);
for (int i = 0; i < eMaxFilterCount; ++i) { for (int i = 0; i < eMaxFilterCount; ++i) {
filters[i].active = false; struct stat sb;
snprintf(filters[i].pipeName, sizeof(filters[i].pipeName), IPTV_FILTER_FILENAME, deviceIndex, i);
stat(filters[i].pipeName, &sb);
if (S_ISFIFO(sb.st_mode))
unlink(filters[i].pipeName);
memset(filters[i].pipeName, '\0', sizeof(filters[i].pipeName));
filters[i].fifoDesc = -1; filters[i].fifoDesc = -1;
filters[i].active = false;
} }
StartSectionHandler();
} }
cIptvDevice::~cIptvDevice() cIptvDevice::~cIptvDevice()
@ -177,29 +185,35 @@ int cIptvDevice::OpenFilter(u_short Pid, u_char Tid, u_char Mask)
// Search the next free filter slot // Search the next free filter slot
for (unsigned int i = 0; i < eMaxFilterCount; ++i) { for (unsigned int i = 0; i < eMaxFilterCount; ++i) {
if (!filters[i].active) { if (!filters[i].active) {
debug("cIptvDevice::OpenFilter(): Pid=%d Tid=%d Mask=%02X Count=%d\n", Pid, Tid, Mask, i); debug("cIptvDevice::OpenFilter(%d): Pid=%d Tid=%02X Mask=%02X Count=%d\n", deviceIndex, Pid, Tid, Mask, i);
uint8_t mask = Mask; uint8_t mask[eMaxFilterMaskLen] = { 0 };
uint8_t filt = Tid; uint8_t filt[eMaxFilterMaskLen] = { 0 };
int err = set_trans_filt(&filter, i, Pid, &mask, &filt, 0); mask[0] = Mask;
if (err < 0) filt[0] = Tid;
error("Cannot set filter %d\n", i); int err = set_trans_filt(&filter, i, Pid, &mask[0], &filt[0], 0);
memset(filters[i].pipeName, '\0', sizeof(filters[i].pipeName)); if (err < 0)
snprintf(filters[i].pipeName, sizeof(filters[i].pipeName), "/tmp/iptvPipe.%d", i); error("Cannot set filter %d\n", i);
err = mknod(filters[i].pipeName, 0644 | S_IFIFO, 0); memset(filters[i].pipeName, '\0', sizeof(filters[i].pipeName));
if (err < 0) { snprintf(filters[i].pipeName, sizeof(filters[i].pipeName), IPTV_FILTER_FILENAME, deviceIndex, i);
char tmp[64]; struct stat sb;
error("ERROR: mknod(): %s", strerror_r(errno, tmp, sizeof(tmp))); stat(filters[i].pipeName, &sb);
unlink(filters[i].pipeName); if (S_ISFIFO(sb.st_mode))
} unlink(filters[i].pipeName);
// Create descriptors err = mknod(filters[i].pipeName, 0644 | S_IFIFO, 0);
int fifoDescriptor = open(filters[i].pipeName, O_RDWR | O_NONBLOCK); if (err < 0) {
int returnDescriptor = open(filters[i].pipeName, O_RDONLY | O_NONBLOCK); char tmp[64];
// Store the write pipe and set active flag error("ERROR: mknod(): %s", strerror_r(errno, tmp, sizeof(tmp)));
filters[i].active = true; break;
filters[i].fifoDesc = fifoDescriptor; }
return returnDescriptor; // Create descriptors
} int fifoDescriptor = open(filters[i].pipeName, O_RDWR | O_NONBLOCK);
} int returnDescriptor = open(filters[i].pipeName, O_RDONLY | O_NONBLOCK);
// Store the write pipe and set active flag
filters[i].fifoDesc = fifoDescriptor;
filters[i].active = true;
return returnDescriptor;
}
}
// No free filter slot found // No free filter slot found
return -1; return -1;
} }
@ -220,6 +234,17 @@ void cIptvDevice::CloseDvr(void)
{ {
debug("cIptvDevice::CloseDvr(%d)\n", deviceIndex); debug("cIptvDevice::CloseDvr(%d)\n", deviceIndex);
pIptvStreamer->Close(); pIptvStreamer->Close();
// Iterate over all filters and clear their settings
for (int i = 0; i < eMaxFilterCount; ++i) {
if (filters[i].active) {
close(filters[i].fifoDesc);
unlink(filters[i].pipeName);
memset(filters[i].pipeName, '\0', sizeof(filters[i].pipeName));
filters[i].fifoDesc = -1;
filters[i].active = false;
clear_trans_filt(&filter, i);
}
}
isOpenDvr = false; isOpenDvr = false;
} }
@ -280,8 +305,7 @@ bool cIptvDevice::GetTSPacket(uchar *&Data)
} }
// There is no data in the fifo, more can be written // There is no data in the fifo, more can be written
else if (!retval) { else if (!retval) {
int err = write(filters[i].fifoDesc, filtered->payload, int err = write(filters[i].fifoDesc, filtered->payload, filtered->length + 3);
filtered->length + 3);
if (err < 0) { if (err < 0) {
char tmp[64]; char tmp[64];
error("ERROR: write(): %s", strerror_r(errno, tmp, sizeof(tmp))); error("ERROR: write(): %s", strerror_r(errno, tmp, sizeof(tmp)));

View File

@ -3,7 +3,7 @@
* *
* See the README file for copyright information and how to reach the author. * See the README file for copyright information and how to reach the author.
* *
* $Id: device.h,v 1.11 2007/09/19 18:17:30 rahrenbe Exp $ * $Id: device.h,v 1.12 2007/09/20 21:15:08 rahrenbe Exp $
*/ */
#ifndef __IPTV_DEVICE_H #ifndef __IPTV_DEVICE_H
@ -36,7 +36,8 @@ public:
// private parts // private parts
private: private:
enum { enum {
eMaxFilterCount = 32 eMaxFilterCount = 32,
eMaxFilterMaskLen = 16
}; };
unsigned int deviceIndex; unsigned int deviceIndex;
bool isPacketDelivered; bool isPacketDelivered;

View File

@ -3,7 +3,7 @@
* *
* See the README file for copyright information and how to reach the author. * See the README file for copyright information and how to reach the author.
* *
* $Id: protocolfile.c,v 1.5 2007/09/16 18:04:15 ajhseppa Exp $ * $Id: protocolfile.c,v 1.6 2007/09/20 21:15:08 rahrenbe Exp $
*/ */
#include <fcntl.h> #include <fcntl.h>
@ -78,18 +78,14 @@ int cIptvProtocolFile::Read(unsigned char* *BufferAddr)
// Rewind if EOF // Rewind if EOF
if (feof(fileStream)) if (feof(fileStream))
rewind(fileStream); rewind(fileStream);
// Sleep before reading the file stream to prevent aggressive busy looping // Sleep before reading the file stream to prevent aggressive busy looping
cCondWait::SleepMs(50); cCondWait::SleepMs(1);
// This check is to prevent a race condition where file may be switched off // This check is to prevent a race condition where file may be switched off
// during the sleep and buffers are disposed. Check here that the plugin is // during the sleep and buffers are disposed. Check here that the plugin is
// still active before accessing the buffers // still active before accessing the buffers
if (fileActive) if (fileActive)
return fread(readBuffer, sizeof(unsigned char), readBufferLen, return fread(readBuffer, sizeof(unsigned char), readBufferLen, fileStream);
fileStream); return -1;
else
return -1;
} }
bool cIptvProtocolFile::Open(void) bool cIptvProtocolFile::Open(void)