mirror of
https://github.com/rofafor/vdr-plugin-satip.git
synced 2023-10-10 11:37:42 +00:00
Compare commits
27 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
fb9c1c6a44 | ||
|
5e2770a0e5 | ||
|
53b643139f | ||
|
9a8c6f8c0d | ||
|
fbbfdfab2b | ||
|
78ef582bea | ||
|
6e72eba09c | ||
|
fb40846171 | ||
|
b19be5b5c5 | ||
|
1a304e9dc2 | ||
|
5ff54d27a3 | ||
|
276370afbb | ||
|
f2081c4f00 | ||
|
388543a58d | ||
|
f46d07a95f | ||
|
43cc15357e | ||
|
5b1af5ba29 | ||
|
80fc28d8cf | ||
|
5e8b7b7c5e | ||
|
88b2ad9244 | ||
|
7b58d9f28f | ||
|
f493df0e3d | ||
|
9a6ae40954 | ||
|
b5ec84fd91 | ||
|
e7a74f3ad4 | ||
|
40d280af10 | ||
|
9f2d99435d |
45
HISTORY
45
HISTORY
@@ -19,3 +19,48 @@ VDR Plugin 'satip' Revision History
|
||||
- Refactored the session code.
|
||||
- Fixed EIT scan functionality.
|
||||
- Updated for vdr-2.1.6.
|
||||
|
||||
2014-03-28: Version 0.2.0
|
||||
|
||||
- Added support for cDevice::Ready().
|
||||
- Fixed pid leaking while disabling section filters.
|
||||
- Fixed keepalive heartbeat.
|
||||
|
||||
2014-04-01: Version 0.2.1
|
||||
|
||||
- Changed implementation to report about RTP packet
|
||||
errors on 5 minutes interval only.
|
||||
- Added a check to write new sections only if there
|
||||
is no data in the read socket.
|
||||
- Fixed keepalive heartbeat again.
|
||||
|
||||
2014-04-05: Version 0.2.2
|
||||
|
||||
- Fixed the default keepalive interval.
|
||||
- Refactored the section filtering.
|
||||
- Added Catalan translation (Thanks to Gabriel Bonich).
|
||||
|
||||
2014-04-12: Version 0.2.3
|
||||
|
||||
- Added Spanish translation (Thanks to Gabriel Bonich).
|
||||
- Fixed parameters of the OPTIONS command.
|
||||
- Added a device identication into the user agent string.
|
||||
- Removed unnecessary PLAY commands and header callbacks.
|
||||
|
||||
2014-04-20: Version 0.3.0
|
||||
|
||||
- Tweaked the pid update mechanism.
|
||||
|
||||
2014-04-27: Version 0.3.1
|
||||
|
||||
- Fixed the device discovery.
|
||||
|
||||
2014-05-10: Version 0.3.2
|
||||
|
||||
- Fixed model detection and OctopusNet DVB-C model quirks.
|
||||
- Added a session id quirk for GSSBOX.
|
||||
|
||||
2014-05-18: Version 0.3.3
|
||||
|
||||
- Added a validity check for the session member.
|
||||
- Added a session id quirk for Triax TSS 400.
|
||||
|
8
README
8
README
@@ -14,7 +14,7 @@ See the file COPYING for more information.
|
||||
|
||||
Requirements:
|
||||
|
||||
- Libcurl - the multiprotocol file transfer library with RTSP support
|
||||
- Libcurl >= 7.36.0 - the multiprotocol file transfer library with RTSP support
|
||||
http://curl.haxx.se/libcurl/
|
||||
|
||||
- PugiXML - Light-weight, simple and fast XML parser for C++
|
||||
@@ -23,7 +23,7 @@ Requirements:
|
||||
TinyXML - a simple, small, C++ XML parser
|
||||
http://www.grinninglizard.com/tinyxml/
|
||||
|
||||
- VDR-2.1.4+ for scrambled channels
|
||||
- VDR >= 2.1.4 for scrambled channels
|
||||
|
||||
Description:
|
||||
|
||||
@@ -108,10 +108,6 @@ Notes:
|
||||
direct access to any DVB card devices. The integrated CAM slot in
|
||||
Octopus Net devices isn't supported.
|
||||
|
||||
- The 100% compliance against SAT>IP specification 1.2 requires a
|
||||
patched VDR providing channel configuration for pilot, T2 system id,
|
||||
and SISO/MISO values.
|
||||
|
||||
Acknowledgements:
|
||||
|
||||
- Big thanks to Digital Devices GmbH for providing the Octopus Net
|
||||
|
23
common.c
23
common.c
@@ -57,6 +57,15 @@ char *StripTags(char *strP)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *SkipZeroes(const char *strP)
|
||||
{
|
||||
if ((uchar)*strP != '0')
|
||||
return (char *)strP;
|
||||
while (*strP && (uchar)*strP == '0')
|
||||
strP++;
|
||||
return (char *)strP;
|
||||
}
|
||||
|
||||
cString ChangeCase(const cString &strP, bool upperP)
|
||||
{
|
||||
cString res(strP);
|
||||
@@ -70,12 +79,10 @@ cString ChangeCase(const cString &strP, bool upperP)
|
||||
|
||||
const section_filter_table_type section_filter_table[SECTION_FILTER_TABLE_SIZE] =
|
||||
{
|
||||
/* description tag pid tid mask */
|
||||
{trNOOP("PAT (0x00)"), "PAT", 0x00, 0x00, 0xFF},
|
||||
{trNOOP("NIT (0x40)"), "NIT", 0x10, 0x40, 0xFF},
|
||||
{trNOOP("SDT (0x42)"), "SDT", 0x11, 0x42, 0xFF},
|
||||
{trNOOP("EIT (0x4E/0x4F)"), "EIT", 0x12, 0x4E, 0xFE},
|
||||
{trNOOP("EIT (0x5X)"), "EIT", 0x12, 0x50, 0xF0},
|
||||
{trNOOP("EIT (0x6X)"), "EIT", 0x12, 0x60, 0xF0},
|
||||
{trNOOP("TDT (0x70)"), "TDT", 0x14, 0x70, 0xFF},
|
||||
/* description tag pid tid mask */
|
||||
{trNOOP("PAT (0x00)"), "PAT", 0x00, 0x00, 0xFF},
|
||||
{trNOOP("NIT (0x40)"), "NIT", 0x10, 0x40, 0xFF},
|
||||
{trNOOP("SDT (0x42)"), "SDT", 0x11, 0x42, 0xFF},
|
||||
{trNOOP("EIT (0x4E/0x4F/0x5X/0x6X)"), "EIT", 0x12, 0x40, 0xC0},
|
||||
{trNOOP("TDT (0x70)"), "TDT", 0x14, 0x70, 0xFF},
|
||||
};
|
||||
|
3
common.h
3
common.h
@@ -36,7 +36,7 @@
|
||||
#define SATIP_STATS_ACTIVE_PIDS_COUNT 10
|
||||
#define SATIP_STATS_ACTIVE_FILTERS_COUNT 10
|
||||
|
||||
#define SECTION_FILTER_TABLE_SIZE 7
|
||||
#define SECTION_FILTER_TABLE_SIZE 5
|
||||
|
||||
#define SATIP_CURL_EASY_GETINFO(X, Y, Z) \
|
||||
if ((res = curl_easy_getinfo((X), (Y), (Z))) != CURLE_OK) { \
|
||||
@@ -93,6 +93,7 @@ uint16_t ts_pid(const uint8_t *bufP);
|
||||
uint8_t payload(const uint8_t *bufP);
|
||||
const char *id_pid(const u_short pidP);
|
||||
char *StripTags(char *strP);
|
||||
char *SkipZeroes(const char *strP);
|
||||
cString ChangeCase(const cString &strP, bool upperP);
|
||||
|
||||
struct section_filter_table_type {
|
||||
|
25
device.c
25
device.c
@@ -19,7 +19,9 @@ cSatipDevice::cSatipDevice(unsigned int indexP)
|
||||
isPacketDeliveredM(false),
|
||||
isOpenDvrM(false),
|
||||
deviceNameM(*cString::sprintf("%s %d", *DeviceType(), deviceIndexM)),
|
||||
channelM()
|
||||
channelM(),
|
||||
createdM(0),
|
||||
mutexM()
|
||||
{
|
||||
unsigned int bufsize = (unsigned int)SATIP_BUFFER_SIZE;
|
||||
bufsize -= (bufsize % TS_SIZE);
|
||||
@@ -144,6 +146,12 @@ cString cSatipDevice::GetInformation(unsigned int pageP)
|
||||
return s;
|
||||
}
|
||||
|
||||
bool cSatipDevice::Ready(void)
|
||||
{
|
||||
//debug("cSatipDevice::%s(%u)", __FUNCTION__, deviceIndexM);
|
||||
return ((cSatipDiscover::GetInstance()->GetServerCount() > 0) || (createdM.Elapsed() > eReadyTimeoutMs));
|
||||
}
|
||||
|
||||
cString cSatipDevice::DeviceType(void) const
|
||||
{
|
||||
//debug("cSatipDevice::%s(%u)", __FUNCTION__, deviceIndexM);
|
||||
@@ -176,7 +184,7 @@ int cSatipDevice::SignalQuality(void) const
|
||||
|
||||
bool cSatipDevice::ProvidesSource(int sourceP) const
|
||||
{
|
||||
debug("cSatipDevice::%s(%u)", __FUNCTION__, deviceIndexM);
|
||||
//debug("cSatipDevice::%s(%u)", __FUNCTION__, deviceIndexM);
|
||||
return (!SatipConfig.IsOperatingModeOff() && !!cSatipDiscover::GetInstance()->GetServer(sourceP));
|
||||
}
|
||||
|
||||
@@ -300,11 +308,12 @@ bool cSatipDevice::SetPid(cPidHandle *handleP, int typeP, bool onP)
|
||||
|
||||
int cSatipDevice::OpenFilter(u_short pidP, u_char tidP, u_char maskP)
|
||||
{
|
||||
//debug("cSatipDevice::%s(%u): pid=%d tid=%d mask=%d", __FUNCTION__, deviceIndexM, pidP, tidP, maskP);
|
||||
//debug("cSatipDevice::%s(%u): pid=%d tid=%d mask=%d", __FUNCTION__, deviceIndexM, pidP, tidP, maskP);
|
||||
if (pSectionFilterHandlerM) {
|
||||
if (pTunerM)
|
||||
int handle = pSectionFilterHandlerM->Open(pidP, tidP, maskP);
|
||||
if (pTunerM && (handle >= 0))
|
||||
pTunerM->SetPid(pidP, ptOther, true);
|
||||
return pSectionFilterHandlerM->Open(pidP, tidP, maskP);
|
||||
return handle;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -372,6 +381,12 @@ unsigned int cSatipDevice::CheckData(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cSatipDevice::GetId(void)
|
||||
{
|
||||
//debug("cSatipDevice::%s(%u)", __FUNCTION__, deviceIndexM);
|
||||
return deviceIndexM;
|
||||
}
|
||||
|
||||
uchar *cSatipDevice::GetData(int *availableP)
|
||||
{
|
||||
//debug("cSatipDevice::%s(%u)", __FUNCTION__, deviceIndexM);
|
||||
|
6
device.h
6
device.h
@@ -26,6 +26,9 @@ public:
|
||||
|
||||
// private parts
|
||||
private:
|
||||
enum {
|
||||
eReadyTimeoutMs = 2000 // in milliseconds
|
||||
};
|
||||
unsigned int deviceIndexM;
|
||||
bool isPacketDeliveredM;
|
||||
bool isOpenDvrM;
|
||||
@@ -34,6 +37,7 @@ private:
|
||||
cRingBufferLinear *tsBufferM;
|
||||
cSatipTuner *pTunerM;
|
||||
cSatipSectionFilterHandler *pSectionFilterHandlerM;
|
||||
cTimeMs createdM;
|
||||
cMutex mutexM;
|
||||
|
||||
// constructor & destructor
|
||||
@@ -54,6 +58,7 @@ private:
|
||||
|
||||
// for channel info
|
||||
public:
|
||||
virtual bool Ready(void);
|
||||
virtual cString DeviceType(void) const;
|
||||
virtual cString DeviceName(void) const;
|
||||
virtual bool AvoidRecording(void) const;
|
||||
@@ -102,6 +107,7 @@ public:
|
||||
public:
|
||||
virtual void WriteData(u_char *bufferP, int lengthP);
|
||||
virtual unsigned int CheckData(void);
|
||||
virtual int GetId(void);
|
||||
};
|
||||
|
||||
#endif // __SATIP_DEVICE_H
|
||||
|
@@ -14,6 +14,7 @@ public:
|
||||
virtual ~cSatipDeviceIf() {}
|
||||
virtual void WriteData(u_char *bufferP, int lengthP) = 0;
|
||||
virtual unsigned int CheckData(void) = 0;
|
||||
virtual int GetId(void) = 0;
|
||||
|
||||
private:
|
||||
cSatipDeviceIf(const cSatipDeviceIf&);
|
||||
|
41
discover.c
41
discover.c
@@ -179,7 +179,7 @@ void cSatipDiscover::Read(void)
|
||||
int len = socketM->Read(buf, eProbeBufferSize);
|
||||
if (len > 0) {
|
||||
//debug("cSatipDiscover::%s(): len=%d", __FUNCTION__, len);
|
||||
bool status = false;
|
||||
bool status = false, valid = false;
|
||||
char *s, *p = reinterpret_cast<char *>(buf), *location = NULL;
|
||||
char *r = strtok_r(p, "\r\n", &s);
|
||||
while (r) {
|
||||
@@ -187,18 +187,30 @@ void cSatipDiscover::Read(void)
|
||||
// Check the status code
|
||||
// HTTP/1.1 200 OK
|
||||
if (!status && startswith(r, "HTTP/1.1 200 OK")) {
|
||||
status = true;
|
||||
}
|
||||
// Check the location data
|
||||
// LOCATION: http://192.168.0.115:8888/octonet.xml
|
||||
if (status && startswith(r, "LOCATION:")) {
|
||||
location = compactspace(r + 9);
|
||||
debug("cSatipDiscover::%s(): location='%s'", __FUNCTION__, location);
|
||||
break;
|
||||
}
|
||||
status = true;
|
||||
}
|
||||
if (status) {
|
||||
// Check the location data
|
||||
// LOCATION: http://192.168.0.115:8888/octonet.xml
|
||||
if (startswith(r, "LOCATION:")) {
|
||||
location = compactspace(r + 9);
|
||||
debug("cSatipDiscover::%s(): location='%s'", __FUNCTION__, location);
|
||||
}
|
||||
// Check the source type
|
||||
// ST: urn:ses-com:device:SatIPServer:1
|
||||
else if (startswith(r, "ST:")) {
|
||||
char *st = compactspace(r + 3);
|
||||
if (strstr(st, "urn:ses-com:device:SatIPServer:1"))
|
||||
valid = true;
|
||||
debug("cSatipDiscover::%s(): st='%s'", __FUNCTION__, st);
|
||||
}
|
||||
// Check whether all the required data is found
|
||||
if (valid && !isempty(location))
|
||||
break;
|
||||
}
|
||||
r = strtok_r(NULL, "\r\n", &s);
|
||||
}
|
||||
if (handleM && !isempty(location)) {
|
||||
if (handleM && valid && !isempty(location)) {
|
||||
long rc = 0;
|
||||
CURLcode res = CURLE_OK;
|
||||
#ifdef DEBUG
|
||||
@@ -251,6 +263,13 @@ void cSatipDiscover::AddServer(const char *addrP, const char *descP, const char
|
||||
}
|
||||
}
|
||||
|
||||
int cSatipDiscover::GetServerCount(void)
|
||||
{
|
||||
//debug("cSatipDiscover::%s()", __FUNCTION__);
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
return serversM ? serversM->Count() : -1;
|
||||
}
|
||||
|
||||
cSatipServer *cSatipDiscover::GetServer(int sourceP, int systemP)
|
||||
{
|
||||
//debug("cSatipDiscover::%s(%d, %d)", __FUNCTION__, sourceP, systemP);
|
||||
|
@@ -56,6 +56,7 @@ public:
|
||||
static void Destroy(void);
|
||||
virtual ~cSatipDiscover();
|
||||
void TriggerScan(void) { probeIntervalM.Set(0); }
|
||||
int GetServerCount(void);
|
||||
cSatipServer *GetServer(int sourceP, int systemP = -1);
|
||||
cSatipServer *GetServer(cSatipServer *serverP);
|
||||
cSatipServers *GetServers(void);
|
||||
|
2
param.c
2
param.c
@@ -158,7 +158,7 @@ cString GetTransponderUrlParameters(const cChannel *channelP)
|
||||
freq /= 1000L;
|
||||
#define ST(s) if (strchr(s, type) && (strchr(s, '0' + dtp.System() + 1) || strchr(s, '*')))
|
||||
#define STBUFLEFT (sizeof(buffer) - (q - buffer))
|
||||
q += snprintf(q, STBUFLEFT, "freq=%s", *dtoa(freq, "%.3f"));
|
||||
q += snprintf(q, STBUFLEFT, "freq=%s", *dtoa(freq, "%lg"));
|
||||
ST(" S *") q += snprintf(q, STBUFLEFT, "&src=%d", ((src > 0) && (src <= 255)) ? src : 1);
|
||||
ST("CS *") q += snprintf(q, STBUFLEFT, "&sr=%d", channelP->Srate());
|
||||
ST(" S *") q += snprintf(q, STBUFLEFT, "&pol=%c", tolower(dtp.Polarization()));
|
||||
|
137
po/ca_ES.po
Normal file
137
po/ca_ES.po
Normal file
@@ -0,0 +1,137 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2007-2014 Rolf Ahrenberg
|
||||
# This file is distributed under the same license as the satip package.
|
||||
# Gabriel Bonich, 2014
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-satip 0.3.3\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2014-05-18 05:18+0200\n"
|
||||
"PO-Revision-Date: 2014-05-18 05:18+0200\n"
|
||||
"Last-Translator: Gabriel Bonich <gbonich@gmail.com>\n"
|
||||
"Language-Team: Catalan <vdr@linuxtv.org>\n"
|
||||
"Language: ca\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
msgid "PAT (0x00)"
|
||||
msgstr "PAT (0x00)"
|
||||
|
||||
msgid "NIT (0x40)"
|
||||
msgstr "NIT (0x40)"
|
||||
|
||||
msgid "SDT (0x42)"
|
||||
msgstr "SDT (0x42)"
|
||||
|
||||
msgid "EIT (0x4E/0x4F/0x5X/0x6X)"
|
||||
msgstr "EIT (0x4E/0x4F/0x5X/0x6X)"
|
||||
|
||||
msgid "TDT (0x70)"
|
||||
msgstr "TDT (0x70)"
|
||||
|
||||
msgid "SAT>IP Devices"
|
||||
msgstr "SAT>IP Dispositius"
|
||||
|
||||
msgid "SAT>IP Device"
|
||||
msgstr "SAT>IP Dispositiu"
|
||||
|
||||
msgid "Address"
|
||||
msgstr "Adressa"
|
||||
|
||||
msgid "Model"
|
||||
msgstr "Model"
|
||||
|
||||
msgid "Description"
|
||||
msgstr "Descripció"
|
||||
|
||||
msgid "Creation date"
|
||||
msgstr "Creació de data"
|
||||
|
||||
msgid "SAT>IP Information"
|
||||
msgstr "SAT>IP Informació"
|
||||
|
||||
msgid "General"
|
||||
msgstr "General"
|
||||
|
||||
msgid "Pids"
|
||||
msgstr "Pids"
|
||||
|
||||
msgid "Filters"
|
||||
msgstr "Filtres"
|
||||
|
||||
msgid "Bits/bytes"
|
||||
msgstr "Bits/Bytes"
|
||||
|
||||
msgid "SAT>IP information not available!"
|
||||
msgstr "SAT>IP Informació no disponible!"
|
||||
|
||||
msgid "off"
|
||||
msgstr "Apagat"
|
||||
|
||||
msgid "low"
|
||||
msgstr "Baix"
|
||||
|
||||
msgid "normal"
|
||||
msgstr "Normal"
|
||||
|
||||
msgid "high"
|
||||
msgstr "Alt"
|
||||
|
||||
msgid "Operating mode"
|
||||
msgstr "Mode de operació"
|
||||
|
||||
msgid ""
|
||||
"Define the used operating mode for all SAT>IP devices:\n"
|
||||
"\n"
|
||||
"off - devices are disabled\n"
|
||||
"low - devices are working at the lowest priority\n"
|
||||
"normal - devices are working within normal parameters\n"
|
||||
"high - devices are working at the highest priority"
|
||||
msgstr ""
|
||||
"Defineig la manera de operar els Disposituis SAT>IP:\n"
|
||||
"\n"
|
||||
"Apagat - Dispositius desactivats\n"
|
||||
"Baix - Dispositius treballan a baixa prioritat\n"
|
||||
"Normal - Dispositius treballan en parametres normals\n"
|
||||
"Alta - Dispositius treballan a prioritat Alta"
|
||||
|
||||
msgid "Enable EPG scanning"
|
||||
msgstr "Activa Escanneig EPG"
|
||||
|
||||
msgid ""
|
||||
"Define whether the EPG background scanning shall be used.\n"
|
||||
"\n"
|
||||
"This setting disables the automatic EIT scanning functionality for all SAT>IP devices."
|
||||
msgstr ""
|
||||
"Definir si s'utilitzarà l'anàlisi en segon pla del EPG.\n"
|
||||
"\n"
|
||||
"Aquesta configuració desactiva la funcionalitat d'escaneig EIT automàtica per a tots els dispositius SAT>IP."
|
||||
|
||||
msgid "Disabled filters"
|
||||
msgstr "Desactiva filtres"
|
||||
|
||||
msgid "none"
|
||||
msgstr "no"
|
||||
|
||||
msgid ""
|
||||
"Define number of section filters to be disabled.\n"
|
||||
"\n"
|
||||
"Certain section filters might cause some unwanted behaviour to VDR such as time being falsely synchronized. By black-listing the filters here useful section data can be left intact for VDR to process."
|
||||
msgstr ""
|
||||
"Defineix el numero de filtres de secció que seran deshabilitats.\n"
|
||||
"\n"
|
||||
"Alguns filtres de secció podrien provocar un comportament no desitjat a VDR, com sincronitzar malament l'hora. Posant aquests filtres a la llista negra, aqui, la secció de dades útil pot ser deixada intacta pel seu procès en el VDR."
|
||||
|
||||
msgid "Filter"
|
||||
msgstr "Filtra"
|
||||
|
||||
msgid "Define an ill-behaving filter to be blacklisted."
|
||||
msgstr "Definir un filtre mal comportar a la llista negra."
|
||||
|
||||
msgid "Active SAT>IP devices:"
|
||||
msgstr "Dispositius SAT>IP actius:"
|
||||
|
||||
msgid "Help"
|
||||
msgstr "Ajuda"
|
20
po/de_DE.po
20
po/de_DE.po
@@ -1,14 +1,14 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2007-2014 Rolf Ahrenberg & Antti Seppala
|
||||
# This file is distributed under the same license as the iptv package.
|
||||
# Copyright (C) 2007-2014 Rolf Ahrenberg
|
||||
# This file is distributed under the same license as the satip package.
|
||||
# Frank Neumann, 2014
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-satip 0.1.1\n"
|
||||
"Project-Id-Version: vdr-satip 0.3.3\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2014-03-16 03:16+0200\n"
|
||||
"PO-Revision-Date: 2014-03-16 03:16+0200\n"
|
||||
"POT-Creation-Date: 2014-05-18 05:18+0200\n"
|
||||
"PO-Revision-Date: 2014-05-18 05:18+0200\n"
|
||||
"Last-Translator: Frank Neumann <fnu@yavdr.org>\n"
|
||||
"Language-Team: German <vdr@linuxtv.org>\n"
|
||||
"Language: de\n"
|
||||
@@ -25,14 +25,8 @@ msgstr "NIT (0x40)"
|
||||
msgid "SDT (0x42)"
|
||||
msgstr "SDT (0x42)"
|
||||
|
||||
msgid "EIT (0x4E/0x4F)"
|
||||
msgstr "EIT (0x4E/0x4F)"
|
||||
|
||||
msgid "EIT (0x5X)"
|
||||
msgstr "EIT (0x5X)"
|
||||
|
||||
msgid "EIT (0x6X)"
|
||||
msgstr "EIT (0x6X)"
|
||||
msgid "EIT (0x4E/0x4F/0x5X/0x6X)"
|
||||
msgstr "EIT (0x4E/0x4F/0x5X/0x6X)"
|
||||
|
||||
msgid "TDT (0x70)"
|
||||
msgstr "TDT (0x70)"
|
||||
|
137
po/es_ES.po
Normal file
137
po/es_ES.po
Normal file
@@ -0,0 +1,137 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2007-2014 Rolf Ahrenberg
|
||||
# This file is distributed under the same license as the satip package.
|
||||
# Gabriel Bonich, 2014
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-satip 0.3.3\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2014-05-18 05:18+0200\n"
|
||||
"PO-Revision-Date: 2014-05-18 05:18+0200\n"
|
||||
"Last-Translator: Gabriel Bonich <gbonich@gmail.com>\n"
|
||||
"Language-Team: Spanish <vdr@linuxtv.org>\n"
|
||||
"Language: es\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
msgid "PAT (0x00)"
|
||||
msgstr "PAT (0x00)"
|
||||
|
||||
msgid "NIT (0x40)"
|
||||
msgstr "NIT (0x40)"
|
||||
|
||||
msgid "SDT (0x42)"
|
||||
msgstr "SDT (0x42)"
|
||||
|
||||
msgid "EIT (0x4E/0x4F/0x5X/0x6X)"
|
||||
msgstr "EIT (0x4E/0x4F/0x5X/0x6X)"
|
||||
|
||||
msgid "TDT (0x70)"
|
||||
msgstr "TDT (0x70)"
|
||||
|
||||
msgid "SAT>IP Devices"
|
||||
msgstr "SAT>IP Dispositivos"
|
||||
|
||||
msgid "SAT>IP Device"
|
||||
msgstr "SAT>IP Dispositivo"
|
||||
|
||||
msgid "Address"
|
||||
msgstr "Dirección"
|
||||
|
||||
msgid "Model"
|
||||
msgstr "Modelo"
|
||||
|
||||
msgid "Description"
|
||||
msgstr "Descripción"
|
||||
|
||||
msgid "Creation date"
|
||||
msgstr "Fecha creación"
|
||||
|
||||
msgid "SAT>IP Information"
|
||||
msgstr "SAT>IP Información"
|
||||
|
||||
msgid "General"
|
||||
msgstr "General"
|
||||
|
||||
msgid "Pids"
|
||||
msgstr "Pids"
|
||||
|
||||
msgid "Filters"
|
||||
msgstr "Filtros"
|
||||
|
||||
msgid "Bits/bytes"
|
||||
msgstr "Bits/Bytes"
|
||||
|
||||
msgid "SAT>IP information not available!"
|
||||
msgstr "SAT>IP Información no disponible!"
|
||||
|
||||
msgid "off"
|
||||
msgstr "Apagado"
|
||||
|
||||
msgid "low"
|
||||
msgstr "Bajo"
|
||||
|
||||
msgid "normal"
|
||||
msgstr "Normal"
|
||||
|
||||
msgid "high"
|
||||
msgstr "Alto"
|
||||
|
||||
msgid "Operating mode"
|
||||
msgstr "Modo de operación"
|
||||
|
||||
msgid ""
|
||||
"Define the used operating mode for all SAT>IP devices:\n"
|
||||
"\n"
|
||||
"off - devices are disabled\n"
|
||||
"low - devices are working at the lowest priority\n"
|
||||
"normal - devices are working within normal parameters\n"
|
||||
"high - devices are working at the highest priority"
|
||||
msgstr ""
|
||||
"Define la manera que trabajan los Dispositivos SAT>IP:\n"
|
||||
"\n"
|
||||
"Apagat - Dispositivos desactivados\n"
|
||||
"Baix - Dispositivos trabajando con prioridad Baja\n"
|
||||
"Normal - Dispositivos trabajando con prioridad Normal\n"
|
||||
"Alta - Dispositivos trabajando con prioridad Alta"
|
||||
|
||||
msgid "Enable EPG scanning"
|
||||
msgstr "Activa Escaneo EPG"
|
||||
|
||||
msgid ""
|
||||
"Define whether the EPG background scanning shall be used.\n"
|
||||
"\n"
|
||||
"This setting disables the automatic EIT scanning functionality for all SAT>IP devices."
|
||||
msgstr ""
|
||||
"Definir si se utilitzará el analisí en segundo plano del EPG.\n"
|
||||
"\n"
|
||||
"Esta configuración desactiva la funcionalidad del escaneo EIT automática para todos los Dispositivos SAT>IP."
|
||||
|
||||
msgid "Disabled filters"
|
||||
msgstr "Desactiva filtros"
|
||||
|
||||
msgid "none"
|
||||
msgstr "no"
|
||||
|
||||
msgid ""
|
||||
"Define number of section filters to be disabled.\n"
|
||||
"\n"
|
||||
"Certain section filters might cause some unwanted behaviour to VDR such as time being falsely synchronized. By black-listing the filters here useful section data can be left intact for VDR to process."
|
||||
msgstr ""
|
||||
"Define el numero de filtros de sección que seran deshabilitados.\n"
|
||||
"\n"
|
||||
"Algunos filtros de sección podrian causar un comportamiento no deseado a VDR, como sincronizar mal la hora. Poniendo estos filtros en la lista negra, aqui, la sección de datos útiles se puede dejar intacta para su proceso con el VDR."
|
||||
|
||||
msgid "Filter"
|
||||
msgstr "Filtra"
|
||||
|
||||
msgid "Define an ill-behaving filter to be blacklisted."
|
||||
msgstr "Define un filtro para poner en la lista negra."
|
||||
|
||||
msgid "Active SAT>IP devices:"
|
||||
msgstr "Dispositivos SAT>IP activos:"
|
||||
|
||||
msgid "Help"
|
||||
msgstr "Ayuda"
|
20
po/fi_FI.po
20
po/fi_FI.po
@@ -1,14 +1,14 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2007-2014 Rolf Ahrenberg & Antti Seppala
|
||||
# This file is distributed under the same license as the iptv package.
|
||||
# Copyright (C) 2007-2014 Rolf Ahrenberg
|
||||
# This file is distributed under the same license as the satip package.
|
||||
# Rolf Ahrenberg, 2014
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-satip 0.1.1\n"
|
||||
"Project-Id-Version: vdr-satip 0.3.3\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2014-03-16 03:16+0200\n"
|
||||
"PO-Revision-Date: 2014-03-16 03:16+0200\n"
|
||||
"POT-Creation-Date: 2014-05-18 05:18+0200\n"
|
||||
"PO-Revision-Date: 2014-05-18 05:18+0200\n"
|
||||
"Last-Translator: Rolf Ahrenberg\n"
|
||||
"Language-Team: Finnish <vdr@linuxtv.org>\n"
|
||||
"Language: fi\n"
|
||||
@@ -25,14 +25,8 @@ msgstr "NIT (0x40)"
|
||||
msgid "SDT (0x42)"
|
||||
msgstr "SDT (0x42)"
|
||||
|
||||
msgid "EIT (0x4E/0x4F)"
|
||||
msgstr "EIT (0x4E/0x4F)"
|
||||
|
||||
msgid "EIT (0x5X)"
|
||||
msgstr "EIT (0x5X)"
|
||||
|
||||
msgid "EIT (0x6X)"
|
||||
msgstr "EIT (0x6X)"
|
||||
msgid "EIT (0x4E/0x4F/0x5X/0x6X)"
|
||||
msgstr "EIT (0x4E/0x4F/0x5X/0x6X)"
|
||||
|
||||
msgid "TDT (0x70)"
|
||||
msgstr "TDT (0x70)"
|
||||
|
6
satip.c
6
satip.c
@@ -13,6 +13,10 @@
|
||||
#include "discover.h"
|
||||
#include "setup.h"
|
||||
|
||||
#if defined(LIBCURL_VERSION_NUM) && LIBCURL_VERSION_NUM < 0x072400
|
||||
#warning "CURL version >= 7.36.0 is recommended"
|
||||
#endif
|
||||
|
||||
#if defined(APIVERSNUM) && APIVERSNUM < 20000
|
||||
#error "VDR-2.0.0 API version or greater is required!"
|
||||
#endif
|
||||
@@ -21,7 +25,7 @@
|
||||
#define GITVERSION ""
|
||||
#endif
|
||||
|
||||
const char VERSION[] = "0.1.1" GITVERSION;
|
||||
const char VERSION[] = "0.3.3" GITVERSION;
|
||||
static const char DESCRIPTION[] = trNOOP("SAT>IP Devices");
|
||||
|
||||
class cPluginSatip : public cPlugin {
|
||||
|
@@ -17,6 +17,7 @@ cSatipSectionFilter::cSatipSectionFilter(int deviceIndexP, uint16_t pidP, uint8_
|
||||
secLenM(0),
|
||||
tsFeedpM(0),
|
||||
pidM(pidP),
|
||||
ringBufferM(new cRingBufferFrame(eDmxMaxSectionCount * eDmxMaxSectionSize)),
|
||||
deviceIndexM(deviceIndexP)
|
||||
{
|
||||
//debug("cSatipSectionFilter::%s(%d, %d)", __FUNCTION__, deviceIndexM, pidM);
|
||||
@@ -48,7 +49,7 @@ cSatipSectionFilter::cSatipSectionFilter(int deviceIndexP, uint16_t pidP, uint8_
|
||||
|
||||
// Create sockets
|
||||
socketM[0] = socketM[1] = -1;
|
||||
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, socketM) != 0) {
|
||||
if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, socketM) != 0) {
|
||||
char tmp[64];
|
||||
error("Opening section filter sockets failed (device=%d pid=%d): %s", deviceIndexM, pidM, strerror_r(errno, tmp, sizeof(tmp)));
|
||||
}
|
||||
@@ -70,6 +71,7 @@ cSatipSectionFilter::~cSatipSectionFilter()
|
||||
if (tmp >= 0)
|
||||
close(tmp);
|
||||
secBufM = NULL;
|
||||
DELETENULL(ringBufferM);
|
||||
}
|
||||
|
||||
inline uint16_t cSatipSectionFilter::GetLength(const uint8_t *dataP)
|
||||
@@ -99,13 +101,8 @@ int cSatipSectionFilter::Filter(void)
|
||||
if (doneqM && !neq)
|
||||
return 0;
|
||||
|
||||
// There is no data in the read socket, more can be written
|
||||
if ((socketM[0] >= 0) && (socketM[1] >= 0) /*&& !select_single_desc(socketM[0], 0, false)*/) {
|
||||
ssize_t len = write(socketM[1], secBufM, secLenM);
|
||||
ERROR_IF(len < 0, "write()");
|
||||
// Update statistics
|
||||
AddSectionStatistic(len, 1);
|
||||
}
|
||||
if (ringBufferM && (secLenM > 0))
|
||||
ringBufferM->Put(new cFrame(secBufM, secLenM));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -211,13 +208,33 @@ void cSatipSectionFilter::Process(const uint8_t* dataP)
|
||||
}
|
||||
}
|
||||
|
||||
bool cSatipSectionFilter::Send(void)
|
||||
{
|
||||
bool result = false;
|
||||
cFrame *section = ringBufferM->Get();
|
||||
if (section) {
|
||||
uchar *data = section->Data();
|
||||
int count = section->Count();
|
||||
if (data && (count > 0) && (socketM[1] >= 0) && (socketM[0] >= 0)) {
|
||||
ssize_t len = send(socketM[1], data, count, MSG_EOR);
|
||||
ERROR_IF(len < 0 && errno != EAGAIN, "send()");
|
||||
if (len > 0) {
|
||||
ringBufferM->Drop(section);
|
||||
result = !!ringBufferM->Available();
|
||||
// Update statistics
|
||||
AddSectionStatistic(len, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
cSatipSectionFilterHandler::cSatipSectionFilterHandler(int deviceIndexP, unsigned int bufferLenP)
|
||||
: cThread("SAT>IP section handler", true),
|
||||
: cThread("SAT>IP section handler"),
|
||||
ringBufferM(new cRingBufferLinear(bufferLenP, TS_SIZE, false, *cString::sprintf("SAT>IP SECTION HANDLER %d", deviceIndexP))),
|
||||
mutexM(),
|
||||
deviceIndexM(deviceIndexP),
|
||||
processedM(false),
|
||||
ringBufferM(new cRingBufferLinear(bufferLenP, TS_SIZE, false, *cString::sprintf("SAT>IP SECTION HANDLER %d", deviceIndexP)))
|
||||
deviceIndexM(deviceIndexP)
|
||||
{
|
||||
debug("cSatipSectionFilterHandler::%s(%d)", __FUNCTION__, deviceIndexM);
|
||||
|
||||
@@ -238,8 +255,9 @@ cSatipSectionFilterHandler::cSatipSectionFilterHandler(int deviceIndexP, unsigne
|
||||
cSatipSectionFilterHandler::~cSatipSectionFilterHandler()
|
||||
{
|
||||
debug("cSatipSectionFilterHandler::%s(%d)", __FUNCTION__, deviceIndexM);
|
||||
Stop();
|
||||
|
||||
// Stop thread
|
||||
if (Running())
|
||||
Cancel(3);
|
||||
DELETE_POINTER(ringBufferM);
|
||||
|
||||
// Destroy all filters
|
||||
@@ -248,26 +266,28 @@ cSatipSectionFilterHandler::~cSatipSectionFilterHandler()
|
||||
Delete(i);
|
||||
}
|
||||
|
||||
bool cSatipSectionFilterHandler::Stop(void)
|
||||
{
|
||||
debug("cSatipSectionFilterHandler::%s(%d): entering", __FUNCTION__, deviceIndexM);
|
||||
// Stop thread
|
||||
if (Running())
|
||||
Cancel(3);
|
||||
return true;
|
||||
}
|
||||
|
||||
void cSatipSectionFilterHandler::Action(void)
|
||||
{
|
||||
debug("cSatipSectionFilterHandler::%s(%d): entering", __FUNCTION__, deviceIndexM);
|
||||
bool processed = false;
|
||||
// Do the thread loop
|
||||
while (Running()) {
|
||||
// Send demuxed section packets through all filters
|
||||
bool retry = false;
|
||||
mutexM.Lock();
|
||||
for (unsigned int i = 0; i < eMaxSecFilterCount; ++i) {
|
||||
if (filtersM[i] && filtersM[i]->Send())
|
||||
retry = true;
|
||||
}
|
||||
mutexM.Unlock();
|
||||
if (retry)
|
||||
continue;
|
||||
// Read one TS packet
|
||||
if (ringBufferM) {
|
||||
int len = 0;
|
||||
if (processedM) {
|
||||
if (processed) {
|
||||
ringBufferM->Del(TS_SIZE);
|
||||
processedM = false;
|
||||
processed = false;
|
||||
}
|
||||
uchar *p = ringBufferM->Get(len);
|
||||
if (p && (len >= TS_SIZE)) {
|
||||
@@ -289,7 +309,7 @@ void cSatipSectionFilterHandler::Action(void)
|
||||
filtersM[i]->Process(p);
|
||||
}
|
||||
mutexM.Unlock();
|
||||
processedM = true;
|
||||
processed = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@@ -8,9 +8,6 @@
|
||||
#ifndef __SATIP_SECTIONFILTER_H
|
||||
#define __SATIP_SECTIONFILTER_H
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/socket.h>
|
||||
#endif // __FreeBSD__
|
||||
#include <vdr/device.h>
|
||||
|
||||
#include "common.h"
|
||||
@@ -18,9 +15,10 @@
|
||||
|
||||
class cSatipSectionFilter : public cSatipSectionStatistics {
|
||||
private:
|
||||
enum dmx_limits {
|
||||
eDmxMaxFilterSize = 18,
|
||||
eDmxMaxSectionSize = 4096,
|
||||
enum {
|
||||
eDmxMaxFilterSize = 18,
|
||||
eDmxMaxSectionCount = 64,
|
||||
eDmxMaxSectionSize = 4096,
|
||||
eDmxMaxSectionFeedSize = (eDmxMaxSectionSize + TS_SIZE)
|
||||
};
|
||||
|
||||
@@ -35,6 +33,7 @@ private:
|
||||
uint16_t tsFeedpM;
|
||||
uint16_t pidM;
|
||||
|
||||
cRingBufferFrame *ringBufferM;
|
||||
int deviceIndexM;
|
||||
int socketM[2];
|
||||
|
||||
@@ -56,6 +55,7 @@ public:
|
||||
cSatipSectionFilter(int deviceIndexP, uint16_t pidP, uint8_t tidP, uint8_t maskP);
|
||||
virtual ~cSatipSectionFilter();
|
||||
void Process(const uint8_t* dataP);
|
||||
bool Send(void);
|
||||
int GetFd(void) { return socketM[0]; }
|
||||
uint16_t GetPid(void) const { return pidM; }
|
||||
};
|
||||
@@ -65,10 +65,9 @@ private:
|
||||
enum {
|
||||
eMaxSecFilterCount = 32
|
||||
};
|
||||
cRingBufferLinear *ringBufferM;
|
||||
cMutex mutexM;
|
||||
int deviceIndexM;
|
||||
bool processedM;
|
||||
cRingBufferLinear *ringBufferM;
|
||||
cSatipSectionFilter *filtersM[eMaxSecFilterCount];
|
||||
|
||||
bool Delete(unsigned int indexP);
|
||||
@@ -80,7 +79,6 @@ protected:
|
||||
public:
|
||||
cSatipSectionFilterHandler(int deviceIndexP, unsigned int bufferLenP);
|
||||
virtual ~cSatipSectionFilterHandler();
|
||||
bool Stop(void);
|
||||
cString GetInformation(void);
|
||||
int Open(u_short pidP, u_char tidP, u_char maskP);
|
||||
void Close(int handleP);
|
||||
|
20
server.c
20
server.c
@@ -16,7 +16,8 @@ cSatipServer::cSatipServer(const char *addressP, const char *descriptionP, const
|
||||
: addressM(addressP),
|
||||
descriptionM(descriptionP),
|
||||
modelM(modelP),
|
||||
modelTypeM(eSatipModelTypeMask),
|
||||
modelTypeM(eSatipModelTypeNone),
|
||||
quirkM(eSatipQuirkNone),
|
||||
useCountM(0),
|
||||
createdM(time(NULL)),
|
||||
lastSeenM(0)
|
||||
@@ -24,6 +25,15 @@ cSatipServer::cSatipServer(const char *addressP, const char *descriptionP, const
|
||||
memset(modelCountM, 0, sizeof(modelCountM));
|
||||
if (isempty(*modelM))
|
||||
modelM = "DVBS-1";
|
||||
// These devices contain a session id bug:
|
||||
// Inverto Airscreen Server IDL 400 ?
|
||||
// Telestar Digibit R1 ?
|
||||
// Elgato EyeTV Netstream 4Sat ?
|
||||
if (!isempty(*descriptionM) &&
|
||||
(strstr(*descriptionM, "GSSBOX") || // Grundig Sat Systems GSS.box DSI 400
|
||||
strstr(*descriptionM, "Triax SatIP Converter") // Triax TSS 400
|
||||
))
|
||||
quirkM |= eSatipQuirkSessionId;
|
||||
char *s, *p = strdup(*modelM);
|
||||
char *r = strtok_r(p, ",", &s);
|
||||
while (r) {
|
||||
@@ -41,7 +51,7 @@ cSatipServer::cSatipServer(const char *addressP, const char *descriptionP, const
|
||||
else
|
||||
modelCountM[eSatipModuleDVBT2] = 1;
|
||||
// Add model quirks here
|
||||
if (strstr(*addressM, "OctopusNet"))
|
||||
if (!isempty(*descriptionM) && strstr(*descriptionM, "OctopusNet"))
|
||||
modelTypeM |= cSatipServer::eSatipModelTypeDVBC;
|
||||
}
|
||||
if (strstr(r, "DVBT")) {
|
||||
@@ -51,7 +61,7 @@ cSatipServer::cSatipServer(const char *addressP, const char *descriptionP, const
|
||||
else
|
||||
modelCountM[eSatipModuleDVBT] = 1;
|
||||
// Add model quirks here
|
||||
if (strstr(*addressM, "OctopusNet"))
|
||||
if (!isempty(*descriptionM) && strstr(*descriptionM, "OctopusNet"))
|
||||
modelTypeM |= cSatipServer::eSatipModelTypeDVBC;
|
||||
}
|
||||
r = strtok_r(NULL, ",", &s);
|
||||
@@ -149,7 +159,7 @@ cString cSatipServers::GetString(cSatipServer *serverP)
|
||||
cString list = "";
|
||||
for (cSatipServer *s = First(); s; s = Next(s)) {
|
||||
if (s == serverP) {
|
||||
list = cString::sprintf("%s:%s:%s", s->Address(), s->Model(), s->Description());
|
||||
list = cString::sprintf("%s|%s|%s", s->Address(), s->Model(), s->Description());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -160,7 +170,7 @@ cString cSatipServers::List(void)
|
||||
{
|
||||
cString list = "";
|
||||
for (cSatipServer *s = First(); s; s = Next(s))
|
||||
list = cString::sprintf("%s%s:%s:%s\n", *list, s->Address(), s->Model(), s->Description());
|
||||
list = cString::sprintf("%s%s|%s|%s\n", *list, s->Address(), s->Model(), s->Description());
|
||||
return list;
|
||||
}
|
||||
|
||||
|
8
server.h
8
server.h
@@ -23,12 +23,19 @@ private:
|
||||
cString modelM;
|
||||
int modelCountM[eSatipModuleCount];
|
||||
int modelTypeM;
|
||||
int quirkM;
|
||||
int useCountM;
|
||||
time_t createdM;
|
||||
cTimeMs lastSeenM;
|
||||
|
||||
public:
|
||||
enum eSatipQuirk {
|
||||
eSatipQuirkNone = 0x00,
|
||||
eSatipQuirkSessionId = 0x01,
|
||||
eSatipQuirkMask = 0x0F
|
||||
};
|
||||
enum eSatipModelType {
|
||||
eSatipModelTypeNone = 0x00,
|
||||
eSatipModelTypeDVBS2 = 0x01,
|
||||
eSatipModelTypeDVBT = 0x02,
|
||||
eSatipModelTypeDVBT2 = 0x04,
|
||||
@@ -43,6 +50,7 @@ public:
|
||||
const char *Description() { return *descriptionM; }
|
||||
const char *Address() { return *addressM; }
|
||||
const char *Model(void) { return modelM; }
|
||||
bool Quirk(int quirkP) { return ((quirkP & eSatipQuirkMask) & quirkM); }
|
||||
int ModelType(void) { return modelTypeM; }
|
||||
bool Match(int modelP) { return ((modelP & eSatipModelTypeMask) & modelTypeM); }
|
||||
int Cable() { return Match(eSatipModelTypeDVBC) ? (Match(eSatipModelTypeDVBT2) ? modelCountM[eSatipModuleDVBT2] : modelCountM[eSatipModuleDVBT]) : 0; } // an ugly hack
|
||||
|
26
socket.c
26
socket.c
@@ -20,7 +20,10 @@
|
||||
|
||||
cSatipSocket::cSatipSocket()
|
||||
: socketPortM(0),
|
||||
socketDescM(-1)
|
||||
socketDescM(-1),
|
||||
lastErrorReportM(0),
|
||||
packetErrorsM(0),
|
||||
sequenceNumberM(-1)
|
||||
{
|
||||
debug("cSatipSocket::%s()", __FUNCTION__);
|
||||
memset(&sockAddrM, 0, sizeof(sockAddrM));
|
||||
@@ -72,8 +75,14 @@ void cSatipSocket::Close(void)
|
||||
close(socketDescM);
|
||||
socketDescM = -1;
|
||||
socketPortM = 0;
|
||||
sequenceNumberM = -1;
|
||||
memset(&sockAddrM, 0, sizeof(sockAddrM));
|
||||
}
|
||||
if (packetErrorsM) {
|
||||
info("detected %d RTP packet errors", packetErrorsM);
|
||||
packetErrorsM = 0;
|
||||
lastErrorReportM = time(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
bool cSatipSocket::Flush(void)
|
||||
@@ -150,6 +159,21 @@ int cSatipSocket::ReadVideo(unsigned char *bufferAddrP, unsigned int bufferLenP)
|
||||
unsigned int cc = bufferAddrP[0] & 0x0F;
|
||||
// Payload type: MPEG2 TS = 33
|
||||
//unsigned int pt = bufferAddrP[1] & 0x7F;
|
||||
// Sequence number
|
||||
int seq = ((bufferAddrP[2] & 0xFF) << 8) | (bufferAddrP[3] & 0xFF);
|
||||
if ((((sequenceNumberM + 1) % 0xFFFF) == 0) && (seq == 0xFFFF))
|
||||
sequenceNumberM = -1;
|
||||
else if ((sequenceNumberM >= 0) && (((sequenceNumberM + 1) % 0xFFFF) != seq)) {
|
||||
packetErrorsM++;
|
||||
if (time(NULL) - lastErrorReportM > eReportIntervalS) {
|
||||
info("detected %d RTP packet errors", packetErrorsM);
|
||||
packetErrorsM = 0;
|
||||
lastErrorReportM = time(NULL);
|
||||
}
|
||||
sequenceNumberM = seq;
|
||||
}
|
||||
else
|
||||
sequenceNumberM = seq;
|
||||
// Header lenght
|
||||
unsigned int headerlen = (3 + cc) * (unsigned int)sizeof(uint32_t);
|
||||
// Check if extension
|
||||
|
6
socket.h
6
socket.h
@@ -12,9 +12,15 @@
|
||||
|
||||
class cSatipSocket {
|
||||
private:
|
||||
enum {
|
||||
eReportIntervalS = 300 // in seconds
|
||||
};
|
||||
int socketPortM;
|
||||
int socketDescM;
|
||||
struct sockaddr_in sockAddrM;
|
||||
time_t lastErrorReportM;
|
||||
int packetErrorsM;
|
||||
int sequenceNumberM;
|
||||
|
||||
public:
|
||||
cSatipSocket();
|
||||
|
193
tuner.c
193
tuner.c
@@ -26,31 +26,32 @@ cSatipTuner::cSatipTuner(cSatipDeviceIf &deviceP, unsigned int packetLenP)
|
||||
headerListM(NULL),
|
||||
keepAliveM(),
|
||||
pidUpdateCacheM(),
|
||||
sessionM(),
|
||||
timeoutM(eKeepAliveIntervalMs),
|
||||
sessionM(""),
|
||||
timeoutM(eMinKeepAliveIntervalMs),
|
||||
openedM(false),
|
||||
tunedM(false),
|
||||
hasLockM(false),
|
||||
signalStrengthM(-1),
|
||||
signalQualityM(-1),
|
||||
streamIdM(-1),
|
||||
pidUpdatedM(false),
|
||||
addPidsM(),
|
||||
delPidsM(),
|
||||
pidsM()
|
||||
{
|
||||
debug("cSatipTuner::%s(%d)", __FUNCTION__, packetBufferLenM);
|
||||
debug("cSatipTuner::%s(%d) [device %d]", __FUNCTION__, packetBufferLenM, deviceM->GetId());
|
||||
// Allocate packet buffer
|
||||
packetBufferM = MALLOC(unsigned char, packetBufferLenM);
|
||||
if (packetBufferM)
|
||||
memset(packetBufferM, 0, packetBufferLenM);
|
||||
else
|
||||
error("MALLOC() failed for packet buffer");
|
||||
error("MALLOC() failed for packet buffer [device %d]", deviceM->GetId());
|
||||
// Start thread
|
||||
Start();
|
||||
}
|
||||
|
||||
cSatipTuner::~cSatipTuner()
|
||||
{
|
||||
debug("cSatipTuner::%s()", __FUNCTION__);
|
||||
debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceM->GetId());
|
||||
// Stop thread
|
||||
sleepM.Signal();
|
||||
if (Running())
|
||||
@@ -83,9 +84,9 @@ size_t cSatipTuner::HeaderCallback(void *ptrP, size_t sizeP, size_t nmembP, void
|
||||
int timeout = -1;
|
||||
char *session = NULL;
|
||||
if (sscanf(r, "Session:%m[^;];timeout=%11d", &session, &timeout) == 2)
|
||||
obj->SetSessionTimeout(skipspace(session), timeout);
|
||||
obj->SetSessionTimeout(skipspace(session), timeout * 1000);
|
||||
else if (sscanf(r, "Session:%m[^;]", &session) == 1)
|
||||
obj->SetSessionTimeout(skipspace(session), -1);
|
||||
obj->SetSessionTimeout(skipspace(session));
|
||||
FREE_POINTER(session);
|
||||
}
|
||||
r = strtok_r(NULL, "\r\n", &s);
|
||||
@@ -96,8 +97,8 @@ size_t cSatipTuner::HeaderCallback(void *ptrP, size_t sizeP, size_t nmembP, void
|
||||
|
||||
void cSatipTuner::Action(void)
|
||||
{
|
||||
debug("cSatipTuner::%s(): entering", __FUNCTION__);
|
||||
cTimeMs timeout(0);
|
||||
debug("cSatipTuner::%s(): entering [device %d]", __FUNCTION__, deviceM->GetId());
|
||||
cTimeMs timeout(eReConnectTimeoutMs);
|
||||
// Increase priority
|
||||
SetPriority(-1);
|
||||
// Do the thread loop
|
||||
@@ -129,7 +130,7 @@ void cSatipTuner::Action(void)
|
||||
}
|
||||
else {
|
||||
// Reconnect if necessary
|
||||
if (openedM && !tunedM && timeout.TimedOut()) {
|
||||
if (openedM && timeout.TimedOut()) {
|
||||
Disconnect();
|
||||
Connect();
|
||||
timeout.Set(eReConnectTimeoutMs);
|
||||
@@ -137,12 +138,12 @@ void cSatipTuner::Action(void)
|
||||
sleepM.Wait(10); // to avoid busy loop and reduce cpu load
|
||||
}
|
||||
}
|
||||
debug("cSatipTuner::%s(): exiting", __FUNCTION__);
|
||||
debug("cSatipTuner::%s(): exiting [device %d]", __FUNCTION__, deviceM->GetId());
|
||||
}
|
||||
|
||||
bool cSatipTuner::Open(void)
|
||||
{
|
||||
debug("cSatipTuner::%s()", __FUNCTION__);
|
||||
debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceM->GetId());
|
||||
if (Connect()) {
|
||||
openedM = true;
|
||||
return true;
|
||||
@@ -152,7 +153,7 @@ bool cSatipTuner::Open(void)
|
||||
|
||||
bool cSatipTuner::Close(void)
|
||||
{
|
||||
debug("cSatipTuner::%s()", __FUNCTION__);
|
||||
debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceM->GetId());
|
||||
openedM = false;
|
||||
Disconnect();
|
||||
return true;
|
||||
@@ -161,7 +162,7 @@ bool cSatipTuner::Close(void)
|
||||
bool cSatipTuner::Connect(void)
|
||||
{
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
debug("cSatipTuner::%s()", __FUNCTION__);
|
||||
debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceM->GetId());
|
||||
|
||||
// Initialize the curl session
|
||||
if (!handleM)
|
||||
@@ -173,17 +174,12 @@ bool cSatipTuner::Connect(void)
|
||||
|
||||
// Just retune
|
||||
if (tunedM && (streamIdM >= 0)) {
|
||||
debug("cSatipTuner::%s(): retune", __FUNCTION__);
|
||||
uri = cString::sprintf("rtsp://%s/stream=%d", *streamAddrM, streamIdM);
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_STREAM_URI, *uri);
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_PLAY);
|
||||
SATIP_CURL_EASY_PERFORM(handleM);
|
||||
if (!ValidateLatestResponse())
|
||||
return false;
|
||||
debug("cSatipTuner::%s(): retune [device %d]", __FUNCTION__, deviceM->GetId());
|
||||
keepAliveM.Set(0);
|
||||
KeepAlive();
|
||||
// Flush any old content
|
||||
if (rtpSocketM)
|
||||
rtpSocketM->Flush();
|
||||
keepAliveM.Set(eKeepAliveIntervalMs);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -192,11 +188,6 @@ bool cSatipTuner::Connect(void)
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_VERBOSE, 1L);
|
||||
#endif
|
||||
|
||||
// Set callback
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_HEADERFUNCTION, cSatipTuner::HeaderCallback);
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEHEADER, this);
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEDATA, this);
|
||||
|
||||
// No progress meter and no signaling
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_NOPROGRESS, 1L);
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_NOSIGNAL, 1L);
|
||||
@@ -206,7 +197,7 @@ bool cSatipTuner::Connect(void)
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_CONNECTTIMEOUT_MS, (long)eConnectTimeoutMs);
|
||||
|
||||
// Set user-agent
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_USERAGENT, *cString::sprintf("vdr-%s/%s", PLUGIN_NAME_I18N, VERSION));
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_USERAGENT, *cString::sprintf("vdr-%s/%s (device %d)", PLUGIN_NAME_I18N, VERSION, deviceM->GetId()));
|
||||
|
||||
// Set URL
|
||||
char *p = curl_easy_unescape(handleM, *streamAddrM, 0, NULL);
|
||||
@@ -224,37 +215,41 @@ bool cSatipTuner::Connect(void)
|
||||
rtcpSocketM->Close();
|
||||
}
|
||||
if ((rtpSocketM->Port() <= 0) || (rtcpSocketM->Port() <= 0)) {
|
||||
error("Cannot open required ports!");
|
||||
error("Cannot open required RTP/RTCP ports [device %d]", deviceM->GetId());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Request server options: "&pids=all" for the whole mux
|
||||
uri = cString::sprintf("rtsp://%s/?%s&pids=0", *streamAddrM, *streamParamM);
|
||||
// Request server options
|
||||
keepAliveM.Set(timeoutM);
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_STREAM_URI, *uri);
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_OPTIONS);
|
||||
SATIP_CURL_EASY_PERFORM(handleM);
|
||||
if (!ValidateLatestResponse())
|
||||
return false;
|
||||
|
||||
// Setup media stream
|
||||
// Setup media stream: "&pids=all" for the whole mux
|
||||
uri = cString::sprintf("rtsp://%s/?%s", *streamAddrM, *streamParamM);
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_STREAM_URI, *uri);
|
||||
transport = cString::sprintf("RTP/AVP;unicast;client_port=%d-%d", rtpSocketM->Port(), rtcpSocketM->Port());
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_TRANSPORT, *transport);
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_SETUP);
|
||||
// Set header callback for catching the session and timeout
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_HEADERFUNCTION, cSatipTuner::HeaderCallback);
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEHEADER, this);
|
||||
SATIP_CURL_EASY_PERFORM(handleM);
|
||||
// Session id is now known - disable header parsing
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_HEADERFUNCTION, NULL);
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEHEADER, NULL);
|
||||
if (nextServerM && nextServerM->Quirk(cSatipServer::eSatipQuirkSessionId) && !isempty(*sessionM) && startswith(*sessionM, "0")) {
|
||||
debug("cSatipTuner::%s(): session id quirk [device %d]", __FUNCTION__, deviceM->GetId());
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_SESSION_ID, SkipZeroes(*sessionM));
|
||||
}
|
||||
if (!ValidateLatestResponse())
|
||||
return false;
|
||||
|
||||
// Start playing
|
||||
uri = cString::sprintf("rtsp://%s/stream=%d", *streamAddrM, streamIdM);
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_STREAM_URI, *uri);
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_SESSION_ID, *sessionM);
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_PLAY);
|
||||
SATIP_CURL_EASY_PERFORM(handleM);
|
||||
if (!ValidateLatestResponse())
|
||||
return false;
|
||||
|
||||
keepAliveM.Set(eKeepAliveIntervalMs);
|
||||
tunedM = true;
|
||||
UpdatePids(true);
|
||||
if (nextServerM) {
|
||||
cSatipDiscover::GetInstance()->UseServer(nextServerM, true);
|
||||
currentServerM = nextServerM;
|
||||
@@ -269,7 +264,7 @@ bool cSatipTuner::Connect(void)
|
||||
bool cSatipTuner::Disconnect(void)
|
||||
{
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
debug("cSatipTuner::%s()", __FUNCTION__);
|
||||
debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceM->GetId());
|
||||
|
||||
// Terminate curl session
|
||||
if (handleM) {
|
||||
@@ -305,13 +300,16 @@ bool cSatipTuner::Disconnect(void)
|
||||
if (currentServerM)
|
||||
cSatipDiscover::GetInstance()->UseServer(currentServerM, false);
|
||||
tunedM = false;
|
||||
timeoutM = eMinKeepAliveIntervalMs;
|
||||
addPidsM.Clear();
|
||||
delPidsM.Clear();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cSatipTuner::ValidateLatestResponse(void)
|
||||
{
|
||||
//debug("cSatipTuner::%s()", __FUNCTION__);
|
||||
//debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceM->GetId());
|
||||
if (handleM) {
|
||||
long rc = 0;
|
||||
CURLcode res = CURLE_OK;
|
||||
@@ -319,7 +317,7 @@ bool cSatipTuner::ValidateLatestResponse(void)
|
||||
if (rc == 200)
|
||||
return true;
|
||||
else if (rc != 0)
|
||||
error("Tuner detected invalid status code: %ld", rc);
|
||||
error("Tuner detected invalid status code %ld [device %d]", rc, deviceM->GetId());
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -327,7 +325,7 @@ bool cSatipTuner::ValidateLatestResponse(void)
|
||||
|
||||
void cSatipTuner::ParseReceptionParameters(const char *paramP)
|
||||
{
|
||||
//debug("cSatipTuner::%s(%s)", __FUNCTION__, paramP);
|
||||
//debug("cSatipTuner::%s(%s) [device %d]", __FUNCTION__, paramP, deviceM->GetId());
|
||||
// DVB-S2:
|
||||
// ver=<major>.<minor>;src=<srcID>;tuner=<feID>,<level>,<lock>,<quality>,<frequency>,<polarisation>,<system>,<type>,<pilots>,<roll_off>,<symbol_rate>,<fec_inner>;pids=<pid0>,...,<pidn>
|
||||
// DVB-T2:
|
||||
@@ -374,21 +372,21 @@ void cSatipTuner::ParseReceptionParameters(const char *paramP)
|
||||
void cSatipTuner::SetStreamId(int streamIdP)
|
||||
{
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
debug("cSatipTuner::%s(%d)", __FUNCTION__, streamIdP);
|
||||
debug("cSatipTuner::%s(%d) [device %d]", __FUNCTION__, streamIdP, deviceM->GetId());
|
||||
streamIdM = streamIdP;
|
||||
}
|
||||
|
||||
void cSatipTuner::SetSessionTimeout(const char *sessionP, int timeoutP)
|
||||
{
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
debug("cSatipTuner::%s(%s, %d)", __FUNCTION__, sessionP, timeoutP);
|
||||
debug("cSatipTuner::%s(%s, %d) [device %d]", __FUNCTION__, sessionP, timeoutP, deviceM->GetId());
|
||||
sessionM = sessionP;
|
||||
timeoutM = timeoutP > 0 ? timeoutP * 1000L : eKeepAliveIntervalMs;
|
||||
timeoutM = (timeoutP > eMinKeepAliveIntervalMs) ? timeoutP : eMinKeepAliveIntervalMs;
|
||||
}
|
||||
|
||||
bool cSatipTuner::SetSource(cSatipServer *serverP, const char *parameterP, const int indexP)
|
||||
{
|
||||
debug("cSatipTuner::%s(%s, %d)", __FUNCTION__, parameterP, indexP);
|
||||
debug("cSatipTuner::%s(%s, %d) [device %d]", __FUNCTION__, parameterP, indexP, deviceM->GetId());
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
nextServerM = cSatipDiscover::GetInstance()->GetServer(serverP);
|
||||
if (nextServerM && !isempty(nextServerM->Address()) && !isempty(parameterP)) {
|
||||
@@ -403,45 +401,90 @@ bool cSatipTuner::SetSource(cSatipServer *serverP, const char *parameterP, const
|
||||
|
||||
bool cSatipTuner::SetPid(int pidP, int typeP, bool onP)
|
||||
{
|
||||
//debug("cSatipTuner::%s(%d, %d, %d)", __FUNCTION__, pidP, typeP, onP);
|
||||
//debug("cSatipTuner::%s(%d, %d, %d) [device %d]", __FUNCTION__, pidP, typeP, onP, deviceM->GetId());
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
bool found = false;
|
||||
for (int i = 0; i < pidsM.Size(); ++i) {
|
||||
if (pidsM[i] == pidP) {
|
||||
found = true;
|
||||
if (!onP) {
|
||||
if (!onP)
|
||||
pidsM.Remove(i);
|
||||
pidUpdatedM = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (onP && !found) {
|
||||
if (onP && !found)
|
||||
pidsM.Append(pidP);
|
||||
pidUpdatedM = true;
|
||||
}
|
||||
// Generate deltas
|
||||
found = false;
|
||||
if (onP) {
|
||||
for (int i = 0; i < addPidsM.Size(); ++i) {
|
||||
if (addPidsM[i] == pidP) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
addPidsM.Append(pidP);
|
||||
for (int i = 0; i < delPidsM.Size(); ++i) {
|
||||
if (delPidsM[i] == pidP) {
|
||||
delPidsM.Remove(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < delPidsM.Size(); ++i) {
|
||||
if (delPidsM[i] == pidP) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
delPidsM.Append(pidP);
|
||||
for (int i = 0; i < addPidsM.Size(); ++i) {
|
||||
if (addPidsM[i] == pidP) {
|
||||
addPidsM.Remove(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
pidUpdateCacheM.Set(ePidUpdateIntervalMs);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cSatipTuner::UpdatePids(void)
|
||||
bool cSatipTuner::UpdatePids(bool forceP)
|
||||
{
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
if (pidUpdateCacheM.TimedOut() && pidUpdatedM && pidsM.Size() && tunedM && handleM && !isempty(*streamAddrM) && (streamIdM > 0)) {
|
||||
//debug("cSatipTuner::%s()", __FUNCTION__);
|
||||
if (((forceP && pidsM.Size()) || (pidUpdateCacheM.TimedOut() && (addPidsM.Size() || delPidsM.Size()))) &&
|
||||
tunedM && handleM && !isempty(*streamAddrM) && (streamIdM > 0)) {
|
||||
CURLcode res = CURLE_OK;
|
||||
//cString uri = cString::sprintf("rtsp://%s/stream=%d?%spids=%d", *streamAddrM, streamIdM, onP ? "add" : "del", pidP);
|
||||
cString uri = cString::sprintf("rtsp://%s/stream=%d?pids=", *streamAddrM, streamIdM);
|
||||
|
||||
for (int i = 0; i < pidsM.Size(); ++i)
|
||||
uri = cString::sprintf("%s%d%s", *uri, pidsM[i], (i == (pidsM.Size() - 1)) ? "" : ",");
|
||||
|
||||
cString uri = cString::sprintf("rtsp://%s/stream=%d", *streamAddrM, streamIdM);
|
||||
if (forceP) {
|
||||
if (pidsM.Size()) {
|
||||
uri = cString::sprintf("%s?pids=", *uri);
|
||||
for (int i = 0; i < pidsM.Size(); ++i)
|
||||
uri = cString::sprintf("%s%d%s", *uri, pidsM[i], (i == (pidsM.Size() - 1)) ? "" : ",");
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (addPidsM.Size()) {
|
||||
uri = cString::sprintf("%s?addpids=", *uri);
|
||||
for (int i = 0; i < addPidsM.Size(); ++i)
|
||||
uri = cString::sprintf("%s%d%s", *uri, addPidsM[i], (i == (addPidsM.Size() - 1)) ? "" : ",");
|
||||
}
|
||||
if (delPidsM.Size()) {
|
||||
uri = cString::sprintf("%s%sdelpids=", *uri, addPidsM.Size() ? "&" : "?");
|
||||
for (int i = 0; i < delPidsM.Size(); ++i)
|
||||
uri = cString::sprintf("%s%d%s", *uri, delPidsM[i], (i == (delPidsM.Size() - 1)) ? "" : ",");
|
||||
}
|
||||
}
|
||||
//debug("cSatipTuner::%s(): %s [device %d]", __FUNCTION__, *uri, deviceM->GetId());
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_STREAM_URI, *uri);
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_PLAY);
|
||||
SATIP_CURL_EASY_PERFORM(handleM);
|
||||
if (ValidateLatestResponse()) {
|
||||
keepAliveM.Set(eKeepAliveIntervalMs);
|
||||
pidUpdatedM = false;
|
||||
addPidsM.Clear();
|
||||
delPidsM.Clear();
|
||||
}
|
||||
else
|
||||
Disconnect();
|
||||
@@ -456,7 +499,7 @@ bool cSatipTuner::KeepAlive(void)
|
||||
{
|
||||
cMutexLock MutexLock(&mutexM);
|
||||
if (tunedM && handleM && keepAliveM.TimedOut()) {
|
||||
debug("cSatipTuner::%s()", __FUNCTION__);
|
||||
debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceM->GetId());
|
||||
CURLcode res = CURLE_OK;
|
||||
cString uri = cString::sprintf("rtsp://%s/stream=%d", *streamAddrM, streamIdM);
|
||||
|
||||
@@ -464,7 +507,7 @@ bool cSatipTuner::KeepAlive(void)
|
||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_OPTIONS);
|
||||
SATIP_CURL_EASY_PERFORM(handleM);
|
||||
if (ValidateLatestResponse())
|
||||
keepAliveM.Set(eKeepAliveIntervalMs);
|
||||
keepAliveM.Set(timeoutM);
|
||||
else
|
||||
Disconnect();
|
||||
|
||||
@@ -476,30 +519,30 @@ bool cSatipTuner::KeepAlive(void)
|
||||
|
||||
int cSatipTuner::SignalStrength(void)
|
||||
{
|
||||
//debug("cSatipTuner::%s()", __FUNCTION__);
|
||||
//debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceM->GetId());
|
||||
return signalStrengthM;
|
||||
}
|
||||
|
||||
int cSatipTuner::SignalQuality(void)
|
||||
{
|
||||
//debug("cSatipTuner::%s()", __FUNCTION__);
|
||||
//debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceM->GetId());
|
||||
return signalQualityM;
|
||||
}
|
||||
|
||||
bool cSatipTuner::HasLock(void)
|
||||
{
|
||||
//debug("cSatipTuner::%s()", __FUNCTION__);
|
||||
//debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceM->GetId());
|
||||
return tunedM && hasLockM;
|
||||
}
|
||||
|
||||
cString cSatipTuner::GetSignalStatus(void)
|
||||
{
|
||||
//debug("cSatipTuner::%s()", __FUNCTION__);
|
||||
//debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceM->GetId());
|
||||
return cString::sprintf("lock=%d strength=%d quality=%d", HasLock(), SignalStrength(), SignalQuality());
|
||||
}
|
||||
|
||||
cString cSatipTuner::GetInformation(void)
|
||||
{
|
||||
//debug("cSatipTuner::%s()", __FUNCTION__);
|
||||
//debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceM->GetId());
|
||||
return tunedM ? cString::sprintf("rtsp://%s/?%s [stream=%d]", *streamAddrM, *streamParamM, streamIdM) : "connection failed";
|
||||
}
|
||||
|
15
tuner.h
15
tuner.h
@@ -26,10 +26,10 @@
|
||||
class cSatipTuner : public cThread, public cSatipTunerStatistics {
|
||||
private:
|
||||
enum {
|
||||
eConnectTimeoutMs = 1500, // in milliseconds
|
||||
ePidUpdateIntervalMs = 100, // in milliseconds
|
||||
eReConnectTimeoutMs = 5000, // in milliseconds
|
||||
eKeepAliveIntervalMs = 600000 // in milliseconds
|
||||
eConnectTimeoutMs = 1500, // in milliseconds
|
||||
ePidUpdateIntervalMs = 250, // in milliseconds
|
||||
eReConnectTimeoutMs = 5000, // in milliseconds
|
||||
eMinKeepAliveIntervalMs = 30000 // in milliseconds
|
||||
};
|
||||
|
||||
static size_t HeaderCallback(void *ptrP, size_t sizeP, size_t nmembP, void *dataP);
|
||||
@@ -58,7 +58,8 @@ private:
|
||||
int signalStrengthM;
|
||||
int signalQualityM;
|
||||
int streamIdM;
|
||||
bool pidUpdatedM;
|
||||
cVector<int> addPidsM;
|
||||
cVector<int> delPidsM;
|
||||
cVector<int> pidsM;
|
||||
|
||||
bool Connect(void);
|
||||
@@ -66,10 +67,10 @@ private:
|
||||
bool ValidateLatestResponse(void);
|
||||
void ParseReceptionParameters(const char *paramP);
|
||||
void SetStreamId(int streamIdP);
|
||||
void SetSessionTimeout(const char *sessionP, int timeoutP);
|
||||
void SetSessionTimeout(const char *sessionP, int timeoutP = 0);
|
||||
bool KeepAlive(void);
|
||||
bool UpdateSignalInfoCache(void);
|
||||
bool UpdatePids(void);
|
||||
bool UpdatePids(bool forceP = false);
|
||||
|
||||
protected:
|
||||
virtual void Action(void);
|
||||
|
Reference in New Issue
Block a user