mirror of
				https://github.com/rofafor/vdr-plugin-iptv.git
				synced 2023-10-10 11:37:03 +00:00 
			
		
		
		
	Compare commits
	
		
			36 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					cbd734fc0d | ||
| 
						 | 
					517547dc15 | ||
| 
						 | 
					60a4d266b7 | ||
| 
						 | 
					6901970b8a | ||
| 
						 | 
					d67f0d6ead | ||
| 
						 | 
					c0fc83cba6 | ||
| 
						 | 
					49fcbc8921 | ||
| 
						 | 
					dbeb014a85 | ||
| 
						 | 
					26cd1aa1f1 | ||
| 
						 | 
					a32cb95960 | ||
| 
						 | 
					abfa46c064 | ||
| 
						 | 
					aa1bfab60d | ||
| 
						 | 
					3ffba13a6c | ||
| 
						 | 
					57d63db034 | ||
| 
						 | 
					2484c3bdd6 | ||
| 
						 | 
					912bf068ac | ||
| 
						 | 
					a8d01e32a1 | ||
| 
						 | 
					d1c2d48a6b | ||
| 
						 | 
					e74d4f88f4 | ||
| 
						 | 
					55bf971e3e | ||
| 
						 | 
					30abbc3e80 | ||
| 
						 | 
					74761da04a | ||
| 
						 | 
					b221a9a406 | ||
| 
						 | 
					fd7a43d733 | ||
| 
						 | 
					d546cac834 | ||
| 
						 | 
					94225ac6a4 | ||
| 
						 | 
					25ec9df0cc | ||
| 
						 | 
					abf0a5ece4 | ||
| 
						 | 
					024ee7ba89 | ||
| 
						 | 
					73906ab698 | ||
| 
						 | 
					ec2ec19f68 | ||
| 
						 | 
					1e8f117988 | ||
| 
						 | 
					00cf880a5d | ||
| 
						 | 
					71472a1033 | ||
| 
						 | 
					0eff9de2ee | ||
| 
						 | 
					9a19009451 | 
							
								
								
									
										51
									
								
								HISTORY
									
									
									
									
									
								
							
							
						
						
									
										51
									
								
								HISTORY
									
									
									
									
									
								
							@@ -70,5 +70,54 @@ VDR Plugin 'iptv' Revision History
 | 
			
		||||
- Updated Italian translation (Thanks to Diego Pierotto).
 | 
			
		||||
- Tweaked pid scanner parameters for HD broadcasts.
 | 
			
		||||
- Fixed opening of fifo tap.
 | 
			
		||||
- Updated iptvstream.sh script to support optional video resolution settings.
 | 
			
		||||
- Updated iptvstream.sh script to support optional video resolution
 | 
			
		||||
  settings.
 | 
			
		||||
- Optimized streamer thread termination.
 | 
			
		||||
 | 
			
		||||
2008-12-16: Version 0.2.3
 | 
			
		||||
 | 
			
		||||
- Updated for vdr-1.7.2.
 | 
			
		||||
- Silenced a compilation warning.
 | 
			
		||||
 | 
			
		||||
2009-02-25: Version 0.2.4
 | 
			
		||||
 | 
			
		||||
- Updated for vdr-1.7.4.
 | 
			
		||||
- Fixed blacklisting of PAT section filter.
 | 
			
		||||
- Set max IPTV device count to VDR's max devices.
 | 
			
		||||
- Fixed a possible crash in sid and pid scanners.
 | 
			
		||||
 | 
			
		||||
2009-03-08: Version 0.2.5
 | 
			
		||||
 | 
			
		||||
- Optimized TS packet data flow.
 | 
			
		||||
- Refactored section filter class.
 | 
			
		||||
- Cleaned up example scripts.
 | 
			
		||||
- Fixed pid scanner to set the existing video stream type
 | 
			
		||||
  (Thanks to ua0lnj for reporting this one).
 | 
			
		||||
- Added optional patches to disable CA updates.
 | 
			
		||||
 | 
			
		||||
2009-03-22: Version 0.2.6
 | 
			
		||||
 | 
			
		||||
- Added a note about recommended frequencies into README.
 | 
			
		||||
- Fixed a locking bug with section filters.
 | 
			
		||||
- Fixed some lint warnings.
 | 
			
		||||
 | 
			
		||||
2009-06-01: Version 0.3.0
 | 
			
		||||
 | 
			
		||||
- Added iptvstream-notrap.sh script.
 | 
			
		||||
- Fixed setting parameters when protocol changes
 | 
			
		||||
  (Thanks to Peter Holik for reporting this one).
 | 
			
		||||
- Updated example scripts to use ffmpeg's direct UDP output
 | 
			
		||||
  and added a new "image.sh" script (Thanks to Peter Holik).
 | 
			
		||||
 | 
			
		||||
2009-10-01: Version 0.3.1
 | 
			
		||||
 | 
			
		||||
- 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.
 | 
			
		||||
 | 
			
		||||
2010-03-05: Version 0.3.2
 | 
			
		||||
 | 
			
		||||
- Updated patches.
 | 
			
		||||
- Fixed argument corruption.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										5
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								Makefile
									
									
									
									
									
								
							@@ -1,7 +1,6 @@
 | 
			
		||||
#
 | 
			
		||||
# Makefile for a Video Disk Recorder plugin
 | 
			
		||||
# Makefile for IPTV plugin
 | 
			
		||||
#
 | 
			
		||||
# $Id: Makefile,v 1.27 2008/02/19 22:29:02 rahrenbe Exp $
 | 
			
		||||
 | 
			
		||||
# Debugging on/off 
 | 
			
		||||
#IPTV_DEBUG = 1
 | 
			
		||||
