From 35d5843a396a5b3144e3abc2571e150c514801e4 Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Thu, 22 Sep 2011 17:24:02 +0200 Subject: re-factored code added stars rating --- dish.c | 248 +++++++++++++++++++++++++++++++++++++++++++++-------------------- dish.h | 56 +++++++++------ eepg.c | 96 +++++++++++-------------- 3 files changed, 247 insertions(+), 153 deletions(-) diff --git a/dish.c b/dish.c index 75ea611..7ea85b1 100644 --- a/dish.c +++ b/dish.c @@ -20,82 +20,92 @@ namespace SI { // returns the value of a sequence of bits in the byte array - static unsigned int getBits(int bitIndex, int bitCount, const unsigned char *byteptr, int length) - { - union { - unsigned char b[4]; - unsigned long val; - } chunk; + static unsigned int getBits(int bitIndex, int bitCount, const unsigned char *byteptr, + int length) { + union + { + unsigned char b[4]; + unsigned long val; + } chunk; - int offset = bitIndex >> 3; - int bitnum = bitIndex - (offset << 3); - int rightend = 32 - bitnum - bitCount; + int offset = bitIndex >> 3; + int bitnum = bitIndex - (offset << 3); + int rightend = 32 - bitnum - bitCount; - chunk.b[3] = byteptr[offset]; - chunk.b[2] = (offset+1 < length) ? byteptr[offset+1] : 0; - chunk.b[1] = (offset+2 < length) ? byteptr[offset+2] : 0; - chunk.b[0] = 0; // Never need to look this far ahead. + chunk.b[3] = byteptr[offset]; + chunk.b[2] = (offset + 1 < length) ? byteptr[offset + 1] : 0; + chunk.b[1] = (offset + 2 < length) ? byteptr[offset + 2] : 0; + chunk.b[0] = 0; // Never need to look this far ahead. - return (unsigned int)(((chunk.val & (0xFFFFFFFF >> bitnum)) >> rightend)); + return (unsigned int) ((((((chunk.val & (0xFFFFFFFF >> bitnum)) >> rightend))))); } - DishDescriptor::DishDescriptor(UnimplementedDescriptor *unimplementedDesc) + DishDescriptor::DishDescriptor() { - text = NULL; + name = NULL; shortText = NULL; + description = NULL; decompressed = NULL; - this->unimplementedDesc = unimplementedDesc; + DishTheme = 0; + DishCategory = 0; + mpaaRating = 0; + starRating = 0; } DishDescriptor::~DishDescriptor() { delete [] decompressed; decompressed = NULL; - delete unimplementedDesc; + delete name; + name = NULL; + delete shortText; + shortText = NULL; + delete description; + description = NULL; } - const char *DishDescriptor::getTheme(int contentNibleLvl2) + const char *DishDescriptor::getTheme() { - const char* theme; - using namespace DISH_THEMES; + const char *theme; + using namespace DISH_THEMES; - switch (contentNibleLvl2) { - case Movie: - theme = "Movie"; - break; - case Sports: - theme = "Sports"; - break; - case News_Business: - theme = "News/Business"; - break; - case Family_Children: - theme = "Family/Children"; - break; - case Education: - theme = "Education"; - break; - case Series_Special: - theme = "Series/Special"; - break; - case Music_Art: - theme = "Music/Art"; - break; - case Religious: - theme = "Religious"; - break; - default: - theme = ""; - break; - } - return theme; + switch (DishTheme){ + case Movie: + theme = "Movie"; + break; + case Sports: + theme = "Sports"; + break; + case News_Business: + theme = "News/Business"; + break; + case Family_Children: + theme = "Family/Children"; + break; + case Education: + theme = "Education"; + break; + case Series_Special: + theme = "Series/Special"; + break; + case Music_Art: + theme = "Music/Art"; + break; + case Religious: + theme = "Religious"; + break; + default: + theme = ""; + break; + } + return theme; } - const char *DishDescriptor::getCategory(int userNible) + const char *DishDescriptor::getCategory() { - using namespace DISH_CATEGORIES; + using namespace DISH_CATEGORIES; - switch (userNible) { + switch (DishCategory) { case Action: return "Action"; case ActionSports: return "Action Sports"; case Adults_only: return "Adults only"; @@ -253,13 +263,108 @@ namespace SI case Yoga: return "Yoga"; default: return ""; } + } + void DishDescriptor::setExtendedtData(unsigned char Tid, CharArray data) + { + Decompress(Tid, data); + if (decompressed) { + char *split = strchr((char*)((decompressed)), 0x0D); // Look for carriage return + //LogD(2, prep("dLength:%d, length:%d, count:%d, decompressed: %s"), dLength, length, count, decompressed); + if(split){ + *split = 0; + shortText = new string((char*)decompressed); + description = new string((split[1] == 0x20) ? split + 2 : split + 1); + }else{ + description = new string((char*)decompressed); + } + delete[] decompressed; + decompressed = NULL; + } else { + shortText = new string(); + description = new string(); + } } - void DishDescriptor::Decompress(unsigned char Tid) + const char *DishDescriptor::getShortText(void) { - const unsigned char *str = unimplementedDesc->getData().getData(); - const unsigned char *cmp = NULL; // Compressed data + string tmp = ""; + if (shortText != NULL) tmp += *shortText; + if(DishTheme > 0){ + if(tmp != "") tmp += " - "; + + tmp += getTheme(); + } + if(DishCategory > 0){ + if(tmp != "") tmp += " - "; + + tmp += getCategory(); + } + return tmp.c_str(); + } + + const char *DishDescriptor::getDescription(void) { + string tmp = ""; + if (description != NULL) tmp += *description; + char* rating = getRating(); + if (rating && rating != "") { + if(tmp != "") tmp += "|"; + tmp += rating; + } + if (starRating > 0) { + if(tmp != "") tmp += "|"; + tmp += getStarRating(); + } + return tmp.c_str(); + } + + void DishDescriptor::setContent(ContentDescriptor::Nibble Nibble) + { + DishTheme = Nibble.getContentNibbleLevel2() & 0xF; + DishCategory = ((Nibble.getUserNibble1() & 0xF) << 4) | (Nibble.getUserNibble2() & 0xF); + } + + void DishDescriptor::setRating(uint16_t rating) + { + uint16_t newRating = (rating >> 10) & 0x07; + if (newRating == 0) newRating = 5; + if (newRating == 6) newRating = 0; + mpaaRating = (newRating << 10) | (rating & 0x3FF); + starRating = (rating >> 13) & 0x07; + } + + const char* DishDescriptor::getRating(){ + static const char *const ratings[8] = { "", "G", "PG", "PG-13", "R", "NR/AO", "", "NC-17" }; + char buffer[19]; + buffer[0] = 0; + strcpy(buffer, ratings[(mpaaRating >> 10) & 0x07]); + if (mpaaRating & 0x3A7F) { + strcat(buffer, " ["); + if (mpaaRating & 0x0230) + strcat(buffer, "V,"); + if (mpaaRating & 0x000A) + strcat(buffer, "L,"); + if (mpaaRating & 0x0044) + strcat(buffer, "N,"); + if (mpaaRating & 0x0101) + strcat(buffer, "SC,"); + if (char *s = strrchr(buffer, ',')) + s[0] = ']'; + } + + return isempty(buffer) ? NULL : buffer; + } + + const char* DishDescriptor::getStarRating(){ + static const char *const critiques[8] = { "", "*", "*+", "**", "**+", "***", "***+", "****" }; + return critiques[starRating & 0x07]; + } + + + void DishDescriptor::Decompress(unsigned char Tid, CharArray data) + { + const unsigned char *str = data.getData(); + const unsigned char *cmp = NULL; int length = 0; // Length of compressed data unsigned int dLength = 0; // Length of decompressed data if((str[3] & 0xFC) == 0x80){ @@ -278,15 +383,14 @@ namespace SI HuffmanTable *table; unsigned int tableSize, numBits; if (Tid > 0x80) { - table = Table255; - tableSize = SIZE_TABLE_255; - numBits = 13; - } - else { - table = Table128; - tableSize = SIZE_TABLE_128; - numBits = 11; - } + table = Table255; + tableSize = SIZE_TABLE_255; + numBits = 13; + } else { + table = Table128; + tableSize = SIZE_TABLE_128; + numBits = 11; + } unsigned int bLength = length << 3; // number of bits unsigned int currentBit = 0, count = 0; while(currentBit < bLength - 1 && count < dLength){ @@ -305,18 +409,8 @@ namespace SI } decompressed[count] = 0; - char *split = strchr((char*)(decompressed), 0x0D); // Look for carriage return - //LogD(2, prep("dLength:%d, length:%d, count:%d, decompressed: %s"), dLength, length, count, decompressed); - if(split){ - *split = 0; - shortText = (char*)(decompressed); - text = (split[1] == 0x20) ? split + 2 : split + 1; - }else{ - text = (char*)(decompressed); - } } - struct DishDescriptor::HuffmanTable DishDescriptor::Table128[SIZE_TABLE_128] = { { 0x0000, 0x20, 0x03 }, { 0x0100, 0x65, 0x04 }, { 0x0180, 0x74, 0x04 }, { 0x0200, 0x61, 0x04 }, { 0x0280, 0x6F, 0x04 }, { 0x0300, 0x73, 0x04 }, @@ -451,4 +545,4 @@ struct DishDescriptor::HuffmanTable DishDescriptor::Table255[SIZE_TABLE_255] = { { 0x1FFD, 0x02, 0x0D }, { 0x1FFE, 0x01, 0x0D }, { 0x1FFF, 0x00, 0x0D } }; -} //end of namespace +} //end of namespace diff --git a/dish.h b/dish.h index fb1689c..7510c67 100644 --- a/dish.h +++ b/dish.h @@ -239,33 +239,47 @@ namespace SI #define SIZE_TABLE_128 128 #define SIZE_TABLE_255 255 -class UnimplementedDescriptor; +using namespace std; class DishDescriptor { public: - DishDescriptor(UnimplementedDescriptor*); - virtual ~DishDescriptor(); - const char* getText(void) const { return text; } + DishDescriptor(); + virtual ~DishDescriptor(); + const char* getName(void) const { return name?name->c_str():""; } + const char* getShortText(void); + const char *getDescription(void); + // const char* getShortText(void) const { return shortText?shortText->c_str():""; } + // const char* getDescription(void) const { return description?description->c_str():""; } + const char *getTheme(); + const char *getCategory(); + const char *getRating(); + const char *getStarRating(); + void setShortData(unsigned char Tid, CharArray data); + void setExtendedtData(unsigned char Tid, CharArray data); + void setRating(uint16_t value); + void setContent(ContentDescriptor::Nibble Nibble); - const char* getShortText(void) const { return shortText; } - const char* getTheme(int contentNibleLvl2); - const char* getCategory(int userNible); - // Decompress the byte arrary and stores the result to a text string - void Decompress(unsigned char Tid); -protected: - const char* text; // name or description of the event - const char* shortText; // usually the episode name - unsigned char* decompressed; - UnimplementedDescriptor* unimplementedDesc; - struct HuffmanTable { - unsigned int startingAddress; - unsigned char character; - unsigned char numberOfBits; - }; - static HuffmanTable Table128[SIZE_TABLE_128]; - static HuffmanTable Table255[SIZE_TABLE_255]; +protected: + // Decompress the byte array and stores the result to a text string + void Decompress(unsigned char Tid, CharArray data); + string *name; // name of the event + string *shortText; // usually the episode name + string *description; // description of the event + unsigned char *decompressed; + uchar DishTheme; + uchar DishCategory; + uint16_t mpaaRating; + uint16_t starRating; + struct HuffmanTable + { + unsigned int startingAddress; + unsigned char character; + unsigned char numberOfBits; + }; + static HuffmanTable Table128[SIZE_TABLE_128]; + static HuffmanTable Table255[SIZE_TABLE_255]; }; } /* namespace SI */ diff --git a/eepg.c b/eepg.c index 5f5f52b..478a9aa 100644 --- a/eepg.c +++ b/eepg.c @@ -10,6 +10,7 @@ * -Freesat patch written by dom /at/ suborbital.org.uk * * + * This code is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. @@ -344,6 +345,7 @@ public: cFilterEEPG (void); virtual void SetStatus (bool On); void Trigger (void); + static const int EIT_PID = 0x12; }; cFilterEEPG::cFilterEEPG (void) @@ -2823,15 +2825,13 @@ extern bool SystemCharacterTableIsSingleByte;*/ class cEIT2:public SI::EIT { public: - cEIT2 (cSchedules * Schedules, int Source, u_char Tid, const u_char * Data, bool OnlyRunningStatus = false); + cEIT2 (cSchedules * Schedules, int Source, u_char Tid, const u_char * Data, bool isEITPid = false, bool OnlyRunningStatus = false); }; -cEIT2::cEIT2 (cSchedules * Schedules, int Source, u_char Tid, const u_char * Data, bool OnlyRunningStatus) +cEIT2::cEIT2 (cSchedules * Schedules, int Source, u_char Tid, const u_char * Data, bool isEITPid, bool OnlyRunningStatus) : SI::EIT (Data, false) { //LogD(2, prep("cEIT2::cEIT2")); - if (Tid > 0 && Format == DISH_BEV) Tid--; - if (!CheckCRCAndParse ()) { LogD(2, prep("!CheckCRCAndParse ()")); return; @@ -2846,7 +2846,7 @@ cEIT2::cEIT2 (cSchedules * Schedules, int Source, u_char Tid, const u_char * Dat return; // only collect data for known channels } - LogD(4, prep("channelID: %s format:%d"), *channel->GetChannelID().ToString(), Format); + //LogD(4, prep("channelID: %s format:%d"), *channel->GetChannelID().ToString(), Format); #ifdef USE_NOEPG // only use epg from channels not blocked by noEPG-patch @@ -2874,6 +2874,11 @@ cEIT2::cEIT2 (cSchedules * Schedules, int Source, u_char Tid, const u_char * Dat if (!SegmentStart) SegmentStart = SiEitEvent.getStartTime (); SegmentEnd = SiEitEvent.getStartTime () + SiEitEvent.getDuration (); + int versionNumber = getVersionNumber(); + // increase version number for DISH_BEV EIT so it does not get overwriten by VDR. + // TODO check the same for other providers. + if (Format == DISH_BEV && isEITPid) versionNumber++; + cEvent *newEvent = NULL; cEvent *rEvent = NULL; cEvent *pEvent = (cEvent *) pSchedule->GetEvent (SiEitEvent.getEventId (), SiEitEvent.getStartTime ()); @@ -2962,7 +2967,7 @@ cEIT2::cEIT2 (cSchedules * Schedules, int Source, u_char Tid, const u_char * Dat continue; } #else - if (pEvent->Version () == getVersionNumber ()) + if (pEvent->Version () == versionNumber) continue; #endif /* DDEPGENTRY */ HasExternalData = ExternalData = true; @@ -2977,7 +2982,7 @@ cEIT2::cEIT2 (cSchedules * Schedules, int Source, u_char Tid, const u_char * Dat // the actual Premiere transponder and the Sat.1/Pro7 transponder), but use different version numbers on // each of them :-( So if one DVB card is tuned to the Premiere transponder, while an other one is tuned // to the Sat.1/Pro7 transponder, events will keep toggling because of the bogus version numbers. - else if (Tid == pEvent->TableID() && pEvent->Version() == getVersionNumber()) + else if (Tid == pEvent->TableID() && pEvent->Version() == versionNumber) continue; } if (!ExternalData) { @@ -2998,7 +3003,7 @@ cEIT2::cEIT2 (cSchedules * Schedules, int Source, u_char Tid, const u_char * Dat } if (OnlyRunningStatus) continue; // do this before setting the version, so that the full update can be done later - pEvent->SetVersion (getVersionNumber()); + pEvent->SetVersion (versionNumber); int LanguagePreferenceShort = -1; int LanguagePreferenceExt = -1; @@ -3006,9 +3011,9 @@ cEIT2::cEIT2 (cSchedules * Schedules, int Source, u_char Tid, const u_char * Dat SI::Descriptor * d; SI::ExtendedEventDescriptors * ExtendedEventDescriptors = NULL; SI::ShortEventDescriptor * ShortEventDescriptor = NULL; - SI::DishDescriptor *DishExtendedEventDescriptor = NULL; - SI::DishDescriptor *DishShortEventDescriptor = NULL; - uchar DishTheme = 0, DishCategory = 0; + //SI::DishDescriptor *DishExtendedEventDescriptor = NULL; + SI::DishDescriptor *DishEventDescriptor = NULL; + //uchar DishTheme = 0, DishCategory = 0; cLinkChannels *LinkChannels = NULL; @@ -3060,13 +3065,11 @@ cEIT2::cEIT2 (cSchedules * Schedules, int Source, u_char Tid, const u_char * Dat Contents[NumContents] = ((Nibble.getContentNibbleLevel1() & 0xF) << 4) | (Nibble.getContentNibbleLevel2() & 0xF); NumContents++; } - if (Format == DISH_BEV && NumContents == 1) { - DishTheme = Nibble.getContentNibbleLevel2() & 0xF; - DishCategory = ((Nibble.getUserNibble1() & 0xF) << 4) | (Nibble.getUserNibble2() & 0xF); - //LogD(2, prep("EEPGDEBUG:DishTheme:%x-DishCategory:%x)"), DishTheme, DishCategory); + if (DishEventDescriptor && NumContents == 1) { + DishEventDescriptor->setContent(Nibble); } - //LogD(2, prep("EEPGDEBUG:Nibble:%x-%x-%x-%x)"), Nibble.getContentNibbleLevel1(),Nibble.getContentNibbleLevel2() - // , Nibble.getUserNibble1(), Nibble.getUserNibble2()); +// LogD(2, prep("EEPGDEBUG:Nibble:%x-%x-%x-%x)"), Nibble.getContentNibbleLevel1(),Nibble.getContentNibbleLevel2() +// , Nibble.getUserNibble1(), Nibble.getUserNibble2()); } pEvent->SetContents(Contents); @@ -3190,33 +3193,27 @@ cEIT2::cEIT2 (cSchedules * Schedules, int Source, u_char Tid, const u_char * Dat } break; case SI::DishExtendedEventDescriptorTag: { - SI::DishDescriptor *deed = new SI::DishDescriptor((SI::UnimplementedDescriptor *)d); - deed->Decompress(Tid); - if (!DishExtendedEventDescriptor) { - DishExtendedEventDescriptor = deed; - d = NULL; // so that it is not deleted + SI::UnimplementedDescriptor *deed = (SI::UnimplementedDescriptor *)d; + if (!DishEventDescriptor) { + DishEventDescriptor = new SI::DishDescriptor(); } + DishEventDescriptor->setExtendedtData(Tid, deed->getData()); HasExternalData = true; } break; case SI::DishShortEventDescriptorTag: { - SI::DishDescriptor *dsed = new SI::DishDescriptor((SI::UnimplementedDescriptor *)d); - dsed->Decompress(Tid); - if (!DishShortEventDescriptor) { - DishShortEventDescriptor = dsed; - d = NULL; // so that it is not deleted + SI::UnimplementedDescriptor *dsed = (SI::UnimplementedDescriptor *)d; + if (!DishEventDescriptor) { + DishEventDescriptor = new SI::DishDescriptor(); } + DishEventDescriptor->setShortData(Tid, dsed->getData()); HasExternalData = true; } break; case SI::DishRatingDescriptorTag: { - if (d->getLength() == 4) { + if (d->getLength() == 4 && DishEventDescriptor) { uint16_t rating = d->getData().TwoBytes(2); - uint16_t newRating = (rating >> 10) & 0x07; - if (newRating == 0) newRating = 5; - if (newRating == 6) newRating = 0; - pEvent->SetParentalRating((newRating << 10) | (rating & 0x3FF)); -// pEvent->SetStarRating((rating >> 13) & 0x07); + DishEventDescriptor->setRating(rating); } } break; @@ -3250,30 +3247,19 @@ cEIT2::cEIT2 (cSchedules * Schedules, int Source, u_char Tid, const u_char * Dat } else if (!HasExternalData) pEvent->SetDescription (NULL); - if (DishShortEventDescriptor) { - pEvent->SetTitle(DishShortEventDescriptor->getText()); - //LogD(2, prep("channelID: %s DishTitle: %s"), *channel->GetChannelID().ToString(), DishShortEventDescriptor->getText()); - } - if (DishExtendedEventDescriptor) { - pEvent->SetDescription(DishExtendedEventDescriptor->getText()); - char *tmp; - if (DishTheme >= 0) { - Asprintf (&tmp, "%s - %s ~ %s", DishExtendedEventDescriptor->getShortText() - , DishExtendedEventDescriptor->getTheme(DishTheme) - , DishExtendedEventDescriptor->getCategory(DishCategory)); - pEvent->SetShortText(tmp); - //LogD(2, prep("EEPGDEBUG:DishTheme:%x-DishCategory:%x)"), DishTheme, DishCategory); - free(tmp); - } else - pEvent->SetShortText(DishExtendedEventDescriptor->getShortText()); + if (DishEventDescriptor) { + pEvent->SetTitle(DishEventDescriptor->getName()); + pEvent->SetDescription(DishEventDescriptor->getDescription()); + pEvent->SetShortText(DishEventDescriptor->getShortText()); + //LogD(2, prep("channelID: %s DishTitle: %s"), *channel->GetChannelID().ToString(), DishEventDescriptor->getName()); //LogD(2, prep("DishDescription: %s"), DishExtendedEventDescriptor->getText()); //LogD(2, prep("DishShortText: %s"), DishExtendedEventDescriptor->getShortText()); } + } delete ExtendedEventDescriptors; delete ShortEventDescriptor; - delete DishExtendedEventDescriptor; - delete DishShortEventDescriptor; + delete DishEventDescriptor; pEvent->SetComponents (Components); @@ -3471,7 +3457,7 @@ void cFilterEEPG::ProcessNextFormat (bool FirstTime = false) AddFilter (pid, 0xb0); //perhaps TID is equal to first data byte? break; case DISH_BEV: - AddFilter (0x12, 0, 0); // event info, actual(0x4e)/other(0x4f) TS, present/following + AddFilter (EIT_PID, 0, 0); // event info, actual(0x4e)/other(0x4f) TS, present/following AddFilter (0x0300, 0, 0); // Dish Network EEPG event info, actual(0x4e)/other(0x4f) TS, present/following AddFilter (0x0441, 0, 0); // Dish Network EEPG event info, actual(0x4e)/other(0x4f) TS, present/following // AddFilter (0x0441, 0x50, 0xf0); // Bell ExpressVU EEPG @@ -3490,7 +3476,7 @@ void cFilterEEPG::ProccessContinuous(u_short Pid, u_char Tid, int Length, const cSchedules *Schedules = (cSchedules*)(cSchedules::Schedules(SchedulesLock)); //Look for other satelite positions only if Dish/Bell ExpressVU for the moment hardcoded pid check if(Schedules) - SI::cEIT2 EIT(Schedules, Source(), Tid, Data); + SI::cEIT2 EIT(Schedules, Source(), Tid, Data, Pid == EIT_PID); else//cEIT EIT (Schedules, Source (), Tid, Data); { @@ -3501,7 +3487,7 @@ void cFilterEEPG::ProccessContinuous(u_short Pid, u_char Tid, int Length, const cSchedulesLock SchedulesLock; cSchedules *Schedules = (cSchedules*)(cSchedules::Schedules(SchedulesLock)); if(Schedules) - SI::cEIT2 EIT(Schedules, Source(), Tid, Data, true); + SI::cEIT2 EIT(Schedules, Source(), Tid, Data, Pid == EIT_PID, true); //cEIT EIT (Schedules, Source (), Tid, Data, true); } @@ -3665,7 +3651,7 @@ void cFilterEEPG::Process (u_short Pid, u_char Tid, const u_char * Data, int Len } //if pmtpid else if (Source ()) { - if ( Pid == 0x12 || Pid == 0x0300 || Pid == 0x0441 ) { + if ( Pid == EIT_PID || Pid == 0x0300 || Pid == 0x0441 ) { if (Tid >= 0x4E) ProccessContinuous(Pid, Tid, Length, Data); return; -- cgit v1.2.3 From 3c9b4d23704e9460e7c3a0d5baa2c9d32feee116 Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Thu, 22 Sep 2011 18:38:52 +0200 Subject: fix compile --- dish.c | 7 ++++--- dish.h | 8 ++++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/dish.c b/dish.c index 7ea85b1..d24c32f 100644 --- a/dish.c +++ b/dish.c @@ -12,9 +12,10 @@ #include "dish.h" #include -#include +//#include #include #include +#include namespace SI { @@ -306,8 +307,8 @@ namespace SI const char *DishDescriptor::getDescription(void) { string tmp = ""; if (description != NULL) tmp += *description; - char* rating = getRating(); - if (rating && rating != "") { + const char* rating = getRating(); + if (rating && strcmp(rating,"") != 0) { if(tmp != "") tmp += "|"; tmp += rating; } diff --git a/dish.h b/dish.h index 7510c67..e6a5b9b 100644 --- a/dish.h +++ b/dish.h @@ -10,6 +10,10 @@ #ifndef LIBSI_DISH_H #define LIBSI_DISH_H +#include +#include +#include + namespace SI { @@ -267,8 +271,8 @@ protected: string *shortText; // usually the episode name string *description; // description of the event unsigned char *decompressed; - uchar DishTheme; - uchar DishCategory; + unsigned char DishTheme; + unsigned char DishCategory; uint16_t mpaaRating; uint16_t starRating; -- cgit v1.2.3 From d826a6882e10a69336aa6c751e6822eada604100 Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Thu, 22 Sep 2011 19:48:39 +0200 Subject: added missing setShortData --- dish.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/dish.c b/dish.c index d24c32f..74e53ff 100644 --- a/dish.c +++ b/dish.c @@ -266,6 +266,18 @@ namespace SI } } + void DishDescriptor::setShortData(unsigned char Tid, CharArray data) + { + Decompress(Tid, data); + if (decompressed) { + name = new string((char*)decompressed); + delete[] decompressed; + decompressed = NULL; + } else { + name = new string(); + } + } + void DishDescriptor::setExtendedtData(unsigned char Tid, CharArray data) { Decompress(Tid, data); -- cgit v1.2.3 From e228e74a720c8f0b7e48c0909a2a29ddc7620252 Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Sun, 2 Oct 2011 17:54:14 +0200 Subject: do not use member pointers --- dish.c | 47 +++++++++++++++++++++++++++-------------------- dish.h | 8 ++++---- 2 files changed, 31 insertions(+), 24 deletions(-) diff --git a/dish.c b/dish.c index 74e53ff..4919ad8 100644 --- a/dish.c +++ b/dish.c @@ -43,9 +43,9 @@ namespace SI DishDescriptor::DishDescriptor() { - name = NULL; - shortText = NULL; - description = NULL; + name = ""; + shortText = ""; + description = ""; decompressed = NULL; DishTheme = 0; DishCategory = 0; @@ -57,12 +57,12 @@ namespace SI { delete [] decompressed; decompressed = NULL; - delete name; - name = NULL; - delete shortText; - shortText = NULL; - delete description; - description = NULL; +// delete name; +// name = NULL; +// delete shortText; +// shortText = NULL; +// delete description; +// description = NULL; } const char *DishDescriptor::getTheme() @@ -270,11 +270,11 @@ namespace SI { Decompress(Tid, data); if (decompressed) { - name = new string((char*)decompressed); + name = string((char*)decompressed); delete[] decompressed; decompressed = NULL; } else { - name = new string(); +// name = new string(); } } @@ -286,23 +286,24 @@ namespace SI //LogD(2, prep("dLength:%d, length:%d, count:%d, decompressed: %s"), dLength, length, count, decompressed); if(split){ *split = 0; - shortText = new string((char*)decompressed); - description = new string((split[1] == 0x20) ? split + 2 : split + 1); + shortText = string((char*)decompressed); + description = string((split[1] == 0x20) ? split + 2 : split + 1); }else{ - description = new string((char*)decompressed); + description = string((char*)decompressed); } delete[] decompressed; decompressed = NULL; } else { - shortText = new string(); - description = new string(); +// shortText = new string(); +// description = new string(); } } const char *DishDescriptor::getShortText(void) { string tmp = ""; - if (shortText != NULL) tmp += *shortText; +// if (shortText != NULL) tmp += *shortText; + tmp += shortText; if(DishTheme > 0){ if(tmp != "") tmp += " - "; @@ -318,14 +319,15 @@ namespace SI const char *DishDescriptor::getDescription(void) { string tmp = ""; - if (description != NULL) tmp += *description; +// if (description != NULL) tmp += *description; + tmp += description; const char* rating = getRating(); if (rating && strcmp(rating,"") != 0) { - if(tmp != "") tmp += "|"; + if(tmp != "") tmp += " ~ "; tmp += rating; } if (starRating > 0) { - if(tmp != "") tmp += "|"; + if(tmp != "") tmp += " ~ "; tmp += getStarRating(); } return tmp.c_str(); @@ -348,6 +350,11 @@ namespace SI const char* DishDescriptor::getRating(){ static const char *const ratings[8] = { "", "G", "PG", "PG-13", "R", "NR/AO", "", "NC-17" }; + + if (mpaaRating == 0) { + return ratings[mpaaRating]; + } + char buffer[19]; buffer[0] = 0; strcpy(buffer, ratings[(mpaaRating >> 10) & 0x07]); diff --git a/dish.h b/dish.h index e6a5b9b..b4efe1c 100644 --- a/dish.h +++ b/dish.h @@ -249,7 +249,7 @@ class DishDescriptor { public: DishDescriptor(); virtual ~DishDescriptor(); - const char* getName(void) const { return name?name->c_str():""; } + const char* getName(void) const { return name.c_str(); } const char* getShortText(void); const char *getDescription(void); // const char* getShortText(void) const { return shortText?shortText->c_str():""; } @@ -267,9 +267,9 @@ public: protected: // Decompress the byte array and stores the result to a text string void Decompress(unsigned char Tid, CharArray data); - string *name; // name of the event - string *shortText; // usually the episode name - string *description; // description of the event + string name; // name of the event + string shortText; // usually the episode name + string description; // description of the event unsigned char *decompressed; unsigned char DishTheme; unsigned char DishCategory; -- cgit v1.2.3 From 45aa02d117af1e6f0b5584de8b06827c4b5fd301 Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Sun, 2 Oct 2011 20:06:49 +0200 Subject: enable EIT scan in eepg --- eepg.c | 11 +++++++++++ eepg.h | 5 +++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/eepg.c b/eepg.c index 478a9aa..e243287 100644 --- a/eepg.c +++ b/eepg.c @@ -3463,6 +3463,11 @@ void cFilterEEPG::ProcessNextFormat (bool FirstTime = false) // AddFilter (0x0441, 0x50, 0xf0); // Bell ExpressVU EEPG // AddFilter (0x0441, 0x60, 0xf0); // Bell ExpressVU EEPG break; + case EIT: + AddFilter (pid, 0x4e, 0xfe); //event info, actual(0x4e)/other(0x4f) TS, present/following + AddFilter (pid, 0x50, 0xf0); //event info, actual TS, schedule(0x50)/schedule for future days(0x5X) + AddFilter (pid, 0x60, 0xf0); //event info, other TS, schedule(0x60)/schedule for future days(0x6X) + break; default: break; } @@ -3631,6 +3636,12 @@ void cFilterEEPG::Process (u_short Pid, u_char Tid, const u_char * Data, int Len && !UnprocessedFormat[DISH_BEV]) { UnprocessedFormat[DISH_BEV] = stream.getPid (); } + + // Enable EIT scan for all except DISH_BEV since it is already enabled + // TODO add setup option + if (!UnprocessedFormat[DISH_BEV]) { + UnprocessedFormat[EIT] = EIT_PID; + } } //if data[1] && data [3] } //if streamtype /*if (Format != PREMIERE) //any format found diff --git a/eepg.h b/eepg.h index 503e800..d306ca0 100644 --- a/eepg.h +++ b/eepg.h @@ -30,14 +30,15 @@ enum EFormat { PREMIERE , FREEVIEW , DISH_BEV , + EIT , //the highest number of EPG-formats that is supported by this plugin - HIGHEST_FORMAT = DISH_BEV + HIGHEST_FORMAT = EIT } Format; #define NAGRA_TABLE_ID 0x55 //the lower the table Id, the more "current" it is; table_id 0x00 never gets overwritten, now/next are at 0x4e or 0x4f! #define DEFAULT_TABLE_ID 0x30 -const char *FormatName[]= {"MediaHighWay 1","MediaHighWay 2","Sky Italy","Sky UK","NagraGuide","Premiere","FreeView","Dish/Bev"}; +const char *FormatName[]= {"MediaHighWay 1","MediaHighWay 2","Sky Italy","Sky UK","NagraGuide","Premiere","FreeView","Dish/Bev","EIT"}; struct sNode { -- cgit v1.2.3 From c55aa9e24581640a036e19cf871c6075354928be Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Mon, 3 Oct 2011 13:57:03 +0200 Subject: added logging for EIT debug fixed table ID initialization --- eepg.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/eepg.c b/eepg.c index e243287..48519e7 100644 --- a/eepg.c +++ b/eepg.c @@ -2151,6 +2151,7 @@ int cFilterEEPG::GetTitlesMHW2 (const u_char * Data, int Length) CleanString (T->Text); Pos += Len + 8; // Sub Theme starts here T->ThemeId = ((Data[7] & 0x3f) << 6) | (Data[Pos] & 0x3f); + T->TableId = DEFAULT_TABLE_ID; //TODO locate the actual table id T->EventId = (Data[Pos + 1] << 8) | Data[Pos + 2]; T->SummaryAvailable = (T->EventId != 0xFFFF); LogI(3, prep("EventId %04x Titlenr %d:SummAv:%x,Name:%s."), T->EventId, @@ -2476,6 +2477,7 @@ int cFilterEEPG::GetTitlesSKYBOX (const u_char * Data, int Length) T->StartTime = ((MjdTime - 40587) * 86400) + ((Data[p + 2] << 9) | (Data[p + 3] << 1)); T->Duration = ((Data[p + 4] << 9) | (Data[p + 5] << 1)); T->ThemeId = Data[p + 6]; + T->TableId = DEFAULT_TABLE_ID; //TODO locate the actual table id //TODO Data[p + 7] is Quality value add it to description //int quality = Data[p + 7]; switch (Data[p + 8] & 0x0F) { @@ -2846,7 +2848,7 @@ cEIT2::cEIT2 (cSchedules * Schedules, int Source, u_char Tid, const u_char * Dat return; // only collect data for known channels } - //LogD(4, prep("channelID: %s format:%d"), *channel->GetChannelID().ToString(), Format); + //LogD(5, prep("channelID: %s format:%d"), *channel->GetChannelID().ToString(), Format); #ifdef USE_NOEPG // only use epg from channels not blocked by noEPG-patch @@ -2891,6 +2893,7 @@ cEIT2::cEIT2 (cSchedules * Schedules, int Source, u_char Tid, const u_char * Dat if (!pEvent) continue; } else { + //LogD(3, prep("existing event channelID: %s Title: %s TableID 0x%02X new TID 0x%02X Version %i, new version %i"), *channel->GetChannelID().ToString(), pEvent->Title(), pEvent->TableID(), Tid, pEvent->Version(), versionNumber); // We have found an existing event, either through its event ID or its start time. pEvent->SetSeen (); // If the existing event has a zero table ID it was defined externally and shall @@ -3025,7 +3028,7 @@ cEIT2::cEIT2 (cSchedules * Schedules, int Source, u_char Tid, const u_char * Dat continue; } - //LogD(2, prep("EEPGDEBUG:d->getDescriptorTAG():%x)"), d->getDescriptorTag ()); + LogD(2, prep("EEPGDEBUG:d->getDescriptorTAG():%x)"), d->getDescriptorTag ()); switch (d->getDescriptorTag ()) { case SI::ExtendedEventDescriptorTag: { @@ -3232,18 +3235,22 @@ cEIT2::cEIT2 (cSchedules * Schedules, int Source, u_char Tid, const u_char * Dat decodeText2 (f, l, buffer, sizeof (buffer)); //ShortEventDescriptor->name.getText(buffer, sizeof(buffer)); pEvent->SetTitle (buffer); + LogD(3, prep("channelID: %s Title: %s"), *channel->GetChannelID().ToString(), pEvent->Title()); l = ShortEventDescriptor->text.getLength(); f = (unsigned char *) ShortEventDescriptor->text.getData().getData(); decodeText2 (f, l, buffer, sizeof (buffer)); //ShortEventDescriptor->text.getText(buffer, sizeof(buffer)); pEvent->SetShortText (buffer); + LogD(3, prep("ShortText: %s"), pEvent->ShortText()); } else if (!HasExternalData) { pEvent->SetTitle (NULL); pEvent->SetShortText (NULL); + LogD(3, prep("SetTitle (NULL)")); } if (ExtendedEventDescriptors) { char buffer[Utf8BufSize (ExtendedEventDescriptors->getMaximumTextLength (": ")) + 1]; pEvent->SetDescription (ExtendedEventDescriptors->getText (buffer, sizeof (buffer), ": ")); + LogD(3, prep("Description: %s"), pEvent->Description()); } else if (!HasExternalData) pEvent->SetDescription (NULL); -- cgit v1.2.3 From 0bbc1965541f357ab6470010d63d7c42e096fafd Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Mon, 3 Oct 2011 14:11:30 +0200 Subject: fix table ID initialization --- eepg.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/eepg.c b/eepg.c index e243287..354471c 100644 --- a/eepg.c +++ b/eepg.c @@ -2151,6 +2151,7 @@ int cFilterEEPG::GetTitlesMHW2 (const u_char * Data, int Length) CleanString (T->Text); Pos += Len + 8; // Sub Theme starts here T->ThemeId = ((Data[7] & 0x3f) << 6) | (Data[Pos] & 0x3f); + T->TableId = DEFAULT_TABLE_ID; //TODO locate the actual table id T->EventId = (Data[Pos + 1] << 8) | Data[Pos + 2]; T->SummaryAvailable = (T->EventId != 0xFFFF); LogI(3, prep("EventId %04x Titlenr %d:SummAv:%x,Name:%s."), T->EventId, @@ -2476,6 +2477,7 @@ int cFilterEEPG::GetTitlesSKYBOX (const u_char * Data, int Length) T->StartTime = ((MjdTime - 40587) * 86400) + ((Data[p + 2] << 9) | (Data[p + 3] << 1)); T->Duration = ((Data[p + 4] << 9) | (Data[p + 5] << 1)); T->ThemeId = Data[p + 6]; + T->TableId = DEFAULT_TABLE_ID; //TODO locate the actual table id //TODO Data[p + 7] is Quality value add it to description //int quality = Data[p + 7]; switch (Data[p + 8] & 0x0F) { @@ -2974,7 +2976,8 @@ cEIT2::cEIT2 (cSchedules * Schedules, int Source, u_char Tid, const u_char * Dat } // If the new event has a higher table ID, let's skip it. // The lower the table ID, the more "current" the information. - else if (Tid > pEvent->TableID ()) + // if the Table ID is DEFAULT_TABLE_ID it is most probably EEPG event so we can overwrite + else if (Tid > pEvent->TableID() && pEvent->TableID () != DEFAULT_TABLE_ID) continue; // If the new event comes from the same table and has the same version number // as the existing one, let's skip it to avoid unnecessary work. -- cgit v1.2.3 From f30f80745607fe4573d8bcba3f643e8eb5ca72ac Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Mon, 3 Oct 2011 15:02:19 +0200 Subject: add process eit setup option for the moment in debug only --- eepg.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/eepg.c b/eepg.c index 2b6c702..1232119 100644 --- a/eepg.c +++ b/eepg.c @@ -110,6 +110,7 @@ public: int RatingInfo; int FixEpg; int DisplayMessage; + int ProcessEIT; #ifdef DEBUG int LogLevel; #endif @@ -127,6 +128,7 @@ cSetupEEPG::cSetupEEPG (void) RatingInfo = 1; FixEpg = 0; DisplayMessage = 1; + ProcessEIT = 0; #ifdef DEBUG LogLevel = 0; #endif @@ -163,6 +165,7 @@ cMenuSetupPremiereEpg::cMenuSetupPremiereEpg (void) Add (new cMenuEditBoolItem (tr ("Display summary message"), &data.DisplayMessage)); #ifdef DEBUG Add (new cMenuEditIntItem (tr ("Level of logging verbosity"), &data.LogLevel, 0, 5)); + Add (new cMenuEditBoolItem (tr ("Process EIT info with EEPG"), &data.ProcessEIT)); #endif } @@ -176,6 +179,7 @@ void cMenuSetupPremiereEpg::Store (void) SetupStore ("DisplayMessage", SetupPE.DisplayMessage); #ifdef DEBUG SetupStore ("LogLevel", SetupPE.LogLevel); + SetupStore ("ProcessEIT", SetupPE.ProcessEIT); #endif } @@ -2879,7 +2883,7 @@ cEIT2::cEIT2 (cSchedules * Schedules, int Source, u_char Tid, const u_char * Dat int versionNumber = getVersionNumber(); // increase version number for DISH_BEV EIT so it does not get overwriten by VDR. // TODO check the same for other providers. - if (Format == DISH_BEV && isEITPid) versionNumber++; + if ((Format == DISH_BEV || SetupPE.ProcessEIT )&& isEITPid) versionNumber++; cEvent *newEvent = NULL; cEvent *rEvent = NULL; @@ -2978,7 +2982,7 @@ cEIT2::cEIT2 (cSchedules * Schedules, int Source, u_char Tid, const u_char * Dat // If the new event has a higher table ID, let's skip it. // The lower the table ID, the more "current" the information. // if the Table ID is DEFAULT_TABLE_ID it is most probably EEPG event so we can overwrite - else if (Tid > pEvent->TableID() && pEvent->TableID () != DEFAULT_TABLE_ID) + else if (Tid > pEvent->TableID() && (SetupPE.ProcessEIT ? pEvent->TableID () != DEFAULT_TABLE_ID : true)) continue; // If the new event comes from the same table and has the same version number // as the existing one, let's skip it to avoid unnecessary work. @@ -3646,8 +3650,7 @@ void cFilterEEPG::Process (u_short Pid, u_char Tid, const u_char * Data, int Len } // Enable EIT scan for all except DISH_BEV since it is already enabled - // TODO add setup option - if (!UnprocessedFormat[DISH_BEV]) { + if (SetupPE.ProcessEIT && !UnprocessedFormat[DISH_BEV]) { UnprocessedFormat[EIT] = EIT_PID; } } //if data[1] && data [3] @@ -4328,6 +4331,8 @@ bool cPluginEEPG::SetupParse (const char *Name, const char *Value) #ifdef DEBUG else if (!strcasecmp (Name, "LogLevel")) SetupPE.LogLevel = atoi (Value); + else if (!strcasecmp (Name, "ProcessEIT")) + SetupPE.ProcessEIT = atoi (Value); #endif else return false; -- cgit v1.2.3 From b4da1b8b6dfec941cb97cc14c7fc14040a7695ff Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Thu, 13 Oct 2011 19:58:23 +0200 Subject: NA tests, not working --- dish.c | 27 ++++++++++++++++++--------- eepg.c | 4 +++- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/dish.c b/dish.c index 4919ad8..7dd8c37 100644 --- a/dish.c +++ b/dish.c @@ -270,7 +270,7 @@ namespace SI { Decompress(Tid, data); if (decompressed) { - name = string((char*)decompressed); + name = string(reinterpret_cast(decompressed)); delete[] decompressed; decompressed = NULL; } else { @@ -282,14 +282,15 @@ namespace SI { Decompress(Tid, data); if (decompressed) { - char *split = strchr((char*)((decompressed)), 0x0D); // Look for carriage return + string str; + char *split = strchr(reinterpret_cast(decompressed), 0x0D); // Look for carriage return //LogD(2, prep("dLength:%d, length:%d, count:%d, decompressed: %s"), dLength, length, count, decompressed); if(split){ *split = 0; - shortText = string((char*)decompressed); + shortText = string(reinterpret_cast(decompressed)); description = string((split[1] == 0x20) ? split + 2 : split + 1); }else{ - description = string((char*)decompressed); + description = string(reinterpret_cast(decompressed)); } delete[] decompressed; decompressed = NULL; @@ -301,35 +302,43 @@ namespace SI const char *DishDescriptor::getShortText(void) { - string tmp = ""; + isyslog("EEPG DISH: shortText: %s", shortText.c_str()); + string tmp = shortText; // if (shortText != NULL) tmp += *shortText; - tmp += shortText; + //if (shortText != NULL) tmp.append(shortText); if(DishTheme > 0){ if(tmp != "") tmp += " - "; - tmp += getTheme(); + tmp.append(getTheme()); + isyslog("EEPG DISH: theme: %s", getTheme()); } if(DishCategory > 0){ if(tmp != "") tmp += " - "; - tmp += getCategory(); + isyslog("EEPG DISH: category: %s", getCategory()); + tmp.append(getCategory()); } + isyslog("EEPG DISH: full shorttext: %s", tmp.c_str()); return tmp.c_str(); } const char *DishDescriptor::getDescription(void) { - string tmp = ""; + string tmp = description; // if (description != NULL) tmp += *description; tmp += description; + isyslog("EEPG DISH: description: %s", description.c_str()); const char* rating = getRating(); if (rating && strcmp(rating,"") != 0) { if(tmp != "") tmp += " ~ "; tmp += rating; + isyslog("EEPG DISH: rating: %s", rating); } if (starRating > 0) { if(tmp != "") tmp += " ~ "; tmp += getStarRating(); + isyslog("EEPG DISH: star: %s", getStarRating()); } + isyslog("EEPG DISH: full description: %s", tmp.c_str()); return tmp.c_str(); } diff --git a/eepg.c b/eepg.c index 1232119..63394d0 100644 --- a/eepg.c +++ b/eepg.c @@ -3256,8 +3256,10 @@ cEIT2::cEIT2 (cSchedules * Schedules, int Source, u_char Tid, const u_char * Dat char buffer[Utf8BufSize (ExtendedEventDescriptors->getMaximumTextLength (": ")) + 1]; pEvent->SetDescription (ExtendedEventDescriptors->getText (buffer, sizeof (buffer), ": ")); LogD(3, prep("Description: %s"), pEvent->Description()); - } else if (!HasExternalData) + } else if (!HasExternalData) { pEvent->SetDescription (NULL); + LogD(3, prep("SetDescription (NULL)")); + } if (DishEventDescriptor) { pEvent->SetTitle(DishEventDescriptor->getName()); -- cgit v1.2.3