mirror of
https://github.com/tuxbox-neutrino/neutrino.git
synced 2025-08-27 15:32:59 +02:00
eitd: SDT thread re-added, as is but without BAT.
TODO: unify SDT thread algo with other threads
This commit is contained in:
@@ -44,6 +44,8 @@
|
||||
#endif
|
||||
|
||||
#include <dvbsi++/descriptor_tag.h>
|
||||
#include <dvbsi++/nvod_reference_descriptor.h>
|
||||
#include <dvbsi++/service_descriptor.h>
|
||||
|
||||
struct descr_generic_header {
|
||||
unsigned descriptor_tag : 8;
|
||||
@@ -61,12 +63,14 @@ struct descr_short_event_header {
|
||||
} __attribute__ ((packed)) ;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
struct descr_service_header {
|
||||
unsigned descriptor_tag : 8;
|
||||
unsigned descriptor_length : 8;
|
||||
unsigned service_typ : 8;
|
||||
unsigned service_provider_name_length : 8;
|
||||
} __attribute__ ((packed)) ;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
struct descr_extended_event_header {
|
||||
@@ -81,6 +85,7 @@ struct descr_extended_event_header {
|
||||
} __attribute__ ((packed)) ;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
struct service_list_entry {
|
||||
unsigned service_id_hi : 8;
|
||||
unsigned service_id_lo : 8;
|
||||
@@ -98,6 +103,7 @@ inline unsigned min(unsigned a, unsigned b)
|
||||
{
|
||||
return b < a ? b : a;
|
||||
}
|
||||
#endif
|
||||
|
||||
void SIsectionEIT::parse(void)
|
||||
{
|
||||
@@ -367,6 +373,7 @@ void SIsectionEIT::parseDescriptors(const uint8_t *des, unsigned len, SIevent &e
|
||||
#endif
|
||||
|
||||
/********************/
|
||||
#if 0
|
||||
bool check_blacklisted(const t_original_network_id onid, const t_transport_stream_id tsid)
|
||||
{
|
||||
if ( (onid == 0x0001) &&
|
||||
@@ -451,9 +458,11 @@ void SIsectionSDT::parseDescriptors(const uint8_t *des, unsigned len, SIservice
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
// Die infos aus dem Puffer holen
|
||||
void SIsectionSDT::parse(void)
|
||||
{
|
||||
#if 0
|
||||
const uint8_t *actPos;
|
||||
const uint8_t *bufEnd;
|
||||
struct sdt_service *sv;
|
||||
@@ -481,114 +490,45 @@ void SIsectionSDT::parse(void)
|
||||
svs.insert(s);
|
||||
actPos += descriptors_loop_length;
|
||||
}
|
||||
|
||||
#endif
|
||||
parsed = 1;
|
||||
}
|
||||
t_transport_stream_id transport_stream_id = getTransportStreamId();
|
||||
t_original_network_id original_network_id = getOriginalNetworkId();
|
||||
const ServiceDescriptionList &slist = *getDescriptions();
|
||||
for (ServiceDescriptionConstIterator sit = slist.begin(); sit != slist.end(); ++sit) {
|
||||
ServiceDescription * service = *sit;
|
||||
|
||||
#if 0 //def ENABLE_FREESATEPG
|
||||
std::string SIsectionEIT::freesatHuffmanDecode(std::string input)
|
||||
{
|
||||
const char *src = input.c_str();
|
||||
uint size = input.length();
|
||||
SIservice s(service->getServiceId(), original_network_id, transport_stream_id);
|
||||
|
||||
if (src[1] == 1 || src[1] == 2)
|
||||
{
|
||||
std::string uncompressed(size * 3, ' ');
|
||||
uint p = 0;
|
||||
struct hufftab *table;
|
||||
unsigned table_length;
|
||||
if (src[1] == 1)
|
||||
{
|
||||
table = fsat_huffman1;
|
||||
table_length = sizeof(fsat_huffman1) / sizeof(fsat_huffman1[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
table = fsat_huffman2;
|
||||
table_length = sizeof(fsat_huffman2) / sizeof(fsat_huffman2[0]);
|
||||
}
|
||||
unsigned value = 0, byte = 2, bit = 0;
|
||||
while (byte < 6 && byte < size)
|
||||
{
|
||||
value |= src[byte] << ((5-byte) * 8);
|
||||
byte++;
|
||||
}
|
||||
char lastch = START;
|
||||
s.flags.EIT_schedule_flag = service->getEitScheduleFlag();
|
||||
s.flags.EIT_present_following_flag = service->getEitPresentFollowingFlag();
|
||||
s.flags.running_status = service->getRunningStatus();
|
||||
s.flags.free_CA_mode = service->getFreeCaMode();
|
||||
|
||||
do
|
||||
DescriptorConstIterator dit;
|
||||
for (dit = service->getDescriptors()->begin(); dit != service->getDescriptors()->end(); ++dit) {
|
||||
switch ((*dit)->getTag()) {
|
||||
case SERVICE_DESCRIPTOR:
|
||||
{
|
||||
bool found = false;
|
||||
unsigned bitShift = 0;
|
||||
if (lastch == ESCAPE)
|
||||
{
|
||||
found = true;
|
||||
// Encoded in the next 8 bits.
|
||||
// Terminated by the first ASCII character.
|
||||
char nextCh = (value >> 24) & 0xff;
|
||||
bitShift = 8;
|
||||
if ((nextCh & 0x80) == 0)
|
||||
lastch = nextCh;
|
||||
if (p >= uncompressed.length())
|
||||
uncompressed.resize(p+10);
|
||||
uncompressed[p++] = nextCh;
|
||||
ServiceDescriptor * d = (ServiceDescriptor *) *dit;
|
||||
s.serviceTyp = d->getServiceType();
|
||||
}
|
||||
else
|
||||
break;
|
||||
case NVOD_REFERENCE_DESCRIPTOR:
|
||||
{
|
||||
for (unsigned j = 0; j < table_length; j++)
|
||||
{
|
||||
if (table[j].last == lastch)
|
||||
{
|
||||
unsigned mask = 0, maskbit = 0x80000000;
|
||||
for (short kk = 0; kk < table[j].bits; kk++)
|
||||
{
|
||||
mask |= maskbit;
|
||||
maskbit >>= 1;
|
||||
NvodReferenceDescriptor * d = (NvodReferenceDescriptor *) *dit;
|
||||
NvodReferenceConstIterator it;
|
||||
const NvodReferenceList* nlist = d->getNvodReferences();
|
||||
for (it = nlist->begin(); it != nlist->end(); ++it) {
|
||||
SInvodReference nvod((*it)->getTransportStreamId(), (*it)->getOriginalNetworkId(), (*it)->getServiceId());
|
||||
s.nvods.insert(nvod);
|
||||
}
|
||||
if ((value & mask) == table[j].value)
|
||||
{
|
||||
char nextCh = table[j].next;
|
||||
bitShift = table[j].bits;
|
||||
if (nextCh != STOP && nextCh != ESCAPE)
|
||||
{
|
||||
if (p >= uncompressed.length())
|
||||
uncompressed.resize(p+10);
|
||||
uncompressed[p++] = nextCh;
|
||||
}
|
||||
found = true;
|
||||
lastch = nextCh;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
svs.insert(s);
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
{
|
||||
// Shift up by the number of bits.
|
||||
for (unsigned b = 0; b < bitShift; b++)
|
||||
{
|
||||
value = (value << 1) & 0xfffffffe;
|
||||
if (byte < size)
|
||||
value |= (src[byte] >> (7-bit)) & 1;
|
||||
if (bit == 7)
|
||||
{
|
||||
bit = 0;
|
||||
byte++;
|
||||
}
|
||||
else bit++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Entry missing in table.
|
||||
uncompressed.resize(p);
|
||||
uncompressed.append("...");
|
||||
return uncompressed;
|
||||
}
|
||||
} while (lastch != STOP && value != 0);
|
||||
|
||||
uncompressed.resize(p);
|
||||
return uncompressed;
|
||||
}
|
||||
else return input;
|
||||
}
|
||||
#endif
|
||||
|
@@ -27,7 +27,9 @@
|
||||
|
||||
#include <endian.h>
|
||||
#include <dvbsi++/event_information_section.h>
|
||||
#include <dvbsi++/service_description_section.h>
|
||||
|
||||
#if 0
|
||||
struct SI_section_SDT_header {
|
||||
unsigned table_id : 8;
|
||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||
@@ -59,6 +61,7 @@ struct SI_section_SDT_header {
|
||||
unsigned original_network_id_lo : 8;
|
||||
unsigned reserved_future_use2 : 8;
|
||||
} __attribute__ ((packed)) ; // 11 bytes
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
struct SI_section_EIT_header {
|
||||
@@ -212,14 +215,25 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class SIsectionSDT : public SIsection
|
||||
class SIsectionSDT : public ServiceDescriptionSection
|
||||
{
|
||||
private:
|
||||
SIservices svs;
|
||||
int parsed;
|
||||
void parse(void);
|
||||
#if 0
|
||||
void parseDescriptors(const uint8_t *desc, unsigned len, SIservice &s);
|
||||
void parseServiceDescriptor(const char *buf, SIservice &s);
|
||||
void parsePrivateDataDescriptor(const char *buf, SIservice &s);
|
||||
void parseNVODreferenceDescriptor(const char *buf, SIservice &s);
|
||||
#endif
|
||||
public:
|
||||
#if 0
|
||||
SIsectionSDT(const SIsection &s) : SIsection(s) {
|
||||
parsed = 0;
|
||||
parse();
|
||||
}
|
||||
|
||||
#endif
|
||||
#if 0
|
||||
// Std-Copy
|
||||
SIsectionSDT(const SIsectionSDT &s) : SIsection(s) {
|
||||
@@ -228,11 +242,12 @@ public:
|
||||
}
|
||||
#endif
|
||||
// Benutzt den uebergebenen Puffer (sollte mit new char[n] allokiert sein)
|
||||
SIsectionSDT(uint8_t *buf) : SIsection(buf) {
|
||||
SIsectionSDT(uint8_t *buf) : ServiceDescriptionSection(buf) {
|
||||
parsed = 0;
|
||||
parse();
|
||||
}
|
||||
|
||||
#if 0
|
||||
t_transport_stream_id transport_stream_id(void) const {
|
||||
return buffer ? ((((struct SI_section_SDT_header *)buffer)->transport_stream_id_hi << 8) |
|
||||
((struct SI_section_SDT_header *)buffer)->transport_stream_id_lo) : 0;
|
||||
@@ -246,6 +261,7 @@ public:
|
||||
return buffer ? ((((struct SI_section_SDT_header *)buffer)->original_network_id_hi << 8) |
|
||||
((struct SI_section_SDT_header *)buffer)->original_network_id_lo) : 0;
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
static void dump(const struct SI_section_SDT_header *header) {
|
||||
if (!header)
|
||||
@@ -272,14 +288,6 @@ public:
|
||||
return svs;
|
||||
}
|
||||
|
||||
private:
|
||||
SIservices svs;
|
||||
int parsed;
|
||||
void parse(void);
|
||||
void parseDescriptors(const uint8_t *desc, unsigned len, SIservice &s);
|
||||
void parseServiceDescriptor(const char *buf, SIservice &s);
|
||||
void parsePrivateDataDescriptor(const char *buf, SIservice &s);
|
||||
void parseNVODreferenceDescriptor(const char *buf, SIservice &s);
|
||||
};
|
||||
|
||||
#endif // SISECTIONS_HPP
|
||||
|
@@ -37,6 +37,7 @@
|
||||
class SIservice;
|
||||
class SIevent;
|
||||
|
||||
#if 0
|
||||
struct sdt_service {
|
||||
unsigned service_id_hi : 8;
|
||||
unsigned service_id_lo : 8;
|
||||
@@ -57,7 +58,7 @@ struct sdt_service {
|
||||
#endif
|
||||
unsigned descriptors_loop_length_lo : 8;
|
||||
} __attribute__ ((packed)) ; // 5 Bytes
|
||||
|
||||
#endif
|
||||
|
||||
class SInvodReference
|
||||
{
|
||||
@@ -72,13 +73,14 @@ public:
|
||||
original_network_id = new_original_network_id;
|
||||
transport_stream_id = new_transport_stream_id;
|
||||
}
|
||||
|
||||
#if 0
|
||||
SInvodReference(const SInvodReference &ref)
|
||||
{
|
||||
service_id = ref.service_id;
|
||||
original_network_id = ref.original_network_id;
|
||||
transport_stream_id = ref.transport_stream_id;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool operator < (const SInvodReference& ref) const
|
||||
{
|
||||
@@ -117,8 +119,28 @@ struct printSInvodReference : public std::unary_function<class SInvodReference,
|
||||
|
||||
typedef std::set <SInvodReference, std::less<SInvodReference> > SInvodReferences;
|
||||
|
||||
class SIservice {
|
||||
class SIservice
|
||||
{
|
||||
//protected:
|
||||
public:
|
||||
struct {
|
||||
unsigned char EIT_schedule_flag : 1;
|
||||
unsigned char EIT_present_following_flag : 1;
|
||||
unsigned char running_status : 3;
|
||||
unsigned char free_CA_mode : 1;
|
||||
} flags;
|
||||
t_service_id service_id;
|
||||
t_original_network_id original_network_id; // Ist innerhalb einer section unnoetig
|
||||
t_transport_stream_id transport_stream_id;
|
||||
unsigned char serviceTyp;
|
||||
int is_actual;
|
||||
SInvodReferences nvods;
|
||||
#if 0 // unused
|
||||
std::string serviceName; // Name aus dem Service-Descriptor
|
||||
std::string providerName; // Name aus dem Service-Descriptor
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
SIservice(const struct sdt_service *s) {
|
||||
service_id = (s->service_id_hi << 8) | s->service_id_lo;
|
||||
original_network_id = 0;
|
||||
@@ -130,6 +152,7 @@ public:
|
||||
flags.free_CA_mode = s->free_CA_mode;
|
||||
is_actual = false;
|
||||
}
|
||||
#endif
|
||||
// Um einen service zum Suchen zu erstellen
|
||||
SIservice(const t_service_id _service_id, const t_original_network_id _original_network_id, const t_transport_stream_id _transport_stream_id)
|
||||
{
|
||||
@@ -139,6 +162,8 @@ public:
|
||||
serviceTyp=0;
|
||||
memset(&flags, 0, sizeof(flags));
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Std-Copy
|
||||
SIservice(const SIservice &s) {
|
||||
service_id = s.service_id;
|
||||
@@ -151,14 +176,7 @@ public:
|
||||
nvods=s.nvods;
|
||||
is_actual=s.is_actual;
|
||||
}
|
||||
t_service_id service_id;
|
||||
t_original_network_id original_network_id; // Ist innerhalb einer section unnoetig
|
||||
t_transport_stream_id transport_stream_id;
|
||||
unsigned char serviceTyp;
|
||||
int is_actual;
|
||||
SInvodReferences nvods;
|
||||
std::string serviceName; // Name aus dem Service-Descriptor
|
||||
std::string providerName; // Name aus dem Service-Descriptor
|
||||
#endif
|
||||
int eitScheduleFlag(void) { return (int)flags.EIT_schedule_flag; }
|
||||
int eitPresentFollowingFlag(void) { return (int)flags.EIT_present_following_flag; }
|
||||
int runningStatus(void) { return (int)flags.running_status; }
|
||||
@@ -178,20 +196,15 @@ public:
|
||||
printf("Original-Network-ID: %hu\n", original_network_id);
|
||||
printf("Service-ID: %hu\n", service_id);
|
||||
printf("Service-Typ: %hhu\n", serviceTyp);
|
||||
#if 0
|
||||
if(providerName.length())
|
||||
printf("Provider-Name: %s\n", providerName.c_str());
|
||||
if(serviceName.length())
|
||||
printf("Service-Name: %s\n", serviceName.c_str());
|
||||
#endif
|
||||
for_each(nvods.begin(), nvods.end(), printSInvodReference());
|
||||
printf("\n");
|
||||
}
|
||||
protected:
|
||||
struct {
|
||||
unsigned char EIT_schedule_flag : 1;
|
||||
unsigned char EIT_present_following_flag : 1;
|
||||
unsigned char running_status : 3;
|
||||
unsigned char free_CA_mode : 1;
|
||||
} flags;
|
||||
};
|
||||
|
||||
// Fuer for_each
|
||||
|
@@ -53,7 +53,8 @@ int getCountryCodeDefaultMapping( const std::string &lang )
|
||||
CountryCodeDefaultMapping.find(lang);
|
||||
if ( it != CountryCodeDefaultMapping.end() )
|
||||
return it->second;
|
||||
return 1; // ISO8859-1 / Latin1
|
||||
return 0;
|
||||
//return 1; // ISO8859-1 / Latin1
|
||||
}
|
||||
|
||||
// 8859-x to ucs-16 coding tables. taken from www.unicode.org/Public/MAPPINGS/ISO8859/
|
||||
|
@@ -61,6 +61,8 @@
|
||||
#include "eitd.h"
|
||||
#include "edvbstring.h"
|
||||
|
||||
#define ENABLE_SDT //FIXME
|
||||
|
||||
// 60 Minuten Zyklus...
|
||||
#define TIME_EIT_SCHEDULED_PAUSE 60 * 60
|
||||
// -- 5 Minutes max. pause should improve behavior (rasc, 2005-05-02)
|
||||
@@ -68,10 +70,7 @@
|
||||
// Zeit die fuer die gewartet wird, bevor der Filter weitergeschaltet wird, falls es automatisch nicht klappt
|
||||
#define TIME_EIT_SKIPPING 90
|
||||
|
||||
#define ENABLE_FREESATEPG // FIXME
|
||||
#ifdef ENABLE_FREESATEPG
|
||||
// a little more time for freesat epg
|
||||
#define TIME_FSEIT_SKIPPING 240
|
||||
#endif
|
||||
|
||||
static bool sectionsd_ready = false;
|
||||
@@ -86,9 +85,6 @@ static unsigned int max_events;
|
||||
#define READ_TIMEOUT_IN_SECONDS 2
|
||||
#define WRITE_TIMEOUT_IN_SECONDS 2
|
||||
|
||||
// Gibt die Anzahl Timeouts an, nach der die Verbindung zum DMX neu gestartet wird (wegen evtl. buffer overflow)
|
||||
// for NIT and SDT threads...
|
||||
#define RESTART_DMX_AFTER_TIMEOUTS 5
|
||||
|
||||
// Timeout in ms for reading from dmx in EIT threads. Dont make this too long
|
||||
// since we are holding the start_stop lock during this read!
|
||||
@@ -154,10 +150,20 @@ static pthread_mutex_t timeThreadSleepMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
/* no matter how big the buffer, we will receive spurious POLLERR's in table 0x60,
|
||||
but those are not a big deal, so let's save some memory */
|
||||
static DMX dmxEIT(0x12, 3000 /*320*/);
|
||||
static DMX dmxCN(0x12, 512, false, 1);
|
||||
|
||||
#ifdef ENABLE_FREESATEPG
|
||||
// a little more time for freesat epg
|
||||
#define TIME_FSEIT_SKIPPING 240
|
||||
static DMX dmxFSEIT(3842, 320);
|
||||
#endif
|
||||
static DMX dmxCN(0x12, 512, false, 1);
|
||||
|
||||
#ifdef ENABLE_SDT
|
||||
#define TIME_SDT_NONEWDATA 5
|
||||
#define RESTART_DMX_AFTER_TIMEOUTS 5
|
||||
#define TIME_SDT_SCHEDULED_PAUSE 2* 60* 60
|
||||
static DMX dmxSDT(0x11, 512, true, 0);
|
||||
#endif
|
||||
int sectionsd_stop = 0;
|
||||
|
||||
static bool slow_addevent = true;
|
||||
@@ -1081,6 +1087,9 @@ static void commandPauseScanning(int connfd, char *data, const unsigned dataLeng
|
||||
dmxEIT.request_pause();
|
||||
#ifdef ENABLE_FREESATEPG
|
||||
dmxFSEIT.request_pause();
|
||||
#endif
|
||||
#ifdef ENABLE_SDT
|
||||
dmxSDT.request_pause();
|
||||
#endif
|
||||
scanning = 0;
|
||||
}
|
||||
@@ -1090,6 +1099,9 @@ static void commandPauseScanning(int connfd, char *data, const unsigned dataLeng
|
||||
dmxEIT.request_unpause();
|
||||
#ifdef ENABLE_FREESATEPG
|
||||
dmxFSEIT.request_unpause();
|
||||
#endif
|
||||
#ifdef ENABLE_SDT
|
||||
dmxSDT.request_unpause();
|
||||
#endif
|
||||
writeLockEvents();
|
||||
if (myCurrentEvent) {
|
||||
@@ -1118,6 +1130,9 @@ static void commandPauseScanning(int connfd, char *data, const unsigned dataLeng
|
||||
dmxEIT.change(0);
|
||||
#ifdef ENABLE_FREESATEPG
|
||||
dmxFSEIT.change(0);
|
||||
#endif
|
||||
#ifdef ENABLE_SDT
|
||||
dmxSDT.change(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1595,6 +1610,9 @@ static void commandserviceChanged(int connfd, char *data, const unsigned dataLen
|
||||
channel_is_blacklisted = true;
|
||||
dmxCN.request_pause();
|
||||
dmxEIT.request_pause();
|
||||
#ifdef ENABLE_SDT
|
||||
dmxSDT.request_pause();
|
||||
#endif
|
||||
}
|
||||
xprintf("[sectionsd] commandserviceChanged: service is filtered!\n");
|
||||
}
|
||||
@@ -1604,6 +1622,9 @@ static void commandserviceChanged(int connfd, char *data, const unsigned dataLen
|
||||
channel_is_blacklisted = false;
|
||||
dmxCN.request_unpause();
|
||||
dmxEIT.request_unpause();
|
||||
#ifdef ENABLE_SDT
|
||||
dmxSDT.request_unpause();
|
||||
#endif
|
||||
xprintf("[sectionsd] commandserviceChanged: service is no longer filtered!\n");
|
||||
}
|
||||
}
|
||||
@@ -1648,6 +1669,9 @@ static void commandserviceChanged(int connfd, char *data, const unsigned dataLen
|
||||
dmxEIT.setCurrentService(messaging_current_servicekey & 0xffff);
|
||||
#ifdef ENABLE_FREESATEPG
|
||||
dmxFSEIT.setCurrentService(messaging_current_servicekey & 0xffff);
|
||||
#endif
|
||||
#ifdef ENABLE_SDT
|
||||
dmxSDT.setCurrentService(messaging_current_servicekey & 0xffff);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
@@ -2516,6 +2540,9 @@ static void deleteSIexceptEPG()
|
||||
writeLockServices();
|
||||
unlockServices();
|
||||
dmxEIT.dropCachedSectionIDs();
|
||||
#ifdef ENABLE_SDT
|
||||
dmxSDT.dropCachedSectionIDs();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void commandFreeMemory(int connfd, char * /*data*/, const unsigned /*dataLength*/)
|
||||
@@ -2587,11 +2614,13 @@ static void commandWriteSI2XML(int connfd, char *data, const unsigned dataLength
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* dummy1: do not send back anything */
|
||||
static void commandDummy1(int, char *, const unsigned)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* dummy2: send back an empty response */
|
||||
static void commandDummy2(int connfd, char *, const unsigned)
|
||||
@@ -3534,6 +3563,212 @@ static void *cnThread(void *)
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_SDT
|
||||
static bool addService(const SIservice &s, const int is_actual)
|
||||
{
|
||||
bool already_exists;
|
||||
bool is_new = false;
|
||||
|
||||
readLockServices();
|
||||
MySIservicesOrderUniqueKey::iterator si = mySIservicesOrderUniqueKey.find(s.uniqueKey());
|
||||
already_exists = (si != mySIservicesOrderUniqueKey.end());
|
||||
unlockServices();
|
||||
|
||||
if ( (!already_exists) || ((is_actual & 7) && (!si->second->is_actual)) ) {
|
||||
|
||||
if (already_exists)
|
||||
{
|
||||
writeLockServices();
|
||||
mySIservicesOrderUniqueKey.erase(s.uniqueKey());
|
||||
unlockServices();
|
||||
}
|
||||
|
||||
SIservice *sp = new SIservice(s);
|
||||
|
||||
if (!sp)
|
||||
{
|
||||
printf("[sectionsd::addService] new SIservice failed.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
SIservicePtr sptr(sp);
|
||||
|
||||
#if 0
|
||||
#define MAX_SIZE_SERVICENAME 50
|
||||
char servicename[MAX_SIZE_SERVICENAME];
|
||||
|
||||
if (sptr->serviceName.empty()) {
|
||||
sprintf(servicename, "%04x", sptr->service_id);
|
||||
servicename[sizeof(servicename) - 1] = 0;
|
||||
sptr->serviceName = servicename;
|
||||
}
|
||||
#endif
|
||||
sptr->is_actual = is_actual;
|
||||
|
||||
writeLockServices();
|
||||
mySIservicesOrderUniqueKey.insert(std::make_pair(sptr->uniqueKey(), sptr));
|
||||
unlockServices();
|
||||
|
||||
if (sptr->nvods.size())
|
||||
{
|
||||
writeLockServices();
|
||||
mySIservicesNVODorderUniqueKey.insert(std::make_pair(sptr->uniqueKey(), sptr));
|
||||
unlockServices();
|
||||
}
|
||||
is_new = true;
|
||||
}
|
||||
|
||||
return is_new;
|
||||
}
|
||||
|
||||
static void *sdtThread(void *)
|
||||
{
|
||||
const unsigned timeoutInMSeconds = 2500;
|
||||
t_transponder_id tid = 0;
|
||||
time_t lastData = 0;
|
||||
time_t zeit = 0;
|
||||
int rs = 0;
|
||||
int is_actual = 0;
|
||||
|
||||
//FIXME
|
||||
dmxSDT.addfilter(0x42, 0xf3 ); //SDT actual = 0x42 + SDT other = 0x46 + BAT = 0x4A
|
||||
|
||||
dprintf("[%sThread] pid %d (%lu) start\n", "sdt", getpid(), pthread_self());
|
||||
|
||||
int timeoutsDMX = 0;
|
||||
uint8_t *static_buf = new uint8_t[MAX_SECTION_LENGTH];
|
||||
int rc;
|
||||
|
||||
if (static_buf == NULL)
|
||||
{
|
||||
xprintf("%s: could not allocate static_buf\n", __FUNCTION__);
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
dmxSDT.start(); // -> unlock
|
||||
|
||||
if (!scanning)
|
||||
dmxSDT.request_pause();
|
||||
|
||||
bool startup = true;
|
||||
|
||||
waitForTimeset();
|
||||
|
||||
while (!sectionsd_stop) {
|
||||
while (!scanning) {
|
||||
if(sectionsd_stop)
|
||||
break;
|
||||
sleep(1);
|
||||
}
|
||||
zeit = time_monotonic();
|
||||
|
||||
if(sectionsd_stop)
|
||||
break;
|
||||
|
||||
readLockMessaging();
|
||||
if (messaging_zap_detected)
|
||||
startup = true;
|
||||
unlockMessaging();
|
||||
|
||||
if ((zeit > lastData + TIME_SDT_NONEWDATA) || (startup))
|
||||
{
|
||||
struct timespec abs_wait;
|
||||
struct timeval now;
|
||||
|
||||
gettimeofday(&now, NULL);
|
||||
TIMEVAL_TO_TIMESPEC(&now, &abs_wait);
|
||||
abs_wait.tv_sec += (TIME_SDT_SCHEDULED_PAUSE);
|
||||
|
||||
dmxSDT.real_pause();
|
||||
/* this is the "last" thread. Means: if this one goes to sleep, sectionsd
|
||||
* sleeps mostly. Worth printing. */
|
||||
printdate_ms(stdout);
|
||||
printf("sdtThread: going to sleep...\n");
|
||||
|
||||
writeLockMessaging();
|
||||
messaging_zap_detected = false;
|
||||
unlockMessaging();
|
||||
|
||||
pthread_mutex_lock( &dmxSDT.start_stop_mutex );
|
||||
rs = pthread_cond_timedwait( &dmxSDT.change_cond, &dmxSDT.start_stop_mutex, &abs_wait );
|
||||
pthread_mutex_unlock( &dmxSDT.start_stop_mutex );
|
||||
|
||||
if(sectionsd_stop)
|
||||
break;
|
||||
|
||||
if (rs == ETIMEDOUT)
|
||||
{
|
||||
dprintf("dmxSDT: waking up again - looking for new services :)\n");
|
||||
dmxSDT.change( 0 ); // -> restart
|
||||
}
|
||||
else if (rs == 0)
|
||||
{
|
||||
dprintf("dmxSDT: waking up again - requested from .change()\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
dprintf("dmxSDT: waking up again - unknown reason?!\n");
|
||||
dmxSDT.real_unpause();
|
||||
}
|
||||
// update zeit after sleep
|
||||
|
||||
startup = false;
|
||||
zeit = time_monotonic();
|
||||
timeoutsDMX = 0;
|
||||
lastData = zeit;
|
||||
}
|
||||
|
||||
if (timeoutsDMX >= RESTART_DMX_AFTER_TIMEOUTS && scanning)
|
||||
{
|
||||
timeoutsDMX = 0;
|
||||
dmxSDT.stop();
|
||||
dmxSDT.start(); // leaves unlocked
|
||||
dputs("\n !!! dmxSDT restarted !!!\n");
|
||||
}
|
||||
|
||||
rc = dmxSDT.getSection(static_buf, timeoutInMSeconds, timeoutsDMX);
|
||||
|
||||
if (rc < 0)
|
||||
continue;
|
||||
|
||||
LongSection sec(static_buf);
|
||||
uint8_t table_id = sec.getTableId();
|
||||
if ((table_id == 0x42) || (table_id == 0x46))
|
||||
{
|
||||
SIsectionSDT sdt(static_buf);
|
||||
|
||||
is_actual = (sdt.getTableId() == 0x42) ? 1 : 0;
|
||||
|
||||
if (is_actual && !sdt.getLastSectionNumber())
|
||||
is_actual = 2;
|
||||
|
||||
bool is_new = false;
|
||||
is_actual = (is_actual | 8);
|
||||
|
||||
for (SIservices::iterator s = sdt.services().begin(); s != sdt.services().end(); s++) {
|
||||
if (addService(*s, is_actual)) {
|
||||
is_new = true;
|
||||
tid = CREATE_TRANSPONDER_ID_FROM_ORIGINALNETWORK_TRANSPORTSTREAM_ID(s->original_network_id,
|
||||
s->transport_stream_id);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_new) {
|
||||
lastData = time_monotonic();
|
||||
|
||||
dprintf("[sdtThread] added %d services [table 0x%x TID: %08x]\n",
|
||||
sdt.services().size(), table_id, tid);
|
||||
}
|
||||
}
|
||||
} // for
|
||||
|
||||
delete[] static_buf;
|
||||
printf("[sectionsd] sdt-thread ended\n");
|
||||
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* helper function for the housekeeping-thread */
|
||||
static void print_meminfo(void)
|
||||
{
|
||||
@@ -3697,6 +3932,9 @@ void sectionsd_main_thread(void */*data*/)
|
||||
pthread_t threadTOT, threadEIT, threadCN, threadHouseKeeping;
|
||||
#ifdef ENABLE_FREESATEPG
|
||||
pthread_t threadFSEIT;
|
||||
#endif
|
||||
#ifdef ENABLE_SDT
|
||||
pthread_t threadSDT;
|
||||
#endif
|
||||
int rc;
|
||||
|
||||
@@ -3704,6 +3942,7 @@ void sectionsd_main_thread(void */*data*/)
|
||||
|
||||
printf("$Id: sectionsd.cpp,v 1.305 2009/07/30 12:41:39 seife Exp $\n");
|
||||
printf("SIevent size: %d\n", sizeof(SIevent));
|
||||
|
||||
/* "export NO_SLOW_ADDEVENT=true" to disable this */
|
||||
slow_addevent = (getenv("NO_SLOW_ADDEVENT") == NULL);
|
||||
if (slow_addevent)
|
||||
@@ -3789,6 +4028,15 @@ printf("SIevent size: %d\n", sizeof(SIevent));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#ifdef ENABLE_SDT
|
||||
printf("\n\n\n[sectionsd] starting SDT thread\n");
|
||||
rc = pthread_create(&threadSDT, 0, sdtThread, 0);
|
||||
|
||||
if (rc) {
|
||||
fprintf(stderr, "[sectionsd] failed to create sdt-thread (rc=%d)\n", rc);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// housekeeping-Thread starten
|
||||
rc = pthread_create(&threadHouseKeeping, 0, houseKeepingThread, 0);
|
||||
@@ -3816,14 +4064,13 @@ printf("SIevent size: %d\n", sizeof(SIevent));
|
||||
|
||||
printdate_ms(stdout);
|
||||
printf("EIT Update Filter: new version 0x%x, Activate cnThread\n", ((SI_section_header*)buf)->version_number);
|
||||
|
||||
writeLockMessaging();
|
||||
// messaging_skipped_sections_ID[0].clear();
|
||||
// messaging_sections_max_ID[0] = -1;
|
||||
// messaging_sections_got_all[0] = false;
|
||||
messaging_have_CN = 0x00;
|
||||
messaging_got_CN = 0x00;
|
||||
messaging_last_requested = time_monotonic();
|
||||
unlockMessaging();
|
||||
|
||||
sched_yield();
|
||||
dmxCN.change(0);
|
||||
sched_yield();
|
||||
@@ -3854,11 +4101,20 @@ printf("SIevent size: %d\n", sizeof(SIevent));
|
||||
pthread_mutex_lock(&dmxCN.start_stop_mutex);
|
||||
pthread_cond_broadcast(&dmxCN.change_cond);
|
||||
pthread_mutex_unlock(&dmxCN.start_stop_mutex);
|
||||
#ifdef ENABLE_SDT
|
||||
pthread_mutex_lock(&dmxSDT.start_stop_mutex);
|
||||
pthread_cond_broadcast(&dmxSDT.change_cond);
|
||||
pthread_mutex_unlock(&dmxSDT.start_stop_mutex);
|
||||
#endif
|
||||
|
||||
printf("pausing...\n");
|
||||
dmxEIT.request_pause();
|
||||
dmxCN.request_pause();
|
||||
#ifdef ENABLE_FREESATEPG
|
||||
dmxFSEIT.request_pause();
|
||||
#endif
|
||||
#ifdef ENABLE_SDT
|
||||
dmxSDT.request_pause();
|
||||
#endif
|
||||
pthread_cancel(threadHouseKeeping);
|
||||
|
||||
@@ -3873,6 +4129,10 @@ printf("SIevent size: %d\n", sizeof(SIevent));
|
||||
pthread_join(threadEIT, NULL);
|
||||
printf("join 3\n");
|
||||
pthread_join(threadCN, NULL);
|
||||
#ifdef ENABLE_SDT
|
||||
printf("join 4\n");
|
||||
pthread_join(threadSDT, NULL);
|
||||
#endif
|
||||
|
||||
eit_stop_update_filter(&eit_update_fd);
|
||||
if(eitDmx)
|
||||
@@ -3884,6 +4144,9 @@ printf("SIevent size: %d\n", sizeof(SIevent));
|
||||
dmxCN.close();
|
||||
#ifdef ENABLE_FREESATEPG
|
||||
dmxFSEIT.close();
|
||||
#endif
|
||||
#ifdef ENABLE_SDT
|
||||
dmxSDT.close();
|
||||
#endif
|
||||
printf("[sectionsd] ended\n");
|
||||
|
||||
|
Reference in New Issue
Block a user