@@ -24,7 +23,7 @@ VERSION = $(shell grep 'static const char VERSION\[\] *=' $(PLUGIN).c | awk '{ p
 | 
			
		||||
### The C++ compiler and options:
 | 
			
		||||
 | 
			
		||||
CXX      ?= g++
 | 
			
		||||
CXXFLAGS ?= -fPIC -g -O2 -Wall -Woverloaded-virtual -Wno-parentheses
 | 
			
		||||
CXXFLAGS ?= -fPIC -g -O2 -Wall -Wextra -Wswitch-default -Wfloat-equal -Wundef -Wpointer-arith -Wconversion -Wcast-align -Wredundant-decls -Wno-unused-parameter -Woverloaded-virtual -Wno-parentheses
 | 
			
		||||
 | 
			
		||||
### The directory environment:
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										30
									
								
								README
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								README
									
									
									
									
									
								
							@@ -111,17 +111,17 @@ Configuration:
 | 
			
		||||
 | 
			
		||||
- channels.conf
 | 
			
		||||
 | 
			
		||||
  TV4;IPTV:4:IPTV|S1P0|EXT|iptvstream.sh|0:P:0:0:680:0:0:4:0:0:0
 | 
			
		||||
  TV3;IPTV:3:IPTV|S0P1|FILE|/video/stream.ts|5:P:0:514:670:2321:0:3:0:0:0
 | 
			
		||||
  TV2;IPTV:2:IPTV|S0P1|HTTP|127.0.0.1/TS/2|3000:P:0:513:660:2321:0:2:0:0:0
 | 
			
		||||
  TV1;IPTV:1:IPTV|S1P0|UDP|127.0.0.1|1234:P:0:512:650:2321:0:1:0:0:0
 | 
			
		||||
           ^ ^    ^    ^   ^         ^    ^
 | 
			
		||||
           | |    |    |   |         |    Source type ("P")
 | 
			
		||||
           | |    |    |   |         IP Port Number, File delay (ms), Script parameter
 | 
			
		||||
           | |    |    |   IP Address, File location, Script location
 | 
			
		||||
           | |    |    Protocol ("UDP", "HTTP", "FILE", "EXT")
 | 
			
		||||
           | |    Parameters ("S" Sid scan, "P" Pid scan, "0" disable, "1" enable)
 | 
			
		||||
           | Plugin ID ("IPTV")
 | 
			
		||||
  TV4;IPTV:40:IPTV|S1P0|EXT|iptvstream.sh|0:P:0:0:680:0:0:4:0:0:0
 | 
			
		||||
  TV3;IPTV:30:IPTV|S0P1|FILE|/video/stream.ts|5:P:0:514:670:2321:0:3:0:0:0
 | 
			
		||||
  TV2;IPTV:20:IPTV|S0P1|HTTP|127.0.0.1/TS/2|3000:P:0:513:660:2321:0:2:0:0:0
 | 
			
		||||
  TV1;IPTV:10:IPTV|S1P0|UDP|127.0.0.1|1234:P:0:512:650:2321:0:1:0:0:0
 | 
			
		||||
           ^  ^    ^    ^   ^         ^    ^
 | 
			
		||||
           |  |    |    |   |         |    Source type ("P")
 | 
			
		||||
           |  |    |    |   |         IP Port Number, File delay (ms), Script parameter
 | 
			
		||||
           |  |    |    |   IP Address, File location, Script location
 | 
			
		||||
           |  |    |    Protocol ("UDP", "HTTP", "FILE", "EXT")
 | 
			
		||||
           |  |    Parameters ("S" Sid scan, "P" Pid scan, "0" disable, "1" enable)
 | 
			
		||||
           |  Plugin ID ("IPTV")
 | 
			
		||||
           Unique enumeration
 | 
			
		||||
 | 
			
		||||
- UDP multicast rules for iptables firewall
 | 
			
		||||
@@ -167,6 +167,14 @@ Notes:
 | 
			
		||||
  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.
 | 
			
		||||
 | 
			
		||||
- Multiple channels with identical service id should have frequency
 | 
			
		||||
  difference of 4 or greater. It's recommended to use frequencies in decades
 | 
			
		||||
  (10, 20, 30, 40, ...) for all IPTV channel entries.
 | 
			
		||||
 | 
			
		||||
- VLC processes won't get killed on some setups with the provided iptvstream.sh
 | 
			
		||||
  script and the iptvstream-notrap.sh script should be used instead in these
 | 
			
		||||
  cases.
 | 
			
		||||
 | 
			
		||||
Acknowledgements:
 | 
			
		||||
 | 
			
		||||
- The IPTV section filtering code is derived from Linux kernel.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								common.c
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								common.c
									
									
									
									
									
								
							@@ -10,7 +10,7 @@
 | 
			
		||||
 | 
			
		||||
uint16_t ts_pid(const uint8_t *buf)
 | 
			
		||||
{
 | 
			
		||||
  return ((buf[1] & 0x1f) << 8) + buf[2];
 | 
			
		||||
  return (uint16_t)(((buf[1] & 0x1f) << 8) + buf[2]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t payload(const uint8_t *tsp)
 | 
			
		||||
@@ -22,7 +22,7 @@ uint8_t payload(const uint8_t *tsp)
 | 
			
		||||
     if (tsp[4] > 183) // corrupted data?
 | 
			
		||||
        return 0;
 | 
			
		||||
     else
 | 
			
		||||
        return (184 - 1) - tsp[4];
 | 
			
		||||
        return (uint8_t)((184 - 1) - tsp[4]);
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
  return 184;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										19
									
								
								common.h
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								common.h
									
									
									
									
									
								
							@@ -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)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										7
									
								
								config.c
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								config.c
									
									
									
									
									
								
							@@ -10,14 +10,13 @@
 | 
			
		||||
cIptvConfig IptvConfig;
 | 
			
		||||
 | 
			
		||||
cIptvConfig::cIptvConfig(void)
 | 
			
		||||
: readBufferTsCount(48),
 | 
			
		||||
  tsBufferSize(2),
 | 
			
		||||
: tsBufferSize(2),
 | 
			
		||||
  tsBufferPrefillRatio(0),
 | 
			
		||||
  extProtocolBasePort(4321),
 | 
			
		||||
  useBytes(1),
 | 
			
		||||
  sectionFiltering(1)
 | 
			
		||||
{
 | 
			
		||||
  for (unsigned int i = 0; i < ARRAY_SIZE(disabledFilters) - 1; ++i)
 | 
			
		||||
  for (unsigned int i = 0; i < ARRAY_SIZE(disabledFilters); ++i)
 | 
			
		||||
      disabledFilters[i] = -1;
 | 
			
		||||
  memset(configDirectory, '\0', sizeof(configDirectory));
 | 
			
		||||
}
 | 
			
		||||
@@ -25,7 +24,7 @@ cIptvConfig::cIptvConfig(void)
 | 
			
		||||
unsigned int cIptvConfig::GetDisabledFiltersCount(void) const
 | 
			
		||||
{
 | 
			
		||||
  unsigned int n = 0;
 | 
			
		||||
  while ((disabledFilters[n] != -1) && (n < ARRAY_SIZE(disabledFilters) - 1))
 | 
			
		||||
  while ((n < ARRAY_SIZE(disabledFilters) && (disabledFilters[n] != -1)))
 | 
			
		||||
        n++;
 | 
			
		||||
  return n;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								config.h
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								config.h
									
									
									
									
									
								
							@@ -14,7 +14,6 @@
 | 
			
		||||
class cIptvConfig
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
  unsigned int readBufferTsCount;
 | 
			
		||||
  unsigned int tsBufferSize;
 | 
			
		||||
  unsigned int tsBufferPrefillRatio;
 | 
			
		||||
  unsigned int extProtocolBasePort;
 | 
			
		||||
@@ -25,7 +24,6 @@ private:
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
  cIptvConfig();
 | 
			
		||||
  unsigned int GetReadBufferTsCount(void) const { return readBufferTsCount; }
 | 
			
		||||
  unsigned int GetTsBufferSize(void) const { return tsBufferSize; }
 | 
			
		||||
  unsigned int GetTsBufferPrefillRatio(void) const { return tsBufferPrefillRatio; }
 | 
			
		||||
  unsigned int GetExtProtocolBasePort(void) const { return extProtocolBasePort; }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										53
									
								
								device.c
									
									
									
									
									
								
							
							
						
						
									
										53
									
								
								device.c
									
									
									
									
									
								
							@@ -8,9 +8,9 @@
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#include "device.h"
 | 
			
		||||
 | 
			
		||||
#define IPTV_MAX_DEVICES 8
 | 
			
		||||
#define IPTV_MAX_DEVICES MAXDEVICES
 | 
			
		||||
 | 
			
		||||
cIptvDevice * IptvDevices[IPTV_MAX_DEVICES] = { NULL };
 | 
			
		||||
static cIptvDevice * IptvDevices[IPTV_MAX_DEVICES] = { NULL };
 | 
			
		||||
 | 
			
		||||
unsigned int cIptvDevice::deviceCount = 0;
 | 
			
		||||
 | 
			
		||||
@@ -20,21 +20,20 @@ cIptvDevice::cIptvDevice(unsigned int Index)
 | 
			
		||||
  isPacketDelivered(false),
 | 
			
		||||
  isOpenDvr(false),
 | 
			
		||||
  sidScanEnabled(false),
 | 
			
		||||
  pidScanEnabled(false),
 | 
			
		||||
  mutex()
 | 
			
		||||
  pidScanEnabled(false)
 | 
			
		||||
{
 | 
			
		||||
  //debug("cIptvDevice::cIptvDevice(%d)\n", deviceIndex);
 | 
			
		||||
  unsigned int bufsize = MEGABYTE(IptvConfig.GetTsBufferSize());
 | 
			
		||||
  bufsize -= (bufsize % TS_SIZE);
 | 
			
		||||
  isyslog("creating IPTV device %d (CardIndex=%d)", deviceIndex, CardIndex());
 | 
			
		||||
  tsBuffer = new cRingBufferLinear(MEGABYTE(IptvConfig.GetTsBufferSize()),
 | 
			
		||||
                                   (TS_SIZE * IptvConfig.GetReadBufferTsCount()),
 | 
			
		||||
                                   false, "IPTV");
 | 
			
		||||
  tsBuffer->SetTimeouts(100, 100);
 | 
			
		||||
  tsBuffer = new cRingBufferLinear(bufsize + 1, TS_SIZE, false,
 | 
			
		||||
                                   *cString::sprintf("IPTV %d", deviceIndex));
 | 
			
		||||
  tsBuffer->SetTimeouts(10, 10);
 | 
			
		||||
  ResetBuffering();
 | 
			
		||||
  pUdpProtocol = new cIptvProtocolUdp();
 | 
			
		||||
  pHttpProtocol = new cIptvProtocolHttp();
 | 
			
		||||
  pFileProtocol = new cIptvProtocolFile();
 | 
			
		||||
  pExtProtocol = new cIptvProtocolExt();
 | 
			
		||||
  pIptvStreamer = new cIptvStreamer(tsBuffer, &mutex);
 | 
			
		||||
  pIptvStreamer = new cIptvStreamer(tsBuffer, (100 * TS_SIZE));
 | 
			
		||||
  pPidScanner = new cPidScanner;
 | 
			
		||||
  // Initialize filter pointers
 | 
			
		||||
  memset(secfilters, '\0', sizeof(secfilters));
 | 
			
		||||
@@ -273,7 +272,7 @@ bool cIptvDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
 | 
			
		||||
  debug("cIptvDevice::SetChannelDevice(%d)\n", deviceIndex);
 | 
			
		||||
  location = GetChannelSettings(Channel->PluginParam(), ¶meter, &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;
 | 
			
		||||
@@ -305,7 +304,7 @@ bool cIptvDevice::DeleteFilter(unsigned int Index)
 | 
			
		||||
  return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cIptvDevice::IsBlackListed(u_short Pid, u_char Tid, u_char Mask)
 | 
			
		||||
bool cIptvDevice::IsBlackListed(u_short Pid, u_char Tid, u_char Mask) const
 | 
			
		||||
{
 | 
			
		||||
  //debug("cIptvDevice::IsBlackListed(%d) Pid=%d Tid=%02X Mask=%02X\n", deviceIndex, Pid, Tid, Mask);
 | 
			
		||||
  // loop through section filter table
 | 
			
		||||
@@ -330,11 +329,13 @@ int cIptvDevice::OpenFilter(u_short Pid, u_char Tid, u_char Mask)
 | 
			
		||||
  // Blacklist check, refuse certain filters
 | 
			
		||||
  if (IsBlackListed(Pid, Tid, Mask))
 | 
			
		||||
     return -1;
 | 
			
		||||
  // Lock
 | 
			
		||||
  cMutexLock MutexLock(&mutex);
 | 
			
		||||
  // Search the next free filter slot
 | 
			
		||||
  for (unsigned int i = 0; i < eMaxSecFilterCount; ++i) {
 | 
			
		||||
      if (!secfilters[i]) {
 | 
			
		||||
         //debug("cIptvDevice::OpenFilter(%d): Pid=%d Tid=%02X Mask=%02X Index=%d\n", deviceIndex, Pid, Tid, Mask, i);
 | 
			
		||||
         secfilters[i] = new cIptvSectionFilter(i, deviceIndex, Pid, Tid, Mask);
 | 
			
		||||
         secfilters[i] = new cIptvSectionFilter(deviceIndex, i, Pid, Tid, Mask);
 | 
			
		||||
         return secfilters[i]->GetReadDesc();
 | 
			
		||||
         }
 | 
			
		||||
      }
 | 
			
		||||
@@ -344,6 +345,9 @@ int cIptvDevice::OpenFilter(u_short Pid, u_char Tid, u_char Mask)
 | 
			
		||||
 | 
			
		||||
void cIptvDevice::CloseFilter(int Handle)
 | 
			
		||||
{
 | 
			
		||||
  // Lock
 | 
			
		||||
  cMutexLock MutexLock(&mutex);
 | 
			
		||||
  // Search the filter for deletion
 | 
			
		||||
  for (unsigned int i = 0; i < eMaxSecFilterCount; ++i) {
 | 
			
		||||
      if (secfilters[i] && (Handle == secfilters[i]->GetReadDesc())) {
 | 
			
		||||
         //debug("cIptvDevice::CloseFilter(%d): %d\n", deviceIndex, Handle);
 | 
			
		||||
@@ -356,14 +360,13 @@ void cIptvDevice::CloseFilter(int Handle)
 | 
			
		||||
bool cIptvDevice::OpenDvr(void)
 | 
			
		||||
{
 | 
			
		||||
  debug("cIptvDevice::OpenDvr(%d)\n", deviceIndex);
 | 
			
		||||
  mutex.Lock();
 | 
			
		||||
  isPacketDelivered = false;
 | 
			
		||||
  tsBuffer->Clear();
 | 
			
		||||
  mutex.Unlock();
 | 
			
		||||
  ResetBuffering();
 | 
			
		||||
  pIptvStreamer->Open();
 | 
			
		||||
  if (pIptvStreamer)
 | 
			
		||||
     pIptvStreamer->Open();
 | 
			
		||||
  if (sidScanEnabled && pSidScanner && IptvConfig.GetSectionFiltering())
 | 
			
		||||
     pSidScanner->SetStatus(true);
 | 
			
		||||
     pSidScanner->Open();
 | 
			
		||||
  isOpenDvr = true;
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
@@ -372,7 +375,7 @@ void cIptvDevice::CloseDvr(void)
 | 
			
		||||
{
 | 
			
		||||
  debug("cIptvDevice::CloseDvr(%d)\n", deviceIndex);
 | 
			
		||||
  if (sidScanEnabled && pSidScanner && IptvConfig.GetSectionFiltering())
 | 
			
		||||
     pSidScanner->SetStatus(false);
 | 
			
		||||
     pSidScanner->Close();
 | 
			
		||||
  if (pIptvStreamer)
 | 
			
		||||
     pIptvStreamer->Close();
 | 
			
		||||
  isOpenDvr = false;
 | 
			
		||||
@@ -407,7 +410,7 @@ bool cIptvDevice::GetTSPacket(uchar *&Data)
 | 
			
		||||
{
 | 
			
		||||
  int Count = 0;
 | 
			
		||||
  //debug("cIptvDevice::GetTSPacket(%d)\n", deviceIndex);
 | 
			
		||||
  if (!IsBuffering()) {
 | 
			
		||||
  if (tsBuffer && !IsBuffering()) {
 | 
			
		||||
     if (isPacketDelivered) {
 | 
			
		||||
        tsBuffer->Del(TS_SIZE);
 | 
			
		||||
        isPacketDelivered = false;
 | 
			
		||||
@@ -424,29 +427,31 @@ 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;
 | 
			
		||||
        Data = p;
 | 
			
		||||
        // Update pid statistics 
 | 
			
		||||
        // Update pid statistics
 | 
			
		||||
        AddPidStatistic(ts_pid(p), payload(p));
 | 
			
		||||
        // Send data also to dvr fifo
 | 
			
		||||
        if (dvrFd >= 0)
 | 
			
		||||
           write(dvrFd, p, TS_SIZE);
 | 
			
		||||
           Count = (int)write(dvrFd, p, TS_SIZE);
 | 
			
		||||
        // Analyze incomplete streams with built-in pid analyzer
 | 
			
		||||
        if (pidScanEnabled && pPidScanner)
 | 
			
		||||
           pPidScanner->Process(p);
 | 
			
		||||
        // Lock
 | 
			
		||||
        cMutexLock MutexLock(&mutex);
 | 
			
		||||
        // Run the data through all filters
 | 
			
		||||
        for (unsigned int i = 0; i < eMaxSecFilterCount; ++i) {
 | 
			
		||||
            if (secfilters[i])
 | 
			
		||||
               secfilters[i]->ProcessData(p);
 | 
			
		||||
               secfilters[i]->Process(p);
 | 
			
		||||
            }
 | 
			
		||||
        return true;
 | 
			
		||||
        }
 | 
			
		||||
     }
 | 
			
		||||
  // Reduce cpu load by preventing busylooping
 | 
			
		||||
  cCondWait::SleepMs(100);
 | 
			
		||||
  cCondWait::SleepMs(10);
 | 
			
		||||
  Data = NULL;
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								device.h
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								device.h
									
									
									
									
									
								
							@@ -74,7 +74,7 @@ private:
 | 
			
		||||
  void ResetBuffering(void);
 | 
			
		||||
  bool IsBuffering(void);
 | 
			
		||||
  bool DeleteFilter(unsigned int Index);
 | 
			
		||||
  bool IsBlackListed(u_short Pid, u_char Tid, u_char Mask);
 | 
			
		||||
  bool IsBlackListed(u_short Pid, u_char Tid, u_char Mask) const;
 | 
			
		||||
 | 
			
		||||
  // for channel selection
 | 
			
		||||
public:
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								iptv.c
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								iptv.c
									
									
									
									
									
								
							@@ -20,7 +20,7 @@
 | 
			
		||||
#error "VDR-1.6.0 API version or greater is required!"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static const char VERSION[]     = "0.2.2";
 | 
			
		||||
static const char VERSION[]     = "0.3.2";
 | 
			
		||||
static const char DESCRIPTION[] = trNOOP("Experience the IPTV");
 | 
			
		||||
 | 
			
		||||
class cPluginIptv : public cPlugin {
 | 
			
		||||
@@ -78,7 +78,7 @@ bool cPluginIptv::ProcessArgs(int argc, char *argv[])
 | 
			
		||||
  // Implement command line argument processing here if applicable.
 | 
			
		||||
  static const struct option long_options[] = {
 | 
			
		||||
    { "devices", required_argument, NULL, 'd' },
 | 
			
		||||
    { NULL }
 | 
			
		||||
    { NULL,      no_argument,       NULL,  0  }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
  int c;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										84
									
								
								iptv/image.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										84
									
								
								iptv/image.sh
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,84 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
# image.sh is used by the VDR iptv plugin to transcode images from
 | 
			
		||||
# a web server to provide a video stream.
 | 
			
		||||
#
 | 
			
		||||
# The script originates from Peter Holik
 | 
			
		||||
#
 | 
			
		||||
# Example channels.conf entries:
 | 
			
		||||
# Energy;IPTV:50:IPTV|S0P0|EXT|png.sh|1:P:0:256:257:0:0:3:0:0:0
 | 
			
		||||
# Temperature;IPTV:60:IPTV|S0P0|EXT|png.sh|2:P:0:256:257:0:0:3:0:0:0
 | 
			
		||||
# Temperature Week;IPTV:70:IPTV|S0P0|EXT|png.sh|3:P:0:256:257:0:0:3:0:0:0
 | 
			
		||||
# Server Temperature;IPTV:80:IPTV|S0P0|EXT|png.sh|4:P:0:256:257:0:0:3:0:0:0
 | 
			
		||||
# Server Temperature Week;IPTV:90:IPTV|S0P0|EXT|png.sh|5:P:0:256:257:0:0:3:0:0:0
 | 
			
		||||
# Traffic;IPTV:100:IPTV|S0P0|EXT|png.sh|6:P:0:256:257:0:0:3:0:0:0
 | 
			
		||||
#
 | 
			
		||||
# webcam.sh is free software; you can redistribute it and/or modify
 | 
			
		||||
# it under the terms of the GNU General Public License as published by
 | 
			
		||||
# the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
# (at your option) any later version.
 | 
			
		||||
#
 | 
			
		||||
# This package is distributed in the hope that it will be useful,
 | 
			
		||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
# GNU General Public License for more details.
 | 
			
		||||
#
 | 
			
		||||
# You should have received a copy of the GNU General Public License
 | 
			
		||||
# along with this package; if not, write to the Free Software
 | 
			
		||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
 | 
			
		||||
# MA 02110-1301, USA.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
if [ $# -ne 2 ]; then
 | 
			
		||||
    logger "$0: error: Invalid parameter count '$#' $*"
 | 
			
		||||
    exit 1
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Channels.conf parameter
 | 
			
		||||
case ${1} in
 | 
			
		||||
    1)
 | 
			
		||||
        URL="http://proxy/cgi-bin/bin/graph.cgi?hostname=proxy;plugin=energy;type=electricity"
 | 
			
		||||
        ;;
 | 
			
		||||
    2)
 | 
			
		||||
        URL="http://proxy/cgi-bin/bin/graph.cgi?hostname=proxy;plugin=temp;type=temperature;type_instance=Outdoor"
 | 
			
		||||
        ;;
 | 
			
		||||
    3)
 | 
			
		||||
        URL="http://proxy/cgi-bin/bin/graph.cgi?hostname=proxy;plugin=temp;type=temperature;type_instance=Outdoor;begin=-604800"
 | 
			
		||||
        ;;
 | 
			
		||||
    4)
 | 
			
		||||
        URL="http://proxy/cgi-bin/bin/graph.cgi?hostname=proxy;plugin=temp;type=temperature;type_instance=Server"
 | 
			
		||||
        ;;
 | 
			
		||||
    5)
 | 
			
		||||
        URL="http://proxy/cgi-bin/bin/graph.cgi?hostname=proxy;plugin=temp;type=temperature;type_instance=Server;begin=-604800"
 | 
			
		||||
        ;;
 | 
			
		||||
    6)
 | 
			
		||||
        URL="http://proxy/cgi-bin/bin/graph.cgi?hostname=proxy;plugin=interface;type=if_octets;type_instance=ppp0"
 | 
			
		||||
        ;;
 | 
			
		||||
    *)
 | 
			
		||||
        URL=""  # Default URL - TODO get dummy picture
 | 
			
		||||
        ;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
# Iptv plugin listens this port
 | 
			
		||||
PORT=${2}
 | 
			
		||||
 | 
			
		||||
# Stream temporary files
 | 
			
		||||
IMAGE=/tmp/image.png
 | 
			
		||||
LOG=/dev/null
 | 
			
		||||
 | 
			
		||||
{
 | 
			
		||||
# Using wget because ffmpeg cannot handle http/1.1 "Transfer-Encoding: chunked"
 | 
			
		||||
wget -q -O "${IMAGE}" "${URL}"
 | 
			
		||||
 | 
			
		||||
# Build stream from audiodump with cycle image as video
 | 
			
		||||
# PID 0x100/256 = Video 0x101/257 = Audio
 | 
			
		||||
exec ffmpeg -v 10 \
 | 
			
		||||
  -analyzeduration 0 \
 | 
			
		||||
  -loop_input \
 | 
			
		||||
  -i "${IMAGE}" \
 | 
			
		||||
  -f mpegts -r 25 -vcodec mpeg2video -b 4000k -s 664x540 -padleft 20 -padright 20 -padtop 16 -padbottom 20 \
 | 
			
		||||
  -an \
 | 
			
		||||
  "udp://127.0.0.1:${PORT}?pkt_size=16356"
 | 
			
		||||
} > ${LOG} 2>&1
 | 
			
		||||
@@ -27,7 +27,7 @@
 | 
			
		||||
 | 
			
		||||
if [ $# -ne 2 ]; then
 | 
			
		||||
    logger "$0: error: Invalid parameter count '$#' $*"
 | 
			
		||||
    exit 1;
 | 
			
		||||
    exit 1
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Channels.conf parameter
 | 
			
		||||
@@ -49,8 +49,8 @@ rm -f "${FIFO}"
 | 
			
		||||
mkfifo "${FIFO}"
 | 
			
		||||
 | 
			
		||||
mplayer -dumpstream "${URL}" \
 | 
			
		||||
 -quiet -nolirc -noautosub -noconsolecontrols -novideo -nojoystick \
 | 
			
		||||
 -dumpfile "$FIFO" &
 | 
			
		||||
  -quiet -nolirc -noautosub -noconsolecontrols -novideo -nojoystick \
 | 
			
		||||
  -dumpfile "$FIFO" &
 | 
			
		||||
 | 
			
		||||
# Time to connect and fill pipe
 | 
			
		||||
sleep 3 
 | 
			
		||||
@@ -58,10 +58,10 @@ sleep 3
 | 
			
		||||
# Build audio only stream
 | 
			
		||||
# PID 0x100/256 = Audio
 | 
			
		||||
ffmpeg -v -1 \
 | 
			
		||||
 -i "${FIFO}" \
 | 
			
		||||
 -title "${TITLE}" \
 | 
			
		||||
 -f mpegts -acodec mp2 -ac 2 -ab 96k -ar 48000 \
 | 
			
		||||
 - | nc -u 127.0.0.1 ${PORT}
 | 
			
		||||
  -i "${FIFO}" \
 | 
			
		||||
  -title "${TITLE}" \
 | 
			
		||||
  -f mpegts -acodec mp2 -ac 2 -ab 96k -ar 48000 \
 | 
			
		||||
  "udp://127.0.0.1:${PORT}?pkt_size=16356"
 | 
			
		||||
 | 
			
		||||
rm -f "${FIFO}"
 | 
			
		||||
} > ${LOG} 2>&1
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										76
									
								
								iptv/iptvstream-notrap.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										76
									
								
								iptv/iptvstream-notrap.sh
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,76 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
#
 | 
			
		||||
# iptvstream.sh can be used by the VDR iptv plugin to transcode external
 | 
			
		||||
# sources
 | 
			
		||||
#
 | 
			
		||||
# (C) 2007 Rolf Ahrenberg, Antti Seppälä
 | 
			
		||||
#
 | 
			
		||||
# iptvstream.sh is free software; you can redistribute it and/or modify
 | 
			
		||||
# it under the terms of the GNU General Public License as published by
 | 
			
		||||
# the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
# (at your option) any later version.
 | 
			
		||||
#
 | 
			
		||||
# This package is distributed in the hope that it will be useful,
 | 
			
		||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
# GNU General Public License for more details.
 | 
			
		||||
#
 | 
			
		||||
# You should have received a copy of the GNU General Public License
 | 
			
		||||
# along with this package; if not, write to the Free Software
 | 
			
		||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
 | 
			
		||||
# MA 02110-1301, USA.
 | 
			
		||||
 | 
			
		||||
if [ $# -ne 2 ]; then
 | 
			
		||||
    logger "$0: error: Invalid parameter count '$#' $*"
 | 
			
		||||
    exit 1
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Channels.conf parameter
 | 
			
		||||
PARAMETER=${1}
 | 
			
		||||
 | 
			
		||||
# Iptv plugin listens this port
 | 
			
		||||
PORT=${2}
 | 
			
		||||
 | 
			
		||||
# Default settings for stream transcoding
 | 
			
		||||
VCODEC=mp2v
 | 
			
		||||
VBITRATE=2400
 | 
			
		||||
ACODEC=mpga
 | 
			
		||||
ABITRATE=320
 | 
			
		||||
 | 
			
		||||
# There is a way to specify multiple URLs in the same script. The selection is
 | 
			
		||||
# then controlled by the extra parameter passed by IPTV plugin to the script
 | 
			
		||||
case ${PARAMETER} in
 | 
			
		||||
    1)
 | 
			
		||||
        URL=""
 | 
			
		||||
        WIDTH=720
 | 
			
		||||
        HEIGHT=576
 | 
			
		||||
        ;;
 | 
			
		||||
    2)
 | 
			
		||||
        URL=""
 | 
			
		||||
        ;;
 | 
			
		||||
    3)
 | 
			
		||||
        URL=""
 | 
			
		||||
        ;;
 | 
			
		||||
    *)
 | 
			
		||||
        URL=""  # Default URL
 | 
			
		||||
        ;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
if [ -z "${URL}" ]; then
 | 
			
		||||
    logger "$0: error: URL not defined!"
 | 
			
		||||
    exit 1
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Create transcoding options
 | 
			
		||||
TRANSCODE_OPTS="vcodec=${VCODEC},acodec=${ACODEC},vb=${VBITRATE},ab=${ABITRATE}"
 | 
			
		||||
if [ -n "${WIDTH}" -a -n "${HEIGHT}" ] ; then
 | 
			
		||||
    TRANSCODE_OPTS="${TRANSCODE_OPTS},width=${WIDTH},height=${HEIGHT}"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Create unique pids for the stream
 | 
			
		||||
let VPID=${PARAMETER}+1
 | 
			
		||||
let APID=${PARAMETER}+2
 | 
			
		||||
let SPID=${PARAMETER}+3
 | 
			
		||||
 | 
			
		||||
# Execute VLC
 | 
			
		||||
exec vlc "${URL}" --sout "#transcode{${TRANSCODE_OPTS}}:standard{access=udp,mux=ts{pid-video=${VPID},pid-audio=${APID},pid-spu=${SPID}},dst=127.0.0.1:${PORT}}" --intf dummy
 | 
			
		||||
@@ -22,7 +22,7 @@
 | 
			
		||||
 | 
			
		||||
if [ $# -ne 2 ]; then
 | 
			
		||||
    logger "$0: error: Invalid parameter count '$#' $*"
 | 
			
		||||
    exit 1;
 | 
			
		||||
    exit 1
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Channels.conf parameter
 | 
			
		||||
@@ -41,24 +41,24 @@ ABITRATE=320
 | 
			
		||||
# then controlled by the extra parameter passed by IPTV plugin to the script
 | 
			
		||||
case ${PARAMETER} in
 | 
			
		||||
    1)
 | 
			
		||||
	URL=""
 | 
			
		||||
	WIDTH=720
 | 
			
		||||
	HEIGHT=576
 | 
			
		||||
	;;
 | 
			
		||||
        URL=""
 | 
			
		||||
        WIDTH=720
 | 
			
		||||
        HEIGHT=576
 | 
			
		||||
        ;;
 | 
			
		||||
    2)
 | 
			
		||||
	URL=""
 | 
			
		||||
	;;
 | 
			
		||||
        URL=""
 | 
			
		||||
        ;;
 | 
			
		||||
    3)
 | 
			
		||||
	URL=""
 | 
			
		||||
	;;
 | 
			
		||||
        URL=""
 | 
			
		||||
        ;;
 | 
			
		||||
    *)
 | 
			
		||||
	URL=""  # Default URL
 | 
			
		||||
	;;
 | 
			
		||||
        URL=""  # Default URL
 | 
			
		||||
        ;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
if [ -z "${URL}" ]; then
 | 
			
		||||
    logger "$0: error: URL not defined!"
 | 
			
		||||
    exit 1;
 | 
			
		||||
    exit 1
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Create transcoding options
 | 
			
		||||
 
 | 
			
		||||
@@ -27,7 +27,7 @@
 | 
			
		||||
 | 
			
		||||
if [ $# -ne 2 ]; then
 | 
			
		||||
    logger "$0: error: Invalid parameter count '$#' $*"
 | 
			
		||||
    exit 1;
 | 
			
		||||
    exit 1
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Channels.conf parameter
 | 
			
		||||
@@ -46,9 +46,9 @@ LOG=/dev/null
 | 
			
		||||
# PID 0x100/256 = Audio
 | 
			
		||||
arecord -q -D hw:0,0 -f dat | \
 | 
			
		||||
ffmpeg -v -1 \
 | 
			
		||||
 -f wav \
 | 
			
		||||
 -i - \
 | 
			
		||||
 -title "${TITLE}" \
 | 
			
		||||
 -f mpegts -acodec mp2 -ac 2 -ab 128k -ar 48000 \
 | 
			
		||||
 - | nc -nu 127.0.0.1 ${PORT}
 | 
			
		||||
  -f wav \
 | 
			
		||||
  -i - \
 | 
			
		||||
  -title "${TITLE}" \
 | 
			
		||||
  -f mpegts -acodec mp2 -ac 2 -ab 128k -ar 48000 \
 | 
			
		||||
  "udp://127.0.0.1:${PORT}?pkt_size=16356"
 | 
			
		||||
} > ${LOG} 2>&1
 | 
			
		||||
 
 | 
			
		||||
@@ -37,7 +37,7 @@ AUDIO_BITRATE=320
 | 
			
		||||
exit_with_error()
 | 
			
		||||
{
 | 
			
		||||
    logger "vlc2iptv: error: $*"
 | 
			
		||||
    exit 1;
 | 
			
		||||
    exit 1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
read_arguments()
 | 
			
		||||
 
 | 
			
		||||
@@ -27,7 +27,7 @@
 | 
			
		||||
 | 
			
		||||
if [ $# -ne 2 ]; then
 | 
			
		||||
    logger "$0: error: Invalid parameter count '$#' $*"
 | 
			
		||||
    exit 1;
 | 
			
		||||
    exit 1
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Channels.conf parameter
 | 
			
		||||
@@ -50,8 +50,8 @@ rm -f "${FIFO}"
 | 
			
		||||
mkfifo "${FIFO}"
 | 
			
		||||
 | 
			
		||||
mplayer -dumpstream "${URL}" \
 | 
			
		||||
 -quiet -nolirc -noautosub -noconsolecontrols -novideo -nojoystick \
 | 
			
		||||
 -dumpfile "${FIFO}" &
 | 
			
		||||
  -quiet -nolirc -noautosub -noconsolecontrols -novideo -nojoystick \
 | 
			
		||||
  -dumpfile "${FIFO}" &
 | 
			
		||||
 | 
			
		||||
# Time to connect and fill pipe
 | 
			
		||||
sleep 3 
 | 
			
		||||
@@ -59,11 +59,11 @@ sleep 3
 | 
			
		||||
# Build stream from audiodump with cycle image as video
 | 
			
		||||
# PID 0x100/256 = Video 0x101/257 = Audio
 | 
			
		||||
ffmpeg -v -1 \
 | 
			
		||||
 -i "${FIFO}" -r 0.5 -loop_input -i '${IMAGE}' \
 | 
			
		||||
 -title "${TITLE}" \
 | 
			
		||||
 -f mpegts -intra -r 24 -vcodec mpeg2video -b 500k -s 352x288 \
 | 
			
		||||
 -acodec mp2 -ac 2 -ab 96k -ar 48000 \
 | 
			
		||||
 - | nc -u 127.0.0.1 ${PORT}
 | 
			
		||||
  -i "${FIFO}" -r 0.5 -loop_input -i '${IMAGE}' \
 | 
			
		||||
  -title "${TITLE}" \
 | 
			
		||||
  -f mpegts -intra -r 24 -vcodec mpeg2video -b 500k -s 352x288 \
 | 
			
		||||
  -acodec mp2 -ac 2 -ab 96k -ar 48000 \
 | 
			
		||||
  "udp://127.0.0.1:${PORT}?pkt_size=16356"
 | 
			
		||||
 | 
			
		||||
rm -f "${FIFO}"
 | 
			
		||||
} > ${LOG} 2>&1
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										11
									
								
								patches/vdr-1.6.0-disable_ca_updates.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								patches/vdr-1.6.0-disable_ca_updates.patch
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
diff -Nru vdr-1.6.0-vanilla/pat.c vdr-1.6.0-disable-ca-updates/pat.c
 | 
			
		||||
--- vdr-1.6.0-vanilla/pat.c	2008-02-08 15:48:31.000000000 +0200
 | 
			
		||||
+++ vdr-1.6.0-disable-ca-updates/pat.c	2009-03-07 14:56:42.000000000 +0200
 | 
			
		||||
@@ -440,6 +440,7 @@
 | 
			
		||||
             }
 | 
			
		||||
         if (Setup.UpdateChannels >= 2) {
 | 
			
		||||
            Channel->SetPids(Vpid, Vpid ? Ppid : 0, Apids, ALangs, Dpids, DLangs, Spids, SLangs, Tpid);
 | 
			
		||||
+           if (!Channel->IsPlug())
 | 
			
		||||
            Channel->SetCaIds(CaDescriptors->CaIds());
 | 
			
		||||
            }
 | 
			
		||||
         Channel->SetCaDescriptors(CaDescriptorHandler.AddCaDescriptors(CaDescriptors));
 | 
			
		||||
							
								
								
									
										12
									
								
								patches/vdr-1.6.0-disable_eitscan.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								patches/vdr-1.6.0-disable_eitscan.patch
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
diff -Nru vdr-1.6.0-vanilla/eitscan.c vdr-1.6.0-disable_eitscan/eitscan.c
 | 
			
		||||
--- vdr-1.6.0-vanilla/eitscan.c	2006-01-07 16:10:17.000000000 +0200
 | 
			
		||||
+++ vdr-1.6.0-disable_eitscan/eitscan.c	2009-06-17 16:04:23.000000000 +0300
 | 
			
		||||
@@ -146,7 +146,7 @@
 | 
			
		||||
                if (Device) {
 | 
			
		||||
                   for (cScanData *ScanData = scanList->First(); ScanData; ScanData = scanList->Next(ScanData)) {
 | 
			
		||||
                       const cChannel *Channel = ScanData->GetChannel();
 | 
			
		||||
-                      if (Channel) {
 | 
			
		||||
+                      if (Channel && !Channel->IsPlug()) {
 | 
			
		||||
                          if (!Channel->Ca() || Channel->Ca() == Device->DeviceNumber() + 1 || Channel->Ca() >= CA_ENCRYPTED_MIN) {
 | 
			
		||||
                             if (Device->ProvidesTransponder(Channel)) {
 | 
			
		||||
                                if (!Device->Receiving()) {
 | 
			
		||||
							
								
								
									
										11
									
								
								patches/vdr-1.7.12-disable_ca_updates.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								patches/vdr-1.7.12-disable_ca_updates.patch
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
diff -Nru vdr-1.7.12-vanilla/pat.c vdr-1.7.12-disable_ca_updates/pat.c
 | 
			
		||||
--- vdr-1.7.12-vanilla/pat.c	2010-02-01 11:45:40.000000000 +0200
 | 
			
		||||
+++ vdr-1.7.12-disable_ca_updates/pat.c	2010-02-01 13:54:32.000000000 +0200
 | 
			
		||||
@@ -458,6 +458,7 @@
 | 
			
		||||
             }
 | 
			
		||||
         if (Setup.UpdateChannels >= 2) {
 | 
			
		||||
            Channel->SetPids(Vpid, Ppid, Vtype, Apids, ALangs, Dpids, DLangs, Spids, SLangs, Tpid);
 | 
			
		||||
+           if (!Channel->IsPlug())
 | 
			
		||||
            Channel->SetCaIds(CaDescriptors->CaIds());
 | 
			
		||||
            Channel->SetSubtitlingDescriptors(SubtitlingTypes, CompositionPageIds, AncillaryPageIds);
 | 
			
		||||
            }
 | 
			
		||||
							
								
								
									
										12
									
								
								patches/vdr-1.7.12-disable_eitscan.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								patches/vdr-1.7.12-disable_eitscan.patch
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
diff -Nru vdr-1.7.12-vanilla/eitscan.c vdr-1.7.12-disable_eitscan/eitscan.c
 | 
			
		||||
--- vdr-1.7.12-vanilla/eitscan.c	2010-02-01 11:45:39.000000000 +0200
 | 
			
		||||
+++ vdr-1.7.12-disable_eitscan/eitscan.c	2010-02-01 13:54:20.000000000 +0200
 | 
			
		||||
@@ -146,7 +146,7 @@
 | 
			
		||||
                if (Device) {
 | 
			
		||||
                   for (cScanData *ScanData = scanList->First(); ScanData; ScanData = scanList->Next(ScanData)) {
 | 
			
		||||
                       const cChannel *Channel = ScanData->GetChannel();
 | 
			
		||||
-                      if (Channel) {
 | 
			
		||||
+                      if (Channel && !Channel->IsPlug()) {
 | 
			
		||||
                          if (!Channel->Ca() || Channel->Ca() == Device->DeviceNumber() + 1 || Channel->Ca() >= CA_ENCRYPTED_MIN) {
 | 
			
		||||
                             if (Device->ProvidesTransponder(Channel)) {
 | 
			
		||||
                                if (!Device->Receiving()) {
 | 
			
		||||
@@ -1,15 +1,15 @@
 | 
			
		||||
diff -Nru vdr-1.7.0-vanilla/channels.c vdr-1.7.0-pluginparam/channels.c
 | 
			
		||||
--- vdr-1.7.0-vanilla/channels.c	2008-04-12 16:49:12.000000000 +0300
 | 
			
		||||
+++ vdr-1.7.0-pluginparam/channels.c	2008-04-13 18:58:41.000000000 +0300
 | 
			
		||||
@@ -216,6 +216,7 @@
 | 
			
		||||
diff -Nru vdr-1.7.12-vanilla/channels.c vdr-1.7.12-pluginparam/channels.c
 | 
			
		||||
--- vdr-1.7.12-vanilla/channels.c	2010-02-01 11:45:39.000000000 +0200
 | 
			
		||||
+++ vdr-1.7.12-pluginparam/channels.c	2010-02-01 13:52:56.000000000 +0200
 | 
			
		||||
@@ -188,6 +188,7 @@
 | 
			
		||||
   shortName = strdup("");
 | 
			
		||||
   provider = strdup("");
 | 
			
		||||
   portalName = strdup("");
 | 
			
		||||
+  pluginParam = strdup("");
 | 
			
		||||
   memset(&__BeginData__, 0, (char *)&__EndData__ - (char *)&__BeginData__);
 | 
			
		||||
   inversion    = DVBFE_INVERSION_AUTO;
 | 
			
		||||
   bandwidth    = DVBFE_BANDWIDTH_AUTO;
 | 
			
		||||
@@ -241,6 +242,7 @@
 | 
			
		||||
   inversion    = INVERSION_AUTO;
 | 
			
		||||
   bandwidth    = 8000000;
 | 
			
		||||
@@ -211,6 +212,7 @@
 | 
			
		||||
   shortName = NULL;
 | 
			
		||||
   provider = NULL;
 | 
			
		||||
   portalName = NULL;
 | 
			
		||||
@@ -17,7 +17,7 @@ diff -Nru vdr-1.7.0-vanilla/channels.c vdr-1.7.0-pluginparam/channels.c
 | 
			
		||||
   schedule     = NULL;
 | 
			
		||||
   linkChannels = NULL;
 | 
			
		||||
   refChannel   = NULL;
 | 
			
		||||
@@ -269,6 +271,7 @@
 | 
			
		||||
@@ -239,6 +241,7 @@
 | 
			
		||||
   free(shortName);
 | 
			
		||||
   free(provider);
 | 
			
		||||
   free(portalName);
 | 
			
		||||
@@ -25,7 +25,7 @@ diff -Nru vdr-1.7.0-vanilla/channels.c vdr-1.7.0-pluginparam/channels.c
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 cChannel& cChannel::operator= (const cChannel &Channel)
 | 
			
		||||
@@ -277,6 +280,7 @@
 | 
			
		||||
@@ -247,6 +250,7 @@
 | 
			
		||||
   shortName = strcpyrealloc(shortName, Channel.shortName);
 | 
			
		||||
   provider = strcpyrealloc(provider, Channel.provider);
 | 
			
		||||
   portalName = strcpyrealloc(portalName, Channel.portalName);
 | 
			
		||||
@@ -33,9 +33,9 @@ diff -Nru vdr-1.7.0-vanilla/channels.c vdr-1.7.0-pluginparam/channels.c
 | 
			
		||||
   memcpy(&__BeginData__, &Channel.__BeginData__, (char *)&Channel.__EndData__ - (char *)&Channel.__BeginData__);
 | 
			
		||||
   return *this;
 | 
			
		||||
 }
 | 
			
		||||
@@ -338,9 +342,26 @@
 | 
			
		||||
      alpha        = Channel->alpha;
 | 
			
		||||
      priority     = Channel->priority;
 | 
			
		||||
@@ -307,9 +311,26 @@
 | 
			
		||||
      guard        = Channel->guard;
 | 
			
		||||
      hierarchy    = Channel->hierarchy;
 | 
			
		||||
      rollOff      = Channel->rollOff;
 | 
			
		||||
+     if (IsPlug())  pluginParam = strcpyrealloc(pluginParam, Channel->pluginParam);
 | 
			
		||||
      }
 | 
			
		||||
@@ -60,7 +60,7 @@ diff -Nru vdr-1.7.0-vanilla/channels.c vdr-1.7.0-pluginparam/channels.c
 | 
			
		||||
 bool cChannel::SetSatTransponderData(int Source, int Frequency, char Polarization, int Srate, int CoderateH, int Modulation, int System, int RollOff)
 | 
			
		||||
 {
 | 
			
		||||
   // Workarounds for broadcaster stupidity:
 | 
			
		||||
@@ -472,6 +493,18 @@
 | 
			
		||||
@@ -439,6 +460,18 @@
 | 
			
		||||
      }
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
@@ -79,7 +79,7 @@ diff -Nru vdr-1.7.0-vanilla/channels.c vdr-1.7.0-pluginparam/channels.c
 | 
			
		||||
 #define STRDIFF 0x01
 | 
			
		||||
 #define VALDIFF 0x02
 | 
			
		||||
 
 | 
			
		||||
@@ -665,7 +698,7 @@
 | 
			
		||||
@@ -652,7 +685,7 @@
 | 
			
		||||
   if (isdigit(type))
 | 
			
		||||
      type = 'S';
 | 
			
		||||
 #define ST(s) if (strchr(s, type))
 | 
			
		||||
@@ -88,7 +88,7 @@ diff -Nru vdr-1.7.0-vanilla/channels.c vdr-1.7.0-pluginparam/channels.c
 | 
			
		||||
   char *q = buffer;
 | 
			
		||||
   *q = 0;
 | 
			
		||||
   ST(" S ")  q += sprintf(q, "%c", polarization);
 | 
			
		||||
@@ -681,6 +714,7 @@
 | 
			
		||||
@@ -666,6 +699,7 @@
 | 
			
		||||
   ST(" S ")  q += PrintParameter(q, 'S', MapToUser(system, SystemValues));
 | 
			
		||||
   ST("  T")  q += PrintParameter(q, 'T', MapToUser(transmission, TransmissionValues));
 | 
			
		||||
   ST("  T")  q += PrintParameter(q, 'Y', MapToUser(hierarchy, HierarchyValues));
 | 
			
		||||
@@ -96,25 +96,25 @@ diff -Nru vdr-1.7.0-vanilla/channels.c vdr-1.7.0-pluginparam/channels.c
 | 
			
		||||
   return buffer;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
@@ -702,7 +736,7 @@
 | 
			
		||||
@@ -694,7 +728,7 @@
 | 
			
		||||
 
 | 
			
		||||
 bool cChannel::StringToParameters(const char *s)
 | 
			
		||||
 {
 | 
			
		||||
-  while (s && *s) {
 | 
			
		||||
+  while (s && *s && !IsPlug()) {
 | 
			
		||||
         switch (toupper(*s)) {
 | 
			
		||||
           case 'A': s = ParseParameter(s, alpha, AlphaValues); break;
 | 
			
		||||
           case 'A': s = SkipDigits(s); break; // for compatibility with the "multiproto" approach - may be removed in future versions
 | 
			
		||||
           case 'B': s = ParseParameter(s, bandwidth, BandwidthValues); break;
 | 
			
		||||
@@ -817,7 +851,7 @@
 | 
			
		||||
@@ -814,7 +848,7 @@
 | 
			
		||||
         dpids[0] = 0;
 | 
			
		||||
         ok = false;
 | 
			
		||||
         if (parambuf && sourcebuf && vpidbuf && apidbuf) {
 | 
			
		||||
-           ok = StringToParameters(parambuf) && (source = cSource::FromString(sourcebuf)) >= 0;
 | 
			
		||||
+           ok = ((source = cSource::FromString(sourcebuf)) >= 0) && StringToParameters(parambuf);
 | 
			
		||||
 
 | 
			
		||||
            char *p = strchr(vpidbuf, '+');
 | 
			
		||||
            if (p)
 | 
			
		||||
@@ -908,6 +942,7 @@
 | 
			
		||||
            char *p;
 | 
			
		||||
            if ((p = strchr(vpidbuf, '=')) != NULL) {
 | 
			
		||||
@@ -911,6 +945,7 @@
 | 
			
		||||
            shortName = strcpyrealloc(shortName, p);
 | 
			
		||||
            }
 | 
			
		||||
         name = strcpyrealloc(name, namebuf);
 | 
			
		||||
@@ -122,10 +122,10 @@ diff -Nru vdr-1.7.0-vanilla/channels.c vdr-1.7.0-pluginparam/channels.c
 | 
			
		||||
 
 | 
			
		||||
         free(parambuf);
 | 
			
		||||
         free(sourcebuf);
 | 
			
		||||
diff -Nru vdr-1.7.0-vanilla/channels.h vdr-1.7.0-pluginparam/channels.h
 | 
			
		||||
--- vdr-1.7.0-vanilla/channels.h	2008-04-12 16:46:50.000000000 +0300
 | 
			
		||||
+++ vdr-1.7.0-pluginparam/channels.h	2008-04-13 18:57:08.000000000 +0300
 | 
			
		||||
@@ -118,6 +118,7 @@
 | 
			
		||||
diff -Nru vdr-1.7.12-vanilla/channels.h vdr-1.7.12-pluginparam/channels.h
 | 
			
		||||
--- vdr-1.7.12-vanilla/channels.h	2010-02-01 11:45:39.000000000 +0200
 | 
			
		||||
+++ vdr-1.7.12-pluginparam/channels.h	2010-02-01 13:52:56.000000000 +0200
 | 
			
		||||
@@ -116,6 +116,7 @@
 | 
			
		||||
   char *shortName;
 | 
			
		||||
   char *provider;
 | 
			
		||||
   char *portalName;
 | 
			
		||||
@@ -141,7 +141,7 @@ diff -Nru vdr-1.7.0-vanilla/channels.h vdr-1.7.0-pluginparam/channels.h
 | 
			
		||||
   int Source(void) const { return source; }
 | 
			
		||||
   int Srate(void) const { return srate; }
 | 
			
		||||
   int Vpid(void) const { return vpid; }
 | 
			
		||||
@@ -212,6 +214,7 @@
 | 
			
		||||
@@ -214,6 +216,7 @@
 | 
			
		||||
   int RollOff(void) const { return rollOff; }
 | 
			
		||||
   const cLinkChannels* LinkChannels(void) const { return linkChannels; }
 | 
			
		||||
   const cChannel *RefChannel(void) const { return refChannel; }
 | 
			
		||||
@@ -149,37 +149,37 @@ diff -Nru vdr-1.7.0-vanilla/channels.h vdr-1.7.0-pluginparam/channels.h
 | 
			
		||||
   bool IsCable(void) const { return cSource::IsCable(source); }
 | 
			
		||||
   bool IsSat(void) const { return cSource::IsSat(source); }
 | 
			
		||||
   bool IsTerr(void) const { return cSource::IsTerr(source); }
 | 
			
		||||
@@ -219,12 +222,14 @@
 | 
			
		||||
@@ -221,12 +224,14 @@
 | 
			
		||||
   bool HasTimer(void) const;
 | 
			
		||||
   int Modification(int Mask = CHANNELMOD_ALL);
 | 
			
		||||
   void CopyTransponderData(const cChannel *Channel);
 | 
			
		||||
+  bool SetPlugTransponderData(int Source, int Frequency, const char *PluginParam);
 | 
			
		||||
   bool SetSatTransponderData(int Source, int Frequency, char Polarization, int Srate, int CoderateH, int Modulation, int System, int RollOff);
 | 
			
		||||
   bool SetCableTransponderData(int Source, int Frequency, int Modulation, int Srate, int CoderateH);
 | 
			
		||||
   bool SetTerrTransponderData(int Source, int Frequency, int Bandwidth, int Modulation, int Hierarchy, int CodeRateH, int CodeRateL, int Guard, int Transmission, int Alpha, int Priority);
 | 
			
		||||
   bool SetTerrTransponderData(int Source, int Frequency, int Bandwidth, int Modulation, int Hierarchy, int CodeRateH, int CodeRateL, int Guard, int Transmission);
 | 
			
		||||
   void SetId(int Nid, int Tid, int Sid, int Rid = 0);
 | 
			
		||||
   void SetName(const char *Name, const char *ShortName, const char *Provider);
 | 
			
		||||
   void SetPortalName(const char *PortalName);
 | 
			
		||||
+  void SetPluginParam(const char *PluginParam);
 | 
			
		||||
   void SetPids(int Vpid, int Ppid, int *Apids, char ALangs[][MAXLANGCODE2], int *Dpids, char DLangs[][MAXLANGCODE2], int *Spids, char SLangs[][MAXLANGCODE2], int Tpid);
 | 
			
		||||
   void SetPids(int Vpid, int Ppid, int Vtype, int *Apids, char ALangs[][MAXLANGCODE2], int *Dpids, char DLangs[][MAXLANGCODE2], int *Spids, char SLangs[][MAXLANGCODE2], int Tpid);
 | 
			
		||||
   void SetCaIds(const int *CaIds); // list must be zero-terminated
 | 
			
		||||
   void SetCaDescriptors(int Level);
 | 
			
		||||
diff -Nru vdr-1.7.0-vanilla/config.h vdr-1.7.0-pluginparam/config.h
 | 
			
		||||
--- vdr-1.7.0-vanilla/config.h	2008-04-12 16:02:10.000000000 +0300
 | 
			
		||||
+++ vdr-1.7.0-pluginparam/config.h	2008-04-13 18:54:25.000000000 +0300
 | 
			
		||||
diff -Nru vdr-1.7.12-vanilla/config.h vdr-1.7.12-pluginparam/config.h
 | 
			
		||||
--- vdr-1.7.12-vanilla/config.h	2010-02-01 11:45:39.000000000 +0200
 | 
			
		||||
+++ vdr-1.7.12-pluginparam/config.h	2010-02-01 13:52:56.000000000 +0200
 | 
			
		||||
@@ -30,6 +30,8 @@
 | 
			
		||||
 #define APIVERSION  "1.7.0"
 | 
			
		||||
 #define APIVERSNUM   10700  // Version * 10000 + Major * 100 + Minor
 | 
			
		||||
 #define APIVERSION  "1.7.12"
 | 
			
		||||
 #define APIVERSNUM   10712  // Version * 10000 + Major * 100 + Minor
 | 
			
		||||
 
 | 
			
		||||
+#define PLUGINPARAMPATCHVERSNUM 1
 | 
			
		||||
+
 | 
			
		||||
 // When loading plugins, VDR searches them by their APIVERSION, which
 | 
			
		||||
 // may be smaller than VDRVERSION in case there have been no changes to
 | 
			
		||||
 // VDR header files since the last APIVERSION. This allows compiled
 | 
			
		||||
diff -Nru vdr-1.7.0-vanilla/menu.c vdr-1.7.0-pluginparam/menu.c
 | 
			
		||||
--- vdr-1.7.0-vanilla/menu.c	2008-04-12 14:37:17.000000000 +0300
 | 
			
		||||
+++ vdr-1.7.0-pluginparam/menu.c	2008-04-13 18:56:07.000000000 +0300
 | 
			
		||||
@@ -189,6 +189,7 @@
 | 
			
		||||
diff -Nru vdr-1.7.12-vanilla/menu.c vdr-1.7.12-pluginparam/menu.c
 | 
			
		||||
--- vdr-1.7.12-vanilla/menu.c	2010-02-01 11:45:39.000000000 +0200
 | 
			
		||||
+++ vdr-1.7.12-pluginparam/menu.c	2010-02-01 13:52:56.000000000 +0200
 | 
			
		||||
@@ -190,6 +190,7 @@
 | 
			
		||||
   cChannel *channel;
 | 
			
		||||
   cChannel data;
 | 
			
		||||
   char name[256];
 | 
			
		||||
@@ -187,7 +187,7 @@ diff -Nru vdr-1.7.0-vanilla/menu.c vdr-1.7.0-pluginparam/menu.c
 | 
			
		||||
   void Setup(void);
 | 
			
		||||
 public:
 | 
			
		||||
   cMenuEditChannel(cChannel *Channel, bool New = false);
 | 
			
		||||
@@ -221,6 +222,7 @@
 | 
			
		||||
@@ -222,6 +223,7 @@
 | 
			
		||||
 
 | 
			
		||||
   // Parameters for all types of sources:
 | 
			
		||||
   strn0cpy(name, data.name, sizeof(name));
 | 
			
		||||
@@ -195,15 +195,15 @@ diff -Nru vdr-1.7.0-vanilla/menu.c vdr-1.7.0-pluginparam/menu.c
 | 
			
		||||
   Add(new cMenuEditStrItem( tr("Name"),          name, sizeof(name)));
 | 
			
		||||
   Add(new cMenuEditSrcItem( tr("Source"),       &data.source));
 | 
			
		||||
   Add(new cMenuEditIntItem( tr("Frequency"),    &data.frequency));
 | 
			
		||||
@@ -255,6 +257,7 @@
 | 
			
		||||
   ST("  T")  Add(new cMenuEditMapItem( tr("Alpha"),        &data.alpha,        AlphaValues));
 | 
			
		||||
   ST("  T")  Add(new cMenuEditMapItem( tr("Priority"),     &data.priority,     PriorityValues));
 | 
			
		||||
@@ -254,6 +256,7 @@
 | 
			
		||||
   ST("  T")  Add(new cMenuEditMapItem( tr("Guard"),        &data.guard,        GuardValues));
 | 
			
		||||
   ST("  T")  Add(new cMenuEditMapItem( tr("Hierarchy"),    &data.hierarchy,    HierarchyValues));
 | 
			
		||||
   ST(" S ")  Add(new cMenuEditMapItem( tr("Rolloff"),      &data.rollOff,      RollOffValues));
 | 
			
		||||
+  ST("P  ")  Add(new cMenuEditStrItem( tr("Parameters"),    pluginParam, sizeof(pluginParam), tr(FileNameChars)));
 | 
			
		||||
 
 | 
			
		||||
   SetCurrent(Get(current));
 | 
			
		||||
   Display();
 | 
			
		||||
@@ -269,6 +272,7 @@
 | 
			
		||||
@@ -268,6 +271,7 @@
 | 
			
		||||
      if (Key == kOk) {
 | 
			
		||||
         if (Channels.HasUniqueChannelID(&data, channel)) {
 | 
			
		||||
            data.name = strcpyrealloc(data.name, name);
 | 
			
		||||
@@ -211,29 +211,29 @@ diff -Nru vdr-1.7.0-vanilla/menu.c vdr-1.7.0-pluginparam/menu.c
 | 
			
		||||
            if (channel) {
 | 
			
		||||
               *channel = data;
 | 
			
		||||
               isyslog("edited channel %d %s", channel->Number(), *data.ToText());
 | 
			
		||||
diff -Nru vdr-1.7.0-vanilla/po/fi_FI.po vdr-1.7.0-pluginparam/po/fi_FI.po
 | 
			
		||||
--- vdr-1.7.0-vanilla/po/fi_FI.po	2008-04-13 17:16:58.000000000 +0300
 | 
			
		||||
+++ vdr-1.7.0-pluginparam/po/fi_FI.po	2008-04-13 18:54:25.000000000 +0300
 | 
			
		||||
@@ -1019,3 +1019,6 @@
 | 
			
		||||
diff -Nru vdr-1.7.12-vanilla/po/fi_FI.po vdr-1.7.12-pluginparam/po/fi_FI.po
 | 
			
		||||
--- vdr-1.7.12-vanilla/po/fi_FI.po	2010-02-01 11:45:40.000000000 +0200
 | 
			
		||||
+++ vdr-1.7.12-pluginparam/po/fi_FI.po	2010-02-01 13:52:56.000000000 +0200
 | 
			
		||||
@@ -1306,3 +1306,6 @@
 | 
			
		||||
 #, c-format
 | 
			
		||||
 msgid "VDR will shut down in %s minutes"
 | 
			
		||||
 msgstr "VDR sammuu %s minuutin kuluttua"
 | 
			
		||||
+
 | 
			
		||||
+msgid "Parameters"
 | 
			
		||||
+msgstr "Parametrit"
 | 
			
		||||
diff -Nru vdr-1.7.0-vanilla/po/fr_FR.po vdr-1.7.0-pluginparam/po/fr_FR.po
 | 
			
		||||
--- vdr-1.7.0-vanilla/po/fr_FR.po	2008-04-13 17:16:58.000000000 +0300
 | 
			
		||||
+++ vdr-1.7.0-pluginparam/po/fr_FR.po	2008-04-13 18:54:25.000000000 +0300
 | 
			
		||||
@@ -1022,3 +1022,6 @@
 | 
			
		||||
diff -Nru vdr-1.7.12-vanilla/po/fr_FR.po vdr-1.7.12-pluginparam/po/fr_FR.po
 | 
			
		||||
--- vdr-1.7.12-vanilla/po/fr_FR.po	2010-02-01 11:45:40.000000000 +0200
 | 
			
		||||
+++ vdr-1.7.12-pluginparam/po/fr_FR.po	2010-02-01 13:52:56.000000000 +0200
 | 
			
		||||
@@ -1309,3 +1309,6 @@
 | 
			
		||||
 #, c-format
 | 
			
		||||
 msgid "VDR will shut down in %s minutes"
 | 
			
		||||
 msgstr "VDR s'arrêtera dans %s minutes"
 | 
			
		||||
+
 | 
			
		||||
+msgid "Parameters"
 | 
			
		||||
+msgstr "Paramètres"
 | 
			
		||||
diff -Nru vdr-1.7.0-vanilla/sources.c vdr-1.7.0-pluginparam/sources.c
 | 
			
		||||
--- vdr-1.7.0-vanilla/sources.c	2008-02-10 16:07:26.000000000 +0200
 | 
			
		||||
+++ vdr-1.7.0-pluginparam/sources.c	2008-04-13 18:54:25.000000000 +0300
 | 
			
		||||
diff -Nru vdr-1.7.12-vanilla/sources.c vdr-1.7.12-pluginparam/sources.c
 | 
			
		||||
--- vdr-1.7.12-vanilla/sources.c	2010-02-01 11:45:40.000000000 +0200
 | 
			
		||||
+++ vdr-1.7.12-pluginparam/sources.c	2010-02-01 13:52:56.000000000 +0200
 | 
			
		||||
@@ -37,6 +37,7 @@
 | 
			
		||||
   char buffer[16];
 | 
			
		||||
   char *q = buffer;
 | 
			
		||||
@@ -250,10 +250,10 @@ diff -Nru vdr-1.7.0-vanilla/sources.c vdr-1.7.0-pluginparam/sources.c
 | 
			
		||||
     case 'C': type = stCable; break;
 | 
			
		||||
     case 'S': type = stSat;   break;
 | 
			
		||||
     case 'T': type = stTerr;  break;
 | 
			
		||||
diff -Nru vdr-1.7.0-vanilla/sources.conf vdr-1.7.0-pluginparam/sources.conf
 | 
			
		||||
--- vdr-1.7.0-vanilla/sources.conf	2007-02-17 18:15:13.000000000 +0200
 | 
			
		||||
+++ vdr-1.7.0-pluginparam/sources.conf	2008-04-13 18:54:25.000000000 +0300
 | 
			
		||||
@@ -188,3 +188,7 @@
 | 
			
		||||
diff -Nru vdr-1.7.12-vanilla/sources.conf vdr-1.7.12-pluginparam/sources.conf
 | 
			
		||||
--- vdr-1.7.12-vanilla/sources.conf	2010-02-01 11:45:39.000000000 +0200
 | 
			
		||||
+++ vdr-1.7.12-pluginparam/sources.conf	2010-02-01 13:52:56.000000000 +0200
 | 
			
		||||
@@ -195,3 +195,7 @@
 | 
			
		||||
 # Terrestrial
 | 
			
		||||
 
 | 
			
		||||
 T       Terrestrial
 | 
			
		||||
@@ -261,9 +261,9 @@ diff -Nru vdr-1.7.0-vanilla/sources.conf vdr-1.7.0-pluginparam/sources.conf
 | 
			
		||||
+# Plugin
 | 
			
		||||
+
 | 
			
		||||
+P       Plugin
 | 
			
		||||
diff -Nru vdr-1.7.0-vanilla/sources.h vdr-1.7.0-pluginparam/sources.h
 | 
			
		||||
--- vdr-1.7.0-vanilla/sources.h	2005-05-14 12:30:41.000000000 +0300
 | 
			
		||||
+++ vdr-1.7.0-pluginparam/sources.h	2008-04-13 18:54:25.000000000 +0300
 | 
			
		||||
diff -Nru vdr-1.7.12-vanilla/sources.h vdr-1.7.12-pluginparam/sources.h
 | 
			
		||||
--- vdr-1.7.12-vanilla/sources.h	2010-02-01 11:45:39.000000000 +0200
 | 
			
		||||
+++ vdr-1.7.12-pluginparam/sources.h	2010-02-01 13:52:56.000000000 +0200
 | 
			
		||||
@@ -16,10 +16,11 @@
 | 
			
		||||
 public:
 | 
			
		||||
   enum eSourceType {
 | 
			
		||||
							
								
								
									
										59
									
								
								pidscanner.c
									
									
									
									
									
								
							
							
						
						
									
										59
									
								
								pidscanner.c
									
									
									
									
									
								
							@@ -120,32 +120,39 @@ void cPidScanner::Process(const uint8_t* buf)
 | 
			
		||||
              return;
 | 
			
		||||
              }
 | 
			
		||||
           cChannel *IptvChannel = Channels.GetByChannelID(channel.GetChannelID());
 | 
			
		||||
           int Apids[MAXAPIDS + 1] = { 0 }; // these lists are zero-terminated
 | 
			
		||||
           int Dpids[MAXDPIDS + 1] = { 0 };
 | 
			
		||||
           int Spids[MAXSPIDS + 1] = { 0 };
 | 
			
		||||
           char ALangs[MAXAPIDS][MAXLANGCODE2] = { "" };
 | 
			
		||||
           char DLangs[MAXDPIDS][MAXLANGCODE2] = { "" };
 | 
			
		||||
           char SLangs[MAXSPIDS][MAXLANGCODE2] = { "" };
 | 
			
		||||
           int Ppid = IptvChannel->Ppid();
 | 
			
		||||
           int Tpid = IptvChannel->Tpid();
 | 
			
		||||
           bool foundApid = false;
 | 
			
		||||
           if (numVpids < PIDSCANNER_VPID_COUNT)
 | 
			
		||||
              Vpid = 0; // No detected video pid
 | 
			
		||||
           else if (numApids < PIDSCANNER_APID_COUNT)
 | 
			
		||||
              Apid = 0; // No detected audio pid
 | 
			
		||||
           for (unsigned int i = 1; i < MAXAPIDS; ++i) {
 | 
			
		||||
               Apids[i] = IptvChannel->Apid(i);
 | 
			
		||||
               if (Apids[i] && (Apids[i] == Apid))
 | 
			
		||||
                  foundApid = true;
 | 
			
		||||
               }
 | 
			
		||||
           if (!foundApid)
 | 
			
		||||
              Apids[0] = Apid;
 | 
			
		||||
           for (unsigned int i = 0; i < MAXDPIDS; ++i)
 | 
			
		||||
               Dpids[i] = IptvChannel->Dpid(i);
 | 
			
		||||
           for (unsigned int i = 0; i < MAXSPIDS; ++i)
 | 
			
		||||
               Spids[i] = IptvChannel->Spid(i);
 | 
			
		||||
           debug("cPidScanner::Process(): Vpid=0x%04X, Apid=0x%04X\n", Vpid, Apid);
 | 
			
		||||
           IptvChannel->SetPids(Vpid, Ppid, Apids, ALangs, Dpids, DLangs, Spids, SLangs, Tpid);
 | 
			
		||||
           if (IptvChannel) {
 | 
			
		||||
              int Apids[MAXAPIDS + 1] = { 0 }; // these lists are zero-terminated
 | 
			
		||||
              int Dpids[MAXDPIDS + 1] = { 0 };
 | 
			
		||||
              int Spids[MAXSPIDS + 1] = { 0 };
 | 
			
		||||
              char ALangs[MAXAPIDS][MAXLANGCODE2] = { "" };
 | 
			
		||||
              char DLangs[MAXDPIDS][MAXLANGCODE2] = { "" };
 | 
			
		||||
              char SLangs[MAXSPIDS][MAXLANGCODE2] = { "" };
 | 
			
		||||
              int Ppid = IptvChannel->Ppid();
 | 
			
		||||
              int Tpid = IptvChannel->Tpid();
 | 
			
		||||
              bool foundApid = false;
 | 
			
		||||
              if (numVpids < PIDSCANNER_VPID_COUNT)
 | 
			
		||||
                 Vpid = 0; // No detected video pid
 | 
			
		||||
              else if (numApids < PIDSCANNER_APID_COUNT)
 | 
			
		||||
                 Apid = 0; // No detected audio pid
 | 
			
		||||
              for (unsigned int i = 1; i < MAXAPIDS; ++i) {
 | 
			
		||||
                  Apids[i] = IptvChannel->Apid(i);
 | 
			
		||||
                  if (Apids[i] && (Apids[i] == Apid))
 | 
			
		||||
                     foundApid = true;
 | 
			
		||||
                  }
 | 
			
		||||
              if (!foundApid)
 | 
			
		||||
                 Apids[0] = Apid;
 | 
			
		||||
              for (unsigned int i = 0; i < MAXDPIDS; ++i)
 | 
			
		||||
                  Dpids[i] = IptvChannel->Dpid(i);
 | 
			
		||||
              for (unsigned int i = 0; i < MAXSPIDS; ++i)
 | 
			
		||||
                  Spids[i] = IptvChannel->Spid(i);
 | 
			
		||||
              debug("cPidScanner::Process(): Vpid=0x%04X, Apid=0x%04X\n", Vpid, Apid);
 | 
			
		||||
#if defined(APIVERSNUM) && APIVERSNUM >= 10704
 | 
			
		||||
              int Vtype = IptvChannel->Vtype();
 | 
			
		||||
              IptvChannel->SetPids(Vpid, Ppid, Vtype, Apids, ALangs, Dpids, DLangs, Spids, SLangs, Tpid);
 | 
			
		||||
#else
 | 
			
		||||
              IptvChannel->SetPids(Vpid, Ppid, Apids, ALangs, Dpids, DLangs, Spids, SLangs, Tpid);
 | 
			
		||||
#endif
 | 
			
		||||
              }
 | 
			
		||||
           Channels.Unlock();
 | 
			
		||||
           process = false;
 | 
			
		||||
           }
 | 
			
		||||
 
 | 
			
		||||
@@ -5,9 +5,9 @@
 | 
			
		||||
#
 | 
			
		||||
msgid ""
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Project-Id-Version: iptv 0.2.0\n"
 | 
			
		||||
"Project-Id-Version: iptv 0.2.5\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: Rolf Ahrenberg\n"
 | 
			
		||||
"POT-Creation-Date: 2008-02-01 23:43+0200\n"
 | 
			
		||||
"POT-Creation-Date: 2009-03-06 22:15+0200\n"
 | 
			
		||||
"PO-Revision-Date: 2007-10-29 21:19+0100\n"
 | 
			
		||||
"Last-Translator: Tobias Grimm <tg@e-tobi.net>\n"
 | 
			
		||||
"Language-Team: German\n"
 | 
			
		||||
@@ -76,6 +76,9 @@ msgstr "Scanne SID"
 | 
			
		||||
msgid "Scan pids"
 | 
			
		||||
msgstr "Scanne PIDS"
 | 
			
		||||
 | 
			
		||||
msgid "Vtype"
 | 
			
		||||
msgstr "Vtype"
 | 
			
		||||
 | 
			
		||||
msgid "Nid"
 | 
			
		||||
msgstr "Nid"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -5,9 +5,9 @@
 | 
			
		||||
#
 | 
			
		||||
msgid ""
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Project-Id-Version: iptv 0.2.0\n"
 | 
			
		||||
"Project-Id-Version: iptv 0.2.5\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: Rolf Ahrenberg\n"
 | 
			
		||||
"POT-Creation-Date: 2008-02-01 23:43+0200\n"
 | 
			
		||||
"POT-Creation-Date: 2009-03-06 22:15+0200\n"
 | 
			
		||||
"PO-Revision-Date: 2007-08-12 23:22+0300\n"
 | 
			
		||||
"Last-Translator: Rolf Ahrenberg\n"
 | 
			
		||||
"Language-Team: <vdr@linuxtv.org>\n"
 | 
			
		||||
@@ -75,6 +75,9 @@ msgstr "Etsi palvelu-ID"
 | 
			
		||||
msgid "Scan pids"
 | 
			
		||||
msgstr "Etsi pidit"
 | 
			
		||||
 | 
			
		||||
msgid "Vtype"
 | 
			
		||||
msgstr "Kuvatyyppi"
 | 
			
		||||
 | 
			
		||||
msgid "Nid"
 | 
			
		||||
msgstr "Verkko-ID"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -6,9 +6,9 @@
 | 
			
		||||
#
 | 
			
		||||
msgid ""
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Project-Id-Version: iptv 0.2.0\n"
 | 
			
		||||
"Project-Id-Version: iptv 0.2.5\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: Rolf Ahrenberg\n"
 | 
			
		||||
"POT-Creation-Date: 2008-02-01 23:43+0200\n"
 | 
			
		||||
"POT-Creation-Date: 2009-03-06 22:15+0200\n"
 | 
			
		||||
"PO-Revision-Date: 2008-01-26 13:14+0100\n"
 | 
			
		||||
"Last-Translator: NIVAL Michaël <mnival@club-internet.fr>\n"
 | 
			
		||||
"Language-Team: French\n"
 | 
			
		||||
@@ -77,6 +77,9 @@ msgstr "Scanne les SID"
 | 
			
		||||
msgid "Scan pids"
 | 
			
		||||
msgstr "Scanne les PID"
 | 
			
		||||
 | 
			
		||||
msgid "Vtype"
 | 
			
		||||
msgstr "Vtype"
 | 
			
		||||
 | 
			
		||||
msgid "Nid"
 | 
			
		||||
msgstr "Nid"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -5,9 +5,9 @@
 | 
			
		||||
#
 | 
			
		||||
msgid ""
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Project-Id-Version: iptv 0.2.0\n"
 | 
			
		||||
"Project-Id-Version: iptv 0.2.5\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: Rolf Ahrenberg\n"
 | 
			
		||||
"POT-Creation-Date: 2008-02-01 23:43+0200\n"
 | 
			
		||||
"POT-Creation-Date: 2009-03-06 22:15+0200\n"
 | 
			
		||||
"PO-Revision-Date: 2008-07-13 03:28+0100\n"
 | 
			
		||||
"Last-Translator: Diego Pierotto <vdr-italian@tiscali.it>\n"
 | 
			
		||||
"Language-Team: Italian\n"
 | 
			
		||||
@@ -76,6 +76,9 @@ msgstr "Scansione Sid"
 | 
			
		||||
msgid "Scan pids"
 | 
			
		||||
msgstr "Scansione Pids"
 | 
			
		||||
 | 
			
		||||
msgid "Vtype"
 | 
			
		||||
msgstr "Vtype"
 | 
			
		||||
 | 
			
		||||
msgid "Nid"
 | 
			
		||||
msgstr "Nid"
 | 
			
		||||
 | 
			
		||||
@@ -180,4 +183,3 @@ msgstr "Definisci un filtro corrotto che sarà messo nella lista nera."
 | 
			
		||||
 | 
			
		||||
msgid "Help"
 | 
			
		||||
msgstr "Aiuto"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -5,9 +5,9 @@
 | 
			
		||||
#
 | 
			
		||||
msgid ""
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Project-Id-Version: iptv 0.2.0\n"
 | 
			
		||||
"Project-Id-Version: iptv 0.2.5\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: Rolf Ahrenberg\n"
 | 
			
		||||
"POT-Creation-Date: 2008-02-01 23:43+0200\n"
 | 
			
		||||
"POT-Creation-Date: 2009-03-06 22:15+0200\n"
 | 
			
		||||
"PO-Revision-Date: 2008-03-16 12:14+0100\n"
 | 
			
		||||
"Last-Translator: Alexander Gross <Bikalexander@gmail.com>\n"
 | 
			
		||||
"Language-Team: Russian <de@li.org>\n"
 | 
			
		||||
@@ -77,6 +77,9 @@ msgstr "Сканировать SID"
 | 
			
		||||
msgid "Scan pids"
 | 
			
		||||
msgstr "Сканировать пиды"
 | 
			
		||||
 | 
			
		||||
msgid "Vtype"
 | 
			
		||||
msgstr "Vtype"
 | 
			
		||||
 | 
			
		||||
msgid "Nid"
 | 
			
		||||
msgstr "Nid"
 | 
			
		||||
 | 
			
		||||
@@ -165,4 +168,3 @@ msgstr "Неправильно работающий фильтр, занести
 | 
			
		||||
 | 
			
		||||
msgid "Help"
 | 
			
		||||
msgstr "Справка"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
@@ -106,7 +106,7 @@ bool cIptvProtocolExt::Open(void)
 | 
			
		||||
{
 | 
			
		||||
  debug("cIptvProtocolExt::Open()\n");
 | 
			
		||||
  // Reject empty script files
 | 
			
		||||
  if (!strlen(scriptFile))
 | 
			
		||||
  if (!strlen(*scriptFile))
 | 
			
		||||
     return false;
 | 
			
		||||
  // Create the listening socket
 | 
			
		||||
  OpenSocket(socketPort);
 | 
			
		||||
@@ -127,9 +127,9 @@ bool cIptvProtocolExt::Close(void)
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int cIptvProtocolExt::Read(unsigned char* *BufferAddr)
 | 
			
		||||
int cIptvProtocolExt::Read(unsigned char* BufferAddr, unsigned int BufferLen)
 | 
			
		||||
{
 | 
			
		||||
  return cIptvUdpSocket::Read(BufferAddr);
 | 
			
		||||
  return cIptvUdpSocket::Read(BufferAddr, BufferLen);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cIptvProtocolExt::Set(const char* Location, const int Parameter, const int Index)
 | 
			
		||||
@@ -139,8 +139,8 @@ bool cIptvProtocolExt::Set(const char* Location, const int Parameter, const int
 | 
			
		||||
     struct stat stbuf;
 | 
			
		||||
     // 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);
 | 
			
		||||
     if ((stat(*scriptFile, &stbuf) != 0) || (strstr(*scriptFile, "..") != 0)) {
 | 
			
		||||
        error("Non-existent or relative path script '%s'", *scriptFile);
 | 
			
		||||
        return false;
 | 
			
		||||
        }
 | 
			
		||||
     scriptParameter = Parameter;
 | 
			
		||||
 
 | 
			
		||||
@@ -25,7 +25,7 @@ private:
 | 
			
		||||
public:
 | 
			
		||||
  cIptvProtocolExt();
 | 
			
		||||
  virtual ~cIptvProtocolExt();
 | 
			
		||||
  int Read(unsigned char* *BufferAddr);
 | 
			
		||||
  int Read(unsigned char* BufferAddr, unsigned int BufferLen);
 | 
			
		||||
  bool Set(const char* Location, const int Parameter, const int Index);
 | 
			
		||||
  bool Open(void);
 | 
			
		||||
  bool Close(void);
 | 
			
		||||
 
 | 
			
		||||
@@ -16,15 +16,11 @@
 | 
			
		||||
 | 
			
		||||
cIptvProtocolFile::cIptvProtocolFile()
 | 
			
		||||
: fileDelay(0),
 | 
			
		||||
  readBufferLen(TS_SIZE * IptvConfig.GetReadBufferTsCount()),
 | 
			
		||||
  fileStream(NULL),
 | 
			
		||||
  isActive(false)
 | 
			
		||||
{
 | 
			
		||||
  debug("cIptvProtocolFile::cIptvProtocolFile()\n");
 | 
			
		||||
  fileLocation = strdup("");
 | 
			
		||||
  // Allocate receive buffer
 | 
			
		||||
  readBuffer = MALLOC(unsigned char, readBufferLen);
 | 
			
		||||
  if (!readBuffer)
 | 
			
		||||
     error("ERROR: MALLOC() failed in ProtocolFile()");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cIptvProtocolFile::~cIptvProtocolFile()
 | 
			
		||||
@@ -34,7 +30,6 @@ cIptvProtocolFile::~cIptvProtocolFile()
 | 
			
		||||
  cIptvProtocolFile::Close();
 | 
			
		||||
  // Free allocated memory
 | 
			
		||||
  free(fileLocation);
 | 
			
		||||
  free(readBuffer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cIptvProtocolFile::OpenFile(void)
 | 
			
		||||
@@ -61,10 +56,9 @@ void cIptvProtocolFile::CloseFile(void)
 | 
			
		||||
     }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int cIptvProtocolFile::Read(unsigned char* *BufferAddr)
 | 
			
		||||
int cIptvProtocolFile::Read(unsigned char* BufferAddr, unsigned int BufferLen)
 | 
			
		||||
{
 | 
			
		||||
   //debug("cIptvProtocolFile::Read()\n");
 | 
			
		||||
   *BufferAddr = readBuffer;
 | 
			
		||||
   // Check errors
 | 
			
		||||
   if (ferror(fileStream)) {
 | 
			
		||||
      debug("Read error\n");
 | 
			
		||||
@@ -81,7 +75,7 @@ int cIptvProtocolFile::Read(unsigned char* *BufferAddr)
 | 
			
		||||
   // during the sleep and buffers are disposed. Check here that the plugin is
 | 
			
		||||
   // still active before accessing the buffers
 | 
			
		||||
   if (isActive)
 | 
			
		||||
      return fread(readBuffer, sizeof(unsigned char), readBufferLen, fileStream);
 | 
			
		||||
      return (int)fread(BufferAddr, sizeof(unsigned char), BufferLen, fileStream);
 | 
			
		||||
   return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -16,8 +16,6 @@ private:
 | 
			
		||||
  char* fileLocation;
 | 
			
		||||
  int fileDelay;
 | 
			
		||||
  FILE* fileStream;
 | 
			
		||||
  unsigned char* readBuffer;
 | 
			
		||||
  unsigned int readBufferLen;
 | 
			
		||||
  bool isActive;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
@@ -27,7 +25,7 @@ private:
 | 
			
		||||
public:
 | 
			
		||||
  cIptvProtocolFile();
 | 
			
		||||
  virtual ~cIptvProtocolFile();
 | 
			
		||||
  int Read(unsigned char* *BufferAddr);
 | 
			
		||||
  int Read(unsigned char* BufferAddr, unsigned int BufferLen);
 | 
			
		||||
  bool Set(const char* Location, const int Parameter, const int Index);
 | 
			
		||||
  bool Open(void);
 | 
			
		||||
  bool Close(void);
 | 
			
		||||
 
 | 
			
		||||
@@ -45,7 +45,7 @@ bool cIptvProtocolHttp::Connect(void)
 | 
			
		||||
 | 
			
		||||
     // First try only the IP address
 | 
			
		||||
     sockAddr.sin_addr.s_addr = inet_addr(streamAddr);
 | 
			
		||||
     
 | 
			
		||||
 | 
			
		||||
     if (sockAddr.sin_addr.s_addr == INADDR_NONE) {
 | 
			
		||||
        debug("Cannot convert %s directly to internet address\n", streamAddr);
 | 
			
		||||
 | 
			
		||||
@@ -53,17 +53,15 @@ 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;
 | 
			
		||||
           }
 | 
			
		||||
 | 
			
		||||
        sockAddr.sin_addr.s_addr = inet_addr(*host->h_addr_list);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
     int err = connect(socketDesc, (struct sockaddr*)&sockAddr,
 | 
			
		||||
		       sizeof(sockAddr));
 | 
			
		||||
     int err = connect(socketDesc, (struct sockaddr *)&sockAddr, sizeof(sockAddr));
 | 
			
		||||
     // Non-blocking sockets always report in-progress error when connected
 | 
			
		||||
     ERROR_IF_FUNC(err < 0 && errno != EINPROGRESS, "connect()", CloseSocket(), return false);
 | 
			
		||||
     // Select with 800ms timeout on the socket completion, check if it is writable
 | 
			
		||||
@@ -78,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;
 | 
			
		||||
        }
 | 
			
		||||
@@ -94,8 +91,8 @@ bool cIptvProtocolHttp::Connect(void)
 | 
			
		||||
                                       "\r\n", streamPath, streamAddr);
 | 
			
		||||
 | 
			
		||||
     debug("Sending http request: %s\n", *buffer);
 | 
			
		||||
     err = send(socketDesc, buffer, strlen(buffer), 0);
 | 
			
		||||
     ERROR_IF_FUNC(err < 0, "send()", CloseSocket(), return false);
 | 
			
		||||
     ssize_t err2 = send(socketDesc, buffer, strlen(buffer), 0);
 | 
			
		||||
     ERROR_IF_FUNC(err2 < 0, "send()", CloseSocket(), return false);
 | 
			
		||||
 | 
			
		||||
     // Now process headers
 | 
			
		||||
     if (!ProcessHeaders()) {
 | 
			
		||||
@@ -123,12 +120,12 @@ bool cIptvProtocolHttp::Disconnect(void)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cIptvProtocolHttp::GetHeaderLine(char* dest, unsigned int destLen,
 | 
			
		||||
				      unsigned int &recvLen)
 | 
			
		||||
                                      unsigned int &recvLen)
 | 
			
		||||
{
 | 
			
		||||
  debug("cIptvProtocolHttp::GetHeaderLine()\n");
 | 
			
		||||
  bool linefeed = false;
 | 
			
		||||
  bool newline = false;
 | 
			
		||||
  char buf[256];
 | 
			
		||||
  char buf[4096];
 | 
			
		||||
  char *bufptr = buf;
 | 
			
		||||
  memset(buf, '\0', sizeof(buf));
 | 
			
		||||
  recvLen = 0;
 | 
			
		||||
@@ -142,7 +139,7 @@ bool cIptvProtocolHttp::GetHeaderLine(char* dest, unsigned int destLen,
 | 
			
		||||
       return false;
 | 
			
		||||
    // Check if data available
 | 
			
		||||
    else if (retval) {
 | 
			
		||||
       int retval = recvfrom(socketDesc, bufptr, 1, MSG_DONTWAIT,
 | 
			
		||||
       ssize_t retval = recvfrom(socketDesc, bufptr, 1, MSG_DONTWAIT,
 | 
			
		||||
                             (struct sockaddr *)&sockAddr, &addrlen);
 | 
			
		||||
       if (retval <= 0)
 | 
			
		||||
          return false;
 | 
			
		||||
@@ -161,6 +158,7 @@ bool cIptvProtocolHttp::GetHeaderLine(char* dest, unsigned int destLen,
 | 
			
		||||
       // Check that buffers won't be exceeded
 | 
			
		||||
       if (recvLen >= sizeof(buf) || recvLen >= destLen) {
 | 
			
		||||
          error("Header wouldn't fit into buffer\n");
 | 
			
		||||
          recvLen = 0;
 | 
			
		||||
          return false;
 | 
			
		||||
          }
 | 
			
		||||
       }
 | 
			
		||||
@@ -179,20 +177,20 @@ bool cIptvProtocolHttp::ProcessHeaders(void)
 | 
			
		||||
  unsigned int lineLength = 0;
 | 
			
		||||
  int response = 0;
 | 
			
		||||
  bool responseFound = false;
 | 
			
		||||
  char buf[256];
 | 
			
		||||
  char buf[4096];
 | 
			
		||||
 | 
			
		||||
  while (!responseFound || lineLength != 0) {
 | 
			
		||||
    memset(buf, '\0', sizeof(buf));
 | 
			
		||||
    if (!GetHeaderLine(buf, sizeof(buf), lineLength))
 | 
			
		||||
       return false;
 | 
			
		||||
    if (!responseFound && sscanf(buf, "HTTP/1.%*i %i ",&response) != 1) {
 | 
			
		||||
    if (!responseFound && sscanf(buf, "HTTP/1.%*i %i ", &response) != 1) {
 | 
			
		||||
       error("Expected HTTP header not found\n");
 | 
			
		||||
       continue;
 | 
			
		||||
       }
 | 
			
		||||
    else
 | 
			
		||||
       responseFound = true;
 | 
			
		||||
    if (response != 200) {
 | 
			
		||||
       error("ERROR: %s\n", buf);
 | 
			
		||||
       error("%s\n", buf);
 | 
			
		||||
       return false;
 | 
			
		||||
       }
 | 
			
		||||
    }
 | 
			
		||||
@@ -214,9 +212,9 @@ bool cIptvProtocolHttp::Close(void)
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int cIptvProtocolHttp::Read(unsigned char* *BufferAddr)
 | 
			
		||||
int cIptvProtocolHttp::Read(unsigned char* BufferAddr, unsigned int BufferLen)
 | 
			
		||||
{
 | 
			
		||||
  return cIptvTcpSocket::Read(BufferAddr);
 | 
			
		||||
  return cIptvTcpSocket::Read(BufferAddr, BufferLen);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cIptvProtocolHttp::Set(const char* Location, const int Parameter, const int Index)
 | 
			
		||||
 
 | 
			
		||||
@@ -20,14 +20,13 @@ private:
 | 
			
		||||
private:
 | 
			
		||||
  bool Connect(void);
 | 
			
		||||
  bool Disconnect(void);
 | 
			
		||||
  bool GetHeaderLine(char* dest, unsigned int destLen,
 | 
			
		||||
		     unsigned int &recvLen);
 | 
			
		||||
  bool GetHeaderLine(char* dest, unsigned int destLen, unsigned int &recvLen);
 | 
			
		||||
  bool ProcessHeaders(void);
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
  cIptvProtocolHttp();
 | 
			
		||||
  virtual ~cIptvProtocolHttp();
 | 
			
		||||
  int Read(unsigned char* *BufferAddr);
 | 
			
		||||
  int Read(unsigned char* BufferAddr, unsigned int BufferLen);
 | 
			
		||||
  bool Set(const char* Location, const int Parameter, const int Index);
 | 
			
		||||
  bool Open(void);
 | 
			
		||||
  bool Close(void);
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,7 @@ class cIptvProtocolIf {
 | 
			
		||||
public:
 | 
			
		||||
  cIptvProtocolIf() {}
 | 
			
		||||
  virtual ~cIptvProtocolIf() {}
 | 
			
		||||
  virtual int Read(unsigned char* *BufferAddr) = 0;
 | 
			
		||||
  virtual int Read(unsigned char* BufferAddr, unsigned int BufferLen) = 0;
 | 
			
		||||
  virtual bool Set(const char* Location, const int Parameter, const int Index) = 0;
 | 
			
		||||
  virtual bool Open(void) = 0;
 | 
			
		||||
  virtual bool Close(void) = 0;
 | 
			
		||||
 
 | 
			
		||||
@@ -91,9 +91,9 @@ bool cIptvProtocolUdp::Close(void)
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int cIptvProtocolUdp::Read(unsigned char* *BufferAddr)
 | 
			
		||||
int cIptvProtocolUdp::Read(unsigned char* BufferAddr, unsigned int BufferLen)
 | 
			
		||||
{
 | 
			
		||||
  return cIptvUdpSocket::Read(BufferAddr);
 | 
			
		||||
  return cIptvUdpSocket::Read(BufferAddr, BufferLen);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cIptvProtocolUdp::Set(const char* Location, const int Parameter, const int Index)
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,7 @@ private:
 | 
			
		||||
public:
 | 
			
		||||
  cIptvProtocolUdp();
 | 
			
		||||
  virtual ~cIptvProtocolUdp();
 | 
			
		||||
  int Read(unsigned char* *BufferAddr);
 | 
			
		||||
  int Read(unsigned char* BufferAddr, unsigned int BufferLen);
 | 
			
		||||
  bool Set(const char* Location, const int Parameter, const int Index);
 | 
			
		||||
  bool Open(void);
 | 
			
		||||
  bool Close(void);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										269
									
								
								sectionfilter.c
									
									
									
									
									
								
							
							
						
						
									
										269
									
								
								sectionfilter.c
									
									
									
									
									
								
							@@ -7,8 +7,8 @@
 | 
			
		||||
 | 
			
		||||
#include "sectionfilter.h"
 | 
			
		||||
 | 
			
		||||
cIptvSectionFilter::cIptvSectionFilter(int Index, int devInd,
 | 
			
		||||
				       u_short Pid, u_char Tid, u_char Mask)
 | 
			
		||||
cIptvSectionFilter::cIptvSectionFilter(int DeviceIndex, int Index,
 | 
			
		||||
                                       uint16_t Pid, uint8_t Tid, uint8_t Mask)
 | 
			
		||||
: pusi_seen(0),
 | 
			
		||||
  feedcc(0),
 | 
			
		||||
  doneq(0),
 | 
			
		||||
@@ -17,10 +17,12 @@ cIptvSectionFilter::cIptvSectionFilter(int Index, int devInd,
 | 
			
		||||
  seclen(0),
 | 
			
		||||
  tsfeedp(0),
 | 
			
		||||
  pid(Pid),
 | 
			
		||||
  id(Index),
 | 
			
		||||
  pipeName("")
 | 
			
		||||
  devid(DeviceIndex),
 | 
			
		||||
  id(Index)
 | 
			
		||||
{
 | 
			
		||||
  //debug("cIptvSectionFilter::cIptvSectionFilter(%d)\n", Index);
 | 
			
		||||
  //debug("cIptvSectionFilter::cIptvSectionFilter(%d, %d)\n", devid, id);
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
  memset(secbuf_base, '\0', sizeof(secbuf_base));
 | 
			
		||||
  memset(filter_value, '\0', sizeof(filter_value));
 | 
			
		||||
  memset(filter_mask, '\0', sizeof(filter_mask));
 | 
			
		||||
@@ -28,159 +30,109 @@ cIptvSectionFilter::cIptvSectionFilter(int Index, int devInd,
 | 
			
		||||
  memset(maskandmode, '\0', sizeof(maskandmode));
 | 
			
		||||
  memset(maskandnotmode, '\0', sizeof(maskandnotmode));
 | 
			
		||||
 | 
			
		||||
  SetPipeName(devInd);
 | 
			
		||||
 | 
			
		||||
  filter_value[0] = Tid;
 | 
			
		||||
  filter_mask[0] = Mask;
 | 
			
		||||
 | 
			
		||||
  // Invert the filter
 | 
			
		||||
  for (int i = 0; i < DMX_MAX_FILTER_SIZE; ++i)
 | 
			
		||||
  for (i = 0; i < DMX_MAX_FILTER_SIZE; ++i)
 | 
			
		||||
      filter_value[i] ^= 0xff;
 | 
			
		||||
 | 
			
		||||
  uint8_t mask, mode, local_doneq = 0;
 | 
			
		||||
  for (int i = 0; i < DMX_MAX_FILTER_SIZE; ++i) {
 | 
			
		||||
  for (i = 0; i < DMX_MAX_FILTER_SIZE; ++i) {
 | 
			
		||||
      mode = filter_mode[i];
 | 
			
		||||
      mask = filter_mask[i];
 | 
			
		||||
      maskandmode[i] = mask & mode;
 | 
			
		||||
      local_doneq |= maskandnotmode[i] = mask & ~mode;
 | 
			
		||||
      maskandmode[i] = (uint8_t)(mask & mode);
 | 
			
		||||
      maskandnotmode[i] = (uint8_t)(mask & ~mode);
 | 
			
		||||
      local_doneq |= maskandnotmode[i];
 | 
			
		||||
      }
 | 
			
		||||
  doneq = local_doneq ? 1 : 0;
 | 
			
		||||
 | 
			
		||||
  struct stat sb;
 | 
			
		||||
  stat(pipeName, &sb);
 | 
			
		||||
  if (S_ISFIFO(sb.st_mode))
 | 
			
		||||
     unlink(pipeName);
 | 
			
		||||
  int err = mknod(pipeName, 0644 | S_IFIFO, 0);
 | 
			
		||||
  ERROR_IF_RET(err < 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)\n", id);
 | 
			
		||||
  close(fifoDescriptor);
 | 
			
		||||
  close(readDescriptor);
 | 
			
		||||
  unlink(pipeName);
 | 
			
		||||
  fifoDescriptor = -1;
 | 
			
		||||
  readDescriptor = -1;
 | 
			
		||||
  //debug("cIptvSectionFilter::~cIptvSectionfilter(%d, %d)\n", devid, id);
 | 
			
		||||
  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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cIptvSectionFilter::SetPipeName(int deviceIndex)
 | 
			
		||||
int cIptvSectionFilter::GetReadDesc(void)
 | 
			
		||||
{
 | 
			
		||||
  pipeName = cString::sprintf(IPTV_FILTER_FILENAME, deviceIndex, id);
 | 
			
		||||
  return socket[0];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int cIptvSectionFilter::GetReadDesc()
 | 
			
		||||
inline uint16_t cIptvSectionFilter::GetLength(const uint8_t *Data)
 | 
			
		||||
{
 | 
			
		||||
  return readDescriptor;
 | 
			
		||||
  return (uint16_t)(3 + ((Data[1] & 0x0f) << 8) + Data[2]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline uint16_t cIptvSectionFilter::section_length(const uint8_t *buf)
 | 
			
		||||
void cIptvSectionFilter::New(void)
 | 
			
		||||
{
 | 
			
		||||
  return 3 + ((buf[1] & 0x0f) << 8) + buf[2];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int cIptvSectionFilter::dmxdev_section_callback(const uint8_t *buffer1, size_t buffer1_len,
 | 
			
		||||
                                                const uint8_t *buffer2, size_t buffer2_len,
 | 
			
		||||
                                                enum dmx_success success)
 | 
			
		||||
{
 | 
			
		||||
  // See if there is data in the fifo
 | 
			
		||||
  int retval = select_single_desc(fifoDescriptor, 0, false);
 | 
			
		||||
  // There is no data in the fifo, more can be written
 | 
			
		||||
  if (!retval) {
 | 
			
		||||
#ifdef DEBUG_PRINTF
 | 
			
		||||
     printf("id = %d, pid %d would now write %d data to buffer\n", id, pid, buffer1_len);
 | 
			
		||||
     for (unsigned int i = 0; i < buffer1_len; ++i)
 | 
			
		||||
         printf("0x%X ", buffer1[i]);
 | 
			
		||||
     printf("\n");
 | 
			
		||||
#endif
 | 
			
		||||
     retval = write(fifoDescriptor, buffer1, buffer1_len);
 | 
			
		||||
     ERROR_IF(retval < 0, "write()");
 | 
			
		||||
     // Update statistics
 | 
			
		||||
     AddSectionStatistic(retval, 1);
 | 
			
		||||
     }
 | 
			
		||||
#ifdef DEBUG_PRINTF
 | 
			
		||||
  else if (retval)
 | 
			
		||||
     printf("id %d pid %d data is already present\n", id, pid);
 | 
			
		||||
#endif
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cIptvSectionFilter::demux_swfilter_section_new()
 | 
			
		||||
{
 | 
			
		||||
#ifdef DEMUX_SECTION_LOSS_LOG
 | 
			
		||||
  if (secbufp < tsfeedp) {
 | 
			
		||||
     int i, n = tsfeedp - secbufp;
 | 
			
		||||
     /*
 | 
			
		||||
      * Section padding is done with 0xff bytes entirely.
 | 
			
		||||
      * Due to speed reasons, we won't check all of them
 | 
			
		||||
      * but just first and last.
 | 
			
		||||
      */
 | 
			
		||||
     if (secbuf[0] != 0xff || secbuf[n - 1] != 0xff) {
 | 
			
		||||
        printf("sectionfilter.c section ts padding loss: %d/%d\n",
 | 
			
		||||
               n, tsfeedp);
 | 
			
		||||
        printf("sectionfilter.c pad data:");
 | 
			
		||||
        for (i = 0; i < n; ++i)
 | 
			
		||||
	    printf(" %02x", secbuf[i]);
 | 
			
		||||
        printf("\n");
 | 
			
		||||
        }
 | 
			
		||||
     }
 | 
			
		||||
#endif
 | 
			
		||||
  tsfeedp = secbufp = seclen = 0;
 | 
			
		||||
  secbuf = secbuf_base;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int cIptvSectionFilter::demux_swfilter_sectionfilter()
 | 
			
		||||
int cIptvSectionFilter::Filter(void)
 | 
			
		||||
{
 | 
			
		||||
  uint8_t neq = 0;
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < DMX_MAX_FILTER_SIZE; ++i) {
 | 
			
		||||
      uint8_t local_xor = filter_value[i] ^ secbuf[i];
 | 
			
		||||
      if (maskandmode[i] & local_xor) {
 | 
			
		||||
#ifdef DEBUG_PRINTF
 | 
			
		||||
         printf("maskandmode discard\n");
 | 
			
		||||
#endif
 | 
			
		||||
         return 0;
 | 
			
		||||
  if (secbuf) {
 | 
			
		||||
     for (i = 0; i < DMX_MAX_FILTER_SIZE; ++i) {
 | 
			
		||||
         uint8_t local_xor = (uint8_t)(filter_value[i] ^ secbuf[i]);
 | 
			
		||||
         if (maskandmode[i] & local_xor)
 | 
			
		||||
            return 0;
 | 
			
		||||
         neq |= (maskandnotmode[i] & local_xor);
 | 
			
		||||
         }
 | 
			
		||||
      neq |= maskandnotmode[i] & local_xor;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
  if (doneq && !neq) {
 | 
			
		||||
#ifdef DEBUG_PRINTF
 | 
			
		||||
     printf("doneq discard, doneq = 0x%X, neq = 0x%X\n", doneq, !neq);
 | 
			
		||||
#endif
 | 
			
		||||
     return 0;
 | 
			
		||||
     if (doneq && !neq)
 | 
			
		||||
        return 0;
 | 
			
		||||
 | 
			
		||||
     // 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);
 | 
			
		||||
        }
 | 
			
		||||
     }
 | 
			
		||||
  return dmxdev_section_callback(secbuf, seclen, NULL, 0, DMX_OK);
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int cIptvSectionFilter::demux_swfilter_section_feed()
 | 
			
		||||
inline int cIptvSectionFilter::Feed(void)
 | 
			
		||||
{
 | 
			
		||||
  if (demux_swfilter_sectionfilter() < 0)
 | 
			
		||||
  if (Filter() < 0)
 | 
			
		||||
     return -1;
 | 
			
		||||
  seclen = 0;
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int cIptvSectionFilter::demux_swfilter_section_copy_dump(const uint8_t *buf, uint8_t len)
 | 
			
		||||
int cIptvSectionFilter::CopyDump(const uint8_t *buf, uint8_t len)
 | 
			
		||||
{
 | 
			
		||||
  uint16_t limit, seclen_local, n;
 | 
			
		||||
 | 
			
		||||
  if (tsfeedp >= DMX_MAX_SECFEED_SIZE)
 | 
			
		||||
     return 0;
 | 
			
		||||
 | 
			
		||||
  if (tsfeedp + len > DMX_MAX_SECFEED_SIZE) {
 | 
			
		||||
#ifdef DEMUX_SECTION_LOSS_LOG
 | 
			
		||||
     printf("sectionfilter.c section buffer full loss: %d/%d\n",
 | 
			
		||||
            tsfeedp + len - DMX_MAX_SECFEED_SIZE,
 | 
			
		||||
            DMX_MAX_SECFEED_SIZE);
 | 
			
		||||
#endif
 | 
			
		||||
     len = DMX_MAX_SECFEED_SIZE - tsfeedp;
 | 
			
		||||
     }
 | 
			
		||||
  if (tsfeedp + len > DMX_MAX_SECFEED_SIZE)
 | 
			
		||||
     len = (uint8_t)(DMX_MAX_SECFEED_SIZE - tsfeedp);
 | 
			
		||||
 | 
			
		||||
  if (len <= 0)
 | 
			
		||||
     return 0;
 | 
			
		||||
@@ -188,108 +140,79 @@ int cIptvSectionFilter::demux_swfilter_section_copy_dump(const uint8_t *buf, uin
 | 
			
		||||
  memcpy(secbuf_base + tsfeedp, buf, len);
 | 
			
		||||
  tsfeedp += len;
 | 
			
		||||
 | 
			
		||||
  /*
 | 
			
		||||
   * Dump all the sections we can find in the data (Emard)
 | 
			
		||||
   */
 | 
			
		||||
  limit = tsfeedp;
 | 
			
		||||
  if (limit > DMX_MAX_SECFEED_SIZE)
 | 
			
		||||
     return -1;	/* internal error should never happen */
 | 
			
		||||
     return -1; // internal error should never happen
 | 
			
		||||
 | 
			
		||||
  /* to be sure always set secbuf */
 | 
			
		||||
  // Always set secbuf
 | 
			
		||||
  secbuf = secbuf_base + secbufp;
 | 
			
		||||
 | 
			
		||||
  for (n = 0; secbufp + 2 < limit; ++n) {
 | 
			
		||||
      seclen_local = section_length(secbuf);
 | 
			
		||||
      if (seclen_local <= 0 || seclen_local > DMX_MAX_SECTION_SIZE ||
 | 
			
		||||
         seclen_local + secbufp > limit)
 | 
			
		||||
      seclen_local = GetLength(secbuf);
 | 
			
		||||
      if ((seclen_local <= 0) || (seclen_local > DMX_MAX_SECTION_SIZE) || ((seclen_local + secbufp) > limit))
 | 
			
		||||
         return 0;
 | 
			
		||||
#ifdef DEBUG_PRINTF
 | 
			
		||||
      printf("Non-mismatching seclen! %d, limit = %d\n", seclen_local, limit);
 | 
			
		||||
#endif
 | 
			
		||||
      seclen = seclen_local;
 | 
			
		||||
      /* dump [secbuf .. secbuf+seclen) */
 | 
			
		||||
      if (pusi_seen)
 | 
			
		||||
         demux_swfilter_section_feed();
 | 
			
		||||
#ifdef DEMUX_SECTION_LOSS_LOG
 | 
			
		||||
      else
 | 
			
		||||
         printf("sectionfilter.c pusi not seen, discarding section data\n");
 | 
			
		||||
#endif
 | 
			
		||||
      secbufp += seclen_local;	/* secbufp and secbuf moving together is */
 | 
			
		||||
      secbuf += seclen_local;	/* redundant but saves pointer arithmetic */
 | 
			
		||||
         Feed();
 | 
			
		||||
      secbufp += seclen_local;
 | 
			
		||||
      secbuf += seclen_local;
 | 
			
		||||
      }
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cIptvSectionFilter::ProcessData(const uint8_t* buf)
 | 
			
		||||
void cIptvSectionFilter::Process(const uint8_t* Data)
 | 
			
		||||
{
 | 
			
		||||
  if (buf[0] != 0x47) {
 | 
			
		||||
     error("Not TS packet: 0x%X\n", buf[0]);
 | 
			
		||||
  if (Data[0] != TS_SYNC_BYTE)
 | 
			
		||||
     return;
 | 
			
		||||
     }
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  // Stop if not the PID this filter is looking for
 | 
			
		||||
  if (ts_pid(buf) != pid)
 | 
			
		||||
  if (ts_pid(Data) != pid)
 | 
			
		||||
     return;
 | 
			
		||||
 | 
			
		||||
  uint8_t count = payload(buf);
 | 
			
		||||
  uint8_t count = payload(Data);
 | 
			
		||||
 | 
			
		||||
  if (count == 0)		/* count == 0 if no payload or out of range */
 | 
			
		||||
  // Check if no payload or out of range
 | 
			
		||||
  if (count == 0)
 | 
			
		||||
     return;
 | 
			
		||||
 | 
			
		||||
  uint8_t p = 188 - count;	/* payload start */
 | 
			
		||||
  // Payload start
 | 
			
		||||
  uint8_t p = (uint8_t)(TS_SIZE - count);
 | 
			
		||||
 | 
			
		||||
  uint8_t cc = buf[3] & 0x0f;
 | 
			
		||||
  uint8_t cc = (uint8_t)(Data[3] & 0x0f);
 | 
			
		||||
  int ccok = ((feedcc + 1) & 0x0f) == cc;
 | 
			
		||||
  feedcc = cc;  
 | 
			
		||||
  feedcc = cc;
 | 
			
		||||
 | 
			
		||||
  int dc_i = 0;
 | 
			
		||||
  if (buf[3] & 0x20) {
 | 
			
		||||
     /* adaption field present, check for discontinuity_indicator */
 | 
			
		||||
     if ((buf[4] > 0) && (buf[5] & 0x80))
 | 
			
		||||
  if (Data[3] & 0x20) {
 | 
			
		||||
     // Adaption field present, check for discontinuity_indicator
 | 
			
		||||
     if ((Data[4] > 0) && (Data[5] & 0x80))
 | 
			
		||||
        dc_i = 1;
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
  if (!ccok || dc_i) {
 | 
			
		||||
#ifdef DEMUX_SECTION_LOSS_LOG
 | 
			
		||||
     printf("sectionfilter.c discontinuity detected %d bytes lost\n",
 | 
			
		||||
            count);
 | 
			
		||||
     /*
 | 
			
		||||
      * those bytes under sume circumstances will again be reported
 | 
			
		||||
      * in the following demux_swfilter_section_new
 | 
			
		||||
      */
 | 
			
		||||
#endif
 | 
			
		||||
     /*
 | 
			
		||||
      * Discontinuity detected. Reset pusi_seen = 0 to
 | 
			
		||||
      * stop feeding of suspicious data until next PUSI=1 arrives
 | 
			
		||||
      */
 | 
			
		||||
     // Discontinuity detected. Reset pusi_seen = 0 to
 | 
			
		||||
     // stop feeding of suspicious data until next PUSI=1 arrives
 | 
			
		||||
     pusi_seen = 0;
 | 
			
		||||
     demux_swfilter_section_new();
 | 
			
		||||
     New();
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
  if (buf[1] & 0x40) {
 | 
			
		||||
     /* PUSI=1 (is set), section boundary is here */
 | 
			
		||||
     if (count > 1 && buf[p] < count) {
 | 
			
		||||
#ifdef DEBUG_PRINTF
 | 
			
		||||
        printf("Valid section\n");
 | 
			
		||||
#endif
 | 
			
		||||
        const uint8_t *before = &buf[p + 1];
 | 
			
		||||
        uint8_t before_len = buf[p];
 | 
			
		||||
  if (Data[1] & 0x40) {
 | 
			
		||||
     // PUSI=1 (is set), section boundary is here
 | 
			
		||||
     if (count > 1 && Data[p] < count) {
 | 
			
		||||
        const uint8_t *before = &Data[p + 1];
 | 
			
		||||
        uint8_t before_len = Data[p];
 | 
			
		||||
        const uint8_t *after = &before[before_len];
 | 
			
		||||
        uint8_t after_len = (count - 1) - before_len;
 | 
			
		||||
        uint8_t after_len = (uint8_t)(count - 1 - before_len);
 | 
			
		||||
        CopyDump(before, before_len);
 | 
			
		||||
 | 
			
		||||
        demux_swfilter_section_copy_dump(before, before_len);
 | 
			
		||||
        /* before start of new section, set pusi_seen = 1 */
 | 
			
		||||
        // Before start of new section, set pusi_seen = 1
 | 
			
		||||
        pusi_seen = 1;
 | 
			
		||||
        demux_swfilter_section_new();
 | 
			
		||||
        demux_swfilter_section_copy_dump(after, after_len);
 | 
			
		||||
        New();
 | 
			
		||||
        CopyDump(after, after_len);
 | 
			
		||||
        }
 | 
			
		||||
#ifdef DEMUX_SECTION_LOSS_LOG
 | 
			
		||||
     else if (count > 0)
 | 
			
		||||
        printf("sectionfilter.c PUSI=1 but %d bytes lost\n", count);
 | 
			
		||||
#endif
 | 
			
		||||
     }
 | 
			
		||||
  else {
 | 
			
		||||
     /* PUSI=0 (is not set), no section boundary */
 | 
			
		||||
     demux_swfilter_section_copy_dump(&buf[p], count);
 | 
			
		||||
     // PUSI=0 (is not set), no section boundary
 | 
			
		||||
     CopyDump(&Data[p], count);
 | 
			
		||||
     }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -8,43 +8,19 @@
 | 
			
		||||
#ifndef __IPTV_SECTIONFILTER_H
 | 
			
		||||
#define __IPTV_SECTIONFILTER_H
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <sys/ioctl.h>
 | 
			
		||||
#include <libgen.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <sys/param.h>
 | 
			
		||||
#include <vdr/device.h>
 | 
			
		||||
 | 
			
		||||
#include "common.h"
 | 
			
		||||
#include "statistics.h"
 | 
			
		||||
 | 
			
		||||
class cIptvSectionFilter : public cIptvSectionStatistics {
 | 
			
		||||
private:
 | 
			
		||||
  enum dmx_success {
 | 
			
		||||
    DMX_OK = 0, /* Received Ok */
 | 
			
		||||
    DMX_LENGTH_ERROR, /* Incorrect length */
 | 
			
		||||
    DMX_OVERRUN_ERROR, /* Receiver ring buffer overrun */
 | 
			
		||||
    DMX_CRC_ERROR, /* Incorrect CRC */
 | 
			
		||||
    DMX_FRAME_ERROR, /* Frame alignment error */
 | 
			
		||||
    DMX_FIFO_ERROR, /* Receiver FIFO overrun */
 | 
			
		||||
    DMX_MISSED_ERROR /* Receiver missed packet */
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  enum dmx_limits {
 | 
			
		||||
    DMX_MAX_FILTER_SIZE  = 18,
 | 
			
		||||
    DMX_MAX_SECTION_SIZE = 4096,
 | 
			
		||||
    DMX_MAX_SECFEED_SIZE = (DMX_MAX_SECTION_SIZE + 188)
 | 
			
		||||
    DMX_MAX_SECFEED_SIZE = (DMX_MAX_SECTION_SIZE + TS_SIZE)
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  int fifoDescriptor;
 | 
			
		||||
  int readDescriptor;
 | 
			
		||||
 | 
			
		||||
  int pusi_seen;
 | 
			
		||||
  int feedcc;
 | 
			
		||||
  int doneq;
 | 
			
		||||
@@ -55,49 +31,32 @@ private:
 | 
			
		||||
  uint16_t seclen;
 | 
			
		||||
  uint16_t tsfeedp;
 | 
			
		||||
  uint16_t pid;
 | 
			
		||||
 | 
			
		||||
  int devid;
 | 
			
		||||
  int id;
 | 
			
		||||
  int socket[2];
 | 
			
		||||
 | 
			
		||||
  uint8_t filter_value[DMX_MAX_FILTER_SIZE];
 | 
			
		||||
  uint8_t filter_mask[DMX_MAX_FILTER_SIZE];
 | 
			
		||||
  uint8_t filter_mode[DMX_MAX_FILTER_SIZE];
 | 
			
		||||
   
 | 
			
		||||
 | 
			
		||||
  uint8_t maskandmode[DMX_MAX_FILTER_SIZE];
 | 
			
		||||
  uint8_t maskandnotmode[DMX_MAX_FILTER_SIZE];
 | 
			
		||||
 | 
			
		||||
  cString pipeName;
 | 
			
		||||
 | 
			
		||||
  inline uint16_t section_length(const uint8_t *buf);
 | 
			
		||||
 | 
			
		||||
  int dmxdev_section_callback(const uint8_t *buffer1,
 | 
			
		||||
                              size_t buffer1_len,
 | 
			
		||||
                              const uint8_t *buffer2,
 | 
			
		||||
                              size_t buffer2_len,
 | 
			
		||||
                              enum dmx_success success);
 | 
			
		||||
 | 
			
		||||
  void demux_swfilter_section_new();
 | 
			
		||||
 | 
			
		||||
  int demux_swfilter_sectionfilter();
 | 
			
		||||
 | 
			
		||||
  inline int demux_swfilter_section_feed();
 | 
			
		||||
 | 
			
		||||
  int demux_swfilter_section_copy_dump(const uint8_t *buf,
 | 
			
		||||
                                       uint8_t len);
 | 
			
		||||
 | 
			
		||||
  int GetFifoDesc();
 | 
			
		||||
  void ClearPipeName();
 | 
			
		||||
  void SetPipeName(int deviceIndex);
 | 
			
		||||
  inline uint16_t GetLength(const uint8_t *Data);
 | 
			
		||||
  void New(void);
 | 
			
		||||
  int Filter(void);
 | 
			
		||||
  inline int Feed(void);
 | 
			
		||||
  int CopyDump(const uint8_t *buf, uint8_t len);
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
  // constructor & destructor
 | 
			
		||||
  cIptvSectionFilter(int Index, int devInd, u_short Pid, u_char Tid,
 | 
			
		||||
                     u_char Mask);
 | 
			
		||||
 | 
			
		||||
  cIptvSectionFilter(int Index, int DeviceIndex, uint16_t Pid,
 | 
			
		||||
                     uint8_t Tid, uint8_t Mask);
 | 
			
		||||
  virtual ~cIptvSectionFilter();
 | 
			
		||||
 | 
			
		||||
  void ProcessData(const uint8_t* buf);
 | 
			
		||||
 | 
			
		||||
  int GetReadDesc();
 | 
			
		||||
  uint16_t GetPid() { return pid; }
 | 
			
		||||
  void Process(const uint8_t* Data);
 | 
			
		||||
  int GetReadDesc(void);
 | 
			
		||||
  uint16_t GetPid(void) const { return pid; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // __IPTV_SECTIONFILTER_H
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										31
									
								
								setup.c
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								setup.c
									
									
									
									
									
								
							@@ -17,10 +17,6 @@
 | 
			
		||||
#include "device.h"
 | 
			
		||||
#include "setup.h"
 | 
			
		||||
 | 
			
		||||
#ifndef trVDR
 | 
			
		||||
#define trVDR(s) tr(s)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// --- cIptvMenuEditChannel --------------------------------------------------
 | 
			
		||||
 | 
			
		||||
class cIptvMenuEditChannel : public cOsdMenu
 | 
			
		||||
@@ -34,7 +30,7 @@ private:
 | 
			
		||||
    eProtocolCount
 | 
			
		||||
  };
 | 
			
		||||
  struct tIptvChannel {
 | 
			
		||||
    int frequency, source, protocol, parameter, vpid, ppid, tpid, sid, nid, tid, rid;
 | 
			
		||||
    int frequency, source, protocol, parameter, vpid, ppid, vtype, tpid, sid, nid, tid, rid;
 | 
			
		||||
    int apid[MAXAPIDS + 1], dpid[MAXDPIDS + 1], spid[MAXSPIDS + 1], caids[MAXCAIDS + 1];
 | 
			
		||||
    int sidscan, pidscan;
 | 
			
		||||
    char name[256], location[256];
 | 
			
		||||
@@ -57,7 +53,7 @@ cIptvMenuEditChannel::cIptvMenuEditChannel(cChannel *Channel, bool New)
 | 
			
		||||
  protocols[eProtocolUDP]  = tr("UDP");
 | 
			
		||||
  protocols[eProtocolHTTP] = tr("HTTP");
 | 
			
		||||
  protocols[eProtocolFILE] = tr("FILE");
 | 
			
		||||
  protocols[eProtocolEXT] = tr("EXT");
 | 
			
		||||
  protocols[eProtocolEXT]  = tr("EXT");
 | 
			
		||||
  channel = Channel;
 | 
			
		||||
  GetChannelData(channel);
 | 
			
		||||
  if (New) {
 | 
			
		||||
@@ -127,6 +123,9 @@ void cIptvMenuEditChannel::GetChannelData(cChannel *Channel)
 | 
			
		||||
     data.source = Channel->Source();
 | 
			
		||||
     data.vpid = Channel->Vpid();
 | 
			
		||||
     data.ppid = Channel->Ppid();
 | 
			
		||||
#if defined(APIVERSNUM) && APIVERSNUM >= 10704
 | 
			
		||||
     data.vtype = Channel->Vtype();
 | 
			
		||||
#endif
 | 
			
		||||
     data.tpid = Channel->Tpid();
 | 
			
		||||
     for (unsigned int i = 0; i < ARRAY_SIZE(data.apid); ++i)
 | 
			
		||||
         data.apid[i] = Channel->Apid(i);
 | 
			
		||||
@@ -152,6 +151,7 @@ void cIptvMenuEditChannel::GetChannelData(cChannel *Channel)
 | 
			
		||||
     data.source = cSource::FromData(cSource::stPlug);
 | 
			
		||||
     data.vpid = 0;
 | 
			
		||||
     data.ppid = 0;
 | 
			
		||||
     data.vtype = 0;
 | 
			
		||||
     data.tpid = 0;
 | 
			
		||||
     for (unsigned int i = 0; i < ARRAY_SIZE(data.apid); ++i)
 | 
			
		||||
         data.apid[i] = 0;
 | 
			
		||||
@@ -196,7 +196,11 @@ void cIptvMenuEditChannel::SetChannelData(cChannel *Channel)
 | 
			
		||||
            break;
 | 
			
		||||
       }
 | 
			
		||||
     char slangs[MAXSPIDS][MAXLANGCODE2] = { "" };
 | 
			
		||||
#if defined(APIVERSNUM) && APIVERSNUM >= 10704
 | 
			
		||||
     Channel->SetPids(data.vpid, data.ppid, data.vtype, data.apid, alangs, data.dpid, dlangs, data.spid, slangs, data.tpid);
 | 
			
		||||
#else
 | 
			
		||||
     Channel->SetPids(data.vpid, data.ppid, data.apid, alangs, data.dpid, dlangs, data.spid, slangs, data.tpid);
 | 
			
		||||
#endif
 | 
			
		||||
     Channel->SetCaIds(data.caids);
 | 
			
		||||
     Channel->SetId(data.nid, data.tid, data.sid, data.rid);
 | 
			
		||||
     Channel->SetName(data.name, "", "IPTV");
 | 
			
		||||
@@ -236,6 +240,9 @@ void cIptvMenuEditChannel::Setup(void)
 | 
			
		||||
  Add(new cMenuEditStrItem(trVDR("Name"),       data.name,     sizeof(data.name)));
 | 
			
		||||
  Add(new cMenuEditIntItem(trVDR("Frequency"), &data.frequency));
 | 
			
		||||
  Add(new cMenuEditIntItem(trVDR("Vpid"),      &data.vpid,     0, 0x1FFF));
 | 
			
		||||
#if defined(APIVERSNUM) && APIVERSNUM >= 10704
 | 
			
		||||
  Add(new cMenuEditIntItem(tr   ("Vtype"),     &data.vtype,    0, 0xFF));
 | 
			
		||||
#endif
 | 
			
		||||
  Add(new cMenuEditIntItem(trVDR("Ppid"),      &data.ppid,     0, 0x1FFF));
 | 
			
		||||
  Add(new cMenuEditIntItem(trVDR("Apid1"),     &data.apid[0],  0, 0x1FFF));
 | 
			
		||||
  Add(new cMenuEditIntItem(trVDR("Apid2"),     &data.apid[1],  0, 0x1FFF));
 | 
			
		||||
@@ -380,7 +387,7 @@ class cIptvMenuChannels : public cOsdMenu
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
  void Setup(void);
 | 
			
		||||
  cChannel *GetChannel(int Index);
 | 
			
		||||
  cChannel *GetChannel(int Index) const;
 | 
			
		||||
  void Propagate(void);
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
@@ -420,16 +427,16 @@ void cIptvMenuChannels::Setup(void)
 | 
			
		||||
  Display();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cChannel *cIptvMenuChannels::GetChannel(int Index)
 | 
			
		||||
cChannel *cIptvMenuChannels::GetChannel(int Index) const
 | 
			
		||||
{
 | 
			
		||||
  cIptvMenuChannelItem *p = (cIptvMenuChannelItem *)Get(Index);
 | 
			
		||||
  cIptvMenuChannelItem *p = dynamic_cast<cIptvMenuChannelItem *>(Get(Index));
 | 
			
		||||
  return p ? (cChannel *)p->Channel() : NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cIptvMenuChannels::Propagate(void)
 | 
			
		||||
{
 | 
			
		||||
  Channels.ReNumber();
 | 
			
		||||
  for (cIptvMenuChannelItem *ci = (cIptvMenuChannelItem *)First(); ci; ci = (cIptvMenuChannelItem *)ci->Next())
 | 
			
		||||
  for (cIptvMenuChannelItem *ci = dynamic_cast<cIptvMenuChannelItem *>(First()); ci; ci = dynamic_cast<cIptvMenuChannelItem *>(ci->Next()))
 | 
			
		||||
      ci->Set();
 | 
			
		||||
  Display();
 | 
			
		||||
  Channels.SetModified(true);
 | 
			
		||||
@@ -607,7 +614,7 @@ eOSState cIptvMenuInfo::ProcessKey(eKeys Key)
 | 
			
		||||
       case kYellow: page = IPTV_DEVICE_INFO_FILTERS;
 | 
			
		||||
                     UpdateInfo();
 | 
			
		||||
                     break;
 | 
			
		||||
       case kBlue:   IptvConfig.SetUseBytes(!IptvConfig.GetUseBytes());
 | 
			
		||||
       case kBlue:   IptvConfig.SetUseBytes(IptvConfig.GetUseBytes() ? 0 : 1);
 | 
			
		||||
                     UpdateInfo();
 | 
			
		||||
                     break;
 | 
			
		||||
       default:      if (timeout.TimedOut())
 | 
			
		||||
@@ -701,7 +708,7 @@ eOSState cIptvPluginSetup::ProcessKey(eKeys Key)
 | 
			
		||||
       case kBlue: return ShowInfo();
 | 
			
		||||
       case kInfo: if (Current() < help.Size())
 | 
			
		||||
                      return AddSubMenu(new cMenuText(cString::sprintf("%s - %s '%s'", tr("Help"), trVDR("Plugin"), PLUGIN_NAME_I18N), help[Current()]));
 | 
			
		||||
       default:    state = osContinue;
 | 
			
		||||
       default:    state = osContinue; break;
 | 
			
		||||
       }
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								setup.h
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								setup.h
									
									
									
									
									
								
							@@ -25,7 +25,7 @@ private:
 | 
			
		||||
 | 
			
		||||
  eOSState EditChannel(void);
 | 
			
		||||
  eOSState ShowInfo(void);
 | 
			
		||||
  virtual void Setup(void);
 | 
			
		||||
  void Setup(void);
 | 
			
		||||
  void StoreFilters(const char *Name, int *Values);
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
 
 | 
			
		||||
@@ -51,8 +51,9 @@ void cSidScanner::Process(u_short Pid, u_char Tid, const u_char *Data, int Lengt
 | 
			
		||||
               if (!Channels.Lock(true, 10))
 | 
			
		||||
                  return;
 | 
			
		||||
               cChannel *IptvChannel = Channels.GetByChannelID(channel.GetChannelID());
 | 
			
		||||
               IptvChannel->SetId(IptvChannel->Nid(), IptvChannel->Tid(),
 | 
			
		||||
                                  assoc.getServiceId(), IptvChannel->Rid());
 | 
			
		||||
               if (IptvChannel)
 | 
			
		||||
                  IptvChannel->SetId(IptvChannel->Nid(), IptvChannel->Tid(),
 | 
			
		||||
                                    assoc.getServiceId(), IptvChannel->Rid());
 | 
			
		||||
               Channels.Unlock();
 | 
			
		||||
               }
 | 
			
		||||
            SetChannel(NULL);
 | 
			
		||||
 
 | 
			
		||||
@@ -17,11 +17,13 @@ private:
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
  virtual void Process(u_short Pid, u_char Tid, const u_char *Data, int Length);
 | 
			
		||||
  virtual void SetStatus(bool On);
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
  cSidScanner(void);
 | 
			
		||||
  virtual void SetStatus(bool On);
 | 
			
		||||
  void SetChannel(const cChannel *Channel);
 | 
			
		||||
  void Open() { SetStatus(true); }
 | 
			
		||||
  void Close() { SetStatus(false); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // __SIDSCANNER_H
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										121
									
								
								socket.c
									
									
									
									
									
								
							
							
						
						
									
										121
									
								
								socket.c
									
									
									
									
									
								
							@@ -20,14 +20,9 @@
 | 
			
		||||
cIptvSocket::cIptvSocket()
 | 
			
		||||
: socketPort(0),
 | 
			
		||||
  socketDesc(-1),
 | 
			
		||||
  readBufferLen(TS_SIZE * IptvConfig.GetReadBufferTsCount()),
 | 
			
		||||
  isActive(false)
 | 
			
		||||
{
 | 
			
		||||
  debug("cIptvSocket::cIptvSocket()\n");
 | 
			
		||||
  // Allocate receive buffer
 | 
			
		||||
  readBuffer = MALLOC(unsigned char, readBufferLen);
 | 
			
		||||
  if (!readBuffer)
 | 
			
		||||
     error("ERROR: MALLOC() failed in socket()");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cIptvSocket::~cIptvSocket()
 | 
			
		||||
@@ -35,8 +30,6 @@ cIptvSocket::~cIptvSocket()
 | 
			
		||||
  debug("cIptvSocket::~cIptvSocket()\n");
 | 
			
		||||
  // Close the socket
 | 
			
		||||
  CloseSocket();
 | 
			
		||||
  // Free allocated memory
 | 
			
		||||
  free(readBuffer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cIptvSocket::OpenSocket(const int Port, const bool isUdp)
 | 
			
		||||
@@ -50,7 +43,7 @@ bool cIptvSocket::OpenSocket(const int Port, const bool isUdp)
 | 
			
		||||
     }
 | 
			
		||||
  // Bind to the socket if it is not active already
 | 
			
		||||
  if (socketDesc < 0) {
 | 
			
		||||
     int yes = 1;     
 | 
			
		||||
     int yes = 1;
 | 
			
		||||
     // Create socket
 | 
			
		||||
     if (isUdp)
 | 
			
		||||
        socketDesc = socket(PF_INET, SOCK_DGRAM, 0);
 | 
			
		||||
@@ -58,14 +51,15 @@ bool cIptvSocket::OpenSocket(const int Port, const bool isUdp)
 | 
			
		||||
        socketDesc = socket(PF_INET, SOCK_STREAM, 0);
 | 
			
		||||
     ERROR_IF_RET(socketDesc < 0, "socket()", return false);
 | 
			
		||||
     // Make it use non-blocking I/O to avoid stuck read calls
 | 
			
		||||
     ERROR_IF_FUNC(fcntl(socketDesc, F_SETFL, O_NONBLOCK), "fcntl()", CloseSocket(), return false);
 | 
			
		||||
     ERROR_IF_FUNC(fcntl(socketDesc, F_SETFL, O_NONBLOCK), "fcntl()",
 | 
			
		||||
                   CloseSocket(), return false);
 | 
			
		||||
     // Allow multiple sockets to use the same PORT number
 | 
			
		||||
     ERROR_IF_FUNC(setsockopt(socketDesc, SOL_SOCKET, SO_REUSEADDR, &yes,
 | 
			
		||||
                              sizeof(yes)) < 0, "setsockopt()", CloseSocket(), return false);
 | 
			
		||||
     ERROR_IF_FUNC(setsockopt(socketDesc, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0, "setsockopt()",
 | 
			
		||||
                   CloseSocket(), return false);
 | 
			
		||||
     // Bind socket
 | 
			
		||||
     memset(&sockAddr, '\0', sizeof(sockAddr));
 | 
			
		||||
     sockAddr.sin_family = AF_INET;
 | 
			
		||||
     sockAddr.sin_port = htons(Port);
 | 
			
		||||
     sockAddr.sin_port = htons((uint16_t)(Port & 0xFFFF));
 | 
			
		||||
     sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
 | 
			
		||||
     if (isUdp) {
 | 
			
		||||
        int err = bind(socketDesc, (struct sockaddr *)&sockAddr, sizeof(sockAddr));
 | 
			
		||||
@@ -104,60 +98,49 @@ bool cIptvUdpSocket::OpenSocket(const int Port)
 | 
			
		||||
  return cIptvSocket::OpenSocket(Port, true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int cIptvUdpSocket::Read(unsigned char* *BufferAddr)
 | 
			
		||||
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);
 | 
			
		||||
  // Set argument point to read buffer
 | 
			
		||||
  *BufferAddr = readBuffer;
 | 
			
		||||
  // Wait 500ms for data
 | 
			
		||||
  int retval = select_single_desc(socketDesc, 500000, false);
 | 
			
		||||
  // Check if error
 | 
			
		||||
  if (retval < 0)
 | 
			
		||||
     return retval;
 | 
			
		||||
  // Check if data available
 | 
			
		||||
  else if (retval) {
 | 
			
		||||
     int len = 0;
 | 
			
		||||
     // Read data from socket
 | 
			
		||||
     if (isActive)
 | 
			
		||||
        len = recvfrom(socketDesc, readBuffer, readBufferLen, MSG_DONTWAIT,
 | 
			
		||||
                       (struct sockaddr *)&sockAddr, &addrlen);
 | 
			
		||||
     ERROR_IF_RET(len < 0, "recvfrom()", return len);
 | 
			
		||||
     if ((len > 0) && (readBuffer[0] == 0x47)) {
 | 
			
		||||
        // Set argument point to read buffer
 | 
			
		||||
        *BufferAddr = &readBuffer[0];
 | 
			
		||||
        return len;
 | 
			
		||||
  int len = 0;
 | 
			
		||||
  // Read data from socket
 | 
			
		||||
  if (isActive && socketDesc && BufferAddr && (BufferLen > 0))
 | 
			
		||||
     len = (int)recvfrom(socketDesc, BufferAddr, BufferLen, MSG_DONTWAIT,
 | 
			
		||||
                    (struct sockaddr *)&sockAddr, &addrlen);
 | 
			
		||||
  if ((len > 0) && (BufferAddr[0] == TS_SYNC_BYTE)) {
 | 
			
		||||
     return len;
 | 
			
		||||
     }
 | 
			
		||||
  else if (len > 3) {
 | 
			
		||||
     // http://www.networksorcery.com/enp/rfc/rfc2250.txt
 | 
			
		||||
     // version
 | 
			
		||||
     unsigned int v = (BufferAddr[0] >> 6) & 0x03;
 | 
			
		||||
     // extension bit
 | 
			
		||||
     unsigned int x = (BufferAddr[0] >> 4) & 0x01;
 | 
			
		||||
     // cscr count
 | 
			
		||||
     unsigned int cc = BufferAddr[0] & 0x0F;
 | 
			
		||||
     // payload type: MPEG2 TS = 33
 | 
			
		||||
     //unsigned int pt = readBuffer[1] & 0x7F;
 | 
			
		||||
     // header lenght
 | 
			
		||||
     unsigned int headerlen = (3 + cc) * (unsigned int)sizeof(uint32_t);
 | 
			
		||||
     // check if extension
 | 
			
		||||
     if (x) {
 | 
			
		||||
        // extension header length
 | 
			
		||||
        unsigned int ehl = (((BufferAddr[headerlen + 2] & 0xFF) << 8) |
 | 
			
		||||
                            (BufferAddr[headerlen + 3] & 0xFF));
 | 
			
		||||
        // update header length
 | 
			
		||||
        headerlen += (ehl + 1) * (unsigned int)sizeof(uint32_t);
 | 
			
		||||
        }
 | 
			
		||||
     else if (len > 3) {
 | 
			
		||||
        // http://www.networksorcery.com/enp/rfc/rfc2250.txt
 | 
			
		||||
        // version
 | 
			
		||||
        unsigned int v = (readBuffer[0] >> 6) & 0x03;
 | 
			
		||||
        // extension bit
 | 
			
		||||
        unsigned int x = (readBuffer[0] >> 4) & 0x01;
 | 
			
		||||
        // cscr count
 | 
			
		||||
        unsigned int cc = readBuffer[0] & 0x0F;
 | 
			
		||||
        // payload type: MPEG2 TS = 33
 | 
			
		||||
        //unsigned int pt = readBuffer[1] & 0x7F;
 | 
			
		||||
        // header lenght
 | 
			
		||||
        unsigned int headerlen = (3 + cc) * sizeof(uint32_t);
 | 
			
		||||
        // check if extension
 | 
			
		||||
        if (x) {
 | 
			
		||||
           // extension header length
 | 
			
		||||
           unsigned int ehl = (((readBuffer[headerlen + 2] & 0xFF) << 8) | (readBuffer[headerlen + 3] & 0xFF));
 | 
			
		||||
           // update header length
 | 
			
		||||
           headerlen += (ehl + 1) * sizeof(uint32_t);
 | 
			
		||||
           }
 | 
			
		||||
        // Check that rtp is version 2 and payload contains multiple of TS packet data
 | 
			
		||||
        if ((v == 2) && (((len - headerlen) % TS_SIZE) == 0) && (readBuffer[headerlen] == 0x47)) {
 | 
			
		||||
           // Set argument point to payload in read buffer
 | 
			
		||||
           *BufferAddr = &readBuffer[headerlen];
 | 
			
		||||
           return (len - headerlen);
 | 
			
		||||
           }
 | 
			
		||||
     // Check that rtp is version 2 and payload contains multiple of TS packet data
 | 
			
		||||
     if ((v == 2) && (((len - headerlen) % TS_SIZE) == 0) &&
 | 
			
		||||
         (BufferAddr[headerlen] == TS_SYNC_BYTE)) {
 | 
			
		||||
        // Set argument point to payload in read buffer
 | 
			
		||||
        memmove(BufferAddr, &BufferAddr[headerlen], (len - headerlen));
 | 
			
		||||
        return (len - headerlen);
 | 
			
		||||
        }
 | 
			
		||||
     }
 | 
			
		||||
  return 0;
 | 
			
		||||
@@ -180,28 +163,18 @@ bool cIptvTcpSocket::OpenSocket(const int Port)
 | 
			
		||||
  return cIptvSocket::OpenSocket(Port, false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int cIptvTcpSocket::Read(unsigned char* *BufferAddr)
 | 
			
		||||
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);
 | 
			
		||||
  // Set argument point to read buffer
 | 
			
		||||
  *BufferAddr = readBuffer;
 | 
			
		||||
  // Wait 500ms for data
 | 
			
		||||
  int retval = select_single_desc(socketDesc, 500000, false);
 | 
			
		||||
  // Check if error
 | 
			
		||||
  if (retval < 0)
 | 
			
		||||
     return retval;
 | 
			
		||||
  // Check if data available
 | 
			
		||||
  else if (retval) {
 | 
			
		||||
     // Read data from socket
 | 
			
		||||
     if (isActive)
 | 
			
		||||
        return recvfrom(socketDesc, readBuffer, readBufferLen, MSG_DONTWAIT,
 | 
			
		||||
                        (struct sockaddr *)&sockAddr, &addrlen);
 | 
			
		||||
     }
 | 
			
		||||
  // Read data from socket
 | 
			
		||||
  if (isActive && socketDesc && BufferAddr && (BufferLen > 0))
 | 
			
		||||
     return (int)recvfrom(socketDesc, BufferAddr, BufferLen, MSG_DONTWAIT,
 | 
			
		||||
                     (struct sockaddr *)&sockAddr, &addrlen);
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								socket.h
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								socket.h
									
									
									
									
									
								
							@@ -14,8 +14,6 @@ class cIptvSocket {
 | 
			
		||||
protected:
 | 
			
		||||
  int socketPort;
 | 
			
		||||
  int socketDesc;
 | 
			
		||||
  unsigned char* readBuffer;
 | 
			
		||||
  unsigned int readBufferLen;
 | 
			
		||||
  struct sockaddr_in sockAddr;
 | 
			
		||||
  bool isActive;
 | 
			
		||||
 | 
			
		||||
@@ -32,7 +30,7 @@ class cIptvUdpSocket : public cIptvSocket {
 | 
			
		||||
public:
 | 
			
		||||
  cIptvUdpSocket();
 | 
			
		||||
  virtual ~cIptvUdpSocket();
 | 
			
		||||
  virtual int Read(unsigned char* *BufferAddr);
 | 
			
		||||
  virtual int Read(unsigned char* BufferAddr, unsigned int BufferLen);
 | 
			
		||||
  bool OpenSocket(const int Port);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -40,7 +38,7 @@ class cIptvTcpSocket : public cIptvSocket {
 | 
			
		||||
public:
 | 
			
		||||
  cIptvTcpSocket();
 | 
			
		||||
  virtual ~cIptvTcpSocket();
 | 
			
		||||
  virtual int Read(unsigned char* *BufferAddr);
 | 
			
		||||
  virtual int Read(unsigned char* BufferAddr, unsigned int BufferLen);
 | 
			
		||||
  bool OpenSocket(const int Port);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								statistics.c
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								statistics.c
									
									
									
									
									
								
							@@ -32,7 +32,7 @@ cString cIptvSectionStatistics::GetSectionStatistic()
 | 
			
		||||
  cMutexLock MutexLock(&mutex);
 | 
			
		||||
  uint64_t elapsed = timer.Elapsed(); /* in milliseconds */
 | 
			
		||||
  timer.Set();
 | 
			
		||||
  long bitrate = elapsed ? (long)((float)1000 / KILOBYTE(1) * filteredData / 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 ? (long)((float)1000 / KILOBYTE(1) * mostActivePids[i].DataAmount / 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,
 | 
			
		||||
@@ -119,7 +119,7 @@ void cIptvPidStatistics::AddPidStatistic(u_short Pid, long Payload)
 | 
			
		||||
      mostActivePids[numberOfElements - 1].pid = Pid;
 | 
			
		||||
      mostActivePids[numberOfElements - 1].DataAmount = Payload;
 | 
			
		||||
     // Re-sort
 | 
			
		||||
     qsort(&mostActivePids, numberOfElements, sizeof(pidStruct), SortPids);
 | 
			
		||||
     qsort(mostActivePids, numberOfElements, sizeof(pidStruct), SortPids);
 | 
			
		||||
     }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -145,7 +145,7 @@ cString cIptvStreamerStatistics::GetStreamerStatistic()
 | 
			
		||||
  cMutexLock MutexLock(&mutex);
 | 
			
		||||
  uint64_t elapsed = timer.Elapsed(); /* in milliseconds */
 | 
			
		||||
  timer.Set();
 | 
			
		||||
  long bitrate = elapsed ? (long)((float)1000 / KILOBYTE(1) * dataBytes / 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 ? (long)((float)1000 / KILOBYTE(1) * dataBytes / 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);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										70
									
								
								streamer.c
									
									
									
									
									
								
							
							
						
						
									
										70
									
								
								streamer.c
									
									
									
									
									
								
							@@ -11,13 +11,19 @@
 | 
			
		||||
#include "common.h"
 | 
			
		||||
#include "streamer.h"
 | 
			
		||||
 | 
			
		||||
cIptvStreamer::cIptvStreamer(cRingBufferLinear* RingBuffer, cMutex* Mutex)
 | 
			
		||||
cIptvStreamer::cIptvStreamer(cRingBufferLinear* RingBuffer, unsigned int PacketLen)
 | 
			
		||||
: cThread("IPTV streamer"),
 | 
			
		||||
  ringBuffer(RingBuffer),
 | 
			
		||||
  mutex(Mutex),
 | 
			
		||||
  packetBufferLen(PacketLen),
 | 
			
		||||
  protocol(NULL)
 | 
			
		||||
{
 | 
			
		||||
  debug("cIptvStreamer::cIptvStreamer()\n");
 | 
			
		||||
  debug("cIptvStreamer::cIptvStreamer(%d)\n", packetBufferLen);
 | 
			
		||||
  // Allocate packet buffer
 | 
			
		||||
  packetBuffer = MALLOC(unsigned char, packetBufferLen);
 | 
			
		||||
  if (packetBuffer)
 | 
			
		||||
     memset(packetBuffer, 0, packetBufferLen);
 | 
			
		||||
  else
 | 
			
		||||
     error("MALLOC() failed for packet buffer");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cIptvStreamer::~cIptvStreamer()
 | 
			
		||||
@@ -25,32 +31,33 @@ cIptvStreamer::~cIptvStreamer()
 | 
			
		||||
  debug("cIptvStreamer::~cIptvStreamer()\n");
 | 
			
		||||
  // Close the protocol
 | 
			
		||||
  Close();
 | 
			
		||||
  protocol = NULL;
 | 
			
		||||
  ringBuffer = NULL;
 | 
			
		||||
  // Free allocated memory
 | 
			
		||||
  free(packetBuffer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cIptvStreamer::Action(void)
 | 
			
		||||
{
 | 
			
		||||
  debug("cIptvStreamer::Action(): Entering\n");
 | 
			
		||||
  // Increase priority
 | 
			
		||||
  //SetPriority(-1);
 | 
			
		||||
  // Do the thread loop
 | 
			
		||||
  while (Running()) {
 | 
			
		||||
    if (ringBuffer && mutex && protocol && ringBuffer->Free()) {
 | 
			
		||||
       unsigned char *buffer = NULL;
 | 
			
		||||
       mutex->Lock();
 | 
			
		||||
       int length = protocol->Read(&buffer);
 | 
			
		||||
       if (length >= 0) {
 | 
			
		||||
          AddStreamerStatistic(length);
 | 
			
		||||
          int p = ringBuffer->Put(buffer, length);
 | 
			
		||||
          if (p != length && Running())
 | 
			
		||||
             ringBuffer->ReportOverflow(length - p);
 | 
			
		||||
          mutex->Unlock();
 | 
			
		||||
          }
 | 
			
		||||
       else {
 | 
			
		||||
          mutex->Unlock();
 | 
			
		||||
          sleep.Wait(100); // to reduce cpu load
 | 
			
		||||
          }
 | 
			
		||||
       }
 | 
			
		||||
    else
 | 
			
		||||
       sleep.Wait(100); // and avoid busy loop
 | 
			
		||||
    }
 | 
			
		||||
  while (packetBuffer && Running()) {
 | 
			
		||||
        int length = -1;
 | 
			
		||||
        if (protocol)
 | 
			
		||||
           length = protocol->Read(packetBuffer, packetBufferLen);
 | 
			
		||||
        if (length > 0) {
 | 
			
		||||
           AddStreamerStatistic(length);
 | 
			
		||||
           if (ringBuffer) {
 | 
			
		||||
              int p = ringBuffer->Put(packetBuffer, length);
 | 
			
		||||
              if (p != length)
 | 
			
		||||
                 ringBuffer->ReportOverflow(length - p);
 | 
			
		||||
              }
 | 
			
		||||
           }
 | 
			
		||||
        else
 | 
			
		||||
           sleep.Wait(10); // to avoid busy loop and reduce cpu load
 | 
			
		||||
        }
 | 
			
		||||
  debug("cIptvStreamer::Action(): Exiting\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -72,15 +79,9 @@ bool cIptvStreamer::Close(void)
 | 
			
		||||
  sleep.Signal();
 | 
			
		||||
  if (Running())
 | 
			
		||||
     Cancel(3);
 | 
			
		||||
  // Close the protocol. A mutex should be taken here to avoid a race condition
 | 
			
		||||
  // where thread Action() may be in the process of accessing the protocol.
 | 
			
		||||
  // Taking a mutex serializes the Close() and Action() -calls.
 | 
			
		||||
  if (mutex)
 | 
			
		||||
     mutex->Lock();
 | 
			
		||||
  // Close the protocol
 | 
			
		||||
  if (protocol)
 | 
			
		||||
     protocol->Close();
 | 
			
		||||
  if (mutex)
 | 
			
		||||
     mutex->Unlock();
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -88,16 +89,17 @@ bool cIptvStreamer::Set(const char* Location, const int Parameter, const int Ind
 | 
			
		||||
{
 | 
			
		||||
  debug("cIptvStreamer::Set(): %s:%d\n", Location, Parameter);
 | 
			
		||||
  if (!isempty(Location)) {
 | 
			
		||||
     // Update protocol; Close the existing one if changed
 | 
			
		||||
     // Update protocol and set location and parameter; Close the existing one if changed
 | 
			
		||||
     if (protocol != Protocol) {
 | 
			
		||||
        if (protocol)
 | 
			
		||||
           protocol->Close();
 | 
			
		||||
        protocol = Protocol;
 | 
			
		||||
        if (protocol)
 | 
			
		||||
        if (protocol) {
 | 
			
		||||
           protocol->Set(Location, Parameter, Index);
 | 
			
		||||
           protocol->Open();
 | 
			
		||||
           }
 | 
			
		||||
        }
 | 
			
		||||
     // Set protocol location and parameter
 | 
			
		||||
     if (protocol)
 | 
			
		||||
     else if (protocol)
 | 
			
		||||
        protocol->Set(Location, Parameter, Index);
 | 
			
		||||
     }
 | 
			
		||||
  return true;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										13
									
								
								streamer.h
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								streamer.h
									
									
									
									
									
								
							@@ -19,16 +19,17 @@
 | 
			
		||||
class cIptvStreamer : public cThread, public cIptvStreamerStatistics {
 | 
			
		||||
private:
 | 
			
		||||
  cRingBufferLinear* ringBuffer;
 | 
			
		||||
  cMutex* mutex;
 | 
			
		||||
  cCondWait sleep;
 | 
			
		||||
  unsigned char* readBuffer;
 | 
			
		||||
  unsigned int readBufferLen;
 | 
			
		||||
  unsigned char* packetBuffer;
 | 
			
		||||
  unsigned int packetBufferLen;
 | 
			
		||||
  cIptvProtocolIf* protocol;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
  cIptvStreamer(cRingBufferLinear* RingBuffer, cMutex* Mutex);
 | 
			
		||||
  virtual ~cIptvStreamer();
 | 
			
		||||
protected:
 | 
			
		||||
  virtual void Action(void);
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
  cIptvStreamer(cRingBufferLinear* RingBuffer, unsigned int PacketLen);
 | 
			
		||||
  virtual ~cIptvStreamer();
 | 
			
		||||
  bool Set(const char* Location, const int Parameter, const int Index, cIptvProtocolIf* Protocol);
 | 
			
		||||
  bool Open(void);
 | 
			
		||||
  bool Close(void);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user