Skip to content

Commit 14eeddf

Browse files
committed
Merge branch 'master' into develop
# Conflicts: # common.cpp # common.h # device.cpp # device.h # ffmpeghandler.cpp # pidscanner.cpp # pidscanner.h # sidscanner.cpp
2 parents e5580b9 + 4aad3be commit 14eeddf

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+3816
-3156
lines changed

HISTORY

+7
Original file line numberDiff line numberDiff line change
@@ -300,3 +300,10 @@ VDR Plugin 'iptv' Revision History
300300
2024-07-17: Version 2.6.0
301301
- Add new stream protocols RADIO and M3U
302302

303+
2024-07-22: Version 2.6.1
304+
- fix multithreading issue
305+
306+
2024-xx-xx: Version xxx
307+
- Add new stream protocol STREAM
308+
- set the default thread-queue-size from 8 to 32
309+
- New plugin parameter -s to set the thread-queue-size

Makefile

+4-11
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ all-redirect: all
7878
OBJS = $(PLUGIN).o common.o config.o device.o pidscanner.o \
7979
protocolcurl.o protocolext.o protocolfile.o protocolhttp.o \
8080
protocoludp.o sectionfilter.o setup.o sidscanner.o socket.o \
81-
protocolm3u.o protocolradio.o m3u8handler.o process.o process_unix.o ffmpeghandler.o \
81+
protocolm3u.o protocolradio.o protocolstream.o \
82+
m3u8handler.o process.o process_unix.o ffmpeghandler.o \
8283
source.o statistics.o streamer.o
8384

8485
### The main target:
@@ -87,10 +88,6 @@ all: $(SOFILE) i18n
8788

8889
### Implicit rules:
8990

90-
%.o: %.c Makefile
91-
@echo CC $@
92-
$(Q)$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
93-
9491
%.o: %.cpp Makefile
9592
@echo CC $@
9693
$(Q)$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
@@ -100,7 +97,7 @@ all: $(SOFILE) i18n
10097
MAKEDEP = $(CXX) -MM -MG
10198
DEPFILE = .dependencies
10299
$(DEPFILE): Makefile
103-
$(Q)$(MAKEDEP) $(CXXFLAGS) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.c) > $@
100+
$(Q)$(MAKEDEP) $(CXXFLAGS) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.cpp) > $@
104101

105102
-include $(DEPFILE)
106103

@@ -116,10 +113,6 @@ I18Npot = $(PODIR)/$(PLUGIN).pot
116113
@echo MO $@
117114
$(Q)msgfmt -c -o $@ $<
118115

119-
#$(I18Npot): $(wildcard *.c)
120-
# @echo GT $@
121-
# $(Q)xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=vdr-$(PLUGIN) --package-version=$(VERSION) --msgid-bugs-address='<see README>' -o $@ `ls $^`
122-
123116
$(I18Npot): $(wildcard *.cpp)
124117
@echo GT $@
125118
$(Q)xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=vdr-$(PLUGIN) --package-version=$(VERSION) --msgid-bugs-address='<see README>' -o $@ `ls $^`
@@ -170,4 +163,4 @@ clean:
170163

171164
.PHONY: cppcheck
172165
cppcheck:
173-
$(Q)cppcheck --language=c++ --enable=all -v -f $(OBJS:%.o=%.c)
166+
$(Q)cppcheck --language=c++ --enable=all -v -f $(OBJS:%.o=%.cpp)

README

+17-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Requirements:
1919

2020
- Libcurl - the multiprotocol file transfer library
2121
http://curl.haxx.se/libcurl/
22+
- yt-dlp - optional. Used for protocol M3U.
2223

2324
Description:
2425

@@ -74,10 +75,18 @@ Information menu:
7475
- [Yellow:Filters] Opens the section filter statistics page.
7576
- [Blue:Bits/bytes] Toggles between bits and bytes mode.
7677

78+
Plugin parameters:
79+
-d <num>, --devices=<number> number of devices to be created
80+
-t <mode>, --trace=<mode> set the tracing mode
81+
-s <num>, --thread-queue-size=<number> set the FFmpeg thread-queue-size
82+
-y <path>, --ytdlp=<path> set the path to yt-dlp. Default /usr/local/bin/yt-dlp
83+
7784
Configuration:
7885

