summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dish.c273
-rw-r--r--dish.h27
-rw-r--r--eepg.c99
3 files changed, 254 insertions, 145 deletions
diff --git a/dish.c b/dish.c
index 7dd8c37..662e170 100644
--- a/dish.c
+++ b/dish.c
@@ -14,6 +14,7 @@
#include <libsi/si.h>
//#include <libsi/descriptor.h>
#include <string.h>
+#include <string>
#include <stdlib.h>
#include <vdr/tools.h>
@@ -43,63 +44,67 @@ namespace SI
DishDescriptor::DishDescriptor()
{
- name = "";
- shortText = "";
- description = "";
- decompressed = NULL;
+ name = NULL;
+ shortText = NULL;
+ description = NULL;
+ decompressedShort = NULL;
+ decompressedExtended = NULL;
DishTheme = 0;
DishCategory = 0;
mpaaRating = 0;
starRating = 0;
+ originalAirDate = 0;
+ programId = NULL;
+ seriesId = NULL;
}
DishDescriptor::~DishDescriptor()
{
- delete [] decompressed;
- decompressed = NULL;
-// delete name;
-// name = NULL;
-// delete shortText;
-// shortText = NULL;
-// delete description;
-// description = NULL;
+ delete [] decompressedShort;
+ decompressedShort = NULL;
+ delete [] decompressedExtended;
+ decompressedExtended = NULL;
+ delete [] programId;
+ programId = NULL;
+ delete [] seriesId;
+ seriesId = NULL;
}
const char *DishDescriptor::getTheme()
{
- const char *theme;
- using namespace DISH_THEMES;
+ const char* theme;
+ using namespace DISH_THEMES;
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;
+ 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()
@@ -268,78 +273,100 @@ namespace SI
void DishDescriptor::setShortData(unsigned char Tid, CharArray data)
{
- Decompress(Tid, data);
- if (decompressed) {
- name = string(reinterpret_cast<char*>(decompressed));
- delete[] decompressed;
- decompressed = NULL;
- } else {
-// name = new string();
+ decompressedShort = Decompress(Tid, data);
+ if (decompressedShort) {
+ name = (char*)decompressedShort;
}
}
void DishDescriptor::setExtendedtData(unsigned char Tid, CharArray data)
{
- Decompress(Tid, data);
- if (decompressed) {
- string str;
- char *split = strchr(reinterpret_cast<char*>(decompressed), 0x0D); // Look for carriage return
+ decompressedExtended = Decompress(Tid, data);
+ if (decompressedExtended) {
+ char *split = strchr((char*)((decompressedExtended)), 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(reinterpret_cast<char*>(decompressed));
- description = string((split[1] == 0x20) ? split + 2 : split + 1);
+ shortText = (char*)decompressedExtended;
+ description = (split[1] == 0x20) ? split + 2 : split + 1;
}else{
- description = string(reinterpret_cast<char*>(decompressed));
+ description = (char*)decompressedExtended;
}
- delete[] decompressed;
- decompressed = NULL;
- } else {
-// shortText = new string();
-// description = new string();
}
}
const char *DishDescriptor::getShortText(void)
{
- isyslog("EEPG DISH: shortText: %s", shortText.c_str());
- string tmp = shortText;
-// if (shortText != NULL) tmp += *shortText;
- //if (shortText != NULL) tmp.append(shortText);
- if(DishTheme > 0){
- if(tmp != "") tmp += " - ";
-
- tmp.append(getTheme());
- isyslog("EEPG DISH: theme: %s", getTheme());
- }
- if(DishCategory > 0){
- if(tmp != "") tmp += " - ";
-
- isyslog("EEPG DISH: category: %s", getCategory());
- tmp.append(getCategory());
- }
- isyslog("EEPG DISH: full shorttext: %s", tmp.c_str());
- return tmp.c_str();
+// string tmp = "";
+//// if (shortText != NULL) tmp += *shortText;
+// tmp += shortText;
+// if(DishTheme > 0){
+// if(tmp != "") tmp += " - ";
+//
+// tmp += getTheme();
+// }
+// if(DishCategory > 0){
+// if(tmp != "") tmp += " - ";
+//
+// tmp += getCategory();
+// }
+// return tmp.c_str();
+ return shortText?shortText:"";
}
const char *DishDescriptor::getDescription(void) {
- 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);
+// string tmp = "";
+//// if (description != NULL) tmp += *description;
+// tmp += description;
+// const char* rating = getRating();
+// if (rating && strcmp(rating,"") != 0) {
+// if(tmp != "") tmp += " ~ ";
+// tmp += rating;
+// }
+// if (starRating > 0) {
+// if(tmp != "") tmp += " ~ ";
+// tmp += getStarRating();
+// }
+// return tmp.c_str();
+ return description?description:"";
+ }
+
+ const char *DishDescriptor::getProgramId(void) {
+ return programId?programId:"";
+ }
+
+ const char *DishDescriptor::getSeriesId(void) {
+ return seriesId?seriesId:"";
+ }
+
+ void DishDescriptor::setEpisodeInfo(CharArray data)
+ {
+ data.addOffset(2);
+ int series = (data[1] << 0x12) | (data[2] << 0x0a) | (data[3] << 0x02) | ((data[4] & 0xc0) >> 0x06);
+ int episode = ((data[4] & 0x3f) << 0x08) | data[5];
+ const char* prefix;
+
+ if (data[0] == 0x7c)
+ prefix = "MV";
+ else if (data[0] == 0x7d)
+ prefix = "SP";
+ else if (data[0] == 0x7e)
+ prefix = "EP";
+ else
+ prefix ="";
+
+ programId = new char[17];
+
+ sprintf(programId, "%s%08d%04d", (data[0] == 0x7e && episode == 0 ? "SH" : prefix), series, episode);
+
+ if (data[0] == 0x7e) {
+ seriesId = new char[11];
+ sprintf(seriesId, "%s%08d", prefix, series);
}
- if (starRating > 0) {
- if(tmp != "") tmp += " ~ ";
- tmp += getStarRating();
- isyslog("EEPG DISH: star: %s", getStarRating());
+
+ if (data.TwoBytes(6) != 0 && data.TwoBytes(6) != 0x9e8b ) {
+ originalAirDate = ((data[6] << 0x08 | data[7]) - 40587) * 86400;
}
- isyslog("EEPG DISH: full description: %s", tmp.c_str());
- return tmp.c_str();
}
void DishDescriptor::setContent(ContentDescriptor::Nibble Nibble)
@@ -364,24 +391,36 @@ namespace SI
return ratings[mpaaRating];
}
- char buffer[19];
- buffer[0] = 0;
- strcpy(buffer, ratings[(mpaaRating >> 10) & 0x07]);
+ std::string str = ratings[(mpaaRating >> 10) & 0x07];
+// char buffer[19];
+// buffer[0] = 0;
+// strcpy(buffer, ratings[(mpaaRating >> 10) & 0x07]);
if (mpaaRating & 0x3A7F) {
- strcat(buffer, " [");
+ str += " [";
+// strcat(buffer, " [");
if (mpaaRating & 0x0230)
- strcat(buffer, "V,");
+ str += "V,";
+// strcat(buffer, "V,");
if (mpaaRating & 0x000A)
- strcat(buffer, "L,");
+ str += "L,";
+// strcat(buffer, "L,");
if (mpaaRating & 0x0044)
- strcat(buffer, "N,");
+ str += "N,";
+// strcat(buffer, "N,");
if (mpaaRating & 0x0101)
- strcat(buffer, "SC,");
- if (char *s = strrchr(buffer, ','))
- s[0] = ']';
+ str += "SC,";
+// strcat(buffer, "SC,");
+// if (char *s = strrchr(buffer, ','))
+// s[0] = ']';
+ if (str.find(',') != std::string::npos) {
+ str.erase(str.find_last_of(','));
}
+ str += "]";
+ }
+
+ return str.c_str();
- return isempty(buffer) ? NULL : buffer;
+// return isempty(buffer) ? "" : buffer;
}
const char* DishDescriptor::getStarRating(){
@@ -389,8 +428,7 @@ namespace SI
return critiques[starRating & 0x07];
}
-
- void DishDescriptor::Decompress(unsigned char Tid, CharArray data)
+ unsigned char* DishDescriptor::Decompress(unsigned char Tid, CharArray data)
{
const unsigned char *str = data.getData();
const unsigned char *cmp = NULL;
@@ -406,20 +444,20 @@ namespace SI
cmp = str + 3;
}
if(length <= 0 || !dLength)
- return;
+ return NULL;
- decompressed = new unsigned char[dLength + 1];
+ unsigned char* decompressed = new unsigned char[dLength + 1];
HuffmanTable *table;
unsigned int tableSize, numBits;
if (Tid > 0x80) {
- table = Table255;
- tableSize = SIZE_TABLE_255;
- numBits = 13;
+ table = Table255;
+ tableSize = SIZE_TABLE_255;
+ numBits = 13;
} else {
- table = Table128;
- tableSize = SIZE_TABLE_128;
- numBits = 11;
- }
+ 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){
@@ -438,6 +476,7 @@ namespace SI
}
decompressed[count] = 0;
+ return decompressed;
}
struct DishDescriptor::HuffmanTable DishDescriptor::Table128[SIZE_TABLE_128] = {
diff --git a/dish.h b/dish.h
index b4efe1c..369a4fd 100644
--- a/dish.h
+++ b/dish.h
@@ -10,9 +10,9 @@
#ifndef LIBSI_DISH_H
#define LIBSI_DISH_H
-#include <string>
#include <libsi/util.h>
#include <libsi/descriptor.h>
+#include <time.h>
namespace SI
{
@@ -249,7 +249,7 @@ class DishDescriptor {
public:
DishDescriptor();
virtual ~DishDescriptor();
- const char* getName(void) const { return name.c_str(); }
+ const char* getName(void) const { return name; }
const char* getShortText(void);
const char *getDescription(void);
// const char* getShortText(void) const { return shortText?shortText->c_str():""; }
@@ -258,23 +258,32 @@ public:
const char *getCategory();
const char *getRating();
const char *getStarRating();
+ const char *getSeriesId();
+ const char *getProgramId();
+ time_t getOriginalAirDate() { return originalAirDate; }
+ bool hasTheme() {return DishTheme > 0;}
+ bool hasCategory() {return DishCategory > 0;}
void setShortData(unsigned char Tid, CharArray data);
void setExtendedtData(unsigned char Tid, CharArray data);
void setRating(uint16_t value);
void setContent(ContentDescriptor::Nibble Nibble);
-
+ void setEpisodeInfo(CharArray data);
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;
+ unsigned char* Decompress(unsigned char Tid, CharArray data);
+ const char* name; // name of the event
+ const char* shortText; // usually the episode name
+ const char* description; // description of the event
+ unsigned char* decompressedShort;
+ unsigned char* decompressedExtended;
unsigned char DishTheme;
unsigned char DishCategory;
uint16_t mpaaRating;
- uint16_t starRating;
+ uint8_t starRating;
+ time_t originalAirDate;
+ char* seriesId;
+ char* programId;
struct HuffmanTable
{
diff --git a/eepg.c b/eepg.c
index 63394d0..15e1329 100644
--- a/eepg.c
+++ b/eepg.c
@@ -2821,7 +2821,9 @@ namespace SI
enum DescriptorTagExt {
DishRatingDescriptorTag = 0x89,
DishShortEventDescriptorTag = 0x91,
- DishExtendedEventDescriptorTag = 0x92 };
+ DishExtendedEventDescriptorTag = 0x92,
+ DishSeriesDescriptorTag = 0x96,
+ };
// typedef InheritEnum< DescriptorTagExt, SI::DescriptorTag > ExtendedDescriptorTag;
@@ -2838,6 +2840,8 @@ cEIT2::cEIT2 (cSchedules * Schedules, int Source, u_char Tid, const u_char * Dat
: SI::EIT (Data, false)
{
//LogD(2, prep("cEIT2::cEIT2"));
+ if (Tid > 0 && (Format == DISH_BEV || (SetupPE.ProcessEIT && isEITPid))) Tid--;
+
if (!CheckCRCAndParse ()) {
LogD(2, prep("!CheckCRCAndParse ()"));
return;
@@ -2881,9 +2885,6 @@ cEIT2::cEIT2 (cSchedules * Schedules, int Source, u_char Tid, const u_char * Dat
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 || SetupPE.ProcessEIT )&& isEITPid) versionNumber++;
cEvent *newEvent = NULL;
cEvent *rEvent = NULL;
@@ -2981,8 +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() && (SetupPE.ProcessEIT ? pEvent->TableID () != DEFAULT_TABLE_ID : true))
+ else if (Tid > pEvent->TableID())
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.
@@ -3033,7 +3033,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: {
@@ -3205,7 +3205,7 @@ cEIT2::cEIT2 (cSchedules * Schedules, int Source, u_char Tid, const u_char * Dat
if (!DishEventDescriptor) {
DishEventDescriptor = new SI::DishDescriptor();
}
- DishEventDescriptor->setExtendedtData(Tid, deed->getData());
+ DishEventDescriptor->setExtendedtData(Tid+1, deed->getData());
HasExternalData = true;
}
break;
@@ -3214,15 +3214,31 @@ cEIT2::cEIT2 (cSchedules * Schedules, int Source, u_char Tid, const u_char * Dat
if (!DishEventDescriptor) {
DishEventDescriptor = new SI::DishDescriptor();
}
- DishEventDescriptor->setShortData(Tid, dsed->getData());
+ DishEventDescriptor->setShortData(Tid+1, dsed->getData());
HasExternalData = true;
}
break;
case SI::DishRatingDescriptorTag: {
- if (d->getLength() == 4 && DishEventDescriptor) {
- uint16_t rating = d->getData().TwoBytes(2);
- DishEventDescriptor->setRating(rating);
- }
+ if (d->getLength() == 4) {
+ if (!DishEventDescriptor) {
+ DishEventDescriptor = new SI::DishDescriptor();
+ }
+ uint16_t rating = d->getData().TwoBytes(2);
+ DishEventDescriptor->setRating(rating);
+ }
+ }
+ break;
+ case SI::DishSeriesDescriptorTag: {
+ if (d->getLength() == 10) {
+ //LogD(2, prep("DishSeriesDescriptorTag: %s)"), (const char*) d->getData().getData());
+ if (!DishEventDescriptor) {
+ DishEventDescriptor = new SI::DishDescriptor();
+ }
+ DishEventDescriptor->setEpisodeInfo(d->getData());
+ }
+// else {
+// LogD(2, prep("DishSeriesDescriptorTag length: %d)"), d->getLength());
+// }
}
break;
default:
@@ -3258,14 +3274,59 @@ cEIT2::cEIT2 (cSchedules * Schedules, int Source, u_char Tid, const u_char * Dat
LogD(3, prep("Description: %s"), pEvent->Description());
} else if (!HasExternalData) {
pEvent->SetDescription (NULL);
- LogD(3, prep("SetDescription (NULL)"));
- }
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());
+ if (DishEventDescriptor->getName())
+ pEvent->SetTitle(DishEventDescriptor->getName());
+ //LogD(2, prep("channelID: %s DishTitle: %s"), *channel->GetChannelID().ToString(), DishShortEventDescriptor->getText());
+// pEvent->SetDescription(DishExtendedEventDescriptor->getText());
+ char *tmp;
+ string fmt;
+ fmt = "%s";
+ if (0 != strcmp(DishEventDescriptor->getShortText(),"") && DishEventDescriptor->hasTheme()) {
+ fmt += " - ";
+ }
+ fmt += "%s";
+ if (DishEventDescriptor->hasTheme() && DishEventDescriptor->hasCategory()) {
+ fmt += " ~ ";
+ }
+ fmt += "%s";
+
+ Asprintf (&tmp, fmt.c_str(), DishEventDescriptor->getShortText()
+ , DishEventDescriptor->getTheme()
+ , DishEventDescriptor->getCategory());
+ pEvent->SetShortText(tmp);
+ //LogD(2, prep("EEPGDEBUG:DishTheme:%x-DishCategory:%x)"), DishTheme, DishCategory);
+ free(tmp);
+
+ fmt = "%s";
+ if (0 != strcmp(DishEventDescriptor->getDescription(),"")
+ && (0 != strcmp(DishEventDescriptor->getRating(),"")
+ || 0 != strcmp(DishEventDescriptor->getStarRating(),""))) {
+ fmt += "\n\nRating: ";
+ }
+ fmt += "%s %s";
+ if (0 != strcmp(DishEventDescriptor->getProgramId(),"")) {
+ fmt += "\n\nProgram ID: ";
+ }
+ fmt += "%s %s%s";
+ time_t orgAirDate = DishEventDescriptor->getOriginalAirDate();
+ char datestr [80];
+ bool dateok = false;
+ if (orgAirDate == 0) {
+ dateok = strftime (datestr,80," Original Air Date: %a %b %d %Y",gmtime(&orgAirDate)) > 0;
+ }
+
+ Asprintf (&tmp, fmt.c_str(), DishEventDescriptor->getDescription()
+ , DishEventDescriptor->getRating()
+ , DishEventDescriptor->getStarRating()
+ , DishEventDescriptor->getProgramId()
+ , DishEventDescriptor->getSeriesId()
+ , orgAirDate == 0 || !dateok ? "" : datestr);
+ pEvent->SetDescription(tmp);
+ free(tmp);
+
+
//LogD(2, prep("DishDescription: %s"), DishExtendedEventDescriptor->getText());
//LogD(2, prep("DishShortText: %s"), DishExtendedEventDescriptor->getShortText());
}