diff options
Diffstat (limited to 'util.c')
-rw-r--r-- | util.c | 169 |
1 files changed, 161 insertions, 8 deletions
@@ -5,6 +5,8 @@ * Author: d.petrovski */ #include "util.h" +#include "log.h" +#include "equivhandler.h" #include <vdr/channels.h> #include <vdr/thread.h> #include <vdr/epg.h> @@ -21,6 +23,12 @@ int Yesterday; int YesterdayEpoch; int YesterdayEpochUTC; +struct hufftab *tables[2][128]; +int table_size[2][128]; + +EFormat Format; +cEquivHandler* EquivHandler; + cChannel *GetChannelByID(tChannelID & channelID, bool searchOtherPos) { cChannel *VC = Channels.GetByChannelID(channelID, true); @@ -155,7 +163,7 @@ class cAddEventThread : public cThread private: cTimeMs LastHandleEvent; // cList<cAddEventListItem> *list; - std::map<tChannelID,cList<cEvent *>*,tChannelIDCompare> *map_list; + std::map<tChannelID,cList<cEvent>*,tChannelIDCompare> *map_list; enum { INSERT_TIMEOUT_IN_MS = 10000 }; protected: virtual void Action(void); @@ -169,14 +177,14 @@ cAddEventThread::cAddEventThread(void) :cThread("cAddEventThread"), LastHandleEvent() { // list = new cList<cAddEventListItem>; - map_list = new std::map<tChannelID,cList<cEvent *>*,tChannelIDCompare>; + map_list = new std::map<tChannelID,cList<cEvent>*,tChannelIDCompare>; } cAddEventThread::~cAddEventThread(void) { LOCK_THREAD; // list->cList::Clear(); - std::map<tChannelID,cList<cEvent *>*,tChannelIDCompare>::iterator it; + std::map<tChannelID,cList<cEvent>*,tChannelIDCompare>::iterator it; for ( it=map_list->begin() ; it != map_list->end(); it++ ) (*it).second->cList::Clear(); Cancel(3); @@ -197,21 +205,28 @@ void cAddEventThread::Action(void) // EpgHandlers.DropOutdated(schedule, e->GetEvent()->StartTime(), e->GetEvent()->EndTime(), e->GetEvent()->TableID(), e->GetEvent()->Version()); // list->Del(e); // } - std::map<tChannelID,cList<cEvent *>*,tChannelIDCompare>::iterator it; + std::map<tChannelID,cList<cEvent>*,tChannelIDCompare>::iterator it; it=map_list->begin(); while (schedules && it != map_list->end()) { cSchedule *schedule = (cSchedule *)schedules->GetSchedule(Channels.GetByChannelID((*it).first), true); while (((*it).second->First()) != NULL) { - cEvent* event = *(*it).second->First(); + cEvent* event = (*it).second->First(); cEvent *pEqvEvent = (cEvent *) schedule->GetEvent (event->EventID(), event->StartTime()); - if (pEqvEvent) + if (pEqvEvent){ + LogD (0, prep("schedule->DelEvent(event)")); schedule->DelEvent(pEqvEvent); + } - schedule->AddEvent(event); + LogD (0, prep("schedule->AddEvent(event)")); + //cCondWait::SleepMs(10); + if (event) + schedule->AddEvent(event); (*it).second->Del(event); } EpgHandlers.SortSchedule(schedule); + //sortSchedules(schedules, (*it).first); + //schedule->Sort(); delete (*it).second; map_list->erase(it); it=map_list->begin(); @@ -224,16 +239,21 @@ void cAddEventThread::Action(void) void cAddEventThread::AddEvent(cEvent *Event, tChannelID ChannelID) { + LogD (0, prep("AddEventT start")); LOCK_THREAD; + LogD (0, prep("AddEventT lock ")); if (map_list->empty() || map_list->count(ChannelID) == 0) { - cList<cEvent *>* list = new cList<cEvent *>; + LogD (0, prep("AddEventT if")); + cList<cEvent>* list = new cList<cEvent>; list->Add(Event); map_list->insert(std::make_pair(ChannelID, list)); } else { + LogD (0, prep("AddEventT else")); (*map_list->find(ChannelID)).second->Add(Event); } // list->Add(new cAddEventListItem(Event, ChannelID)); LastHandleEvent.Set(INSERT_TIMEOUT_IN_MS); + LogD (0, prep("AddEventT end")); } static cAddEventThread AddEventThread; @@ -242,11 +262,144 @@ static cAddEventThread AddEventThread; void AddEvent(cEvent *Event, tChannelID ChannelID) { + LogD (0, prep("AddEvent")); AddEventThread.AddEvent(Event, ChannelID); if (!AddEventThread.Active()) AddEventThread.Start(); } +/** \brief Decode an EPG string as necessary + * + * \param src - Possibly encoded string + * \param size - Size of the buffer + * + * \retval NULL - Can't decode + * \return A decoded string + */ +char *freesat_huffman_decode (const unsigned char *src, size_t size) +{ + int tableid; +// freesat_decode_error = 0; + + if (src[0] == 0x1f && (src[1] == 1 || src[1] == 2)) { + int uncompressed_len = 30; + char *uncompressed = (char *) calloc (1, uncompressed_len + 1); + unsigned value = 0, byte = 2, bit = 0; + int p = 0; + unsigned char lastch = START; + + tableid = src[1] - 1; + while (byte < 6 && byte < size) { + value |= src[byte] << ((5 - byte) * 8); + byte++; + } + //freesat_table_load (); /**< Load the tables as necessary */ + + do { + bool found = false; + unsigned bitShift = 0; + if (lastch == ESCAPE) { + char nextCh = (value >> 24) & 0xff; + found = true; + // Encoded in the next 8 bits. + // Terminated by the first ASCII character. + bitShift = 8; + if ((nextCh & 0x80) == 0) + lastch = nextCh; + if (p >= uncompressed_len) { + uncompressed_len += 10; + uncompressed = (char *) REALLOC (uncompressed, uncompressed_len + 1); + } + uncompressed[p++] = nextCh; + uncompressed[p] = 0; + } else { + int j; + for (j = 0; j < table_size[tableid][lastch]; j++) { + unsigned mask = 0, maskbit = 0x80000000; + short kk; + for (kk = 0; kk < tables[tableid][lastch][j].bits; kk++) { + mask |= maskbit; + maskbit >>= 1; + } + if ((value & mask) == tables[tableid][lastch][j].value) { + char nextCh = tables[tableid][lastch][j].next; + bitShift = tables[tableid][lastch][j].bits; + if (nextCh != STOP && nextCh != ESCAPE) { + if (p >= uncompressed_len) { + uncompressed_len += 10; + uncompressed = (char *) REALLOC (uncompressed, uncompressed_len + 1); + } + uncompressed[p++] = nextCh; + uncompressed[p] = 0; + } + found = true; + lastch = nextCh; + break; + } + } + } + if (found) { + // Shift up by the number of bits. + unsigned b; + for (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 { + LogE (0, prep("Missing table %d entry: <%s>"), tableid + 1, uncompressed); + // Entry missing in table. + return uncompressed; + } + } while (lastch != STOP && value != 0); + + return uncompressed; + } + return NULL; +} + +void decodeText2 (const unsigned char *from, int len, char *buffer, int buffsize) +{ + if (from[0] == 0x1f) { + char *temp = freesat_huffman_decode (from, len); + if (temp) { + len = strlen (temp); + len = len < buffsize - 1 ? len : buffsize - 1; + strncpy (buffer, temp, len); + buffer[len] = 0; + free (temp); + return; + } + } + + SI::String convStr; + SI::CharArray charArray; + charArray.assign(from, len); + convStr.setData(charArray, len); + //LogE(5, prep("decodeText2 from %s - length %d"), from, len); + convStr.getText(buffer, buffsize); + //LogE(5, prep("decodeText2 buffer %s - buffsize %d"), buffer, buffsize); +} + +void sortSchedules(cSchedules * Schedules, tChannelID channelID){ + + LogD(3, prep("Start sortEquivalent %s"), *channelID.ToString()); + + cChannel *pChannel = GetChannelByID (channelID, false); + cSchedule *pSchedule; + if (pChannel) { + pSchedule = (cSchedule *) (Schedules->GetSchedule(pChannel, true)); + pSchedule->Sort(); + Schedules->SetModified(pSchedule); + } + if (EquivHandler->getEquiChanMap().count(*channelID.ToString()) > 0) + EquivHandler->sortEquivalents(channelID, Schedules); +} } |