7986
- channels.conf
8087

88+
TV8;IPTV:70:S=1|P=0|F=M3U|U=other.cfg|A=2|Y=1:I:0:200:201,202,203,204,205:0:0:11:1:100:0
89+
ST1:IPTV:90:S=1|P=0|F=STREAM|U=http%3A//locahost/stream?id=10|A=1:I:0:514:670:2321:0:5:0:200:0
8190
RD1:IPTV:80:S=1|P=0|F=RADIO|U=http%3A//wdr-1live-live.icecast.wdr.de/wdr/1live/live/mp3/128/stream.mp3|A=8:I:0:270:271,272,273,274,275:0:0:8:1:9:8
8291
TV7;IPTV:70:S=1|P=0|F=M3U|U=list1.cfg|A=5:I:0:200:201,202,203,204,205:0:0:11:1:100:0
8392
TV6;IPTV:60:S=1|P=0|F=EXT|U=iptvstream.sh|A=0:I:0:0:680:0:0:6:0:0:0
@@ -87,13 +96,16 @@ Configuration:
8796
TV2;IPTV:20:S=1|P=0|F=UDP|[email protected]|A=1234:I:0:512:650:2321:0:2:0:0:0
8897
TV1;IPTV:10:S=1|P=0|F=UDP|U=127.0.0.1|A=1234:I:0:512:650:2321:0:1:0:0:0
8998
^ ^ ^ ^ ^ ^ ^
99+
| | | | | | |
90100
| | | | | | Source type ("I")
91101
| | | | | Stream parameter
92102
| | | | | UDP: multicast port
93103
| | | | | CURL: <<to be defined>>
94104
| | | | | HTTP: HTTP port number
95105
| | | | | FILE: file delay (ms)
96106
| | | | | EXT: script parameter
107+
| | | | | M3U: Y=1 uses yt-dlp to determine the video URL
108+
| | | | | Y=2 tries to find the video URL internally
97109
| | | | Stream address
98110
| | | | UDP: multicast [source@]group address
99111
| | | | CURL: HTTP/HTTPS URL; colons (%3A) and pipes (%7C) shall be URL encoded
@@ -102,7 +114,8 @@ Configuration:
102114
| | | | EXT: script location
103115
| | | | M3U: m3u playlist
104116
| | | | RADIO: An URL for a radio stream
105-
| | | Stream protocol ("UDP", "CURL", "HTTP", "FILE", "EXT", "M3U", "RADIO")
117+
| | | | STREAM: An URL for a video stream
118+
| | | Stream protocol ("UDP", "CURL", "HTTP", "FILE", "EXT", "M3U", "RADIO", "STREAM")
106119
| | Pid scanner ("0" disable, "1" enable)
107120
| Section id (Sid/Nid/Tid) scanner ("0" disable, "1" enable)
108121
Unique enumeration
@@ -155,6 +168,9 @@ External streaming:
155168
TID = 100 Select a transponder.
156169
RID = 0 (Radio only 1)
157170

171+
It is possible to use parameter Y=1 to use yt-dlp to determine the m3u8 URL.
172+
Useful e.g. for youtube videos. Needs yt-dlp.
173+
158174
Notes:
159175

160176
- Working EIT requires correct Nid/Tid/Sid values as the NIT filter cannot

common.cpp

+72-58
Original file line numberDiff line numberDiff line change
@@ -9,85 +9,99 @@
99
#include <vdr/tools.h>
1010
#include "common.h"
1111

