Skip to content

Commit fe6b6ce

Browse files
committed
Initial revision
0 parents  commit fe6b6ce

12 files changed

+1401
-0
lines changed

COPYING

+340
Large diffs are not rendered by default.

HISTORY

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
VDR Plugin 'iptv' Revision History
2+
----------------------------------
3+
4+
2007-09-10: Version 0.0.1
5+
6+
- Initial revision.

Makefile

+123
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
#
2+
# Makefile for a Video Disk Recorder plugin
3+
#
4+
# $Id: Makefile,v 1.1 2007/09/12 17:28:59 rahrenbe Exp $
5+
6+
# Debugging on/off
7+
IPTV_DEBUG = 1
8+
9+
# Strip debug symbols? Set eg. to /bin/true if not
10+
STRIP = strip
11+
12+
# The official name of this plugin.
13+
# This name will be used in the '-P...' option of VDR to load the plugin.
14+
# By default the main source file also carries this name.
15+
# IMPORTANT: the presence of this macro is important for the Make.config
16+
# file. So it must be defined, even if it is not used here!
17+
#
18+
PLUGIN = iptv
19+
20+
### The version number of this plugin (taken from the main source file):
21+
22+
VERSION = $(shell grep 'static const char \*VERSION *=' $(PLUGIN).c | awk '{ print $$6 }' | sed -e 's/[";]//g')
23+
24+
### The C++ compiler and options:
25+
26+
CXX ?= g++
27+
CXXFLAGS ?= -fPIC -g -O2 -Wall -Woverloaded-virtual
28+
29+
### The directory environment:
30+
31+
VDRDIR = ../../..
32+
LIBDIR = ../../lib
33+
TMPDIR = /tmp
34+
35+
### Allow user defined options to overwrite defaults:
36+
37+
-include $(VDRDIR)/Make.config
38+
39+
### The version number of VDR's plugin API (taken from VDR's "config.h"):
40+
41+
APIVERSION = $(shell sed -ne '/define APIVERSION/s/^.*"\(.*\)".*$$/\1/p' $(VDRDIR)/config.h)
42+
43+
### The name of the distribution archive:
44+
45+
ARCHIVE = $(PLUGIN)-$(VERSION)
46+
PACKAGE = vdr-$(ARCHIVE)
47+
48+
### Includes and Defines (add further entries here):
49+
50+
INCLUDES += -I$(VDRDIR)/include
51+
52+
DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
53+
54+
ifdef IPTV_DEBUG
55+
DEFINES += -DDEBUG
56+
endif
57+
58+
### The object files (add further files here):
59+
60+
OBJS = $(PLUGIN).o device.o streamer.o
61+
62+
### The main target:
63+
64+
all: libvdr-$(PLUGIN).so i18n
65+
66+
### Implicit rules:
67+
68+
%.o: %.c
69+
$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) $<
70+
71+
### Dependencies:
72+
73+
MAKEDEP = $(CXX) -MM -MG
74+
DEPFILE = .dependencies
75+
$(DEPFILE): Makefile
76+
@$(MAKEDEP) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.c) > $@
77+
78+
-include $(DEPFILE)
79+
80+
### Internationalization (I18N):
81+
82+
PODIR = po
83+
LOCALEDIR = $(VDRDIR)/locale
84+
I18Npo = $(wildcard $(PODIR)/*.po)
85+
I18Nmo = $(addsuffix .mo, $(foreach file, $(I18Npo), $(basename $(file))))
86+
I18Ndirs = $(notdir $(foreach file, $(I18Npo), $(basename $(file))))
87+
I18Npot = $(PODIR)/$(PLUGIN).pot
88+
89+
%.mo: %.po
90+
msgfmt -c -o $@ $<
91+
92+
$(I18Npot): $(wildcard *.c)
93+
xgettext -C -cTRANSLATORS --no-wrap -F -k -ktr -ktrNOOP --msgid-bugs-address='Rolf Ahrenberg' -o $@ $(wildcard *.c)
94+
95+
$(I18Npo): $(I18Npot)
96+
msgmerge -U --no-wrap -F --backup=none -q $@ $<
97+
98+
i18n: $(I18Nmo)
99+
@mkdir -p $(LOCALEDIR)
100+
for i in $(I18Ndirs); do\
101+
mkdir -p $(LOCALEDIR)/$$i/LC_MESSAGES;\
102+
cp $(PODIR)/$$i.mo $(LOCALEDIR)/$$i/LC_MESSAGES/vdr-$(PLUGIN).mo;\
103+
done
104+
105+
### Targets:
106+
107+
libvdr-$(PLUGIN).so: $(OBJS)
108+
$(CXX) $(CXXFLAGS) -shared $(OBJS) -o $@
109+
ifndef IPTV_DEBUG
110+
@$(STRIP) $@
111+
endif
112+
@cp --remove-destination $@ $(LIBDIR)/$@.$(APIVERSION)
113+
114+
dist: clean
115+
@-rm -rf $(TMPDIR)/$(ARCHIVE)
116+
@mkdir $(TMPDIR)/$(ARCHIVE)
117+
@cp -a * $(TMPDIR)/$(ARCHIVE)
118+
@tar czf $(PACKAGE).tgz -C $(TMPDIR) $(ARCHIVE)
119+
@-rm -rf $(TMPDIR)/$(ARCHIVE)
120+
@echo Distribution package created as $(PACKAGE).tgz
121+
122+
clean:
123+
@-rm -f $(OBJS) $(DEPFILE) *.so *.tgz core* *~ $(PODIR)/*.mo $(PODIR)/*.pot

README

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
This is a IPTV for the Video Disk Recorder (VDR).
2+
3+
Written by: R o l f . A h r e n b e r g @ s c i . f i
4+
A n t t i . S e p p a l a @
5+
6+
Project's homepage: http://www.saunalahti.fi/~rahrenbe/vdr/iptv/
7+
8+
Latest version available at: http://www.saunalahti.fi/~rahrenbe/vdr/iptv/
9+
10+
This program is free software; you can redistribute it and/or modify
11+
it under the terms of the GNU General Public License as published by
12+
the Free Software Foundation; either version 2 of the License, or
13+
(at your option) any later version.
14+
See the file COPYING for more information.
15+
16+
Description:
17+
18+
TBD
19+
20+
Channels.conf examples:
21+
22+
TV1:1:IPTV-UDP-192.168.0.1-1234:P:27500:512:650:2321:0:17:8438:4097:0
23+
TV2:2:IPTV-UDP-192.168.0.2-1234:P:27500:513:660:2321:0:33:8438:4097:0
24+
^ ^ ^ ^ ^ ^
25+
| | | | | Source type ("P")
26+
| | | | IP Port Number
27+
| | | IP Address
28+
| | Protocol ("UDP")
29+
| Plugin ID ("IPTV")
30+
Unique enumeration

common.h

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* common.h: IPTV plugin for the Video Disk Recorder
3+
*
4+
* See the README file for copyright information and how to reach the author.
5+
*
6+
* $Id: common.h,v 1.1 2007/09/12 17:28:59 rahrenbe Exp $
7+
*/
8+
9+
#ifndef __IPTV_COMMON_H
10+
#define __IPTV_COMMON_H
11+
12+
#include <vdr/tools.h>
13+
14+
#ifdef DEBUG
15+
#define debug(x...) dsyslog("IPTV: " x);
16+
#define error(x...) esyslog("IPTV: " x);
17+
#else
18+
#define debug(x...) ;
19+
#define error(x...) esyslog("IPTV: " x);
20+
#endif
21+
22+
#endif // __IPTV_COMMON_H
23+

device.c

+186
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
/*
2+
* device.c: IPTV plugin for the Video Disk Recorder
3+
*
4+
* See the README file for copyright information and how to reach the author.
5+
*
6+
* $Id: device.c,v 1.1 2007/09/12 17:28:59 rahrenbe Exp $
7+
*/
8+
9+
#include "common.h"
10+
#include "device.h"
11+
12+
#define IPTV_MAX_DEVICES 8
13+
14+
cIptvDevice * IptvDevices[IPTV_MAX_DEVICES];
15+
16+
unsigned int cIptvDevice::deviceCount = 0;
17+
18+
cIptvDevice::cIptvDevice(unsigned int Index)
19+
: deviceIndex(Index),
20+
isPacketDelivered(false),
21+
isOpenDvr(false),
22+
pIptvStreamer(NULL)
23+
{
24+
debug("cIptvDevice::cIptvDevice()\n");
25+
tsBuffer = new cRingBufferLinear(MEGABYTE(8), TS_SIZE, false, "IPTV");
26+
tsBuffer->SetTimeouts(100, 100);
27+
pIptvStreamer = new cIptvStreamer(tsBuffer, &mutex);
28+
}
29+
30+
cIptvDevice::~cIptvDevice()
31+
{
32+
debug("cIptvDevice::~cIptvDevice()\n");
33+
if (pIptvStreamer)
34+
delete pIptvStreamer;
35+
delete tsBuffer;
36+
}
37+
38+
bool cIptvDevice::Initialize(unsigned int DeviceCount)
39+
{
40+
debug("cIptvDevice::Initialize()\n");
41+
if (DeviceCount > IPTV_MAX_DEVICES)
42+
DeviceCount = IPTV_MAX_DEVICES;
43+
for (unsigned int i = 0; i < DeviceCount; ++i)
44+
IptvDevices[i] = new cIptvDevice(i);
45+
return true;
46+
}
47+
48+
unsigned int cIptvDevice::Count(void)
49+
{
50+
unsigned int count = 0;
51+
debug("cIptvDevice::Count()\n");
52+
for (unsigned int i = 0; i < IPTV_MAX_DEVICES; ++i) {
53+
if (IptvDevices[i])
54+
count++;
55+
}
56+
return count;
57+
}
58+
59+
cIptvDevice *cIptvDevice::Get(unsigned int DeviceIndex)
60+
{
61+
debug("cIptvDevice::Get()\n");
62+
if ((DeviceIndex > 0) && (DeviceIndex <= IPTV_MAX_DEVICES))
63+
return IptvDevices[DeviceIndex - 1];
64+
return NULL;
65+
}
66+
67+
cString cIptvDevice::GetChannelSettings(const char *Param, int *IpPort, int *Protocol)
68+
{
69+
unsigned int a, b, c, d;
70+
71+
debug("cIptvDevice::GetChannelSettings()\n");
72+
if (sscanf(Param, "IPTV-UDP-%u.%u.%u.%u-%u", &a, &b, &c, &d, IpPort) == 5) {
73+
debug("UDP channel detected\n");
74+
Protocol = (int*)(cIptvStreamer::PROTOCOL_UDP);
75+
return cString::sprintf("%u.%u.%u.%u", a, b, c, d);
76+
}
77+
else if (sscanf(Param, "IPTV-RTSP-%u.%u.%u.%u-%u", &a, &b, &c, &d, IpPort) == 5) {
78+
debug("RTSP channel detected\n");
79+
Protocol = (int*)(cIptvStreamer::PROTOCOL_RTSP);
80+
return cString::sprintf("%u.%u.%u.%u", a, b, c, d);
81+
}
82+
else if (sscanf(Param, "IPTV-HTTP-%u.%u.%u.%u-%u", &a, &b, &c, &d, IpPort) == 5) {
83+
debug("HTTP channel detected\n");
84+
Protocol = (int*)cIptvStreamer::PROTOCOL_HTTP;
85+
return cString::sprintf("%u.%u.%u.%u", a, b, c, d);
86+
}
87+
return NULL;
88+
}
89+
90+
bool cIptvDevice::ProvidesIptv(const char *Param) const
91+
{
92+
debug("cIptvDevice::ProvidesIptv()\n");
93+
return (strncmp(Param, "IPTV", 4) == 0);
94+
}
95+
96+
bool cIptvDevice::ProvidesSource(int Source) const
97+
{
98+
debug("cIptvDevice::ProvidesSource()\n");
99+
return ((Source & cSource::st_Mask) == cSource::stPlug);
100+
}
101+
102+
bool cIptvDevice::ProvidesTransponder(const cChannel *Channel) const
103+
{
104+
debug("cIptvDevice::ProvidesTransponder()\n");
105+
return (ProvidesSource(Channel->Source()) && ProvidesIptv(Channel->Param()));
106+
}
107+
108+
bool cIptvDevice::ProvidesChannel(const cChannel *Channel, int Priority, bool *NeedsDetachReceivers) const
109+
{
110+
bool result = false;
111+
bool needsDetachReceivers = false;
112+
113+
debug("cIptvDevice::ProvidesChannel()\n");
114+
if (ProvidesTransponder(Channel))
115+
result = true;
116+
if (NeedsDetachReceivers)
117+
*NeedsDetachReceivers = needsDetachReceivers;
118+
return result;
119+
}
120+
121+
bool cIptvDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
122+
{
123+
int port, protocol;
124+
cString addr;
125+
126+
debug("cIptvDevice::SetChannelDevice()\n");
127+
addr = GetChannelSettings(Channel->Param(), &port, &protocol);
128+
if (addr)
129+
pIptvStreamer->SetStream(addr, port, protocol);
130+
return true;
131+
}
132+
133+
bool cIptvDevice::SetPid(cPidHandle *Handle, int Type, bool On)
134+
{
135+
debug("cIptvDevice::SetPid()\n");
136+
return true;
137+
}
138+
139+
bool cIptvDevice::OpenDvr(void)
140+
{
141+
debug("cIptvDevice::OpenDvr()\n");
142+
mutex.Lock();
143+
isPacketDelivered = false;
144+
tsBuffer->Clear();
145+
mutex.Unlock();
146+
pIptvStreamer->Activate();
147+
isOpenDvr = true;
148+
return true;
149+
}
150+
151+
void cIptvDevice::CloseDvr(void)
152+
{
153+
debug("cIptvDevice::CloseDvr()\n");
154+
pIptvStreamer->Deactivate();
155+
isOpenDvr = false;
156+
}
157+
158+
bool cIptvDevice::GetTSPacket(uchar *&Data)
159+
{
160+
int Count = 0;
161+
//debug("cIptvDevice::GetTSPacket()\n");
162+
if (isPacketDelivered) {
163+
tsBuffer->Del(TS_SIZE);
164+
isPacketDelivered = false;
165+
}
166+
uchar *p = tsBuffer->Get(Count);
167+
if (p && Count >= TS_SIZE) {
168+
if (*p != TS_SYNC_BYTE) {
169+
for (int i = 1; i < Count; i++) {
170+
if (p[i] == TS_SYNC_BYTE) {
171+
Count = i;
172+
break;
173+
}
174+
}
175+
tsBuffer->Del(Count);
176+
error("ERROR: skipped %d bytes to sync on TS packet\n", Count);
177+
return false;
178+
}
179+
isPacketDelivered = true;
180+
Data = p;
181+
return true;
182+
}
183+
Data = NULL;
184+
return true;
185+
}
186+

0 commit comments

Comments
 (0)