Added support for fifo dvr and modificationsfor vdr-1.5.15.

This commit is contained in:
Rolf Ahrenberg 2008-02-17 19:18:47 +00:00
parent 398a8d75b9
commit 71b0e52712
10 changed files with 62 additions and 49 deletions

4
README
View File

@ -166,6 +166,10 @@ Notes:
- The following section filters are recommended to be disabled: - The following section filters are recommended to be disabled:
"NIT (0x40)", "SDT (0x42)", "TDT (0x70)" "NIT (0x40)", "SDT (0x42)", "TDT (0x70)"
- The IPTV devices look for a "/tmp/vdr-iptv<devicenumber>.dvr" fifo at
startup. If the fifo is found and succesfully opened, the device writes
the current data stream into it. This can be used for debugging purposes.
Acknowledgements: Acknowledgements:
- The IPTV section filtering code is derived from Linux kernel. - The IPTV section filtering code is derived from Linux kernel.

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: common.h,v 1.19 2008/01/04 23:36:37 ajhseppa Exp $ * $Id: common.h,v 1.20 2008/02/17 19:18:47 rahrenbe Exp $
*/ */
#ifndef __IPTV_COMMON_H #ifndef __IPTV_COMMON_H
@ -29,6 +29,9 @@
#define trVDR(s) tr(s) #define trVDR(s) tr(s)
#endif #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 #define IPTV_DEVICE_INFO_ALL 0
#define IPTV_DEVICE_INFO_GENERAL 1 #define IPTV_DEVICE_INFO_GENERAL 1
#define IPTV_DEVICE_INFO_PIDS 2 #define IPTV_DEVICE_INFO_PIDS 2

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.c,v 1.83 2008/02/01 21:54:24 rahrenbe Exp $ * $Id: device.c,v 1.84 2008/02/17 19:18:47 rahrenbe Exp $
*/ */
#include "config.h" #include "config.h"
@ -17,6 +17,7 @@ unsigned int cIptvDevice::deviceCount = 0;
cIptvDevice::cIptvDevice(unsigned int Index) cIptvDevice::cIptvDevice(unsigned int Index)
: deviceIndex(Index), : deviceIndex(Index),
dvrFd(-1),
isPacketDelivered(false), isPacketDelivered(false),
isOpenDvr(false), isOpenDvr(false),
sidScanEnabled(false), sidScanEnabled(false),
@ -43,11 +44,24 @@ cIptvDevice::cIptvDevice(unsigned int Index)
pSidScanner = new cSidScanner; pSidScanner = new cSidScanner;
if (pSidScanner) if (pSidScanner)
AttachFilter(pSidScanner); AttachFilter(pSidScanner);
// Check if dvr fifo exists
struct stat sb;
cString filename = cString::sprintf(IPTV_DVR_FILENAME, deviceIndex);
stat(filename, &sb);
if (S_ISFIFO(sb.st_mode)) {
dvrFd = open(filename, O_WRONLY | O_NONBLOCK);
if (dvrFd >= 0)
dsyslog("IPTV device %d redirecting input stream to '%s'", deviceIndex, *filename);
}
} }
cIptvDevice::~cIptvDevice() cIptvDevice::~cIptvDevice()
{ {
debug("cIptvDevice::~cIptvDevice(%d)\n", deviceIndex); debug("cIptvDevice::~cIptvDevice(%d)\n", deviceIndex);
#if defined(APIVERSNUM) && APIVERSNUM >= 10515
// Stop section handler of iptv device
StopSectionHandler();
#endif
DELETE_POINTER(pIptvStreamer); DELETE_POINTER(pIptvStreamer);
DELETE_POINTER(pUdpProtocol); DELETE_POINTER(pUdpProtocol);
DELETE_POINTER(pHttpProtocol); DELETE_POINTER(pHttpProtocol);
@ -63,6 +77,12 @@ cIptvDevice::~cIptvDevice()
// Destroy all filters // Destroy all filters
for (int i = 0; i < eMaxSecFilterCount; ++i) for (int i = 0; i < eMaxSecFilterCount; ++i)
DeleteFilter(i); DeleteFilter(i);
// Close dvr fifo
if (dvrFd >= 0) {
int fd = dvrFd;
dvrFd = -1;
close(fd);
}
} }
bool cIptvDevice::Initialize(unsigned int DeviceCount) bool cIptvDevice::Initialize(unsigned int DeviceCount)
@ -436,6 +456,9 @@ bool cIptvDevice::GetTSPacket(uchar *&Data)
Data = p; Data = p;
// Update pid statistics // Update pid statistics
AddPidStatistic(ts_pid(p), payload(p)); AddPidStatistic(ts_pid(p), payload(p));
// Send data also to dvr fifo
if (dvrFd >= 0)
write(dvrFd, p, TS_SIZE);
// Analyze incomplete streams with built-in pid analyzer // Analyze incomplete streams with built-in pid analyzer
if (pidScanEnabled && pPidScanner) if (pidScanEnabled && pPidScanner)
pPidScanner->Process(p); pPidScanner->Process(p);

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.38 2008/01/31 22:28:53 rahrenbe Exp $ * $Id: device.h,v 1.39 2008/02/17 19:18:47 rahrenbe Exp $
*/ */
#ifndef __IPTV_DEVICE_H #ifndef __IPTV_DEVICE_H
@ -35,6 +35,7 @@ private:
eMaxSecFilterCount = 32 eMaxSecFilterCount = 32
}; };
unsigned int deviceIndex; unsigned int deviceIndex;
int dvrFd;
bool isPacketDelivered; bool isPacketDelivered;
bool isOpenDvr; bool isOpenDvr;
bool sidScanEnabled; bool sidScanEnabled;

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: protocolext.c,v 1.23 2008/01/30 21:57:33 rahrenbe Exp $ * $Id: protocolext.c,v 1.24 2008/02/17 19:18:47 rahrenbe Exp $
*/ */
#include <sys/wait.h> #include <sys/wait.h>
@ -22,11 +22,10 @@
cIptvProtocolExt::cIptvProtocolExt() cIptvProtocolExt::cIptvProtocolExt()
: pid(-1), : pid(-1),
scriptFile(""),
scriptParameter(0) scriptParameter(0)
{ {
debug("cIptvProtocolExt::cIptvProtocolExt()\n"); debug("cIptvProtocolExt::cIptvProtocolExt()\n");
scriptFile = strdup("");
listenAddr = strdup("127.0.0.1");
} }
cIptvProtocolExt::~cIptvProtocolExt() cIptvProtocolExt::~cIptvProtocolExt()
@ -34,9 +33,6 @@ cIptvProtocolExt::~cIptvProtocolExt()
debug("cIptvProtocolExt::~cIptvProtocolExt()\n"); debug("cIptvProtocolExt::~cIptvProtocolExt()\n");
// Drop the socket connection // Drop the socket connection
cIptvProtocolExt::Close(); cIptvProtocolExt::Close();
// Free allocated memory
free(scriptFile);
free(listenAddr);
} }
void cIptvProtocolExt::ExecuteScript(void) void cIptvProtocolExt::ExecuteScript(void)
@ -56,15 +52,12 @@ void cIptvProtocolExt::ExecuteScript(void)
for (int i = STDERR_FILENO + 1; i < MaxPossibleFileDescriptors; i++) for (int i = STDERR_FILENO + 1; i < MaxPossibleFileDescriptors; i++)
close(i); close(i);
// Execute the external script // Execute the external script
char* cmd = NULL; cString cmd = cString::sprintf("%s %d %d", *scriptFile, scriptParameter, socketPort);
asprintf(&cmd, "%s %d %d", scriptFile, scriptParameter, socketPort); debug("cIptvProtocolExt::ExecuteScript(child): %s\n", *cmd);
debug("cIptvProtocolExt::ExecuteScript(child): %s\n", cmd); if (execl("/bin/sh", "sh", "-c", *cmd, NULL) == -1) {
if (execl("/bin/sh", "sh", "-c", cmd, NULL) == -1) { error("ERROR: Script execution failed: %s", *cmd);
error("ERROR: Script execution failed: %s", cmd);
free(cmd);
_exit(-1); _exit(-1);
} }
free(cmd);
_exit(0); _exit(0);
} }
else { else {
@ -87,7 +80,7 @@ void cIptvProtocolExt::TerminateScript(void)
retval = 0; retval = 0;
waitms += timeoutms; waitms += timeoutms;
if ((waitms % 2000) == 0) { if ((waitms % 2000) == 0) {
error("ERROR: Script '%s' won't terminate - killing it!", scriptFile); error("ERROR: Script '%s' won't terminate - killing it!", *scriptFile);
kill(pid, SIGKILL); kill(pid, SIGKILL);
} }
// Clear wait status to make sure child exit status is accessible // Clear wait status to make sure child exit status is accessible
@ -146,10 +139,9 @@ bool cIptvProtocolExt::Set(const char* Location, const int Parameter, const int
if (!isempty(Location)) { if (!isempty(Location)) {
struct stat stbuf; struct stat stbuf;
// Update script file and parameter // Update script file and parameter
free(scriptFile); scriptFile = cString::sprintf("%s/%s", IptvConfig.GetConfigDirectory(), Location);
asprintf(&scriptFile, "%s/%s", IptvConfig.GetConfigDirectory(), Location);
if ((stat(scriptFile, &stbuf) != 0) || (strstr(scriptFile, "..") != 0)) { if ((stat(scriptFile, &stbuf) != 0) || (strstr(scriptFile, "..") != 0)) {
error("ERROR: Non-existent or relative path script '%s'", scriptFile); error("ERROR: Non-existent or relative path script '%s'", *scriptFile);
return false; return false;
} }
scriptParameter = Parameter; scriptParameter = Parameter;
@ -162,5 +154,5 @@ bool cIptvProtocolExt::Set(const char* Location, const int Parameter, const int
cString cIptvProtocolExt::GetInformation(void) cString cIptvProtocolExt::GetInformation(void)
{ {
//debug("cIptvProtocolExt::GetInformation()"); //debug("cIptvProtocolExt::GetInformation()");
return cString::sprintf("ext://%s:%d", scriptFile, scriptParameter); return cString::sprintf("ext://%s:%d", *scriptFile, scriptParameter);
} }

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: protocolext.h,v 1.9 2008/01/04 23:36:37 ajhseppa Exp $ * $Id: protocolext.h,v 1.10 2008/02/17 19:18:47 rahrenbe Exp $
*/ */
#ifndef __IPTV_PROTOCOLEXT_H #ifndef __IPTV_PROTOCOLEXT_H
@ -16,8 +16,7 @@
class cIptvProtocolExt : public cIptvUdpSocket, public cIptvProtocolIf { class cIptvProtocolExt : public cIptvUdpSocket, public cIptvProtocolIf {
private: private:
int pid; int pid;
char* listenAddr; cString scriptFile;
char* scriptFile;
int scriptParameter; int scriptParameter;
private: private:

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: protocolhttp.c,v 1.23 2008/01/30 21:57:33 rahrenbe Exp $ * $Id: protocolhttp.c,v 1.24 2008/02/17 19:18:47 rahrenbe Exp $
*/ */
#include <sys/types.h> #include <sys/types.h>
@ -88,17 +88,14 @@ bool cIptvProtocolHttp::Connect(void)
} }
// Formulate and send HTTP request // Formulate and send HTTP request
char buffer[256]; cString buffer = cString::sprintf("GET %s HTTP/1.1\r\n"
memset(buffer, '\0', sizeof(buffer)); "Host: %s\r\n"
snprintf(buffer, sizeof(buffer), "User-Agent: vdr-iptv\r\n"
"GET %s HTTP/1.1\r\n" "Range: bytes=0-\r\n"
"Host: %s\r\n" "Connection: Close\r\n"
"User-Agent: vdr-iptv\r\n" "\r\n", streamPath, streamAddr);
"Range: bytes=0-\r\n"
"Connection: Close\r\n"
"\r\n", streamPath, streamAddr);
//debug("Sending http request: %s\n", buffer); debug("Sending http request: %s\n", *buffer);
err = send(socketDesc, buffer, strlen(buffer), 0); err = send(socketDesc, buffer, strlen(buffer), 0);
ERROR_IF_FUNC(err < 0, "send()", CloseSocket(), return false); ERROR_IF_FUNC(err < 0, "send()", CloseSocket(), return false);

View File

@ -3,13 +3,10 @@
* *
* 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: sectionfilter.c,v 1.18 2008/01/30 21:57:33 rahrenbe Exp $ * $Id: sectionfilter.c,v 1.19 2008/02/17 19:18:47 rahrenbe Exp $
*/ */
#include "sectionfilter.h" #include "sectionfilter.h"
#include "statistics.h"
#define IPTV_FILTER_FILENAME "/tmp/vdr-iptv%d.filter%d"
cIptvSectionFilter::cIptvSectionFilter(int Index, int devInd, cIptvSectionFilter::cIptvSectionFilter(int Index, int devInd,
u_short Pid, u_char Tid, u_char Mask) u_short Pid, u_char Tid, u_char Mask)
@ -21,7 +18,8 @@ cIptvSectionFilter::cIptvSectionFilter(int Index, int devInd,
seclen(0), seclen(0),
tsfeedp(0), tsfeedp(0),
pid(Pid), pid(Pid),
id(Index) id(Index),
pipeName("")
{ {
//debug("cIptvSectionFilter::cIptvSectionFilter(%d)\n", Index); //debug("cIptvSectionFilter::cIptvSectionFilter(%d)\n", Index);
memset(secbuf_base, '\0', sizeof(secbuf_base)); memset(secbuf_base, '\0', sizeof(secbuf_base));
@ -30,7 +28,6 @@ cIptvSectionFilter::cIptvSectionFilter(int Index, int devInd,
memset(filter_mode, '\0', sizeof(filter_mode)); memset(filter_mode, '\0', sizeof(filter_mode));
memset(maskandmode, '\0', sizeof(maskandmode)); memset(maskandmode, '\0', sizeof(maskandmode));
memset(maskandnotmode, '\0', sizeof(maskandnotmode)); memset(maskandnotmode, '\0', sizeof(maskandnotmode));
memset(pipeName, '\0', sizeof(pipeName));
SetPipeName(devInd); SetPipeName(devInd);
@ -68,14 +65,13 @@ cIptvSectionFilter::~cIptvSectionFilter()
close(fifoDescriptor); close(fifoDescriptor);
close(readDescriptor); close(readDescriptor);
unlink(pipeName); unlink(pipeName);
memset(pipeName, '\0', sizeof(pipeName));
fifoDescriptor = -1; fifoDescriptor = -1;
readDescriptor = -1; readDescriptor = -1;
} }
void cIptvSectionFilter::SetPipeName(int deviceIndex) void cIptvSectionFilter::SetPipeName(int deviceIndex)
{ {
snprintf(pipeName, sizeof(pipeName), IPTV_FILTER_FILENAME, deviceIndex, id); pipeName = cString::sprintf(IPTV_FILTER_FILENAME, deviceIndex, id);
} }
int cIptvSectionFilter::GetReadDesc() int cIptvSectionFilter::GetReadDesc()

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: sectionfilter.h,v 1.7 2007/10/08 23:51:58 rahrenbe Exp $ * $Id: sectionfilter.h,v 1.8 2008/02/17 19:18:47 rahrenbe Exp $
*/ */
#ifndef __IPTV_SECTIONFILTER_H #ifndef __IPTV_SECTIONFILTER_H
@ -65,7 +65,7 @@ private:
uint8_t maskandmode[DMX_MAX_FILTER_SIZE]; uint8_t maskandmode[DMX_MAX_FILTER_SIZE];
uint8_t maskandnotmode[DMX_MAX_FILTER_SIZE]; uint8_t maskandnotmode[DMX_MAX_FILTER_SIZE];
char pipeName[128]; cString pipeName;
inline uint16_t section_length(const uint8_t *buf); inline uint16_t section_length(const uint8_t *buf);

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: setup.c,v 1.53 2008/02/01 21:54:24 rahrenbe Exp $ * $Id: setup.c,v 1.54 2008/02/17 19:18:47 rahrenbe Exp $
*/ */
#include <string.h> #include <string.h>
@ -417,9 +417,7 @@ cIptvMenuChannelItem::cIptvMenuChannelItem(cChannel *Channel)
void cIptvMenuChannelItem::Set(void) void cIptvMenuChannelItem::Set(void)
{ {
char *buffer = NULL; SetText(cString::sprintf("%d\t%s", channel->Number(), channel->Name()), false);
asprintf(&buffer, "%d\t%s", channel->Number(), channel->Name());
SetText(buffer, false);
} }
// --- cIptvMenuChannels ----------------------------------------------------- // --- cIptvMenuChannels -----------------------------------------------------