Modified sectionfilters to use socket pair instead of filesystem fifos.

This commit is contained in:
Rolf Ahrenberg 2009-10-01 18:48:28 +03:00
parent dbeb014a85
commit 49fcbc8921
10 changed files with 52 additions and 56 deletions

View File

@ -114,3 +114,5 @@ VDR Plugin 'iptv' Revision History
- Updated patches.
- Added optional patches to disable EIT scanning.
- Fixed handling of HTTP protocol headers.
- Modified sectionfilters to use socket pair instead of
filesystem fifos.

View File

@ -14,10 +14,10 @@
#ifdef DEBUG
#define debug(x...) dsyslog("IPTV: " x);
#define error(x...) esyslog("IPTV: " x);
#define error(x...) esyslog("ERROR: " x);
#else
#define debug(x...) ;
#define error(x...) esyslog("IPTV: " x);
#define error(x...) esyslog("ERROR: " x);
#endif
#ifndef trNOOP
@ -28,7 +28,6 @@
#define trVDR(s) tr(s)
#endif
#define IPTV_FILTER_FILENAME "/tmp/vdr-iptv%d.filter%d"
#define IPTV_DVR_FILENAME "/tmp/vdr-iptv%d.dvr"
#define IPTV_DEVICE_INFO_ALL 0
@ -42,13 +41,13 @@
#define SECTION_FILTER_TABLE_SIZE 7
#define ERROR_IF_FUNC(exp, errstr, func, ret) \
do { \
if (exp) { \
char tmp[64]; \
error("ERROR: "errstr": %s", strerror_r(errno, tmp, sizeof(tmp))); \
func; \
ret; \
} \
do { \
if (exp) { \
char tmp[64]; \
error(errstr": %s", strerror_r(errno, tmp, sizeof(tmp))); \
func; \
ret; \
} \
} while (0)

View File

@ -272,7 +272,7 @@ bool cIptvDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
debug("cIptvDevice::SetChannelDevice(%d)\n", deviceIndex);
location = GetChannelSettings(Channel->PluginParam(), &parameter, &sidscan, &pidscan, &protocol);
if (isempty(location)) {
error("ERROR: Unrecognized IPTV channel settings: %s", Channel->PluginParam());
error("Unrecognized IPTV channel settings: %s", Channel->PluginParam());
return false;
}
sidScanEnabled = sidscan ? true : false;
@ -427,7 +427,7 @@ bool cIptvDevice::GetTSPacket(uchar *&Data)
}
}
tsBuffer->Del(Count);
error("ERROR: skipped %d bytes to sync on TS packet\n", Count);
error("Skipped %d bytes to sync on TS packet\n", Count);
return false;
}
isPacketDelivered = true;

View File

@ -39,7 +39,7 @@ void cIptvProtocolExt::ExecuteScript(void)
debug("cIptvProtocolExt::ExecuteScript()\n");
// Check if already executing
if (pid > 0) {
error("ERROR: Cannot execute script!");
error("Cannot execute script!");
return;
}
// Let's fork
@ -54,7 +54,7 @@ void cIptvProtocolExt::ExecuteScript(void)
cString cmd = cString::sprintf("%s %d %d", *scriptFile, scriptParameter, socketPort);
debug("cIptvProtocolExt::ExecuteScript(child): %s\n", *cmd);
if (execl("/bin/sh", "sh", "-c", *cmd, NULL) == -1) {
error("ERROR: Script execution failed: %s", *cmd);
error("Script execution failed: %s", *cmd);
_exit(-1);
}
_exit(0);
@ -79,7 +79,7 @@ void cIptvProtocolExt::TerminateScript(void)
retval = 0;
waitms += timeoutms;
if ((waitms % 2000) == 0) {
error("ERROR: Script '%s' won't terminate - killing it!", *scriptFile);
error("Script '%s' won't terminate - killing it!", *scriptFile);
kill(pid, SIGKILL);
}
// Clear wait status to make sure child exit status is accessible
@ -140,7 +140,7 @@ bool cIptvProtocolExt::Set(const char* Location, const int Parameter, const int
// Update script file and parameter
scriptFile = cString::sprintf("%s/%s", IptvConfig.GetConfigDirectory(), Location);
if ((stat(*scriptFile, &stbuf) != 0) || (strstr(*scriptFile, "..") != 0)) {
error("ERROR: Non-existent or relative path script '%s'", *scriptFile);
error("Non-existent or relative path script '%s'", *scriptFile);
return false;
}
scriptParameter = Parameter;

View File

@ -53,9 +53,8 @@ bool cIptvProtocolHttp::Connect(void)
struct hostent *host;
host = gethostbyname(streamAddr);
if (!host) {
error("%s is not valid address\n", streamAddr);
char tmp[64];
error("ERROR: %s", strerror_r(h_errno, tmp, sizeof(tmp)));
error("%s is not valid address: %s", streamAddr, strerror_r(h_errno, tmp, sizeof(tmp)));
return false;
}
@ -77,9 +76,8 @@ bool cIptvProtocolHttp::Connect(void)
// If not any errors, then socket must be ready and connected
if (socketStatus != 0) {
error("Cannot connect to %s\n", streamAddr);
char tmp[64];
error("ERROR: %s", strerror_r(socketStatus, tmp, sizeof(tmp)));
error("Cannot connect to %s: %s", streamAddr, strerror_r(socketStatus, tmp, sizeof(tmp)));
CloseSocket();
return false;
}
@ -192,7 +190,7 @@ bool cIptvProtocolHttp::ProcessHeaders(void)
else
responseFound = true;
if (response != 200) {
error("ERROR: %s\n", buf);
error("%s\n", buf);
return false;
}
}

