diff --git a/Makefile b/Makefile index e2cd97e..cbe7ffc 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # # Makefile for a Video Disk Recorder plugin # -# $Id: Makefile,v 1.10 2007/09/26 22:10:17 rahrenbe Exp $ +# $Id: Makefile,v 1.11 2007/09/28 16:44:59 rahrenbe Exp $ # Debugging on/off #IPTV_DEBUG = 1 @@ -57,7 +57,7 @@ endif ### The object files (add further files here): -OBJS = $(PLUGIN).o config.o setup.o device.o streamer.o protocoludp.o protocolrtp.o \ +OBJS = $(PLUGIN).o config.o setup.o device.o streamer.o protocoludp.o \ protocolhttp.o protocolfile.o sectionfilter.o ### The main target: diff --git a/README b/README index 8044462..ecaba6c 100644 --- a/README +++ b/README @@ -38,12 +38,11 @@ make plugins Channels.conf examples: TV1;IPTV:1:IPTV|UDP|127.0.0.1|1234:P:0:512:650:2321:0:1:0:0:0 -TV1;IPTV:1:IPTV|RTP|127.0.0.1|1234:P:0:512:650:2321:0:1:0:0:0 ^ ^ ^ ^ ^ ^ | | | | | Source type ("P") | | | | IP Port Number | | | IP Address or File Location - | | Protocol ("UDP", "RTP", "HTTP", "FILE") + | | Protocol ("UDP", "HTTP", "FILE") | Plugin ID ("IPTV") Unique enumeration diff --git a/config.c b/config.c index 3d1abdf..b16cea1 100644 --- a/config.c +++ b/config.c @@ -3,7 +3,7 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: config.c,v 1.6 2007/09/27 22:30:50 rahrenbe Exp $ + * $Id: config.c,v 1.7 2007/09/28 16:44:59 rahrenbe Exp $ */ #include "common.h" @@ -12,12 +12,9 @@ cIptvConfig IptvConfig; cIptvConfig::cIptvConfig(void) -: tsBufferSize(2), +: readBufferTsCount(48), + tsBufferSize(2), tsBufferPrefillRatio(0), - udpBufferSize(20), - rtpBufferSize(20), - httpBufferSize(20), - fileBufferSize(20), - maxBufferSize(40) // must be bigger than protocol buffer sizes! + fileIdleTimeMs(5) { } diff --git a/config.h b/config.h index 3e695be..65d4988 100644 --- a/config.h +++ b/config.h @@ -3,7 +3,7 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: config.h,v 1.5 2007/09/26 19:49:35 rahrenbe Exp $ + * $Id: config.h,v 1.6 2007/09/28 16:44:59 rahrenbe Exp $ */ #ifndef __IPTV_CONFIG_H @@ -15,28 +15,20 @@ class cIptvConfig { protected: + unsigned int readBufferTsCount; unsigned int tsBufferSize; unsigned int tsBufferPrefillRatio; - unsigned int udpBufferSize; - unsigned int rtpBufferSize; - unsigned int httpBufferSize; - unsigned int fileBufferSize; - unsigned int maxBufferSize; + unsigned int fileIdleTimeMs; + public: cIptvConfig(); + unsigned int GetReadBufferTsCount(void) { return readBufferTsCount; } unsigned int GetTsBufferSize(void) { return tsBufferSize; } unsigned int GetTsBufferPrefillRatio(void) { return tsBufferPrefillRatio; } - unsigned int GetUdpBufferSize(void) { return udpBufferSize; } - unsigned int GetRtpBufferSize(void) { return rtpBufferSize; } - unsigned int GetHttpBufferSize(void) { return httpBufferSize; } - unsigned int GetFileBufferSize(void) { return fileBufferSize; } - unsigned int GetMaxBufferSize(void) { return maxBufferSize; } + unsigned int GetFileIdleTimeMs(void) { return fileIdleTimeMs; } void SetTsBufferSize(unsigned int Size) { tsBufferSize = Size; } void SetTsBufferPrefillRatio(unsigned int Ratio) { tsBufferPrefillRatio = Ratio; } - void SetUdpBufferSize(unsigned int Size) { udpBufferSize = Size; } - void SetRtpBufferSize(unsigned int Size) { rtpBufferSize = Size; } - void SetHttpBufferSize(unsigned int Size) { httpBufferSize = Size; } - void SetFileBufferSize(unsigned int Size) { fileBufferSize = Size; } + void SetFileIdleTimeMs(unsigned int TimeMs) { fileIdleTimeMs = TimeMs; } }; extern cIptvConfig IptvConfig; diff --git a/device.c b/device.c index 4a345f2..2a82ee1 100644 --- a/device.c +++ b/device.c @@ -3,7 +3,7 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: device.c,v 1.42 2007/09/28 14:49:10 ajhseppa Exp $ + * $Id: device.c,v 1.43 2007/09/28 16:44:59 rahrenbe Exp $ */ #include "common.h" @@ -24,12 +24,11 @@ cIptvDevice::cIptvDevice(unsigned int Index) { debug("cIptvDevice::cIptvDevice(%d)\n", deviceIndex); tsBuffer = new cRingBufferLinear(MEGABYTE(IptvConfig.GetTsBufferSize()), - (TS_SIZE * IptvConfig.GetMaxBufferSize()), + (TS_SIZE * IptvConfig.GetReadBufferTsCount()), false, "IPTV"); tsBuffer->SetTimeouts(100, 100); ResetBuffering(); pUdpProtocol = new cIptvProtocolUdp(); - pRtpProtocol = new cIptvProtocolRtp(); pHttpProtocol = new cIptvProtocolHttp(); pFileProtocol = new cIptvProtocolFile(); pIptvStreamer = new cIptvStreamer(tsBuffer, &mutex); @@ -87,11 +86,6 @@ cString cIptvDevice::GetChannelSettings(const char *Param, int *IpPort, cIptvPro *Protocol = pUdpProtocol; return addr; } - else if (sscanf(Param, "IPTV|RTP|%a[^|]|%u", &loc, IpPort) == 2) { - cString addr(loc, true); - *Protocol = pRtpProtocol; - return addr; - } else if (sscanf(Param, "IPTV|HTTP|%a[^|]|%u", &loc, IpPort) == 2) { cString addr(loc, true); *Protocol = pHttpProtocol; @@ -173,17 +167,15 @@ bool cIptvDevice::DeleteFilter(unsigned int Index) bool cIptvDevice::IsBlackListed(u_short Pid, u_char Tid, u_char Mask) { //debug("cIptvDevice::IsBlackListed(%d) Pid=%d Tid=%02X Mask=%02X\n", deviceIndex, Pid, Tid, Mask); - // Black list. Should maybe be configurable via plugin setup menu - switch(Pid) { - - case 0x14: // TDT pid - return true; - - default: - break; - } - + switch (Pid) { + case 0x10: // NIT (0x40) + case 0x11: // SDT (0x42) + case 0x14: // TDT (0x70) + return true; + default: + break; + } return false; } diff --git a/device.h b/device.h index 85da431..2e30e2a 100644 --- a/device.h +++ b/device.h @@ -3,7 +3,7 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: device.h,v 1.19 2007/09/28 14:49:10 ajhseppa Exp $ + * $Id: device.h,v 1.20 2007/09/28 16:44:59 rahrenbe Exp $ */ #ifndef __IPTV_DEVICE_H @@ -11,7 +11,6 @@ #include #include "protocoludp.h" -#include "protocolrtp.h" #include "protocolhttp.h" #include "protocolfile.h" #include "streamer.h" @@ -36,7 +35,6 @@ private: cRingBufferLinear *tsBuffer; int tsBufferPrefill; cIptvProtocolUdp *pUdpProtocol; - cIptvProtocolRtp *pRtpProtocol; cIptvProtocolHttp *pHttpProtocol; cIptvProtocolFile *pFileProtocol; cIptvStreamer *pIptvStreamer; diff --git a/iptv.c b/iptv.c index 28b57a8..f25a6e3 100644 --- a/iptv.c +++ b/iptv.c @@ -3,7 +3,7 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: iptv.c,v 1.5 2007/09/16 13:38:20 rahrenbe Exp $ + * $Id: iptv.c,v 1.6 2007/09/28 16:44:59 rahrenbe Exp $ */ #include @@ -158,12 +158,8 @@ bool cPluginIptv::SetupParse(const char *Name, const char *Value) IptvConfig.SetTsBufferSize(atoi(Value)); else if (!strcasecmp(Name, "TsBufferPrefill")) IptvConfig.SetTsBufferPrefillRatio(atoi(Value)); - else if (!strcasecmp(Name, "UdpBufferSize")) - IptvConfig.SetUdpBufferSize(atoi(Value)); - else if (!strcasecmp(Name, "HttpBufferSize")) - IptvConfig.SetHttpBufferSize(atoi(Value)); - else if (!strcasecmp(Name, "FileBufferSize")) - IptvConfig.SetFileBufferSize(atoi(Value)); + else if (!strcasecmp(Name, "FileIdleTimeMs")) + IptvConfig.SetFileIdleTimeMs(atoi(Value)); else return false; return true; diff --git a/po/fi_FI.po b/po/fi_FI.po index 4d19a29..fd0a1bd 100644 --- a/po/fi_FI.po +++ b/po/fi_FI.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.5.7\n" "Report-Msgid-Bugs-To: Rolf Ahrenberg\n" -"POT-Creation-Date: 2007-09-26 20:00+0300\n" +"POT-Creation-Date: 2007-09-28 18:57+0300\n" "PO-Revision-Date: 2007-08-12 23:22+0300\n" "Last-Translator: Rolf Ahrenberg\n" "Language-Team: \n" @@ -19,58 +19,42 @@ msgstr "" msgid "Experiment the IPTV" msgstr "Koe IPTV:n ihmeellinen maailma" -#: setup.c:54 +#: setup.c:53 msgid "UDP" msgstr "UDP" -#: setup.c:55 -msgid "RTP" -msgstr "RTP" - -#: setup.c:56 +#: setup.c:54 msgid "HTTP" msgstr "HTTP" -#: setup.c:57 +#: setup.c:55 msgid "FILE" msgstr "FILE" -#: setup.c:180 +#: setup.c:170 msgid "Protocol" msgstr "Protokolla" -#: setup.c:188 +#: setup.c:178 msgid "Address" msgstr "Osoite" -#: setup.c:189 +#: setup.c:179 msgid "Port" msgstr "Portti" -#: setup.c:307 +#: setup.c:296 msgid "IPTV Channels" msgstr "IPTV-kanavat" -#: setup.c:444 +#: setup.c:430 msgid "TS buffer size [MB]" msgstr "TS-puskurin koko [MB]" -#: setup.c:445 +#: setup.c:431 msgid "TS buffer prefill ratio [%]" msgstr "TS-puskurin esitäyttöaste [%]" -#: setup.c:446 -msgid "UDP buffer size [packets]" -msgstr "UDP-puskurin koko [pakettia]" - -#: setup.c:447 -msgid "RTP buffer size [packets]" -msgstr "RTP-puskurin koko [pakettia]" - -#: setup.c:448 -msgid "HTTP buffer size [packets]" -msgstr "HTTP-puskurin koko [pakettia]" - -#: setup.c:449 -msgid "FILE buffer size [packets]" -msgstr "FILE-puskurin koko [pakettia]" +#: setup.c:432 +msgid "FILE protocol idle time [ms]" +msgstr "FILE-prokollan joutoaika [ms]" diff --git a/protocolfile.c b/protocolfile.c index 12cdf21..a689182 100644 --- a/protocolfile.c +++ b/protocolfile.c @@ -3,7 +3,7 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: protocolfile.c,v 1.7 2007/09/20 21:45:51 rahrenbe Exp $ + * $Id: protocolfile.c,v 1.8 2007/09/28 16:44:59 rahrenbe Exp $ */ #include @@ -16,13 +16,13 @@ #include "protocolfile.h" cIptvProtocolFile::cIptvProtocolFile() -: fileActive(false) +: readBufferLen(TS_SIZE * IptvConfig.GetReadBufferTsCount()), + isActive(false) { - debug("cIptvProtocolFile::cIptvProtocolFile(): %d/%d packets\n", - IptvConfig.GetFileBufferSize(), IptvConfig.GetMaxBufferSize()); + debug("cIptvProtocolFile::cIptvProtocolFile()\n"); streamAddr = strdup(""); // Allocate receive buffer - readBuffer = MALLOC(unsigned char, (TS_SIZE * IptvConfig.GetMaxBufferSize())); + readBuffer = MALLOC(unsigned char, readBufferLen); if (!readBuffer) error("ERROR: MALLOC() failed in ProtocolFile()"); } @@ -41,7 +41,7 @@ bool cIptvProtocolFile::OpenFile(void) { debug("cIptvProtocolFile::OpenFile()\n"); // Check that stream address is valid - if (!fileActive && !isempty(streamAddr)) { + if (!isActive && !isempty(streamAddr)) { fileStream = fopen(streamAddr, "rb"); if (ferror(fileStream) || !fileStream) { char tmp[64]; @@ -49,7 +49,7 @@ bool cIptvProtocolFile::OpenFile(void) return false; } // Update active flag - fileActive = true; + isActive = true; } return true; } @@ -58,10 +58,10 @@ void cIptvProtocolFile::CloseFile(void) { debug("cIptvProtocolFile::CloseFile()\n"); // Check that file stream is valid - if (fileActive && !isempty(streamAddr)) { + if (isActive && !isempty(streamAddr)) { fclose(fileStream); // Update active flag - fileActive = false; + isActive = false; } } @@ -78,12 +78,13 @@ int cIptvProtocolFile::Read(unsigned char* *BufferAddr) if (feof(fileStream)) rewind(fileStream); // Sleep before reading the file stream to prevent aggressive busy looping - cCondWait::SleepMs(1); + // and prevent transfer ringbuffer overflows + cCondWait::SleepMs(IptvConfig.GetFileIdleTimeMs()); // 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 // still active before accessing the buffers - if (fileActive) - return fread(readBuffer, sizeof(unsigned char), (TS_SIZE * IptvConfig.GetFileBufferSize()), fileStream); + if (isActive) + return fread(readBuffer, sizeof(unsigned char), readBufferLen, fileStream); return -1; } diff --git a/protocolfile.h b/protocolfile.h index 30a3065..02d557a 100644 --- a/protocolfile.h +++ b/protocolfile.h @@ -3,7 +3,7 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: protocolfile.h,v 1.3 2007/09/20 21:45:51 rahrenbe Exp $ + * $Id: protocolfile.h,v 1.4 2007/09/28 16:44:59 rahrenbe Exp $ */ #ifndef __IPTV_PROTOCOLFILE_H @@ -18,7 +18,8 @@ private: int streamPort; FILE* fileStream; unsigned char* readBuffer; - bool fileActive; + unsigned int readBufferLen; + bool isActive; private: bool OpenFile(void); diff --git a/protocolhttp.c b/protocolhttp.c index 08342a1..8b3c314 100644 --- a/protocolhttp.c +++ b/protocolhttp.c @@ -3,7 +3,7 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: protocolhttp.c,v 1.5 2007/09/26 19:49:35 rahrenbe Exp $ + * $Id: protocolhttp.c,v 1.6 2007/09/28 16:44:59 rahrenbe Exp $ */ #include @@ -22,14 +22,14 @@ cIptvProtocolHttp::cIptvProtocolHttp() : streamPort(3000), socketDesc(-1), + readBufferLen(TS_SIZE * IptvConfig.GetReadBufferTsCount()), isActive(false) { - debug("cIptvProtocolHttp::cIptvProtocolHttp(): %d/%d packets\n", - IptvConfig.GetHttpBufferSize(), IptvConfig.GetMaxBufferSize()); + debug("cIptvProtocolHttp::cIptvProtocolHttp()\n"); streamAddr = strdup(""); streamPath = strdup("/"); // Allocate receive buffer - readBuffer = MALLOC(unsigned char, (TS_SIZE * IptvConfig.GetMaxBufferSize())); + readBuffer = MALLOC(unsigned char, readBufferLen); if (!readBuffer) error("ERROR: MALLOC() failed in ProtocolHttp()"); } @@ -237,8 +237,8 @@ int cIptvProtocolHttp::Read(unsigned char* *BufferAddr) // Check if data available else if (retval) { // Read data from socket - return recvfrom(socketDesc, readBuffer, (TS_SIZE * IptvConfig.GetHttpBufferSize()), - MSG_DONTWAIT, (struct sockaddr *)&sockAddr, &addrlen); + return recvfrom(socketDesc, readBuffer, readBufferLen, MSG_DONTWAIT, + (struct sockaddr *)&sockAddr, &addrlen); } return 0; } diff --git a/protocolhttp.h b/protocolhttp.h index 3e4d3f9..01a42b3 100644 --- a/protocolhttp.h +++ b/protocolhttp.h @@ -3,7 +3,7 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: protocolhttp.h,v 1.4 2007/09/26 19:49:35 rahrenbe Exp $ + * $Id: protocolhttp.h,v 1.5 2007/09/28 16:44:59 rahrenbe Exp $ */ #ifndef __IPTV_PROTOCOLHTTP_H @@ -19,6 +19,7 @@ private: int streamPort; int socketDesc; unsigned char* readBuffer; + unsigned int readBufferLen; struct sockaddr_in sockAddr; bool isActive; diff --git a/protocolrtp.c b/protocolrtp.c deleted file mode 100644 index d0e0ba7..0000000 --- a/protocolrtp.c +++ /dev/null @@ -1,230 +0,0 @@ -/* - * protocolrtp.c: IPTV plugin for the Video Disk Recorder - * - * See the README file for copyright information and how to reach the author. - * - * $Id: protocolrtp.c,v 1.3 2007/09/27 22:30:50 rahrenbe Exp $ - */ - -#include -#include -#include -#include -#include - -#include - -#include "common.h" -#include "config.h" -#include "protocolrtp.h" - -cIptvProtocolRtp::cIptvProtocolRtp() -: streamPort(1234), - socketDesc(-1), - isActive(false) -{ - debug("cIptvProtocolRtp::cIptvProtocolRtp(): %d/%d packets\n", - IptvConfig.GetRtpBufferSize(), IptvConfig.GetMaxBufferSize()); - streamAddr = strdup(""); - // Allocate receive buffer - readBuffer = MALLOC(unsigned char, (TS_SIZE * IptvConfig.GetMaxBufferSize())); - if (!readBuffer) - error("ERROR: MALLOC() failed in ProtocolRtp()"); -} - -cIptvProtocolRtp::~cIptvProtocolRtp() -{ - debug("cIptvProtocolRtp::~cIptvProtocolRtp()\n"); - // Drop the multicast group and close the socket - Close(); - // Free allocated memory - free(streamAddr); - free(readBuffer); -} - -bool cIptvProtocolRtp::OpenSocket(const int Port) -{ - debug("cIptvProtocolRtp::OpenSocket()\n"); - // If socket is there already and it is bound to a different port, it must - // be closed first - if (Port != streamPort) { - debug("cIptvProtocolRtp::OpenSocket(): Socket tear-down\n"); - CloseSocket(); - } - // Bind to the socket if it is not active already - if (socketDesc < 0) { - int yes = 1; - // Create socket - socketDesc = socket(PF_INET, SOCK_DGRAM, 0); - if (socketDesc < 0) { - char tmp[64]; - error("ERROR: socket(): %s", strerror_r(errno, tmp, sizeof(tmp))); - return false; - } - // Make it use non-blocking I/O to avoid stuck read calls - if (fcntl(socketDesc, F_SETFL, O_NONBLOCK)) { - char tmp[64]; - error("ERROR: fcntl(): %s", strerror_r(errno, tmp, sizeof(tmp))); - CloseSocket(); - return false; - } - // Allow multiple sockets to use the same PORT number - if (setsockopt(socketDesc, SOL_SOCKET, SO_REUSEADDR, &yes, - sizeof(yes)) < 0) { - char tmp[64]; - error("ERROR: setsockopt(): %s", strerror_r(errno, tmp, sizeof(tmp))); - CloseSocket(); - return false; - } - // Bind socket - memset(&sockAddr, '\0', sizeof(sockAddr)); - sockAddr.sin_family = AF_INET; - sockAddr.sin_port = htons(Port); - sockAddr.sin_addr.s_addr = htonl(INADDR_ANY); - int err = bind(socketDesc, (struct sockaddr *)&sockAddr, sizeof(sockAddr)); - if (err < 0) { - char tmp[64]; - error("ERROR: bind(): %s", strerror_r(errno, tmp, sizeof(tmp))); - CloseSocket(); - return false; - } - // Update stream port - streamPort = Port; - } - return true; -} - -void cIptvProtocolRtp::CloseSocket(void) -{ - debug("cIptvProtocolRtp::CloseSocket()\n"); - // Check if socket exists - if (socketDesc >= 0) { - close(socketDesc); - socketDesc = -1; - } -} - -bool cIptvProtocolRtp::JoinMulticast(void) -{ - debug("cIptvProtocolRtp::JoinMulticast()\n"); - // Check that stream address is valid - if (!isActive && !isempty(streamAddr)) { - // Ensure that socket is valid - OpenSocket(streamPort); - // Join a new multicast group - struct ip_mreq mreq; - mreq.imr_multiaddr.s_addr = inet_addr(streamAddr); - mreq.imr_interface.s_addr = htonl(INADDR_ANY); - int err = setsockopt(socketDesc, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, - sizeof(mreq)); - if (err < 0) { - char tmp[64]; - error("ERROR: setsockopt(): %s", strerror_r(errno, tmp, sizeof(tmp))); - return false; - } - // Update multicasting flag - isActive = true; - } - return true; -} - -bool cIptvProtocolRtp::DropMulticast(void) -{ - debug("cIptvProtocolRtp::DropMulticast()\n"); - // Check that stream address is valid - if (isActive && !isempty(streamAddr)) { - // Ensure that socket is valid - OpenSocket(streamPort); - // Drop the multicast group - struct ip_mreq mreq; - mreq.imr_multiaddr.s_addr = inet_addr(streamAddr); - mreq.imr_interface.s_addr = htonl(INADDR_ANY); - int err = setsockopt(socketDesc, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, - sizeof(mreq)); - if (err < 0) { - char tmp[64]; - error("ERROR: setsockopt(): %s", strerror_r(errno, tmp, sizeof(tmp))); - return false; - } - // Update multicasting flag - isActive = false; - } - return true; -} - -int cIptvProtocolRtp::Read(unsigned char* *BufferAddr) -{ - //debug("cIptvProtocolRtp::Read()\n"); - socklen_t addrlen = sizeof(sockAddr); - // Wait for data - struct timeval tv; - tv.tv_sec = 0; - tv.tv_usec = 500000; - // Use select - fd_set rfds; - FD_ZERO(&rfds); - FD_SET(socketDesc, &rfds); - int retval = select(socketDesc + 1, &rfds, NULL, NULL, &tv); - // Check if error - if (retval < 0) { - char tmp[64]; - error("ERROR: select(): %s", strerror_r(errno, tmp, sizeof(tmp))); - return -1; - } - // Check if data available - else if (retval) { - // Read data from socket - int len = recvfrom(socketDesc, readBuffer, (TS_SIZE * IptvConfig.GetRtpBufferSize()), - MSG_DONTWAIT, (struct sockaddr *)&sockAddr, &addrlen); - if (len > 3) { - // http://www.networksorcery.com/enp/rfc/rfc2250.txt - unsigned int v = (readBuffer[0] >> 6) & 0x03; - unsigned int x = (readBuffer[0] >> 4) & 0x01; - unsigned int cc = readBuffer[0] & 0x0F; - unsigned int pt = readBuffer[1] & 0x7F; - unsigned int headerlen = (3 + cc) * sizeof(uint32_t); - if (x) - headerlen += ((((readBuffer[headerlen + 2] & 0xFF) << 8) | (readBuffer[headerlen + 3] & 0xFF)) + 1) * sizeof(uint32_t); - // Check if payload type is MPEG2 TS and payload contains multiple of TS packet data - if ((v == 2) && (pt == 33) && (((len - headerlen) % TS_SIZE) == 0)) { - // Set argument point to payload in read buffer - *BufferAddr = &readBuffer[headerlen]; - return (len - headerlen); - } - } - } - return 0; -} - -bool cIptvProtocolRtp::Open(void) -{ - debug("cIptvProtocolRtp::Open(): streamAddr=%s\n", streamAddr); - // Join a new multicast group - JoinMulticast(); - return true; -} - -bool cIptvProtocolRtp::Close(void) -{ - debug("cIptvProtocolRtp::Close(): streamAddr=%s\n", streamAddr); - // Drop the multicast group - DropMulticast(); - // Close the socket - CloseSocket(); - return true; -} - -bool cIptvProtocolRtp::Set(const char* Address, const int Port) -{ - debug("cIptvProtocolRtp::Set(): %s:%d\n", Address, Port); - if (!isempty(Address)) { - // Drop the multicast group - DropMulticast(); - // Update stream address and port - streamAddr = strcpyrealloc(streamAddr, Address); - streamPort = Port; - // Join a new multicast group - JoinMulticast(); - } - return true; -} diff --git a/protocolrtp.h b/protocolrtp.h deleted file mode 100644 index 14c5afe..0000000 --- a/protocolrtp.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * protocolrtp.h: IPTV plugin for the Video Disk Recorder - * - * See the README file for copyright information and how to reach the author. - * - * $Id: protocolrtp.h,v 1.1 2007/09/26 19:49:35 rahrenbe Exp $ - */ - -#ifndef __IPTV_PROTOCOLRTP_H -#define __IPTV_PROTOCOLRTP_H - -#include -#include "protocolif.h" - -class cIptvProtocolRtp : public cIptvProtocolIf { -private: - char* streamAddr; - int streamPort; - int socketDesc; - unsigned char* readBuffer; - struct sockaddr_in sockAddr; - bool isActive; - -private: - bool OpenSocket(const int Port); - void CloseSocket(void); - bool JoinMulticast(void); - bool DropMulticast(void); - -public: - cIptvProtocolRtp(); - virtual ~cIptvProtocolRtp(); - virtual int Read(unsigned char* *BufferAddr); - virtual bool Set(const char* Address, const int Port); - virtual bool Open(void); - virtual bool Close(void); -}; - -#endif // __IPTV_PROTOCOLRTP_H - diff --git a/protocoludp.c b/protocoludp.c index 367d270..58efef0 100644 --- a/protocoludp.c +++ b/protocoludp.c @@ -3,7 +3,7 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: protocoludp.c,v 1.7 2007/09/26 19:49:35 rahrenbe Exp $ + * $Id: protocoludp.c,v 1.8 2007/09/28 16:44:59 rahrenbe Exp $ */ #include @@ -21,13 +21,13 @@ cIptvProtocolUdp::cIptvProtocolUdp() : streamPort(1234), socketDesc(-1), + readBufferLen(TS_SIZE * IptvConfig.GetReadBufferTsCount()), isActive(false) { - debug("cIptvProtocolUdp::cIptvProtocolUdp(): %d/%d packets\n", - IptvConfig.GetUdpBufferSize(), IptvConfig.GetMaxBufferSize()); + debug("cIptvProtocolUdp::cIptvProtocolUdp()\n"); streamAddr = strdup(""); // Allocate receive buffer - readBuffer = MALLOC(unsigned char, (TS_SIZE * IptvConfig.GetMaxBufferSize())); + readBuffer = MALLOC(unsigned char, readBufferLen); if (!readBuffer) error("ERROR: MALLOC() failed in ProtocolUdp()"); } @@ -176,8 +176,29 @@ int cIptvProtocolUdp::Read(unsigned char* *BufferAddr) // Check if data available else if (retval) { // Read data from socket - return recvfrom(socketDesc, readBuffer, (TS_SIZE * IptvConfig.GetUdpBufferSize()), - MSG_DONTWAIT, (struct sockaddr *)&sockAddr, &addrlen); + int len = recvfrom(socketDesc, readBuffer, readBufferLen, MSG_DONTWAIT, + (struct sockaddr *)&sockAddr, &addrlen); + if ((len > 0) && (readBuffer[0] == 0x47)) { + // Set argument point to read buffer + *BufferAddr = &readBuffer[0]; + return len; + } + else if (len > 3) { + // http://www.networksorcery.com/enp/rfc/rfc2250.txt + unsigned int v = (readBuffer[0] >> 6) & 0x03; + unsigned int x = (readBuffer[0] >> 4) & 0x01; + unsigned int cc = readBuffer[0] & 0x0F; + unsigned int pt = readBuffer[1] & 0x7F; + unsigned int headerlen = (3 + cc) * sizeof(uint32_t); + if (x) + headerlen += ((((readBuffer[headerlen + 2] & 0xFF) << 8) | (readBuffer[headerlen + 3] & 0xFF)) + 1) * sizeof(uint32_t); + // Check if payload type is MPEG2 TS and payload contains multiple of TS packet data + if ((v == 2) && (pt == 33) && (((len - headerlen) % TS_SIZE) == 0)) { + // Set argument point to payload in read buffer + *BufferAddr = &readBuffer[headerlen]; + return (len - headerlen); + } + } } return 0; } diff --git a/protocoludp.h b/protocoludp.h index 06892ba..698d0d8 100644 --- a/protocoludp.h +++ b/protocoludp.h @@ -3,7 +3,7 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: protocoludp.h,v 1.5 2007/09/26 19:49:35 rahrenbe Exp $ + * $Id: protocoludp.h,v 1.6 2007/09/28 16:44:59 rahrenbe Exp $ */ #ifndef __IPTV_PROTOCOLUDP_H @@ -18,6 +18,7 @@ private: int streamPort; int socketDesc; unsigned char* readBuffer; + unsigned int readBufferLen; struct sockaddr_in sockAddr; bool isActive; diff --git a/setup.c b/setup.c index a50e22f..79340d9 100644 --- a/setup.c +++ b/setup.c @@ -3,7 +3,7 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: setup.c,v 1.10 2007/09/27 22:30:50 rahrenbe Exp $ + * $Id: setup.c,v 1.11 2007/09/28 16:44:59 rahrenbe Exp $ */ #include @@ -26,7 +26,6 @@ class cIptvMenuEditChannel : public cOsdMenu private: enum { eProtocolUDP, - eProtocolRTP, eProtocolHTTP, eProtocolFILE, eProtocolCount @@ -52,7 +51,6 @@ cIptvMenuEditChannel::cIptvMenuEditChannel(cChannel *Channel, bool New) :cOsdMenu(trVDR("Edit channel"), 16) { protocols[eProtocolUDP] = tr("UDP"); - protocols[eProtocolRTP] = tr("RTP"); protocols[eProtocolHTTP] = tr("HTTP"); protocols[eProtocolFILE] = tr("FILE"); channel = Channel; @@ -74,11 +72,6 @@ cString cIptvMenuEditChannel::GetIptvSettings(const char *Param, int *Port, int *Protocol = eProtocolUDP; return addr; } - else if (sscanf(Param, "IPTV|RTP|%a[^|]|%u", &loc, Port) == 2) { - cString addr(loc, true); - *Protocol = eProtocolRTP; - return addr; - } else if (sscanf(Param, "IPTV|HTTP|%a[^|]|%u", &loc, Port) == 2) { cString addr(loc, true); *Protocol = eProtocolHTTP; @@ -156,9 +149,6 @@ void cIptvMenuEditChannel::SetChannelData(cChannel *Channel) case eProtocolHTTP: param = cString::sprintf("IPTV|HTTP|%s|%d", data.location, data.port); break; - case eProtocolRTP: - param = cString::sprintf("IPTV|RTP|%s|%d", data.location, data.port); - break; default: case eProtocolUDP: param = cString::sprintf("IPTV|UDP|%s|%d", data.location, data.port); @@ -246,7 +236,6 @@ eOSState cIptvMenuEditChannel::ProcessKey(eKeys Key) data.port = 3000; break; default: - case eProtocolRTP: case eProtocolUDP: strn0cpy(data.location, "127.0.0.1", sizeof(data.location)); data.port = 1234; @@ -429,10 +418,7 @@ cIptvPluginSetup::cIptvPluginSetup() { tsBufferSize = IptvConfig.GetTsBufferSize(); tsBufferPrefill = IptvConfig.GetTsBufferPrefillRatio(); - udpBufferSize = IptvConfig.GetUdpBufferSize(); - rtpBufferSize = IptvConfig.GetRtpBufferSize(); - httpBufferSize = IptvConfig.GetHttpBufferSize(); - fileBufferSize = IptvConfig.GetFileBufferSize(); + fileIdleTimeMs = IptvConfig.GetFileIdleTimeMs(); Setup(); SetHelp(trVDR("Channels"), NULL, NULL, NULL); } @@ -441,12 +427,9 @@ void cIptvPluginSetup::Setup(void) { int current = Current(); Clear(); - Add(new cMenuEditIntItem(tr("TS buffer size [MB]"), &tsBufferSize, 2, 16)); - Add(new cMenuEditIntItem(tr("TS buffer prefill ratio [%]"), &tsBufferPrefill, 0, 40)); - Add(new cMenuEditIntItem(tr("UDP buffer size [packets]"), &udpBufferSize, 1, IptvConfig.GetMaxBufferSize())); - Add(new cMenuEditIntItem(tr("RTP buffer size [packets]"), &rtpBufferSize, 1, IptvConfig.GetMaxBufferSize())); - Add(new cMenuEditIntItem(tr("HTTP buffer size [packets]"), &httpBufferSize, 1, IptvConfig.GetMaxBufferSize())); - Add(new cMenuEditIntItem(tr("FILE buffer size [packets]"), &fileBufferSize, 1, IptvConfig.GetMaxBufferSize())); + Add(new cMenuEditIntItem(tr("TS buffer size [MB]"), &tsBufferSize, 2, 16)); + Add(new cMenuEditIntItem(tr("TS buffer prefill ratio [%]"), &tsBufferPrefill, 0, 40)); + Add(new cMenuEditIntItem(tr("FILE protocol idle time [ms]"), &fileIdleTimeMs, 1, 100)); SetCurrent(Get(current)); Display(); } @@ -475,16 +458,10 @@ void cIptvPluginSetup::Store(void) // Store values into setup.conf SetupStore("TsBufferSize", tsBufferSize); SetupStore("TsBufferPrefill", tsBufferPrefill); - SetupStore("UdpBufferSize", udpBufferSize); - SetupStore("RtpBufferSize", rtpBufferSize); - SetupStore("HttpBufferSize", httpBufferSize); - SetupStore("FileBufferSize", fileBufferSize); + SetupStore("FileIdleTimeMs", fileIdleTimeMs); // Update global config IptvConfig.SetTsBufferSize(tsBufferSize); IptvConfig.SetTsBufferPrefillRatio(tsBufferPrefill); - IptvConfig.SetUdpBufferSize(udpBufferSize); - IptvConfig.SetRtpBufferSize(rtpBufferSize); - IptvConfig.SetHttpBufferSize(httpBufferSize); - IptvConfig.SetFileBufferSize(fileBufferSize); + IptvConfig.SetFileIdleTimeMs(fileIdleTimeMs); } diff --git a/setup.h b/setup.h index 90997d6..d64e8a2 100644 --- a/setup.h +++ b/setup.h @@ -3,7 +3,7 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: setup.h,v 1.5 2007/09/26 19:49:35 rahrenbe Exp $ + * $Id: setup.h,v 1.6 2007/09/28 16:44:59 rahrenbe Exp $ */ #ifndef __IPTV_SETUP_H @@ -16,10 +16,7 @@ class cIptvPluginSetup : public cMenuSetupPage private: int tsBufferSize; int tsBufferPrefill; - int udpBufferSize; - int rtpBufferSize; - int httpBufferSize; - int fileBufferSize; + int fileIdleTimeMs; eOSState EditChannel(void); virtual void Setup(void);