From f11cea68e7ca7c55d837feef9d48b0db50931e85 Mon Sep 17 00:00:00 2001 From: "[CST] Focus" Date: Mon, 21 May 2012 14:33:38 +0400 Subject: [PATCH] src/eitd/SIevents.cpp: add back old event parse code --- src/eitd/SIevents.cpp | 179 ++++++++++++++++++++++++++++++++++++++++++ src/eitd/SIevents.hpp | 90 ++++++++++++++++++++- 2 files changed, 268 insertions(+), 1 deletion(-) diff --git a/src/eitd/SIevents.cpp b/src/eitd/SIevents.cpp index 8205686cc..9e5c75bde 100644 --- a/src/eitd/SIevents.cpp +++ b/src/eitd/SIevents.cpp @@ -43,6 +43,36 @@ const std::string languangeOFF = "OFF"; +struct descr_generic_header { + unsigned descriptor_tag : 8; + unsigned descriptor_length : 8; +} __attribute__ ((packed)) ; + +struct descr_short_event_header { + unsigned descriptor_tag : 8; + unsigned descriptor_length : 8; + unsigned language_code_hi : 8; + unsigned language_code_mid : 8; + unsigned language_code_lo : 8; + unsigned event_name_length : 8; +} __attribute__ ((packed)) ; + +struct descr_extended_event_header { + unsigned descriptor_tag : 8; + unsigned descriptor_length : 8; + unsigned descriptor_number : 4; + unsigned last_descriptor_number : 4; + unsigned iso_639_2_language_code_hi : 8; + unsigned iso_639_2_language_code_mid : 8; + unsigned iso_639_2_language_code_lo : 8; + unsigned length_of_items : 8; +} __attribute__ ((packed)) ; + +inline unsigned min(unsigned a, unsigned b) +{ + return b < a ? b : a; +} + SIevent::SIevent(const t_original_network_id _original_network_id, const t_transport_stream_id _transport_stream_id, const t_service_id _service_id, const unsigned short _event_id) { @@ -55,6 +85,29 @@ SIevent::SIevent(const t_original_network_id _original_network_id, const t_trans running = 0; } +SIevent::SIevent(const struct eit_event *e) +{ + eventID = (e->event_id_hi << 8) | e->event_id_lo; + time_t start_time = changeUTCtoCtime(((const unsigned char *)e) + 2); + unsigned long duration = 0; + + if (!((e->duration_hi == 0xff) && (e->duration_mid == 0xff) && (e->duration_lo == 0xff))) + duration = ((e->duration_hi)>>4)*10*3600L + ((e->duration_hi)&0x0f)*3600L + + ((e->duration_mid)>>4)*10*60L + ((e->duration_mid)&0x0f)*60L + + ((e->duration_lo)>>4)*10 + ((e->duration_lo)&0x0f); + + if (start_time && duration) + times.insert(SItime(start_time, duration)); + + running = (int)e->running_status; + + table_id = 0xFF; /* not set */ + version = 0xFF; + service_id = 0; + original_network_id = 0; + transport_stream_id = 0; +} + void SIevent::parse(Event &event) { int tsidonid = (transport_stream_id << 16) | original_network_id; @@ -150,6 +203,132 @@ void SIevent::parse(Event &event) } } +void SIevent::parseDescriptors(const uint8_t *des, unsigned len) +{ + struct descr_generic_header *desc; + /* we pass the buffer including the eit_event header, so we have to + * skip it here... */ + des += sizeof(struct eit_event); + len -= sizeof(struct eit_event); + while(len>=sizeof(struct descr_generic_header)) { + desc=(struct descr_generic_header *)des; + /*printf("Type: %s\n", decode_descr(desc->descriptor_tag)); */ + if(desc->descriptor_tag==0x4D) + parseShortEventDescriptor((const uint8_t *)desc, len); + else if(desc->descriptor_tag==0x4E) + parseExtendedEventDescriptor((const uint8_t *)desc, len); + else if(desc->descriptor_tag==0x54) + parseContentDescriptor((const uint8_t *)desc, len); + else if(desc->descriptor_tag==0x50) + parseComponentDescriptor((const uint8_t *)desc, len); + else if(desc->descriptor_tag==0x55) + parseParentalRatingDescriptor((const uint8_t *)desc, len); + else if(desc->descriptor_tag==0x4A) { + parseLinkageDescriptor((const uint8_t *)desc, len); + } +#if 0 + else if(desc->descriptor_tag==0x69) + parsePDCDescriptor((const char *)desc, e, len); +#endif + if((unsigned)(desc->descriptor_length+2)>len) + break; + len-=desc->descriptor_length+2; + des+=desc->descriptor_length+2; + } +} + +void SIevent::parseShortEventDescriptor(const uint8_t *buf, unsigned maxlen) +{ + struct descr_short_event_header *evt=(struct descr_short_event_header *)buf; + if((evt->descriptor_length+sizeof(descr_generic_header) > maxlen) || + (evt->descriptor_lengthlanguage_code_hi), tolower(evt->language_code_mid), tolower(evt->language_code_lo), '\0'}; + std::string language(lang); + int table = getCountryCodeDefaultMapping(language); + + buf+=sizeof(struct descr_short_event_header); + if(evt->event_name_length) + setName(language, convertDVBUTF8((const char*) buf, evt->event_name_length, table, tsidonid)); + + buf+=evt->event_name_length; + unsigned char textlength=*((unsigned char *)buf); + if(textlength > 2) + setText(language, convertDVBUTF8((const char*) (++buf), textlength, table, tsidonid)); +} + +void SIevent::parseExtendedEventDescriptor(const uint8_t *buf, unsigned maxlen) +{ + struct descr_extended_event_header *evt=(struct descr_extended_event_header *)buf; + if((evt->descriptor_length+sizeof(descr_generic_header)>maxlen) || + (evt->descriptor_lengthiso_639_2_language_code_hi), tolower(evt->iso_639_2_language_code_mid), tolower(evt->iso_639_2_language_code_lo), '\0'}; + std::string language(lang); + int table = getCountryCodeDefaultMapping(language); + + unsigned char *items=(unsigned char *)(buf+sizeof(struct descr_extended_event_header)); + while(items < (unsigned char *)(buf + sizeof(struct descr_extended_event_header) + evt->length_of_items)) { + if(*items) { + itemDescription.append(convertDVBUTF8((const char *)(items+1), min(maxlen-(items+1-buf), *items), table, tsidonid)); + itemDescription.append("\n"); + } + items+=1+*items; + if(*items) { + item.append(convertDVBUTF8((const char *)(items+1), min(maxlen-(items+1-buf), *items), table, tsidonid)); + item.append("\n"); + } + items+=1+*items; + } + if(*items) + appendExtendedText(language, convertDVBUTF8((const char *)(items+1), min(maxlen-(items+1-buf), (*items)), table, tsidonid)); +} + +void SIevent::parseContentDescriptor(const uint8_t *buf, unsigned maxlen) +{ + struct descr_generic_header *cont=(struct descr_generic_header *)buf; + if(cont->descriptor_length+sizeof(struct descr_generic_header)>maxlen) + return; + + const uint8_t *classification=buf+sizeof(struct descr_generic_header); + while(classification <= buf+sizeof(struct descr_generic_header)+cont->descriptor_length-2) { + contentClassification+=std::string((const char *)classification, 1); + userClassification+=std::string((const char *)classification+1, 1); + classification+=2; + } +} + +void SIevent::parseComponentDescriptor(const uint8_t *buf, unsigned maxlen) +{ + if(maxlen>=sizeof(struct descr_component_header)) + components.insert(SIcomponent((const struct descr_component_header *)buf)); +} + +void SIevent::parseParentalRatingDescriptor(const uint8_t *buf, unsigned maxlen) +{ + struct descr_generic_header *cont=(struct descr_generic_header *)buf; + if(cont->descriptor_length+sizeof(struct descr_generic_header)>maxlen) + return; + const uint8_t *s=buf+sizeof(struct descr_generic_header); + while(sdescriptor_length-4) { + ratings.insert(SIparentalRating(std::string((const char *)s, 3), *(s+3))); + s+=4; + } +} +void SIevent::parseLinkageDescriptor(const uint8_t *buf, unsigned maxlen) +{ + if(maxlen>=sizeof(struct descr_linkage_header)) { + SIlinkage l((const struct descr_linkage_header *)buf); + linkage_descs.insert(linkage_descs.end(), l); + } +} + char SIevent::getFSK() const { for (SIparentalRatings::iterator it = ratings.begin(); it != ratings.end(); ++it) diff --git a/src/eitd/SIevents.hpp b/src/eitd/SIevents.hpp index 9fe70d58e..6acec8d76 100644 --- a/src/eitd/SIevents.hpp +++ b/src/eitd/SIevents.hpp @@ -32,6 +32,67 @@ #include #include "edvbstring.h" +struct eit_event { + unsigned event_id_hi : 8; + unsigned event_id_lo : 8; + unsigned start_time_hi : 8; + unsigned start_time_hi2 : 8; + unsigned start_time_mid : 8; + unsigned start_time_lo2 : 8; + unsigned start_time_lo : 8; + unsigned duration_hi : 8; + unsigned duration_mid : 8; + unsigned duration_lo : 8; +#if __BYTE_ORDER == __BIG_ENDIAN + unsigned running_status : 3; + unsigned free_CA_mode : 1; + unsigned descriptors_loop_length_hi : 4; +#else + unsigned descriptors_loop_length_hi : 4; + unsigned free_CA_mode : 1; + unsigned running_status : 3; +#endif + unsigned descriptors_loop_length_lo : 8; +} __attribute__ ((packed)) ; + + +struct descr_component_header { + unsigned descriptor_tag : 8; + unsigned descriptor_length : 8; +#if __BYTE_ORDER == __BIG_ENDIAN + unsigned reserved_future_use : 4; + unsigned stream_content : 4; +#else + unsigned stream_content : 4; + unsigned reserved_future_use : 4; +#endif + unsigned component_type : 8; + unsigned component_tag : 8; + unsigned iso_639_2_language_code_hi : 8; + unsigned iso_639_2_language_code_mid : 8; + unsigned iso_639_2_language_code_lo : 8; +} __attribute__ ((packed)) ; + +struct descr_linkage_header { + unsigned descriptor_tag : 8; + unsigned descriptor_length : 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 service_id_hi : 8; + unsigned service_id_lo : 8; + unsigned linkage_type : 8; +} __attribute__ ((packed)) ; + +struct descr_pdc_header { + unsigned descriptor_tag : 8; + unsigned descriptor_length : 8; + unsigned pil0 : 8; + unsigned pil1 : 8; + unsigned pil2 : 8; +} __attribute__ ((packed)) ; + class SIlinkage { public: unsigned char linkageType; @@ -46,7 +107,15 @@ public: originalNetworkId = 0; serviceId = 0; } - + + SIlinkage(const struct descr_linkage_header *link) { + linkageType = link->linkage_type; + transportStreamId = (link->transport_stream_id_hi << 8) | link->transport_stream_id_lo; + originalNetworkId = (link->original_network_id_hi << 8) | link->original_network_id_lo; + serviceId = (link->service_id_hi << 8) | link->service_id_lo; + if (link->descriptor_length > sizeof(struct descr_linkage_header) - 2) + name = convertDVBUTF8(((const char *)link)+sizeof(struct descr_linkage_header), link->descriptor_length-(sizeof(struct descr_linkage_header)-2), 0, 0); + } void dump(void) const { printf("Linakge Type: 0x%02hhx\n", linkageType); @@ -113,6 +182,15 @@ class SIcomponent componentType=0; componentTag=0; } + SIcomponent(const struct descr_component_header *comp) { + streamContent=comp->stream_content; + componentType=comp->component_type; + componentTag=comp->component_tag; + if(comp->descriptor_length>sizeof(struct descr_component_header)-2) + component=convertDVBUTF8(((const char *)comp)+sizeof(struct descr_component_header), + comp->descriptor_length-(sizeof(struct descr_component_header)-2), 0, 0); + } + void dump(void) const { if(component.length()) printf("Component: %s\n", component.c_str()); @@ -264,6 +342,13 @@ class SIevent std::map langExtendedText; int running; + void parseShortEventDescriptor(const uint8_t *buf, unsigned maxlen); + void parseExtendedEventDescriptor(const uint8_t *buf, unsigned maxlen); + void parseContentDescriptor(const uint8_t *buf, unsigned maxlen); + void parseComponentDescriptor(const uint8_t *buf, unsigned maxlen); + void parseParentalRatingDescriptor(const uint8_t *buf, unsigned maxlen); + void parseLinkageDescriptor(const uint8_t *buf, unsigned maxlen); + protected: int saveXML0(FILE *f) const; int saveXML2(FILE *f) const; @@ -298,7 +383,10 @@ class SIevent version = 0xFF; running = false; } + SIevent(const struct eit_event *e); + void parse(Event &event); + void parseDescriptors(const uint8_t *des, unsigned len); // Name aus dem Short-Event-Descriptor std::string getName() const;