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:
"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:
- 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.
*
* $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
@ -29,6 +29,9 @@
#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
#define IPTV_DEVICE_INFO_GENERAL 1
#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.
*
* $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"
@ -17,6 +17,7 @@ unsigned int cIptvDevice::deviceCount = 0;
cIptvDevice::cIptvDevice(unsigned int Index)
: deviceIndex(Index),
dvrFd(-1),
isPacketDelivered(false),
isOpenDvr(false),
sidScanEnabled(false),
@ -43,11 +44,24 @@ cIptvDevice::cIptvDevice(unsigned int Index)
pSidScanner = new cSidScanner;
if (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()
{
debug("cIptvDevice::~cIptvDevice(%d)\n", deviceIndex);
#if defined(APIVERSNUM) && APIVERSNUM >= 10515
// Stop section handler of iptv device
StopSectionHandler();
#endif
DELETE_POINTER(pIptvStreamer);
DELETE_POINTER(pUdpProtocol);
DELETE_POINTER(pHttpProtocol);
@ -63,6 +77,12 @@ cIptvDevice::~cIptvDevice()
// Destroy all filters
for (int i = 0; i < eMaxSecFilterCount; ++i)
DeleteFilter(i);
// Close dvr fifo
if (dvrFd >= 0) {
int fd = dvrFd;
dvrFd = -1;
close(fd);
}
}
bool cIptvDevice::Initialize(unsigned int DeviceCount)
@ -436,6 +456,9 @@ bool cIptvDevice::GetTSPacket(uchar *&Data)
Data = p;
// Update pid statistics
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
if (pidScanEnabled && pPidScanner)
pPidScanner->Process(p);

View File

@ -3,7 +3,7 @@
*
* 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
@ -35,6 +35,7 @@ private:
eMaxSecFilterCount = 32
};
unsigned int deviceIndex;
int dvrFd;
bool isPacketDelivered;
bool isOpenDvr;
bool sidScanEnabled;

View File

@ -3,7 +3,7 @@
*
* 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>
@ -22,11 +22,10 @@
cIptvProtocolExt::cIptvProtocolExt()
: pid(-1),
scriptFile(""),
scriptParameter(0)
{
debug("cIptvProtocolExt::cIptvProtocolExt()\n");
scriptFile = strdup("");
listenAddr = strdup("127.0.0.1");
}
cIptvProtocolExt::~cIptvProtocolExt()
@ -34,9 +33,6 @@ cIptvProtocolExt::~cIptvProtocolExt()
debug("cIptvProtocolExt::~cIptvProtocolExt()\n");
// Drop the socket connection
cIptvProtocolExt::Close();
// Free allocated memory
free(scriptFile);
free(listenAddr);
}
void cIptvProtocolExt::ExecuteScript(void)
@ -56,15 +52,12 @@ void cIptvProtocolExt::ExecuteScript(void)
for (int i = STDERR_FILENO + 1; i < MaxPossibleFileDescriptors; i++)
close(i);
// Execute the external script
char* cmd = NULL;
asprintf(&cmd, "%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);
free(cmd);
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);
_exit(-1);
}
free(cmd);
_exit(0);
}
else {
@ -87,7 +80,7 @@ void cIptvProtocolExt::TerminateScript(void)
retval = 0;
waitms += timeoutms;
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);
}
// 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)) {
struct stat stbuf;
// Update script file and parameter
free(scriptFile);
asprintf(&scriptFile, "%s/%s", IptvConfig.GetConfigDirectory(), Location);
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("ERROR: Non-existent or relative path script '%s'", *scriptFile);
return false;
}
scriptParameter = Parameter;
@ -162,5 +154,5 @@ bool cIptvProtocolExt::Set(const char* Location, const int Parameter, const int
cString cIptvProtocolExt::GetInformation(void)
{
//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.
*
* $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
@ -16,8 +16,7 @@
class cIptvProtocolExt : public cIptvUdpSocket, public cIptvProtocolIf {
private:
int pid;
char* listenAddr;
char* scriptFile;
cString scriptFile;
int scriptParameter;
private:

View File

@ -3,7 +3,7 @@
*
* 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>
@ -88,17 +88,14 @@ bool cIptvProtocolHttp::Connect(void)
}
// Formulate and send HTTP request
char buffer[256];
memset(buffer, '\0', sizeof(buffer));
snprintf(buffer, sizeof(buffer),
"GET %s HTTP/1.1\r\n"
"Host: %s\r\n"
"User-Agent: vdr-iptv\r\n"
"Range: bytes=0-\r\n"
"Connection: Close\r\n"
"\r\n", streamPath, streamAddr);
cString buffer = cString::sprintf("GET %s HTTP/1.1\r\n"
"Host: %s\r\n"
"User-Agent: vdr-iptv\r\n"
"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);
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.
*
* $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 "statistics.h"
#define IPTV_FILTER_FILENAME "/tmp/vdr-iptv%d.filter%d"
cIptvSectionFilter::cIptvSectionFilter(int Index, int devInd,
u_short Pid, u_char Tid, u_char Mask)
@ -21,7 +18,8 @@ cIptvSectionFilter::cIptvSectionFilter(int Index, int devInd,
seclen(0),
tsfeedp(0),
pid(Pid),
id(Index)
id(Index),
pipeName("")
{
//debug("cIptvSectionFilter::cIptvSectionFilter(%d)\n", Index);
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(maskandmode, '\0', sizeof(maskandmode));
memset(maskandnotmode, '\0', sizeof(maskandnotmode));
memset(pipeName, '\0', sizeof(pipeName));
SetPipeName(devInd);
@ -68,14 +65,13 @@ cIptvSectionFilter::~cIptvSectionFilter()
close(fifoDescriptor);
close(readDescriptor);
unlink(pipeName);
memset(pipeName, '\0', sizeof(pipeName));
fifoDescriptor = -1;
readDescriptor = -1;
}
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()

View File

@ -3,7 +3,7 @@
*
* 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
@ -65,7 +65,7 @@ private:
uint8_t maskandmode[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);

View File

@ -3,7 +3,7 @@
*
* 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>
@ -417,9 +417,7 @@ cIptvMenuChannelItem::cIptvMenuChannelItem(cChannel *Channel)
void cIptvMenuChannelItem::Set(void)
{
char *buffer = NULL;
asprintf(&buffer, "%d\t%s", channel->Number(), channel->Name());
SetText(buffer, false);
SetText(cString::sprintf("%d\t%s", channel->Number(), channel->Name()), false);
}
// --- cIptvMenuChannels -----------------------------------------------------