mirror of
https://github.com/rofafor/vdr-plugin-iptv.git
synced 2023-10-10 11:37:03 +00:00
Compare commits
23 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 |
27
HISTORY
27
HISTORY
@@ -94,3 +94,30 @@ VDR Plugin 'iptv' Revision History
|
||||
- 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.
|
||||
|
||||
2
Makefile
2
Makefile
@@ -23,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;
|
||||
|
||||
21
common.h
21
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
|
||||
@@ -41,16 +40,14 @@
|
||||
|
||||
#define SECTION_FILTER_TABLE_SIZE 7
|
||||
|
||||
#define TS_SYNC_BYTE 0x47
|
||||
|
||||
#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)
|
||||
|
||||
|
||||
|
||||
2
config.c
2
config.c
@@ -24,7 +24,7 @@ cIptvConfig::cIptvConfig(void)
|
||||
unsigned int cIptvConfig::GetDisabledFiltersCount(void) const
|
||||
{
|
||||
unsigned int n = 0;
|
||||
while ((disabledFilters[n] != -1) && (n < ARRAY_SIZE(disabledFilters)))
|
||||
while ((n < ARRAY_SIZE(disabledFilters) && (disabledFilters[n] != -1)))
|
||||
n++;
|
||||
return n;
|
||||
}
|
||||
|
||||
21
device.c
21
device.c
@@ -10,7 +10,7 @@
|
||||
|
||||
#define IPTV_MAX_DEVICES MAXDEVICES
|
||||
|
||||
cIptvDevice * IptvDevices[IPTV_MAX_DEVICES] = { NULL };
|
||||
static cIptvDevice * IptvDevices[IPTV_MAX_DEVICES] = { NULL };
|
||||
|
||||
unsigned int cIptvDevice::deviceCount = 0;
|
||||
|
||||
@@ -272,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;
|
||||
@@ -304,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
|
||||
@@ -329,6 +329,8 @@ 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]) {
|
||||
@@ -343,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);
|
||||
@@ -361,7 +366,7 @@ bool cIptvDevice::OpenDvr(void)
|
||||
if (pIptvStreamer)
|
||||
pIptvStreamer->Open();
|
||||
if (sidScanEnabled && pSidScanner && IptvConfig.GetSectionFiltering())
|
||||
pSidScanner->SetStatus(true);
|
||||
pSidScanner->Open();
|
||||
isOpenDvr = true;
|
||||
return true;
|
||||
}
|
||||
@@ -370,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;
|
||||
@@ -422,7 +427,7 @@ bool cIptvDevice::GetTSPacket(uchar *&Data)
|
||||
}
|
||||
}
|
||||
tsBuffer->Del(Count);
|
||||
error("ERROR: skipped %d bytes to sync on TS packet\n", Count);
|
||||
error("Skipped %d bytes to sync on TS packet\n", Count);
|
||||
return false;
|
||||
}
|
||||
isPacketDelivered = true;
|
||||
@@ -431,10 +436,12 @@ bool cIptvDevice::GetTSPacket(uchar *&Data)
|
||||
AddPidStatistic(ts_pid(p), payload(p));
|
||||
// Send data also to dvr fifo
|
||||
if (dvrFd >= 0)
|
||||
Count = 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])
|
||||
|
||||
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.5";
|
||||
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
|
||||
@@ -61,7 +61,7 @@ ffmpeg -v -1 \
|
||||
-i "${FIFO}" \
|
||||
-title "${TITLE}" \
|
||||
-f mpegts -acodec mp2 -ac 2 -ab 96k -ar 48000 \
|
||||
- | nc -u 127.0.0.1 ${PORT}
|
||||
"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
|
||||
@@ -50,5 +50,5 @@ ffmpeg -v -1 \
|
||||
-i - \
|
||||
-title "${TITLE}" \
|
||||
-f mpegts -acodec mp2 -ac 2 -ab 128k -ar 48000 \
|
||||
- | nc -nu 127.0.0.1 ${PORT}
|
||||
"udp://127.0.0.1:${PORT}?pkt_size=16356"
|
||||
} > ${LOG} 2>&1
|
||||
|
||||
@@ -63,7 +63,7 @@ ffmpeg -v -1 \
|
||||
-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}
|
||||
"udp://127.0.0.1:${PORT}?pkt_size=16356"
|
||||
|
||||
rm -f "${FIFO}"
|
||||
} > ${LOG} 2>&1
|
||||
|
||||
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,6 +1,6 @@
|
||||
diff -Nru vdr-1.7.4-vanilla/channels.c vdr-1.7.4-pluginparam/channels.c
|
||||
--- vdr-1.7.4-vanilla/channels.c 2009-01-26 11:44:48.000000000 +0200
|
||||
+++ vdr-1.7.4-pluginparam/channels.c 2009-02-24 13:31:33.000000000 +0200
|
||||
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("");
|
||||
@@ -33,7 +33,7 @@ diff -Nru vdr-1.7.4-vanilla/channels.c vdr-1.7.4-pluginparam/channels.c
|
||||
memcpy(&__BeginData__, &Channel.__BeginData__, (char *)&Channel.__EndData__ - (char *)&Channel.__BeginData__);
|
||||
return *this;
|
||||
}
|
||||
@@ -306,9 +310,26 @@
|
||||
@@ -307,9 +311,26 @@
|
||||
guard = Channel->guard;
|
||||
hierarchy = Channel->hierarchy;
|
||||
rollOff = Channel->rollOff;
|
||||
@@ -60,7 +60,7 @@ diff -Nru vdr-1.7.4-vanilla/channels.c vdr-1.7.4-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:
|
||||
@@ -438,6 +459,18 @@
|
||||
@@ -439,6 +460,18 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ diff -Nru vdr-1.7.4-vanilla/channels.c vdr-1.7.4-pluginparam/channels.c
|
||||
#define STRDIFF 0x01
|
||||
#define VALDIFF 0x02
|
||||
|
||||
@@ -632,7 +665,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.4-vanilla/channels.c vdr-1.7.4-pluginparam/channels.c
|
||||
char *q = buffer;
|
||||
*q = 0;
|
||||
ST(" S ") q += sprintf(q, "%c", polarization);
|
||||
@@ -646,6 +679,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,7 +96,7 @@ diff -Nru vdr-1.7.4-vanilla/channels.c vdr-1.7.4-pluginparam/channels.c
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@@ -674,7 +708,7 @@
|
||||
@@ -694,7 +728,7 @@
|
||||
|
||||
bool cChannel::StringToParameters(const char *s)
|
||||
{
|
||||
@@ -105,7 +105,7 @@ diff -Nru vdr-1.7.4-vanilla/channels.c vdr-1.7.4-pluginparam/channels.c
|
||||
switch (toupper(*s)) {
|
||||
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;
|
||||
@@ -792,7 +826,7 @@
|
||||
@@ -814,7 +848,7 @@
|
||||
dpids[0] = 0;
|
||||
ok = false;
|
||||
if (parambuf && sourcebuf && vpidbuf && apidbuf) {
|
||||
@@ -114,7 +114,7 @@ diff -Nru vdr-1.7.4-vanilla/channels.c vdr-1.7.4-pluginparam/channels.c
|
||||
|
||||
char *p;
|
||||
if ((p = strchr(vpidbuf, '=')) != NULL) {
|
||||
@@ -887,6 +921,7 @@
|
||||
@@ -911,6 +945,7 @@
|
||||
shortName = strcpyrealloc(shortName, p);
|
||||
}
|
||||
name = strcpyrealloc(name, namebuf);
|
||||
@@ -122,9 +122,9 @@ diff -Nru vdr-1.7.4-vanilla/channels.c vdr-1.7.4-pluginparam/channels.c
|
||||
|
||||
free(parambuf);
|
||||
free(sourcebuf);
|
||||
diff -Nru vdr-1.7.4-vanilla/channels.h vdr-1.7.4-pluginparam/channels.h
|
||||
--- vdr-1.7.4-vanilla/channels.h 2009-01-26 11:44:48.000000000 +0200
|
||||
+++ vdr-1.7.4-pluginparam/channels.h 2009-02-24 13:31:33.000000000 +0200
|
||||
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;
|
||||
@@ -133,7 +133,7 @@ diff -Nru vdr-1.7.4-vanilla/channels.h vdr-1.7.4-pluginparam/channels.h
|
||||
int __BeginData__;
|
||||
int frequency; // MHz
|
||||
int source;
|
||||
@@ -171,6 +172,7 @@
|
||||
@@ -174,6 +175,7 @@
|
||||
int Frequency(void) const { return frequency; } ///< Returns the actual frequency, as given in 'channels.conf'
|
||||
int Transponder(void) const; ///< Returns the transponder frequency in MHz, plus the polarization in case of sat
|
||||
static int Transponder(int Frequency, char Polarization); ///< builds the transponder from the given Frequency and Polarization
|
||||
@@ -141,7 +141,7 @@ diff -Nru vdr-1.7.4-vanilla/channels.h vdr-1.7.4-pluginparam/channels.h
|
||||
int Source(void) const { return source; }
|
||||
int Srate(void) const { return srate; }
|
||||
int Vpid(void) const { return vpid; }
|
||||
@@ -208,6 +210,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,7 +149,7 @@ diff -Nru vdr-1.7.4-vanilla/channels.h vdr-1.7.4-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); }
|
||||
@@ -215,12 +218,14 @@
|
||||
@@ -221,12 +224,14 @@
|
||||
bool HasTimer(void) const;
|
||||
int Modification(int Mask = CHANNELMOD_ALL);
|
||||
void CopyTransponderData(const cChannel *Channel);
|
||||
@@ -164,21 +164,21 @@ diff -Nru vdr-1.7.4-vanilla/channels.h vdr-1.7.4-pluginparam/channels.h
|
||||
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.4-vanilla/config.h vdr-1.7.4-pluginparam/config.h
|
||||
--- vdr-1.7.4-vanilla/config.h 2009-01-26 11:44:48.000000000 +0200
|
||||
+++ vdr-1.7.4-pluginparam/config.h 2009-02-24 13:31:33.000000000 +0200
|
||||
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.4"
|
||||
#define APIVERSNUM 10704 // 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.4-vanilla/menu.c vdr-1.7.4-pluginparam/menu.c
|
||||
--- vdr-1.7.4-vanilla/menu.c 2009-01-26 11:44:48.000000000 +0200
|
||||
+++ vdr-1.7.4-pluginparam/menu.c 2009-02-24 13:31:33.000000000 +0200
|
||||
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;
|
||||
@@ -211,29 +211,29 @@ diff -Nru vdr-1.7.4-vanilla/menu.c vdr-1.7.4-pluginparam/menu.c
|
||||
if (channel) {
|
||||
*channel = data;
|
||||
isyslog("edited channel %d %s", channel->Number(), *data.ToText());
|
||||
diff -Nru vdr-1.7.4-vanilla/po/fi_FI.po vdr-1.7.4-pluginparam/po/fi_FI.po
|
||||
--- vdr-1.7.4-vanilla/po/fi_FI.po 2009-01-26 11:44:48.000000000 +0200
|
||||
+++ vdr-1.7.4-pluginparam/po/fi_FI.po 2009-02-24 13:31:33.000000000 +0200
|
||||
@@ -1010,3 +1010,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.4-vanilla/po/fr_FR.po vdr-1.7.4-pluginparam/po/fr_FR.po
|
||||
--- vdr-1.7.4-vanilla/po/fr_FR.po 2009-01-26 11:44:48.000000000 +0200
|
||||
+++ vdr-1.7.4-pluginparam/po/fr_FR.po 2009-02-24 13:31:33.000000000 +0200
|
||||
@@ -1013,3 +1013,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.4-vanilla/sources.c vdr-1.7.4-pluginparam/sources.c
|
||||
--- vdr-1.7.4-vanilla/sources.c 2009-01-26 11:44:48.000000000 +0200
|
||||
+++ vdr-1.7.4-pluginparam/sources.c 2009-02-24 13:31:33.000000000 +0200
|
||||
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.4-vanilla/sources.c vdr-1.7.4-pluginparam/sources.c
|
||||
case 'C': type = stCable; break;
|
||||
case 'S': type = stSat; break;
|
||||
case 'T': type = stTerr; break;
|
||||
diff -Nru vdr-1.7.4-vanilla/sources.conf vdr-1.7.4-pluginparam/sources.conf
|
||||
--- vdr-1.7.4-vanilla/sources.conf 2009-01-26 11:44:48.000000000 +0200
|
||||
+++ vdr-1.7.4-pluginparam/sources.conf 2009-02-24 13:31:33.000000000 +0200
|
||||
@@ -194,3 +194,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.4-vanilla/sources.conf vdr-1.7.4-pluginparam/sources.conf
|
||||
+# Plugin
|
||||
+
|
||||
+P Plugin
|
||||
diff -Nru vdr-1.7.4-vanilla/sources.h vdr-1.7.4-pluginparam/sources.h
|
||||
--- vdr-1.7.4-vanilla/sources.h 2009-01-26 11:44:48.000000000 +0200
|
||||
+++ vdr-1.7.4-pluginparam/sources.h 2009-02-24 13:31:33.000000000 +0200
|
||||
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 {
|
||||
@@ -1,11 +0,0 @@
|
||||
diff -Nru vdr-1.7.4-vanilla/pat.c vdr-1.7.4-disable-ca-updates/pat.c
|
||||
--- vdr-1.7.4-vanilla/pat.c 2008-07-06 17:01:32.000000000 +0300
|
||||
+++ vdr-1.7.4-disable-ca-updates/pat.c 2009-03-07 14:54:12.000000000 +0200
|
||||
@@ -444,6 +444,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->SetCaDescriptors(CaDescriptorHandler.AddCaDescriptors(CaDescriptors));
|
||||
@@ -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);
|
||||
@@ -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;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
cIptvProtocolFile::cIptvProtocolFile()
|
||||
: fileDelay(0),
|
||||
fileStream(NULL),
|
||||
isActive(false)
|
||||
{
|
||||
debug("cIptvProtocolFile::cIptvProtocolFile()\n");
|
||||
@@ -74,7 +75,7 @@ int cIptvProtocolFile::Read(unsigned char* BufferAddr, unsigned int BufferLen)
|
||||
// during the sleep and buffers are disposed. Check here that the plugin is
|
||||
// still active before accessing the buffers
|
||||
if (isActive)
|
||||
return fread(BufferAddr, sizeof(unsigned char), BufferLen, fileStream);
|
||||
return (int)fread(BufferAddr, sizeof(unsigned char), BufferLen, fileStream);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,8 +20,7 @@ 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:
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include "sectionfilter.h"
|
||||
|
||||
cIptvSectionFilter::cIptvSectionFilter(int DeviceIndex, int Index,
|
||||
u_short Pid, u_char Tid, u_char Mask)
|
||||
uint16_t Pid, uint8_t Tid, uint8_t Mask)
|
||||
: pusi_seen(0),
|
||||
feedcc(0),
|
||||
doneq(0),
|
||||
@@ -18,8 +18,7 @@ cIptvSectionFilter::cIptvSectionFilter(int DeviceIndex, int Index,
|
||||
tsfeedp(0),
|
||||
pid(Pid),
|
||||
devid(DeviceIndex),
|
||||
id(Index),
|
||||
pipeName("")
|
||||
id(Index)
|
||||
{
|
||||
//debug("cIptvSectionFilter::cIptvSectionFilter(%d, %d)\n", devid, id);
|
||||
int i;
|
||||
@@ -42,42 +41,46 @@ cIptvSectionFilter::cIptvSectionFilter(int DeviceIndex, int Index,
|
||||
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;
|
||||
pipeName = cString::sprintf(IPTV_FILTER_FILENAME, devid, id);
|
||||
stat(pipeName, &sb);
|
||||
if (S_ISFIFO(sb.st_mode))
|
||||
unlink(pipeName);
|
||||
i = mknod(pipeName, 0644 | S_IFIFO, 0);
|
||||
ERROR_IF_RET(i < 0, "mknod()", return);
|
||||
|
||||
// Create descriptors
|
||||
fifoDescriptor = open(pipeName, O_RDWR | O_NONBLOCK);
|
||||
readDescriptor = open(pipeName, O_RDONLY | O_NONBLOCK);
|
||||
// Create sockets
|
||||
socket[0] = socket[1] = -1;
|
||||
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, socket) != 0) {
|
||||
char tmp[64];
|
||||
error("Opening section filter sockets failed (device=%d id=%d): %s\n", devid, id, strerror_r(errno, tmp, sizeof(tmp)));
|
||||
}
|
||||
else if ((fcntl(socket[0], F_SETFL, O_NONBLOCK) != 0) || (fcntl(socket[1], F_SETFL, O_NONBLOCK) != 0)) {
|
||||
char tmp[64];
|
||||
error("Setting section filter socket to non-blocking mode failed (device=%d id=%d): %s", devid, id, strerror_r(errno, tmp, sizeof(tmp)));
|
||||
}
|
||||
}
|
||||
|
||||
cIptvSectionFilter::~cIptvSectionFilter()
|
||||
{
|
||||
//debug("cIptvSectionFilter::~cIptvSectionfilter(%d, %d)\n", devid, id);
|
||||
close(fifoDescriptor);
|
||||
close(readDescriptor);
|
||||
unlink(pipeName);
|
||||
fifoDescriptor = -1;
|
||||
readDescriptor = -1;
|
||||
int tmp = socket[1];
|
||||
socket[1] = -1;
|
||||
if (tmp >= 0)
|
||||
close(tmp);
|
||||
tmp = socket[0];
|
||||
socket[0] = -1;
|
||||
if (tmp >= 0)
|
||||
close(tmp);
|
||||
secbuf = NULL;
|
||||
}
|
||||
|
||||
int cIptvSectionFilter::GetReadDesc(void)
|
||||
{
|
||||
return readDescriptor;
|
||||
return socket[0];
|
||||
}
|
||||
|
||||
inline uint16_t cIptvSectionFilter::GetLength(const uint8_t *Data)
|
||||
{
|
||||
return 3 + ((Data[1] & 0x0f) << 8) + Data[2];
|
||||
return (uint16_t)(3 + ((Data[1] & 0x0f) << 8) + Data[2]);
|
||||
}
|
||||
|
||||
void cIptvSectionFilter::New(void)
|
||||
@@ -91,24 +94,25 @@ 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)
|
||||
return 0;
|
||||
neq |= maskandnotmode[i] & local_xor;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
if (doneq && !neq)
|
||||
return 0;
|
||||
if (doneq && !neq)
|
||||
return 0;
|
||||
|
||||
// There is no data in the fifo, more can be written
|
||||
if (!select_single_desc(fifoDescriptor, 0, false)) {
|
||||
i = write(fifoDescriptor, secbuf, seclen);
|
||||
ERROR_IF(i < 0, "write()");
|
||||
// Update statistics
|
||||
AddSectionStatistic(i, 1);
|
||||
// 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 0;
|
||||
}
|
||||
|
||||
@@ -128,7 +132,7 @@ int cIptvSectionFilter::CopyDump(const uint8_t *buf, uint8_t len)
|
||||
return 0;
|
||||
|
||||
if (tsfeedp + len > DMX_MAX_SECFEED_SIZE)
|
||||
len = DMX_MAX_SECFEED_SIZE - tsfeedp;
|
||||
len = (uint8_t)(DMX_MAX_SECFEED_SIZE - tsfeedp);
|
||||
|
||||
if (len <= 0)
|
||||
return 0;
|
||||
@@ -138,15 +142,14 @@ int cIptvSectionFilter::CopyDump(const uint8_t *buf, uint8_t len)
|
||||
|
||||
limit = tsfeedp;
|
||||
if (limit > DMX_MAX_SECFEED_SIZE)
|
||||
return -1; // internal error should never happen
|
||||
return -1; // internal error should never happen
|
||||
|
||||
// Always set secbuf
|
||||
secbuf = secbuf_base + secbufp;
|
||||
|
||||
for (n = 0; secbufp + 2 < limit; ++n) {
|
||||
seclen_local = GetLength(secbuf);
|
||||
if (seclen_local <= 0 || seclen_local > DMX_MAX_SECTION_SIZE ||
|
||||
seclen_local + secbufp > limit)
|
||||
if ((seclen_local <= 0) || (seclen_local > DMX_MAX_SECTION_SIZE) || ((seclen_local + secbufp) > limit))
|
||||
return 0;
|
||||
seclen = seclen_local;
|
||||
if (pusi_seen)
|
||||
@@ -173,9 +176,9 @@ void cIptvSectionFilter::Process(const uint8_t* Data)
|
||||
return;
|
||||
|
||||
// Payload start
|
||||
uint8_t p = TS_SIZE - count;
|
||||
uint8_t p = (uint8_t)(TS_SIZE - count);
|
||||
|
||||
uint8_t cc = Data[3] & 0x0f;
|
||||
uint8_t cc = (uint8_t)(Data[3] & 0x0f);
|
||||
int ccok = ((feedcc + 1) & 0x0f) == cc;
|
||||
feedcc = cc;
|
||||
|
||||
@@ -199,7 +202,7 @@ void cIptvSectionFilter::Process(const uint8_t* Data)
|
||||
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);
|
||||
|
||||
// Before start of new section, set pusi_seen = 1
|
||||
|
||||
@@ -15,25 +15,12 @@
|
||||
|
||||
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 + TS_SIZE)
|
||||
};
|
||||
|
||||
int fifoDescriptor;
|
||||
int readDescriptor;
|
||||
|
||||
int pusi_seen;
|
||||
int feedcc;
|
||||
int doneq;
|
||||
@@ -47,7 +34,7 @@ private:
|
||||
|
||||
int devid;
|
||||
int id;
|
||||
cString pipeName;
|
||||
int socket[2];
|
||||
|
||||
uint8_t filter_value[DMX_MAX_FILTER_SIZE];
|
||||
uint8_t filter_mask[DMX_MAX_FILTER_SIZE];
|
||||
@@ -64,12 +51,12 @@ private:
|
||||
|
||||
public:
|
||||
// constructor & destructor
|
||||
cIptvSectionFilter(int Index, int DeviceIndex, 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 Process(const uint8_t* Data);
|
||||
int GetReadDesc(void);
|
||||
uint16_t GetPid(void) { return pid; }
|
||||
uint16_t GetPid(void) const { return pid; }
|
||||
};
|
||||
|
||||
#endif // __IPTV_SECTIONFILTER_H
|
||||
|
||||
16
setup.c
16
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
|
||||
@@ -391,7 +387,7 @@ class cIptvMenuChannels : public cOsdMenu
|
||||
{
|
||||
private:
|
||||
void Setup(void);
|
||||
cChannel *GetChannel(int Index);
|
||||
cChannel *GetChannel(int Index) const;
|
||||
void Propagate(void);
|
||||
|
||||
protected:
|
||||
@@ -431,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);
|
||||
@@ -618,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())
|
||||
@@ -712,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:
|
||||
|
||||
@@ -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
|
||||
|
||||
18
socket.c
18
socket.c
@@ -59,7 +59,7 @@ bool cIptvSocket::OpenSocket(const int Port, const bool isUdp)
|
||||
// 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));
|
||||
@@ -103,14 +103,14 @@ 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);
|
||||
int len = 0;
|
||||
// Read data from socket
|
||||
if (isActive)
|
||||
len = recvfrom(socketDesc, BufferAddr, BufferLen, MSG_DONTWAIT,
|
||||
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;
|
||||
@@ -126,14 +126,14 @@ int cIptvUdpSocket::Read(unsigned char* BufferAddr, unsigned int BufferLen)
|
||||
// payload type: MPEG2 TS = 33
|
||||
//unsigned int pt = readBuffer[1] & 0x7F;
|
||||
// header lenght
|
||||
unsigned int headerlen = (3 + cc) * sizeof(uint32_t);
|
||||
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) * sizeof(uint32_t);
|
||||
headerlen += (ehl + 1) * (unsigned int)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) &&
|
||||
@@ -168,13 +168,13 @@ 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);
|
||||
// Read data from socket
|
||||
if (isActive)
|
||||
return recvfrom(socketDesc, BufferAddr, BufferLen, MSG_DONTWAIT,
|
||||
if (isActive && socketDesc && BufferAddr && (BufferLen > 0))
|
||||
return (int)recvfrom(socketDesc, BufferAddr, BufferLen, MSG_DONTWAIT,
|
||||
(struct sockaddr *)&sockAddr, &addrlen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
15
streamer.c
15
streamer.c
@@ -21,9 +21,9 @@ cIptvStreamer::cIptvStreamer(cRingBufferLinear* RingBuffer, unsigned int PacketL
|
||||
// Allocate packet buffer
|
||||
packetBuffer = MALLOC(unsigned char, packetBufferLen);
|
||||
if (packetBuffer)
|
||||
memset(packetBuffer, 0, packetBufferLen);
|
||||
memset(packetBuffer, 0, packetBufferLen);
|
||||
else
|
||||
error("ERROR: MALLOC() failed for packet buffer");
|
||||
error("MALLOC() failed for packet buffer");
|
||||
}
|
||||
|
||||
cIptvStreamer::~cIptvStreamer()
|
||||
@@ -31,6 +31,8 @@ cIptvStreamer::~cIptvStreamer()
|
||||
debug("cIptvStreamer::~cIptvStreamer()\n");
|
||||
// Close the protocol
|
||||
Close();
|
||||
protocol = NULL;
|
||||
ringBuffer = NULL;
|
||||
// Free allocated memory
|
||||
free(packetBuffer);
|
||||
}
|
||||
@@ -87,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;
|
||||
|
||||
@@ -24,10 +24,12 @@ private:
|
||||
unsigned int packetBufferLen;
|
||||
cIptvProtocolIf* protocol;
|
||||
|
||||
protected:
|
||||
virtual void Action(void);
|
||||
|
||||
public:
|
||||
cIptvStreamer(cRingBufferLinear* RingBuffer, unsigned int PacketLen);
|
||||
virtual ~cIptvStreamer();
|
||||
virtual void Action(void);
|
||||
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