mirror of
https://github.com/rofafor/vdr-plugin-satip.git
synced 2023-10-10 11:37:42 +00:00
Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
78ef582bea | ||
|
|
6e72eba09c | ||
|
|
fb40846171 | ||
|
|
b19be5b5c5 | ||
|
|
1a304e9dc2 | ||
|
|
5ff54d27a3 | ||
|
|
276370afbb | ||
|
|
f2081c4f00 | ||
|
|
388543a58d | ||
|
|
f46d07a95f | ||
|
|
43cc15357e | ||
|
|
5b1af5ba29 | ||
|
|
80fc28d8cf | ||
|
|
5e8b7b7c5e | ||
|
|
88b2ad9244 | ||
|
|
7b58d9f28f | ||
|
|
f493df0e3d | ||
|
|
9a6ae40954 | ||
|
|
b5ec84fd91 | ||
|
|
e7a74f3ad4 | ||
|
|
40d280af10 | ||
|
|
9f2d99435d |
31
HISTORY
31
HISTORY
@@ -19,3 +19,34 @@ VDR Plugin 'satip' Revision History
|
|||||||
- Refactored the session code.
|
- Refactored the session code.
|
||||||
- Fixed EIT scan functionality.
|
- Fixed EIT scan functionality.
|
||||||
- Updated for vdr-2.1.6.
|
- 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.
|
||||||
|
|||||||
8
README
8
README
@@ -14,7 +14,7 @@ See the file COPYING for more information.
|
|||||||
|
|
||||||
Requirements:
|
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/
|
http://curl.haxx.se/libcurl/
|
||||||
|
|
||||||
- PugiXML - Light-weight, simple and fast XML parser for C++
|
- PugiXML - Light-weight, simple and fast XML parser for C++
|
||||||
@@ -23,7 +23,7 @@ Requirements:
|
|||||||
TinyXML - a simple, small, C++ XML parser
|
TinyXML - a simple, small, C++ XML parser
|
||||||
http://www.grinninglizard.com/tinyxml/
|
http://www.grinninglizard.com/tinyxml/
|
||||||
|
|
||||||
- VDR-2.1.4+ for scrambled channels
|
- VDR >= 2.1.4 for scrambled channels
|
||||||
|
|
||||||
Description:
|
Description:
|
||||||
|
|
||||||
@@ -108,10 +108,6 @@ Notes:
|
|||||||
direct access to any DVB card devices. The integrated CAM slot in
|
direct access to any DVB card devices. The integrated CAM slot in
|
||||||
Octopus Net devices isn't supported.
|
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:
|
Acknowledgements:
|
||||||
|
|
||||||
- Big thanks to Digital Devices GmbH for providing the Octopus Net
|
- Big thanks to Digital Devices GmbH for providing the Octopus Net
|
||||||
|
|||||||
14
common.c
14
common.c
@@ -70,12 +70,10 @@ cString ChangeCase(const cString &strP, bool upperP)
|
|||||||
|
|
||||||
const section_filter_table_type section_filter_table[SECTION_FILTER_TABLE_SIZE] =
|
const section_filter_table_type section_filter_table[SECTION_FILTER_TABLE_SIZE] =
|
||||||
{
|
{
|
||||||
/* description tag pid tid mask */
|
/* description tag pid tid mask */
|
||||||
{trNOOP("PAT (0x00)"), "PAT", 0x00, 0x00, 0xFF},
|
{trNOOP("PAT (0x00)"), "PAT", 0x00, 0x00, 0xFF},
|
||||||
{trNOOP("NIT (0x40)"), "NIT", 0x10, 0x40, 0xFF},
|
{trNOOP("NIT (0x40)"), "NIT", 0x10, 0x40, 0xFF},
|
||||||
{trNOOP("SDT (0x42)"), "SDT", 0x11, 0x42, 0xFF},
|
{trNOOP("SDT (0x42)"), "SDT", 0x11, 0x42, 0xFF},
|
||||||
{trNOOP("EIT (0x4E/0x4F)"), "EIT", 0x12, 0x4E, 0xFE},
|
{trNOOP("EIT (0x4E/0x4F/0x5X/0x6X)"), "EIT", 0x12, 0x40, 0xC0},
|
||||||
{trNOOP("EIT (0x5X)"), "EIT", 0x12, 0x50, 0xF0},
|
{trNOOP("TDT (0x70)"), "TDT", 0x14, 0x70, 0xFF},
|
||||||
{trNOOP("EIT (0x6X)"), "EIT", 0x12, 0x60, 0xF0},
|
|
||||||
{trNOOP("TDT (0x70)"), "TDT", 0x14, 0x70, 0xFF},
|
|
||||||
};
|
};
|
||||||
|
|||||||
2
common.h
2
common.h
@@ -36,7 +36,7 @@
|
|||||||
#define SATIP_STATS_ACTIVE_PIDS_COUNT 10
|
#define SATIP_STATS_ACTIVE_PIDS_COUNT 10
|
||||||
#define SATIP_STATS_ACTIVE_FILTERS_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) \
|
#define SATIP_CURL_EASY_GETINFO(X, Y, Z) \
|
||||||
if ((res = curl_easy_getinfo((X), (Y), (Z))) != CURLE_OK) { \
|
if ((res = curl_easy_getinfo((X), (Y), (Z))) != CURLE_OK) { \
|
||||||
|
|||||||
25
device.c
25
device.c
@@ -19,7 +19,9 @@ cSatipDevice::cSatipDevice(unsigned int indexP)
|
|||||||
isPacketDeliveredM(false),
|
isPacketDeliveredM(false),
|
||||||
isOpenDvrM(false),
|
isOpenDvrM(false),
|
||||||
deviceNameM(*cString::sprintf("%s %d", *DeviceType(), deviceIndexM)),
|
deviceNameM(*cString::sprintf("%s %d", *DeviceType(), deviceIndexM)),
|
||||||
channelM()
|
channelM(),
|
||||||
|
createdM(0),
|
||||||
|
mutexM()
|
||||||
{
|
{
|
||||||
unsigned int bufsize = (unsigned int)SATIP_BUFFER_SIZE;
|
unsigned int bufsize = (unsigned int)SATIP_BUFFER_SIZE;
|
||||||
bufsize -= (bufsize % TS_SIZE);
|
bufsize -= (bufsize % TS_SIZE);
|
||||||
@@ -144,6 +146,12 @@ cString cSatipDevice::GetInformation(unsigned int pageP)
|
|||||||
return s;
|
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
|
cString cSatipDevice::DeviceType(void) const
|
||||||
{
|
{
|
||||||
//debug("cSatipDevice::%s(%u)", __FUNCTION__, deviceIndexM);
|
//debug("cSatipDevice::%s(%u)", __FUNCTION__, deviceIndexM);
|
||||||
@@ -176,7 +184,7 @@ int cSatipDevice::SignalQuality(void) const
|
|||||||
|
|
||||||
bool cSatipDevice::ProvidesSource(int sourceP) 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));
|
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)
|
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 (pSectionFilterHandlerM) {
|
||||||
if (pTunerM)
|
int handle = pSectionFilterHandlerM->Open(pidP, tidP, maskP);
|
||||||
|
if (pTunerM && (handle >= 0))
|
||||||
pTunerM->SetPid(pidP, ptOther, true);
|
pTunerM->SetPid(pidP, ptOther, true);
|
||||||
return pSectionFilterHandlerM->Open(pidP, tidP, maskP);
|
return handle;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -372,6 +381,12 @@ unsigned int cSatipDevice::CheckData(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cSatipDevice::GetId(void)
|
||||||
|
{
|
||||||
|
//debug("cSatipDevice::%s(%u)", __FUNCTION__, deviceIndexM);
|
||||||
|
return deviceIndexM;
|
||||||
|
}
|
||||||
|
|
||||||
uchar *cSatipDevice::GetData(int *availableP)
|
uchar *cSatipDevice::GetData(int *availableP)
|
||||||
{
|
{
|
||||||
//debug("cSatipDevice::%s(%u)", __FUNCTION__, deviceIndexM);
|
//debug("cSatipDevice::%s(%u)", __FUNCTION__, deviceIndexM);
|
||||||
|
|||||||
6
device.h
6
device.h
@@ -26,6 +26,9 @@ public:
|
|||||||
|
|
||||||
// private parts
|
// private parts
|
||||||
private:
|
private:
|
||||||
|
enum {
|
||||||
|
eReadyTimeoutMs = 2000 // in milliseconds
|
||||||
|
};
|
||||||
unsigned int deviceIndexM;
|
unsigned int deviceIndexM;
|
||||||
bool isPacketDeliveredM;
|
bool isPacketDeliveredM;
|
||||||
bool isOpenDvrM;
|
bool isOpenDvrM;
|
||||||
@@ -34,6 +37,7 @@ private:
|
|||||||
cRingBufferLinear *tsBufferM;
|
cRingBufferLinear *tsBufferM;
|
||||||
cSatipTuner *pTunerM;
|
cSatipTuner *pTunerM;
|
||||||
cSatipSectionFilterHandler *pSectionFilterHandlerM;
|
cSatipSectionFilterHandler *pSectionFilterHandlerM;
|
||||||
|
cTimeMs createdM;
|
||||||
cMutex mutexM;
|
cMutex mutexM;
|
||||||
|
|
||||||
// constructor & destructor
|
// constructor & destructor
|
||||||
@@ -54,6 +58,7 @@ private:
|
|||||||
|
|
||||||
// for channel info
|
// for channel info
|
||||||
public:
|
public:
|
||||||
|
virtual bool Ready(void);
|
||||||
virtual cString DeviceType(void) const;
|
virtual cString DeviceType(void) const;
|
||||||
virtual cString DeviceName(void) const;
|
virtual cString DeviceName(void) const;
|
||||||
virtual bool AvoidRecording(void) const;
|
virtual bool AvoidRecording(void) const;
|
||||||
@@ -102,6 +107,7 @@ public:
|
|||||||
public:
|
public:
|
||||||
virtual void WriteData(u_char *bufferP, int lengthP);
|
virtual void WriteData(u_char *bufferP, int lengthP);
|
||||||
virtual unsigned int CheckData(void);
|
virtual unsigned int CheckData(void);
|
||||||
|
virtual int GetId(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __SATIP_DEVICE_H
|
#endif // __SATIP_DEVICE_H
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ public:
|
|||||||
virtual ~cSatipDeviceIf() {}
|
virtual ~cSatipDeviceIf() {}
|
||||||
virtual void WriteData(u_char *bufferP, int lengthP) = 0;
|
virtual void WriteData(u_char *bufferP, int lengthP) = 0;
|
||||||
virtual unsigned int CheckData(void) = 0;
|
virtual unsigned int CheckData(void) = 0;
|
||||||
|
virtual int GetId(void) = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
cSatipDeviceIf(const cSatipDeviceIf&);
|
cSatipDeviceIf(const cSatipDeviceIf&);
|
||||||
|
|||||||
@@ -251,6 +251,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)
|
cSatipServer *cSatipDiscover::GetServer(int sourceP, int systemP)
|
||||||
{
|
{
|
||||||
//debug("cSatipDiscover::%s(%d, %d)", __FUNCTION__, sourceP, systemP);
|
//debug("cSatipDiscover::%s(%d, %d)", __FUNCTION__, sourceP, systemP);
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ public:
|
|||||||
static void Destroy(void);
|
static void Destroy(void);
|
||||||
virtual ~cSatipDiscover();
|
virtual ~cSatipDiscover();
|
||||||
void TriggerScan(void) { probeIntervalM.Set(0); }
|
void TriggerScan(void) { probeIntervalM.Set(0); }
|
||||||
|
int GetServerCount(void);
|
||||||
cSatipServer *GetServer(int sourceP, int systemP = -1);
|
cSatipServer *GetServer(int sourceP, int systemP = -1);
|
||||||
cSatipServer *GetServer(cSatipServer *serverP);
|
cSatipServer *GetServer(cSatipServer *serverP);
|
||||||
cSatipServers *GetServers(void);
|
cSatipServers *GetServers(void);
|
||||||
|
|||||||
2
param.c
2
param.c
@@ -158,7 +158,7 @@ cString GetTransponderUrlParameters(const cChannel *channelP)
|
|||||||
freq /= 1000L;
|
freq /= 1000L;
|
||||||
#define ST(s) if (strchr(s, type) && (strchr(s, '0' + dtp.System() + 1) || strchr(s, '*')))
|
#define ST(s) if (strchr(s, type) && (strchr(s, '0' + dtp.System() + 1) || strchr(s, '*')))
|
||||||
#define STBUFLEFT (sizeof(buffer) - (q - buffer))
|
#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(" S *") q += snprintf(q, STBUFLEFT, "&src=%d", ((src > 0) && (src <= 255)) ? src : 1);
|
||||||
ST("CS *") q += snprintf(q, STBUFLEFT, "&sr=%d", channelP->Srate());
|
ST("CS *") q += snprintf(q, STBUFLEFT, "&sr=%d", channelP->Srate());
|
||||||
ST(" S *") q += snprintf(q, STBUFLEFT, "&pol=%c", tolower(dtp.Polarization()));
|
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.0\n"
|
||||||
|
"Report-Msgid-Bugs-To: <see README>\n"
|
||||||
|
"POT-Creation-Date: 2014-04-20 04:20+0200\n"
|
||||||
|
"PO-Revision-Date: 2014-04-20 04:20+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.
|
# VDR plugin language source file.
|
||||||
# Copyright (C) 2007-2014 Rolf Ahrenberg & Antti Seppala
|
# Copyright (C) 2007-2014 Rolf Ahrenberg
|
||||||
# This file is distributed under the same license as the iptv package.
|
# This file is distributed under the same license as the satip package.
|
||||||
# Frank Neumann, 2014
|
# Frank Neumann, 2014
|
||||||
#
|
#
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: vdr-satip 0.1.1\n"
|
"Project-Id-Version: vdr-satip 0.3.0\n"
|
||||||
"Report-Msgid-Bugs-To: <see README>\n"
|
"Report-Msgid-Bugs-To: <see README>\n"
|
||||||
"POT-Creation-Date: 2014-03-16 03:16+0200\n"
|
"POT-Creation-Date: 2014-04-20 04:20+0200\n"
|
||||||
"PO-Revision-Date: 2014-03-16 03:16+0200\n"
|
"PO-Revision-Date: 2014-04-20 04:20+0200\n"
|
||||||
"Last-Translator: Frank Neumann <fnu@yavdr.org>\n"
|
"Last-Translator: Frank Neumann <fnu@yavdr.org>\n"
|
||||||
"Language-Team: German <vdr@linuxtv.org>\n"
|
"Language-Team: German <vdr@linuxtv.org>\n"
|
||||||
"Language: de\n"
|
"Language: de\n"
|
||||||
@@ -25,14 +25,8 @@ msgstr "NIT (0x40)"
|
|||||||
msgid "SDT (0x42)"
|
msgid "SDT (0x42)"
|
||||||
msgstr "SDT (0x42)"
|
msgstr "SDT (0x42)"
|
||||||
|
|
||||||
msgid "EIT (0x4E/0x4F)"
|
msgid "EIT (0x4E/0x4F/0x5X/0x6X)"
|
||||||
msgstr "EIT (0x4E/0x4F)"
|
msgstr "EIT (0x4E/0x4F/0x5X/0x6X)"
|
||||||
|
|
||||||
msgid "EIT (0x5X)"
|
|
||||||
msgstr "EIT (0x5X)"
|
|
||||||
|
|
||||||
msgid "EIT (0x6X)"
|
|
||||||
msgstr "EIT (0x6X)"
|
|
||||||
|
|
||||||
msgid "TDT (0x70)"
|
msgid "TDT (0x70)"
|
||||||
msgstr "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.0\n"
|
||||||
|
"Report-Msgid-Bugs-To: <see README>\n"
|
||||||
|
"POT-Creation-Date: 2014-04-20 04:20+0200\n"
|
||||||
|
"PO-Revision-Date: 2014-04-20 04:20+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.
|
# VDR plugin language source file.
|
||||||
# Copyright (C) 2007-2014 Rolf Ahrenberg & Antti Seppala
|
# Copyright (C) 2007-2014 Rolf Ahrenberg
|
||||||
# This file is distributed under the same license as the iptv package.
|
# This file is distributed under the same license as the satip package.
|
||||||
# Rolf Ahrenberg, 2014
|
# Rolf Ahrenberg, 2014
|
||||||
#
|
#
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: vdr-satip 0.1.1\n"
|
"Project-Id-Version: vdr-satip 0.3.0\n"
|
||||||
"Report-Msgid-Bugs-To: <see README>\n"
|
"Report-Msgid-Bugs-To: <see README>\n"
|
||||||
"POT-Creation-Date: 2014-03-16 03:16+0200\n"
|
"POT-Creation-Date: 2014-04-20 04:20+0200\n"
|
||||||
"PO-Revision-Date: 2014-03-16 03:16+0200\n"
|
"PO-Revision-Date: 2014-04-20 04:20+0200\n"
|
||||||
"Last-Translator: Rolf Ahrenberg\n"
|
"Last-Translator: Rolf Ahrenberg\n"
|
||||||
"Language-Team: Finnish <vdr@linuxtv.org>\n"
|
"Language-Team: Finnish <vdr@linuxtv.org>\n"
|
||||||
"Language: fi\n"
|
"Language: fi\n"
|
||||||
@@ -25,14 +25,8 @@ msgstr "NIT (0x40)"
|
|||||||
msgid "SDT (0x42)"
|
msgid "SDT (0x42)"
|
||||||
msgstr "SDT (0x42)"
|
msgstr "SDT (0x42)"
|
||||||
|
|
||||||
msgid "EIT (0x4E/0x4F)"
|
msgid "EIT (0x4E/0x4F/0x5X/0x6X)"
|
||||||
msgstr "EIT (0x4E/0x4F)"
|
msgstr "EIT (0x4E/0x4F/0x5X/0x6X)"
|
||||||
|
|
||||||
msgid "EIT (0x5X)"
|
|
||||||
msgstr "EIT (0x5X)"
|
|
||||||
|
|
||||||
msgid "EIT (0x6X)"
|
|
||||||
msgstr "EIT (0x6X)"
|
|
||||||
|
|
||||||
msgid "TDT (0x70)"
|
msgid "TDT (0x70)"
|
||||||
msgstr "TDT (0x70)"
|
msgstr "TDT (0x70)"
|
||||||
|
|||||||
6
satip.c
6
satip.c
@@ -13,6 +13,10 @@
|
|||||||
#include "discover.h"
|
#include "discover.h"
|
||||||
#include "setup.h"
|
#include "setup.h"
|
||||||
|
|
||||||
|
#if defined(LIBCURL_VERSION_NUM) && LIBCURL_VERSION_NUM < 0x072400
|
||||||
|
#warning "CURL version >= 0.7.36 is recommended"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(APIVERSNUM) && APIVERSNUM < 20000
|
#if defined(APIVERSNUM) && APIVERSNUM < 20000
|
||||||
#error "VDR-2.0.0 API version or greater is required!"
|
#error "VDR-2.0.0 API version or greater is required!"
|
||||||
#endif
|
#endif
|
||||||
@@ -21,7 +25,7 @@
|
|||||||
#define GITVERSION ""
|
#define GITVERSION ""
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const char VERSION[] = "0.1.1" GITVERSION;
|
const char VERSION[] = "0.3.0" GITVERSION;
|
||||||
static const char DESCRIPTION[] = trNOOP("SAT>IP Devices");
|
static const char DESCRIPTION[] = trNOOP("SAT>IP Devices");
|
||||||
|
|
||||||
class cPluginSatip : public cPlugin {
|
class cPluginSatip : public cPlugin {
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ cSatipSectionFilter::cSatipSectionFilter(int deviceIndexP, uint16_t pidP, uint8_
|
|||||||
secLenM(0),
|
secLenM(0),
|
||||||
tsFeedpM(0),
|
tsFeedpM(0),
|
||||||
pidM(pidP),
|
pidM(pidP),
|
||||||
|
ringBufferM(new cRingBufferFrame(eDmxMaxSectionCount * eDmxMaxSectionSize)),
|
||||||
deviceIndexM(deviceIndexP)
|
deviceIndexM(deviceIndexP)
|
||||||
{
|
{
|
||||||
//debug("cSatipSectionFilter::%s(%d, %d)", __FUNCTION__, deviceIndexM, pidM);
|
//debug("cSatipSectionFilter::%s(%d, %d)", __FUNCTION__, deviceIndexM, pidM);
|
||||||
@@ -48,7 +49,7 @@ cSatipSectionFilter::cSatipSectionFilter(int deviceIndexP, uint16_t pidP, uint8_
|
|||||||
|
|
||||||
// Create sockets
|
// Create sockets
|
||||||
socketM[0] = socketM[1] = -1;
|
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];
|
char tmp[64];
|
||||||
error("Opening section filter sockets failed (device=%d pid=%d): %s", deviceIndexM, pidM, strerror_r(errno, tmp, sizeof(tmp)));
|
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)
|
if (tmp >= 0)
|
||||||
close(tmp);
|
close(tmp);
|
||||||
secBufM = NULL;
|
secBufM = NULL;
|
||||||
|
DELETENULL(ringBufferM);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint16_t cSatipSectionFilter::GetLength(const uint8_t *dataP)
|
inline uint16_t cSatipSectionFilter::GetLength(const uint8_t *dataP)
|
||||||
@@ -99,13 +101,8 @@ int cSatipSectionFilter::Filter(void)
|
|||||||
if (doneqM && !neq)
|
if (doneqM && !neq)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// There is no data in the read socket, more can be written
|
if (ringBufferM && (secLenM > 0))
|
||||||
if ((socketM[0] >= 0) && (socketM[1] >= 0) /*&& !select_single_desc(socketM[0], 0, false)*/) {
|
ringBufferM->Put(new cFrame(secBufM, secLenM));
|
||||||
ssize_t len = write(socketM[1], secBufM, secLenM);
|
|
||||||
ERROR_IF(len < 0, "write()");
|
|
||||||
// Update statistics
|
|
||||||
AddSectionStatistic(len, 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 0;
|
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)
|
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(),
|
mutexM(),
|
||||||
deviceIndexM(deviceIndexP),
|
deviceIndexM(deviceIndexP)
|
||||||
processedM(false),
|
|
||||||
ringBufferM(new cRingBufferLinear(bufferLenP, TS_SIZE, false, *cString::sprintf("SAT>IP SECTION HANDLER %d", deviceIndexP)))
|
|
||||||
{
|
{
|
||||||
debug("cSatipSectionFilterHandler::%s(%d)", __FUNCTION__, deviceIndexM);
|
debug("cSatipSectionFilterHandler::%s(%d)", __FUNCTION__, deviceIndexM);
|
||||||
|
|
||||||
@@ -238,8 +255,9 @@ cSatipSectionFilterHandler::cSatipSectionFilterHandler(int deviceIndexP, unsigne
|
|||||||
cSatipSectionFilterHandler::~cSatipSectionFilterHandler()
|
cSatipSectionFilterHandler::~cSatipSectionFilterHandler()
|
||||||
{
|
{
|
||||||
debug("cSatipSectionFilterHandler::%s(%d)", __FUNCTION__, deviceIndexM);
|
debug("cSatipSectionFilterHandler::%s(%d)", __FUNCTION__, deviceIndexM);
|
||||||
Stop();
|
// Stop thread
|
||||||
|
if (Running())
|
||||||
|
Cancel(3);
|
||||||
DELETE_POINTER(ringBufferM);
|
DELETE_POINTER(ringBufferM);
|
||||||
|
|
||||||
// Destroy all filters
|
// Destroy all filters
|
||||||
@@ -248,26 +266,28 @@ cSatipSectionFilterHandler::~cSatipSectionFilterHandler()
|
|||||||
Delete(i);
|
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)
|
void cSatipSectionFilterHandler::Action(void)
|
||||||
{
|
{
|
||||||
debug("cSatipSectionFilterHandler::%s(%d): entering", __FUNCTION__, deviceIndexM);
|
debug("cSatipSectionFilterHandler::%s(%d): entering", __FUNCTION__, deviceIndexM);
|
||||||
|
bool processed = false;
|
||||||
// Do the thread loop
|
// Do the thread loop
|
||||||
while (Running()) {
|
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
|
// Read one TS packet
|
||||||
if (ringBufferM) {
|
if (ringBufferM) {
|
||||||
int len = 0;
|
int len = 0;
|
||||||
if (processedM) {
|
if (processed) {
|
||||||
ringBufferM->Del(TS_SIZE);
|
ringBufferM->Del(TS_SIZE);
|
||||||
processedM = false;
|
processed = false;
|
||||||
}
|
}
|
||||||
uchar *p = ringBufferM->Get(len);
|
uchar *p = ringBufferM->Get(len);
|
||||||
if (p && (len >= TS_SIZE)) {
|
if (p && (len >= TS_SIZE)) {
|
||||||
@@ -289,7 +309,7 @@ void cSatipSectionFilterHandler::Action(void)
|
|||||||
filtersM[i]->Process(p);
|
filtersM[i]->Process(p);
|
||||||
}
|
}
|
||||||
mutexM.Unlock();
|
mutexM.Unlock();
|
||||||
processedM = true;
|
processed = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,9 +8,6 @@
|
|||||||
#ifndef __SATIP_SECTIONFILTER_H
|
#ifndef __SATIP_SECTIONFILTER_H
|
||||||
#define __SATIP_SECTIONFILTER_H
|
#define __SATIP_SECTIONFILTER_H
|
||||||
|
|
||||||
#ifdef __FreeBSD__
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#endif // __FreeBSD__
|
|
||||||
#include <vdr/device.h>
|
#include <vdr/device.h>
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
@@ -18,9 +15,10 @@
|
|||||||
|
|
||||||
class cSatipSectionFilter : public cSatipSectionStatistics {
|
class cSatipSectionFilter : public cSatipSectionStatistics {
|
||||||
private:
|
private:
|
||||||
enum dmx_limits {
|
enum {
|
||||||
eDmxMaxFilterSize = 18,
|
eDmxMaxFilterSize = 18,
|
||||||
eDmxMaxSectionSize = 4096,
|
eDmxMaxSectionCount = 64,
|
||||||
|
eDmxMaxSectionSize = 4096,
|
||||||
eDmxMaxSectionFeedSize = (eDmxMaxSectionSize + TS_SIZE)
|
eDmxMaxSectionFeedSize = (eDmxMaxSectionSize + TS_SIZE)
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -35,6 +33,7 @@ private:
|
|||||||
uint16_t tsFeedpM;
|
uint16_t tsFeedpM;
|
||||||
uint16_t pidM;
|
uint16_t pidM;
|
||||||
|
|
||||||
|
cRingBufferFrame *ringBufferM;
|
||||||
int deviceIndexM;
|
int deviceIndexM;
|
||||||
int socketM[2];
|
int socketM[2];
|
||||||
|
|
||||||
@@ -56,6 +55,7 @@ public:
|
|||||||
cSatipSectionFilter(int deviceIndexP, uint16_t pidP, uint8_t tidP, uint8_t maskP);
|
cSatipSectionFilter(int deviceIndexP, uint16_t pidP, uint8_t tidP, uint8_t maskP);
|
||||||
virtual ~cSatipSectionFilter();
|
virtual ~cSatipSectionFilter();
|
||||||
void Process(const uint8_t* dataP);
|
void Process(const uint8_t* dataP);
|
||||||
|
bool Send(void);
|
||||||
int GetFd(void) { return socketM[0]; }
|
int GetFd(void) { return socketM[0]; }
|
||||||
uint16_t GetPid(void) const { return pidM; }
|
uint16_t GetPid(void) const { return pidM; }
|
||||||
};
|
};
|
||||||
@@ -65,10 +65,9 @@ private:
|
|||||||
enum {
|
enum {
|
||||||
eMaxSecFilterCount = 32
|
eMaxSecFilterCount = 32
|
||||||
};
|
};
|
||||||
|
cRingBufferLinear *ringBufferM;
|
||||||
cMutex mutexM;
|
cMutex mutexM;
|
||||||
int deviceIndexM;
|
int deviceIndexM;
|
||||||
bool processedM;
|
|
||||||
cRingBufferLinear *ringBufferM;
|
|
||||||
cSatipSectionFilter *filtersM[eMaxSecFilterCount];
|
cSatipSectionFilter *filtersM[eMaxSecFilterCount];
|
||||||
|
|
||||||
bool Delete(unsigned int indexP);
|
bool Delete(unsigned int indexP);
|
||||||
@@ -80,7 +79,6 @@ protected:
|
|||||||
public:
|
public:
|
||||||
cSatipSectionFilterHandler(int deviceIndexP, unsigned int bufferLenP);
|
cSatipSectionFilterHandler(int deviceIndexP, unsigned int bufferLenP);
|
||||||
virtual ~cSatipSectionFilterHandler();
|
virtual ~cSatipSectionFilterHandler();
|
||||||
bool Stop(void);
|
|
||||||
cString GetInformation(void);
|
cString GetInformation(void);
|
||||||
int Open(u_short pidP, u_char tidP, u_char maskP);
|
int Open(u_short pidP, u_char tidP, u_char maskP);
|
||||||
void Close(int handleP);
|
void Close(int handleP);
|
||||||
|
|||||||
4
server.c
4
server.c
@@ -149,7 +149,7 @@ cString cSatipServers::GetString(cSatipServer *serverP)
|
|||||||
cString list = "";
|
cString list = "";
|
||||||
for (cSatipServer *s = First(); s; s = Next(s)) {
|
for (cSatipServer *s = First(); s; s = Next(s)) {
|
||||||
if (s == serverP) {
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -160,7 +160,7 @@ cString cSatipServers::List(void)
|
|||||||
{
|
{
|
||||||
cString list = "";
|
cString list = "";
|
||||||
for (cSatipServer *s = First(); s; s = Next(s))
|
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;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
26
socket.c
26
socket.c
@@ -20,7 +20,10 @@
|
|||||||
|
|
||||||
cSatipSocket::cSatipSocket()
|
cSatipSocket::cSatipSocket()
|
||||||
: socketPortM(0),
|
: socketPortM(0),
|
||||||
socketDescM(-1)
|
socketDescM(-1),
|
||||||
|
lastErrorReportM(0),
|
||||||
|
packetErrorsM(0),
|
||||||
|
sequenceNumberM(-1)
|
||||||
{
|
{
|
||||||
debug("cSatipSocket::%s()", __FUNCTION__);
|
debug("cSatipSocket::%s()", __FUNCTION__);
|
||||||
memset(&sockAddrM, 0, sizeof(sockAddrM));
|
memset(&sockAddrM, 0, sizeof(sockAddrM));
|
||||||
@@ -72,8 +75,14 @@ void cSatipSocket::Close(void)
|
|||||||
close(socketDescM);
|
close(socketDescM);
|
||||||
socketDescM = -1;
|
socketDescM = -1;
|
||||||
socketPortM = 0;
|
socketPortM = 0;
|
||||||
|
sequenceNumberM = -1;
|
||||||
memset(&sockAddrM, 0, sizeof(sockAddrM));
|
memset(&sockAddrM, 0, sizeof(sockAddrM));
|
||||||
}
|
}
|
||||||
|
if (packetErrorsM) {
|
||||||
|
info("detected %d RTP packet errors", packetErrorsM);
|
||||||
|
packetErrorsM = 0;
|
||||||
|
lastErrorReportM = time(NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cSatipSocket::Flush(void)
|
bool cSatipSocket::Flush(void)
|
||||||
@@ -150,6 +159,21 @@ int cSatipSocket::ReadVideo(unsigned char *bufferAddrP, unsigned int bufferLenP)
|
|||||||
unsigned int cc = bufferAddrP[0] & 0x0F;
|
unsigned int cc = bufferAddrP[0] & 0x0F;
|
||||||
// Payload type: MPEG2 TS = 33
|
// Payload type: MPEG2 TS = 33
|
||||||
//unsigned int pt = bufferAddrP[1] & 0x7F;
|
//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
|
// Header lenght
|
||||||
unsigned int headerlen = (3 + cc) * (unsigned int)sizeof(uint32_t);
|
unsigned int headerlen = (3 + cc) * (unsigned int)sizeof(uint32_t);
|
||||||
// Check if extension
|
// Check if extension
|
||||||
|
|||||||
6
socket.h
6
socket.h
@@ -12,9 +12,15 @@
|
|||||||
|
|
||||||
class cSatipSocket {
|
class cSatipSocket {
|
||||||
private:
|
private:
|
||||||
|
enum {
|
||||||
|
eReportIntervalS = 300 // in seconds
|
||||||
|
};
|
||||||
int socketPortM;
|
int socketPortM;
|
||||||
int socketDescM;
|
int socketDescM;
|
||||||
struct sockaddr_in sockAddrM;
|
struct sockaddr_in sockAddrM;
|
||||||
|
time_t lastErrorReportM;
|
||||||
|
int packetErrorsM;
|
||||||
|
int sequenceNumberM;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cSatipSocket();
|
cSatipSocket();
|
||||||
|
|||||||
188
tuner.c
188
tuner.c
@@ -27,30 +27,31 @@ cSatipTuner::cSatipTuner(cSatipDeviceIf &deviceP, unsigned int packetLenP)
|
|||||||
keepAliveM(),
|
keepAliveM(),
|
||||||
pidUpdateCacheM(),
|
pidUpdateCacheM(),
|
||||||
sessionM(),
|
sessionM(),
|
||||||
timeoutM(eKeepAliveIntervalMs),
|
timeoutM(eMinKeepAliveIntervalMs),
|
||||||
openedM(false),
|
openedM(false),
|
||||||
tunedM(false),
|
tunedM(false),
|
||||||
hasLockM(false),
|
hasLockM(false),
|
||||||
signalStrengthM(-1),
|
signalStrengthM(-1),
|
||||||
signalQualityM(-1),
|
signalQualityM(-1),
|
||||||
streamIdM(-1),
|
streamIdM(-1),
|
||||||
pidUpdatedM(false),
|
addPidsM(),
|
||||||
|
delPidsM(),
|
||||||
pidsM()
|
pidsM()
|
||||||
{
|
{
|
||||||
debug("cSatipTuner::%s(%d)", __FUNCTION__, packetBufferLenM);
|
debug("cSatipTuner::%s(%d) [device %d]", __FUNCTION__, packetBufferLenM, deviceM->GetId());
|
||||||
// Allocate packet buffer
|
// Allocate packet buffer
|
||||||
packetBufferM = MALLOC(unsigned char, packetBufferLenM);
|
packetBufferM = MALLOC(unsigned char, packetBufferLenM);
|
||||||
if (packetBufferM)
|
if (packetBufferM)
|
||||||
memset(packetBufferM, 0, packetBufferLenM);
|
memset(packetBufferM, 0, packetBufferLenM);
|
||||||
else
|
else
|
||||||
error("MALLOC() failed for packet buffer");
|
error("MALLOC() failed for packet buffer [device %d]", deviceM->GetId());
|
||||||
// Start thread
|
// Start thread
|
||||||
Start();
|
Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
cSatipTuner::~cSatipTuner()
|
cSatipTuner::~cSatipTuner()
|
||||||
{
|
{
|
||||||
debug("cSatipTuner::%s()", __FUNCTION__);
|
debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceM->GetId());
|
||||||
// Stop thread
|
// Stop thread
|
||||||
sleepM.Signal();
|
sleepM.Signal();
|
||||||
if (Running())
|
if (Running())
|
||||||
@@ -83,9 +84,9 @@ size_t cSatipTuner::HeaderCallback(void *ptrP, size_t sizeP, size_t nmembP, void
|
|||||||
int timeout = -1;
|
int timeout = -1;
|
||||||
char *session = NULL;
|
char *session = NULL;
|
||||||
if (sscanf(r, "Session:%m[^;];timeout=%11d", &session, &timeout) == 2)
|
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)
|
else if (sscanf(r, "Session:%m[^;]", &session) == 1)
|
||||||
obj->SetSessionTimeout(skipspace(session), -1);
|
obj->SetSessionTimeout(skipspace(session));
|
||||||
FREE_POINTER(session);
|
FREE_POINTER(session);
|
||||||
}
|
}
|
||||||
r = strtok_r(NULL, "\r\n", &s);
|
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)
|
void cSatipTuner::Action(void)
|
||||||
{
|
{
|
||||||
debug("cSatipTuner::%s(): entering", __FUNCTION__);
|
debug("cSatipTuner::%s(): entering [device %d]", __FUNCTION__, deviceM->GetId());
|
||||||
cTimeMs timeout(0);
|
cTimeMs timeout(eReConnectTimeoutMs);
|
||||||
// Increase priority
|
// Increase priority
|
||||||
SetPriority(-1);
|
SetPriority(-1);
|
||||||
// Do the thread loop
|
// Do the thread loop
|
||||||
@@ -129,7 +130,7 @@ void cSatipTuner::Action(void)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Reconnect if necessary
|
// Reconnect if necessary
|
||||||
if (openedM && !tunedM && timeout.TimedOut()) {
|
if (openedM && timeout.TimedOut()) {
|
||||||
Disconnect();
|
Disconnect();
|
||||||
Connect();
|
Connect();
|
||||||
timeout.Set(eReConnectTimeoutMs);
|
timeout.Set(eReConnectTimeoutMs);
|
||||||
@@ -137,12 +138,12 @@ void cSatipTuner::Action(void)
|
|||||||
sleepM.Wait(10); // to avoid busy loop and reduce cpu load
|
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)
|
bool cSatipTuner::Open(void)
|
||||||
{
|
{
|
||||||
debug("cSatipTuner::%s()", __FUNCTION__);
|
debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceM->GetId());
|
||||||
if (Connect()) {
|
if (Connect()) {
|
||||||
openedM = true;
|
openedM = true;
|
||||||
return true;
|
return true;
|
||||||
@@ -152,7 +153,7 @@ bool cSatipTuner::Open(void)
|
|||||||
|
|
||||||
bool cSatipTuner::Close(void)
|
bool cSatipTuner::Close(void)
|
||||||
{
|
{
|
||||||
debug("cSatipTuner::%s()", __FUNCTION__);
|
debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceM->GetId());
|
||||||
openedM = false;
|
openedM = false;
|
||||||
Disconnect();
|
Disconnect();
|
||||||
return true;
|
return true;
|
||||||
@@ -161,7 +162,7 @@ bool cSatipTuner::Close(void)
|
|||||||
bool cSatipTuner::Connect(void)
|
bool cSatipTuner::Connect(void)
|
||||||
{
|
{
|
||||||
cMutexLock MutexLock(&mutexM);
|
cMutexLock MutexLock(&mutexM);
|
||||||
debug("cSatipTuner::%s()", __FUNCTION__);
|
debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceM->GetId());
|
||||||
|
|
||||||
// Initialize the curl session
|
// Initialize the curl session
|
||||||
if (!handleM)
|
if (!handleM)
|
||||||
@@ -173,17 +174,12 @@ bool cSatipTuner::Connect(void)
|
|||||||
|
|
||||||
// Just retune
|
// Just retune
|
||||||
if (tunedM && (streamIdM >= 0)) {
|
if (tunedM && (streamIdM >= 0)) {
|
||||||
debug("cSatipTuner::%s(): retune", __FUNCTION__);
|
debug("cSatipTuner::%s(): retune [device %d]", __FUNCTION__, deviceM->GetId());
|
||||||
uri = cString::sprintf("rtsp://%s/stream=%d", *streamAddrM, streamIdM);
|
keepAliveM.Set(0);
|
||||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_STREAM_URI, *uri);
|
KeepAlive();
|
||||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_PLAY);
|
|
||||||
SATIP_CURL_EASY_PERFORM(handleM);
|
|
||||||
if (!ValidateLatestResponse())
|
|
||||||
return false;
|
|
||||||
// Flush any old content
|
// Flush any old content
|
||||||
if (rtpSocketM)
|
if (rtpSocketM)
|
||||||
rtpSocketM->Flush();
|
rtpSocketM->Flush();
|
||||||
keepAliveM.Set(eKeepAliveIntervalMs);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,11 +188,6 @@ bool cSatipTuner::Connect(void)
|
|||||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_VERBOSE, 1L);
|
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_VERBOSE, 1L);
|
||||||
#endif
|
#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
|
// No progress meter and no signaling
|
||||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_NOPROGRESS, 1L);
|
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_NOPROGRESS, 1L);
|
||||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_NOSIGNAL, 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);
|
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_CONNECTTIMEOUT_MS, (long)eConnectTimeoutMs);
|
||||||
|
|
||||||
// Set user-agent
|
// 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
|
// Set URL
|
||||||
char *p = curl_easy_unescape(handleM, *streamAddrM, 0, NULL);
|
char *p = curl_easy_unescape(handleM, *streamAddrM, 0, NULL);
|
||||||
@@ -224,37 +215,38 @@ bool cSatipTuner::Connect(void)
|
|||||||
rtcpSocketM->Close();
|
rtcpSocketM->Close();
|
||||||
}
|
}
|
||||||
if ((rtpSocketM->Port() <= 0) || (rtcpSocketM->Port() <= 0)) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Request server options: "&pids=all" for the whole mux
|
// Request server options
|
||||||
uri = cString::sprintf("rtsp://%s/?%s&pids=0", *streamAddrM, *streamParamM);
|
keepAliveM.Set(timeoutM);
|
||||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_STREAM_URI, *uri);
|
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_SETOPT(handleM, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_OPTIONS);
|
||||||
SATIP_CURL_EASY_PERFORM(handleM);
|
SATIP_CURL_EASY_PERFORM(handleM);
|
||||||
if (!ValidateLatestResponse())
|
if (!ValidateLatestResponse())
|
||||||
return false;
|
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());
|
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_TRANSPORT, *transport);
|
||||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_SETUP);
|
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);
|
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);
|
||||||
|
//SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_SESSION_ID, *sessionM);
|
||||||
if (!ValidateLatestResponse())
|
if (!ValidateLatestResponse())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Start playing
|
// 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;
|
tunedM = true;
|
||||||
|
UpdatePids(true);
|
||||||
if (nextServerM) {
|
if (nextServerM) {
|
||||||
cSatipDiscover::GetInstance()->UseServer(nextServerM, true);
|
cSatipDiscover::GetInstance()->UseServer(nextServerM, true);
|
||||||
currentServerM = nextServerM;
|
currentServerM = nextServerM;
|
||||||
@@ -269,7 +261,7 @@ bool cSatipTuner::Connect(void)
|
|||||||
bool cSatipTuner::Disconnect(void)
|
bool cSatipTuner::Disconnect(void)
|
||||||
{
|
{
|
||||||
cMutexLock MutexLock(&mutexM);
|
cMutexLock MutexLock(&mutexM);
|
||||||
debug("cSatipTuner::%s()", __FUNCTION__);
|
debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceM->GetId());
|
||||||
|
|
||||||
// Terminate curl session
|
// Terminate curl session
|
||||||
if (handleM) {
|
if (handleM) {
|
||||||
@@ -305,13 +297,16 @@ bool cSatipTuner::Disconnect(void)
|
|||||||
if (currentServerM)
|
if (currentServerM)
|
||||||
cSatipDiscover::GetInstance()->UseServer(currentServerM, false);
|
cSatipDiscover::GetInstance()->UseServer(currentServerM, false);
|
||||||
tunedM = false;
|
tunedM = false;
|
||||||
|
timeoutM = eMinKeepAliveIntervalMs;
|
||||||
|
addPidsM.Clear();
|
||||||
|
delPidsM.Clear();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cSatipTuner::ValidateLatestResponse(void)
|
bool cSatipTuner::ValidateLatestResponse(void)
|
||||||
{
|
{
|
||||||
//debug("cSatipTuner::%s()", __FUNCTION__);
|
//debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceM->GetId());
|
||||||
if (handleM) {
|
if (handleM) {
|
||||||
long rc = 0;
|
long rc = 0;
|
||||||
CURLcode res = CURLE_OK;
|
CURLcode res = CURLE_OK;
|
||||||
@@ -319,7 +314,7 @@ bool cSatipTuner::ValidateLatestResponse(void)
|
|||||||
if (rc == 200)
|
if (rc == 200)
|
||||||
return true;
|
return true;
|
||||||
else if (rc != 0)
|
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;
|
return false;
|
||||||
@@ -327,7 +322,7 @@ bool cSatipTuner::ValidateLatestResponse(void)
|
|||||||
|
|
||||||
void cSatipTuner::ParseReceptionParameters(const char *paramP)
|
void cSatipTuner::ParseReceptionParameters(const char *paramP)
|
||||||
{
|
{
|
||||||
//debug("cSatipTuner::%s(%s)", __FUNCTION__, paramP);
|
//debug("cSatipTuner::%s(%s) [device %d]", __FUNCTION__, paramP, deviceM->GetId());
|
||||||
// DVB-S2:
|
// 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>
|
// 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:
|
// DVB-T2:
|
||||||
@@ -374,21 +369,21 @@ void cSatipTuner::ParseReceptionParameters(const char *paramP)
|
|||||||
void cSatipTuner::SetStreamId(int streamIdP)
|
void cSatipTuner::SetStreamId(int streamIdP)
|
||||||
{
|
{
|
||||||
cMutexLock MutexLock(&mutexM);
|
cMutexLock MutexLock(&mutexM);
|
||||||
debug("cSatipTuner::%s(%d)", __FUNCTION__, streamIdP);
|
debug("cSatipTuner::%s(%d) [device %d]", __FUNCTION__, streamIdP, deviceM->GetId());
|
||||||
streamIdM = streamIdP;
|
streamIdM = streamIdP;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSatipTuner::SetSessionTimeout(const char *sessionP, int timeoutP)
|
void cSatipTuner::SetSessionTimeout(const char *sessionP, int timeoutP)
|
||||||
{
|
{
|
||||||
cMutexLock MutexLock(&mutexM);
|
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;
|
sessionM = sessionP;
|
||||||
timeoutM = timeoutP > 0 ? timeoutP * 1000L : eKeepAliveIntervalMs;
|
timeoutM = (timeoutP > eMinKeepAliveIntervalMs) ? timeoutP : eMinKeepAliveIntervalMs;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cSatipTuner::SetSource(cSatipServer *serverP, const char *parameterP, const int indexP)
|
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);
|
cMutexLock MutexLock(&mutexM);
|
||||||
nextServerM = cSatipDiscover::GetInstance()->GetServer(serverP);
|
nextServerM = cSatipDiscover::GetInstance()->GetServer(serverP);
|
||||||
if (nextServerM && !isempty(nextServerM->Address()) && !isempty(parameterP)) {
|
if (nextServerM && !isempty(nextServerM->Address()) && !isempty(parameterP)) {
|
||||||
@@ -403,45 +398,90 @@ bool cSatipTuner::SetSource(cSatipServer *serverP, const char *parameterP, const
|
|||||||
|
|
||||||
bool cSatipTuner::SetPid(int pidP, int typeP, bool onP)
|
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);
|
cMutexLock MutexLock(&mutexM);
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (int i = 0; i < pidsM.Size(); ++i) {
|
for (int i = 0; i < pidsM.Size(); ++i) {
|
||||||
if (pidsM[i] == pidP) {
|
if (pidsM[i] == pidP) {
|
||||||
found = true;
|
found = true;
|
||||||
if (!onP) {
|
if (!onP)
|
||||||
pidsM.Remove(i);
|
pidsM.Remove(i);
|
||||||
pidUpdatedM = true;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (onP && !found) {
|
if (onP && !found)
|
||||||
pidsM.Append(pidP);
|
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);
|
pidUpdateCacheM.Set(ePidUpdateIntervalMs);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cSatipTuner::UpdatePids(void)
|
bool cSatipTuner::UpdatePids(bool forceP)
|
||||||
{
|
{
|
||||||
cMutexLock MutexLock(&mutexM);
|
cMutexLock MutexLock(&mutexM);
|
||||||
if (pidUpdateCacheM.TimedOut() && pidUpdatedM && pidsM.Size() && tunedM && handleM && !isempty(*streamAddrM) && (streamIdM > 0)) {
|
if (((forceP && pidsM.Size()) || (pidUpdateCacheM.TimedOut() && (addPidsM.Size() || delPidsM.Size()))) &&
|
||||||
//debug("cSatipTuner::%s()", __FUNCTION__);
|
tunedM && handleM && !isempty(*streamAddrM) && (streamIdM > 0)) {
|
||||||
CURLcode res = CURLE_OK;
|
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", *streamAddrM, streamIdM);
|
||||||
cString uri = cString::sprintf("rtsp://%s/stream=%d?pids=", *streamAddrM, streamIdM);
|
if (forceP) {
|
||||||
|
if (pidsM.Size()) {
|
||||||
for (int i = 0; i < pidsM.Size(); ++i)
|
uri = cString::sprintf("%s?pids=", *uri);
|
||||||
uri = cString::sprintf("%s%d%s", *uri, pidsM[i], (i == (pidsM.Size() - 1)) ? "" : ",");
|
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_STREAM_URI, *uri);
|
||||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_PLAY);
|
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_PLAY);
|
||||||
SATIP_CURL_EASY_PERFORM(handleM);
|
SATIP_CURL_EASY_PERFORM(handleM);
|
||||||
if (ValidateLatestResponse()) {
|
if (ValidateLatestResponse()) {
|
||||||
keepAliveM.Set(eKeepAliveIntervalMs);
|
addPidsM.Clear();
|
||||||
pidUpdatedM = false;
|
delPidsM.Clear();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Disconnect();
|
Disconnect();
|
||||||
@@ -456,7 +496,7 @@ bool cSatipTuner::KeepAlive(void)
|
|||||||
{
|
{
|
||||||
cMutexLock MutexLock(&mutexM);
|
cMutexLock MutexLock(&mutexM);
|
||||||
if (tunedM && handleM && keepAliveM.TimedOut()) {
|
if (tunedM && handleM && keepAliveM.TimedOut()) {
|
||||||
debug("cSatipTuner::%s()", __FUNCTION__);
|
debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceM->GetId());
|
||||||
CURLcode res = CURLE_OK;
|
CURLcode res = CURLE_OK;
|
||||||
cString uri = cString::sprintf("rtsp://%s/stream=%d", *streamAddrM, streamIdM);
|
cString uri = cString::sprintf("rtsp://%s/stream=%d", *streamAddrM, streamIdM);
|
||||||
|
|
||||||
@@ -464,7 +504,7 @@ bool cSatipTuner::KeepAlive(void)
|
|||||||
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_OPTIONS);
|
SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_OPTIONS);
|
||||||
SATIP_CURL_EASY_PERFORM(handleM);
|
SATIP_CURL_EASY_PERFORM(handleM);
|
||||||
if (ValidateLatestResponse())
|
if (ValidateLatestResponse())
|
||||||
keepAliveM.Set(eKeepAliveIntervalMs);
|
keepAliveM.Set(timeoutM);
|
||||||
else
|
else
|
||||||
Disconnect();
|
Disconnect();
|
||||||
|
|
||||||
@@ -476,30 +516,30 @@ bool cSatipTuner::KeepAlive(void)
|
|||||||
|
|
||||||
int cSatipTuner::SignalStrength(void)
|
int cSatipTuner::SignalStrength(void)
|
||||||
{
|
{
|
||||||
//debug("cSatipTuner::%s()", __FUNCTION__);
|
//debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceM->GetId());
|
||||||
return signalStrengthM;
|
return signalStrengthM;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cSatipTuner::SignalQuality(void)
|
int cSatipTuner::SignalQuality(void)
|
||||||
{
|
{
|
||||||
//debug("cSatipTuner::%s()", __FUNCTION__);
|
//debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceM->GetId());
|
||||||
return signalQualityM;
|
return signalQualityM;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cSatipTuner::HasLock(void)
|
bool cSatipTuner::HasLock(void)
|
||||||
{
|
{
|
||||||
//debug("cSatipTuner::%s()", __FUNCTION__);
|
//debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceM->GetId());
|
||||||
return tunedM && hasLockM;
|
return tunedM && hasLockM;
|
||||||
}
|
}
|
||||||
|
|
||||||
cString cSatipTuner::GetSignalStatus(void)
|
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());
|
return cString::sprintf("lock=%d strength=%d quality=%d", HasLock(), SignalStrength(), SignalQuality());
|
||||||
}
|
}
|
||||||
|
|
||||||
cString cSatipTuner::GetInformation(void)
|
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";
|
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 {
|
class cSatipTuner : public cThread, public cSatipTunerStatistics {
|
||||||
private:
|
private:
|
||||||
enum {
|
enum {
|
||||||
eConnectTimeoutMs = 1500, // in milliseconds
|
eConnectTimeoutMs = 1500, // in milliseconds
|
||||||
ePidUpdateIntervalMs = 100, // in milliseconds
|
ePidUpdateIntervalMs = 250, // in milliseconds
|
||||||
eReConnectTimeoutMs = 5000, // in milliseconds
|
eReConnectTimeoutMs = 5000, // in milliseconds
|
||||||
eKeepAliveIntervalMs = 600000 // in milliseconds
|
eMinKeepAliveIntervalMs = 30000 // in milliseconds
|
||||||
};
|
};
|
||||||
|
|
||||||
static size_t HeaderCallback(void *ptrP, size_t sizeP, size_t nmembP, void *dataP);
|
static size_t HeaderCallback(void *ptrP, size_t sizeP, size_t nmembP, void *dataP);
|
||||||
@@ -58,7 +58,8 @@ private:
|
|||||||
int signalStrengthM;
|
int signalStrengthM;
|
||||||
int signalQualityM;
|
int signalQualityM;
|
||||||
int streamIdM;
|
int streamIdM;
|
||||||
bool pidUpdatedM;
|
cVector<int> addPidsM;
|
||||||
|
cVector<int> delPidsM;
|
||||||
cVector<int> pidsM;
|
cVector<int> pidsM;
|
||||||
|
|
||||||
bool Connect(void);
|
bool Connect(void);
|
||||||
@@ -66,10 +67,10 @@ private:
|
|||||||
bool ValidateLatestResponse(void);
|
bool ValidateLatestResponse(void);
|
||||||
void ParseReceptionParameters(const char *paramP);
|
void ParseReceptionParameters(const char *paramP);
|
||||||
void SetStreamId(int streamIdP);
|
void SetStreamId(int streamIdP);
|
||||||
void SetSessionTimeout(const char *sessionP, int timeoutP);
|
void SetSessionTimeout(const char *sessionP, int timeoutP = 0);
|
||||||
bool KeepAlive(void);
|
bool KeepAlive(void);
|
||||||
bool UpdateSignalInfoCache(void);
|
bool UpdateSignalInfoCache(void);
|
||||||
bool UpdatePids(void);
|
bool UpdatePids(bool forceP = false);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void Action(void);
|
virtual void Action(void);
|
||||||
|
|||||||
Reference in New Issue
Block a user