diff --git a/src/eitd/SIsections.cpp b/src/eitd/SIsections.cpp index de34a976a..82c426f68 100644 --- a/src/eitd/SIsections.cpp +++ b/src/eitd/SIsections.cpp @@ -41,6 +41,12 @@ #include "debug.h" #include "edvbstring.h" +inline unsigned min(unsigned a, unsigned b) +{ + return b < a ? b : a; +} + +#ifdef USE_DVBSI_EVENTS void SIsectionEIT::parse(void) { const EventList &elist = *getEvents(); @@ -66,6 +72,46 @@ void SIsectionEIT::parse(void) } parsed = 1; } +#else +void SIsectionEIT::parse(void) +{ + const uint8_t *actPos; + const uint8_t *bufEnd; + struct eit_event *evt; + unsigned short descriptors_loop_length; + + if (!buffer || parsed) + return; + + struct SI_section_header *siheader = (SI_section_header*) buffer; + unsigned short bufferLength = siheader->section_length_hi << 8 | siheader->section_length_lo; + + if (bufferLength < sizeof(SI_section_EIT_header) + sizeof(struct eit_event)) { + bufferLength=0; + return; + } + + unsigned char table_id = header()->table_id; + unsigned char version_number = header()->version_number; + actPos = buffer + sizeof(SI_section_EIT_header); + bufEnd = buffer + bufferLength; + + while (actPos < bufEnd - sizeof(struct eit_event)) { + evt = (struct eit_event *) actPos; + SIevent e(evt); + e.service_id = service_id(); + e.original_network_id = original_network_id(); + e.transport_stream_id = transport_stream_id(); + e.table_id = table_id; + e.version = version_number; + descriptors_loop_length = sizeof(struct eit_event) + ((evt->descriptors_loop_length_hi << 8) | evt->descriptors_loop_length_lo); + e.parseDescriptors(actPos, min((unsigned)(bufEnd - actPos), descriptors_loop_length)); + evts.insert(e); + actPos += descriptors_loop_length; + } + parsed = 1; +} +#endif void SIsectionSDT::parse(void) { diff --git a/src/eitd/SIsections.hpp b/src/eitd/SIsections.hpp index 932141657..21b4df4b2 100644 --- a/src/eitd/SIsections.hpp +++ b/src/eitd/SIsections.hpp @@ -29,15 +29,89 @@ #include #include -class SIsectionEIT : public EventInformationSection +#define USE_DVBSI_EVENTS + +struct SI_section_EIT_header { + unsigned table_id : 8; +#if __BYTE_ORDER == __BIG_ENDIAN + unsigned section_syntax_indicator : 1; + unsigned reserved_future_use : 1; + unsigned reserved1 : 2; + unsigned section_length_hi : 4; +#else + unsigned section_length_hi : 4; + unsigned reserved1 : 2; + unsigned reserved_future_use : 1; + unsigned section_syntax_indicator : 1; +#endif + unsigned section_length_lo : 8; + unsigned service_id_hi : 8; + unsigned service_id_lo : 8; +#if __BYTE_ORDER == __BIG_ENDIAN + unsigned reserved2 : 2; + unsigned version_number : 5; + unsigned current_next_indicator : 1; +#else + unsigned current_next_indicator : 1; + unsigned version_number : 5; + unsigned reserved2 : 2; +#endif + unsigned section_number : 8; + unsigned last_section_number : 8; + unsigned transport_stream_id_hi : 8; + unsigned transport_stream_id_lo : 8; + unsigned original_network_id_hi : 8; + unsigned original_network_id_lo : 8; + unsigned segment_last_section_number : 8; + unsigned last_table_id : 8; +} __attribute__ ((packed)) ; // 14 bytes + +struct SI_section_header { + unsigned table_id : 8; +#if __BYTE_ORDER == __BIG_ENDIAN + unsigned section_syntax_indicator : 1; + unsigned reserved_future_use : 1; + unsigned reserved1 : 2; + unsigned section_length_hi : 4; +#else + unsigned section_length_hi : 4; + unsigned reserved1 : 2; + unsigned reserved_future_use : 1; + unsigned section_syntax_indicator : 1; +#endif + unsigned section_length_lo : 8; + unsigned table_id_extension_hi : 8; + unsigned table_id_extension_lo : 8; +#if __BYTE_ORDER == __BIG_ENDIAN + unsigned reserved2 : 2; + unsigned version_number : 5; + unsigned current_next_indicator : 1; +#else + unsigned current_next_indicator : 1; + unsigned version_number : 5; + unsigned reserved2 : 2; +#endif + unsigned section_number : 8; + unsigned last_section_number : 8; +} __attribute__ ((packed)) ; // 8 bytes + +class SIsectionEIT +#ifdef USE_DVBSI_EVENTS + : public EventInformationSection +#endif { protected: + uint8_t * buffer; SIevents evts; int parsed; void parse(void); public: - SIsectionEIT(uint8_t *buf) : EventInformationSection(buf) + SIsectionEIT(uint8_t *buf) +#ifdef USE_DVBSI_EVENTS + : EventInformationSection(buf) +#endif { + buffer = buf; parsed = 0; parse(); } @@ -49,6 +123,24 @@ public: int is_parsed(void) const { return parsed; } + t_service_id service_id(void) const { + return buffer ? ((((struct SI_section_EIT_header *)buffer)->service_id_hi << 8) | + ((struct SI_section_EIT_header *)buffer)->service_id_lo): 0; + } + + t_original_network_id original_network_id(void) const { + return buffer ? ((((struct SI_section_EIT_header *)buffer)->original_network_id_hi << 8) | + ((struct SI_section_EIT_header *)buffer)->original_network_id_lo) : 0; + } + + t_transport_stream_id transport_stream_id(void) const { + return buffer ? ((((struct SI_section_EIT_header *)buffer)->transport_stream_id_hi << 8) | + ((struct SI_section_EIT_header *)buffer)->transport_stream_id_lo) : 0; + } + + struct SI_section_EIT_header const *header(void) const { + return (struct SI_section_EIT_header *)buffer; + } }; class SIsectionSDT : public ServiceDescriptionSection