12-
uint16_t ts_pid(const uint8_t *bufP)
13-
{
14-
return (uint16_t)(((bufP[1] & 0x1f) << 8) + bufP[2]);
12+
uint16_t ts_pid(const uint8_t *bufP) {
13+
return (uint16_t) (((bufP[1] & 0x1f) << 8) + bufP[2]);
1514
}
1615

17-
uint8_t payload(const uint8_t *bufP)
18-
{
19-
if (!(bufP[3] & 0x10)) // no payload?
20-
return 0;
21-
22-
if (bufP[3] & 0x20) { // adaptation field?
23-
if (bufP[4] > 183) // corrupted data?
16+
uint8_t payload(const uint8_t *bufP) {
17+
if (!(bufP[3] & 0x10)) {// no payload?
2418
return 0;
25-
else
26-
return (uint8_t)((184 - 1) - bufP[4]);
27-
}
19+
}
20+
21+
if (bufP[3] & 0x20) { // adaptation field?
22+
if (bufP[4] > 183) { // corrupted data?
23+
return 0;
24+
} else {
25+
return (uint8_t) ((184 - 1) - bufP[4]);
26+
}
27+
}
2828

29-
return 184;
29+
return 184;
3030
}
3131

32-
const char *id_pid(const u_short pidP)
33-
{
34-
for (int i = 0; i < SECTION_FILTER_TABLE_SIZE; ++i) {
35-
if (pidP == section_filter_table[i].pid)
36-
return section_filter_table[i].tag;
37-
}
38-
return "---";
32+
const char *id_pid(const u_short pidP) {
33+
for (int i = 0; i < SECTION_FILTER_TABLE_SIZE; ++i) {
34+
if (pidP==section_filter_table[i].pid) {
35+
return section_filter_table[i].tag;
36+
}
37+
}
38+
return "---";
3939
}
4040

41-
int select_single_desc(int descriptorP, const int usecsP, const bool selectWriteP)
42-
{
43-
// Wait for data
44-
struct timeval tv;
45-
tv.tv_sec = 0;
46-
tv.tv_usec = usecsP;
47-
// Use select
48-
fd_set infd;
49-
fd_set outfd;
50-
fd_set errfd;
51-
FD_ZERO(&infd);
52-
FD_ZERO(&outfd);
53-
FD_ZERO(&errfd);
54-
FD_SET(descriptorP, &errfd);
55-
if (selectWriteP)
56-
FD_SET(descriptorP, &outfd);
57-
else
58-
FD_SET(descriptorP, &infd);
59-
int retval = select(descriptorP + 1, &infd, &outfd, &errfd, &tv);
60-
// Check if error
61-
ERROR_IF_RET(retval < 0, "select()", return retval);
62-
return retval;
41+
int select_single_desc(int descriptorP, const int usecsP, const bool selectWriteP) {
42+
// Wait for data
43+
struct timeval tv;
44+
tv.tv_sec = 0;
45+
tv.tv_usec = usecsP;
46+
// Use select
47+
fd_set infd;
48+
fd_set outfd;
49+
fd_set errfd;
50+
FD_ZERO(&infd);
51+
FD_ZERO(&outfd);
52+
FD_ZERO(&errfd);
53+
FD_SET(descriptorP, &errfd);
54+
55+
if (selectWriteP) {
56+
FD_SET(descriptorP, &outfd);
57+
} else {
58+
FD_SET(descriptorP, &infd);
59+
}
60+
61+
int retval = select(descriptorP + 1, &infd, &outfd, &errfd, &tv);
62+
63+
// Check if error
64+
ERROR_IF_RET(retval < 0, "select()", return retval);
65+
return retval;
6366
}
6467

65-
cString ChangeCase(const cString &strP, bool upperP)
66-
{
67-
cString res(strP);
68-
char *p = (char *)*res;
69-
while (p && *p) {
68+
cString ChangeCase(const cString &strP, bool upperP) {
69+
cString res(strP);
70+
char *p = (char *) *res;
71+
72+
while (p && *p) {
7073
*p = upperP ? toupper(*p) : tolower(*p);
7174
++p;
72-
}
73-
return res;
75+
}
76+
return res;
7477
}
7578

7679
const section_filter_table_type section_filter_table[SECTION_FILTER_TABLE_SIZE] =
77-
{
78-
/* description tag pid tid mask */
79-
{trNOOP("PAT (0x00)"), "PAT", 0x00, 0x00, 0xFF},
80-
{trNOOP("NIT (0x40)"), "NIT", 0x10, 0x40, 0xFF},
81-
{trNOOP("SDT (0x42)"), "SDT", 0x11, 0x42, 0xFF},
82-
{trNOOP("EIT (0x4E/0x4F/0x5X/0x6X)"), "EIT", 0x12, 0x40, 0xC0},
83-
{trNOOP("TDT (0x70)"), "TDT", 0x14, 0x70, 0xFF},
84-
};
80+
{
81+
/* description tag pid tid mask */
82+
{trNOOP("PAT (0x00)"), "PAT", 0x00, 0x00, 0xFF},
83+
{trNOOP("NIT (0x40)"), "NIT", 0x10, 0x40, 0xFF},
84+
{trNOOP("SDT (0x42)"), "SDT", 0x11, 0x42, 0xFF},
85+
{trNOOP("EIT (0x4E/0x4F/0x5X/0x6X)"), "EIT", 0x12, 0x40, 0xC0},
86+
{trNOOP("TDT (0x70)"), "TDT", 0x14, 0x70, 0xFF},
87+
};
88+
89+
std::string ReplaceAll(std::string str, const std::string &from, const std::string &to) {
90+
size_t start_pos = 0;
91+
92+
while ((start_pos = str.find(from, start_pos))!=std::string::npos) {
93+
str.replace(start_pos, from.length(), to);
94+
start_pos += to.length(); // Handles case where 'to' is a substring of 'from'
95+
}
96+
return str;
97+
}
8598

8699
void printBacktrace() {
87100
cStringList stringList;
88101

89102
cBackTrace::BackTrace(stringList, 0, false);
90103
esyslog("[iptv] Backtrace size: %d", stringList.Size());
104+
91105
for (int i = 0; i < stringList.Size(); ++i) {
92106
esyslog("[iptv] ==> %s", stringList[i]);
93107
}

common.h

+3-10
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,16 @@
55
*
66
*/
77

8-
#ifndef __IPTV_COMMON_H
9-
#define __IPTV_COMMON_H
8+
#pragma once
109

10+
#include <string>
1111
#include <vdr/tools.h>
1212
#include <vdr/config.h>
1313
#include <vdr/i18n.h>
1414

1515
#define ELEMENTS(x) (sizeof(x) / sizeof(x[0]))
16-
1716
#define IPTV_BUFFER_SIZE KILOBYTE(2048)
18-
1917
#define IPTV_DVR_FILENAME "/tmp/vdr-iptv%d.dvr"
20-
2118
#define IPTV_SOURCE_CHARACTER 'I'
2219

2320
#define IPTV_DEVICE_INFO_ALL 0
@@ -26,10 +23,8 @@
2623
#define IPTV_DEVICE_INFO_FILTERS 3
2724
#define IPTV_DEVICE_INFO_PROTOCOL 4
2825
#define IPTV_DEVICE_INFO_BITRATE 5
29-
3026
#define IPTV_STATS_ACTIVE_PIDS_COUNT 10
3127
#define IPTV_STATS_ACTIVE_FILTERS_COUNT 10
32-
3328
#define SECTION_FILTER_TABLE_SIZE 5
3429

3530
#define ERROR_IF_FUNC(exp, errstr, func, ret) \
@@ -44,7 +39,6 @@
4439
} while (0)
4540

4641
#define ERROR_IF_RET(exp, errstr, ret) ERROR_IF_FUNC(exp, errstr, ,ret);
47-
4842
#define ERROR_IF(exp, errstr) ERROR_IF_FUNC(exp, errstr, , );
4943

5044
#define DELETE_POINTER(ptr) \
@@ -63,6 +57,7 @@ uint8_t payload(const uint8_t *bufP);
6357
const char *id_pid(const u_short pidP);
6458
int select_single_desc(int descriptorP, const int usecsP, const bool selectWriteP);
6559
cString ChangeCase(const cString &strP, bool upperP);
60+
std::string ReplaceAll(std::string str, const std::string &from, const std::string &to);
6661
void printBacktrace();
6762

6863
struct section_filter_table_type {
@@ -77,5 +72,3 @@ extern const section_filter_table_type section_filter_table[SECTION_FILTER_TABLE
7772

7873
extern const char VERSION[];
7974

80-
#endif // __IPTV_COMMON_H
81-

0 commit comments

Comments
 (0)