View File

@ -18,8 +18,7 @@ cIptvSectionFilter::cIptvSectionFilter(int DeviceIndex, int Index,
tsfeedp(0),
pid(Pid),
devid(DeviceIndex),
id(Index),
pipeName("")
id(Index)
{
//debug("cIptvSectionFilter::cIptvSectionFilter(%d, %d)\n", devid, id);
int i;
@ -48,33 +47,35 @@ cIptvSectionFilter::cIptvSectionFilter(int DeviceIndex, int Index,
}
doneq = local_doneq ? 1 : 0;
struct stat sb;
pipeName = cString::sprintf(IPTV_FILTER_FILENAME, devid, id);
stat(pipeName, &sb);
if (S_ISFIFO(sb.st_mode))
unlink(pipeName);
i = mknod(pipeName, 0644 | S_IFIFO, 0);
ERROR_IF_RET(i < 0, "mknod()", return);
// Create descriptors
fifoDescriptor = open(pipeName, O_RDWR | O_NONBLOCK);
readDescriptor = open(pipeName, O_RDONLY | O_NONBLOCK);
// Create sockets
socket[0] = socket[1] = -1;
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, socket) != 0) {
char tmp[64];
error("Opening section filter sockets failed (device=%d id=%d): %s\n", devid, id, strerror_r(errno, tmp, sizeof(tmp)));
}
else if ((fcntl(socket[0], F_SETFL, O_NONBLOCK) != 0) || (fcntl(socket[1], F_SETFL, O_NONBLOCK) != 0)) {
char tmp[64];
error("Setting section filter socket to non-blocking mode failed (device=%d id=%d): %s", devid, id, strerror_r(errno, tmp, sizeof(tmp)));
}
}
cIptvSectionFilter::~cIptvSectionFilter()
{
//debug("cIptvSectionFilter::~cIptvSectionfilter(%d, %d)\n", devid, id);
close(fifoDescriptor);
close(readDescriptor);
unlink(pipeName);
fifoDescriptor = -1;
readDescriptor = -1;
int tmp = socket[1];
socket[1] = -1;
if (tmp >= 0)
close(tmp);
tmp = socket[0];
socket[0] = -1;
if (tmp >= 0)
close(tmp);
secbuf = NULL;
}
int cIptvSectionFilter::GetReadDesc(void)
{
return readDescriptor;
return socket[0];
}
inline uint16_t cIptvSectionFilter::GetLength(const uint8_t *Data)
@ -104,9 +105,9 @@ int cIptvSectionFilter::Filter(void)
if (doneq && !neq)
return 0;
// There is no data in the fifo, more can be written
if (!select_single_desc(fifoDescriptor, 0, false)) {
ssize_t len = write(fifoDescriptor, secbuf, seclen);
// There is no data in the read socket, more can be written
if ((socket[0] >= 0) && (socket[1] >= 0) /*&& !select_single_desc(socket[0], 0, false)*/) {
ssize_t len = write(socket[1], secbuf, seclen);
ERROR_IF(len < 0, "write()");
// Update statistics
AddSectionStatistic(len, 1);
@ -148,8 +149,7 @@ int cIptvSectionFilter::CopyDump(const uint8_t *buf, uint8_t len)
for (n = 0; secbufp + 2 < limit; ++n) {
seclen_local = GetLength(secbuf);
if (seclen_local <= 0 || seclen_local > DMX_MAX_SECTION_SIZE ||
seclen_local + secbufp > limit)
if ((seclen_local <= 0) || (seclen_local > DMX_MAX_SECTION_SIZE) || ((seclen_local + secbufp) > limit))
return 0;
seclen = seclen_local;
if (pusi_seen)

View File

@ -21,9 +21,6 @@ private:
DMX_MAX_SECFEED_SIZE = (DMX_MAX_SECTION_SIZE + TS_SIZE)
};
int fifoDescriptor;
int readDescriptor;
int pusi_seen;
int feedcc;
int doneq;
@ -37,7 +34,7 @@ private:
int devid;
int id;
cString pipeName;
int socket[2];
uint8_t filter_value[DMX_MAX_FILTER_SIZE];
uint8_t filter_mask[DMX_MAX_FILTER_SIZE];

View File

@ -103,7 +103,7 @@ int cIptvUdpSocket::Read(unsigned char* BufferAddr, unsigned int BufferLen)
//debug("cIptvUdpSocket::Read()\n");
// Error out if socket not initialized
if (socketDesc <= 0) {
error("ERROR: Invalid socket in %s\n", __FUNCTION__);
error("Invalid socket in %s\n", __FUNCTION__);
return -1;
}
socklen_t addrlen = sizeof(sockAddr);
@ -168,7 +168,7 @@ int cIptvTcpSocket::Read(unsigned char* BufferAddr, unsigned int BufferLen)
//debug("cIptvTcpSocket::Read()\n");
// Error out if socket not initialized
if (socketDesc <= 0) {
error("ERROR: Invalid socket in %s\n", __FUNCTION__);
error("Invalid socket in %s\n", __FUNCTION__);
return -1;
}
socklen_t addrlen = sizeof(sockAddr);

View File

@ -32,7 +32,7 @@ cString cIptvSectionStatistics::GetSectionStatistic()
cMutexLock MutexLock(&mutex);
uint64_t elapsed = timer.Elapsed(); /* in milliseconds */
timer.Set();
long bitrate = elapsed ? (1000L * filteredData / KILOBYTE(1) / elapsed) : 0L;
long bitrate = elapsed ? (long)(1000.0L * filteredData / KILOBYTE(1) / elapsed) : 0L;
if (!IptvConfig.GetUseBytes())
bitrate *= 8;
// no trailing linefeed here!
@ -75,7 +75,7 @@ cString cIptvPidStatistics::GetPidStatistic()
cString info("Active pids:\n");
for (unsigned int i = 0; i < IPTV_STATS_ACTIVE_PIDS_COUNT; ++i) {
if (mostActivePids[i].pid) {
long bitrate = elapsed ? (1000L * mostActivePids[i].DataAmount / KILOBYTE(1) / elapsed) : 0L;
long bitrate = elapsed ? (long)(1000.0L * mostActivePids[i].DataAmount / KILOBYTE(1) / elapsed) : 0L;
if (!IptvConfig.GetUseBytes())
bitrate *= 8;
info = cString::sprintf("%sPid %d: %4d (%4ld k%s/s)\n", *info, i,
@ -145,7 +145,7 @@ cString cIptvStreamerStatistics::GetStreamerStatistic()
cMutexLock MutexLock(&mutex);
uint64_t elapsed = timer.Elapsed(); /* in milliseconds */
timer.Set();
long bitrate = elapsed ? (1000L * dataBytes / KILOBYTE(1) / elapsed) : 0L;
long bitrate = elapsed ? (long)(1000.0L * dataBytes / KILOBYTE(1) / elapsed) : 0L;
if (!IptvConfig.GetUseBytes())
bitrate *= 8;
cString info = cString::sprintf("Stream bitrate: %ld k%s/s\n", bitrate, IptvConfig.GetUseBytes() ? "B" : "bit");
@ -182,7 +182,7 @@ cString cIptvBufferStatistics::GetBufferStatistic()
cMutexLock MutexLock(&mutex);
uint64_t elapsed = timer.Elapsed(); /* in milliseconds */
timer.Set();
long bitrate = elapsed ? (1000L * dataBytes / KILOBYTE(1) / elapsed) : 0L;
long bitrate = elapsed ? (long)(1000.0L * dataBytes / KILOBYTE(1) / elapsed) : 0L;
long totalSpace = MEGABYTE(IptvConfig.GetTsBufferSize());
float percentage = (float)((float)usedSpace / (float)totalSpace * 100.0);
long totalKilos = totalSpace / KILOBYTE(1);

View File

@ -23,7 +23,7 @@ cIptvStreamer::cIptvStreamer(cRingBufferLinear* RingBuffer, unsigned int PacketL
if (packetBuffer)
memset(packetBuffer, 0, packetBufferLen);
else
error("ERROR: MALLOC() failed for packet buffer");
error("MALLOC() failed for packet buffer");
}
cIptvStreamer::~cIptvStreamer()