X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/a5275b224cc48c49d249501ba029ea932d2c95c2..06ca56e60c8d3e13d161b481b7716303bd3aa9f2:/lib/dvb/epgcache.cpp diff --git a/lib/dvb/epgcache.cpp b/lib/dvb/epgcache.cpp index d400dd27..59c62037 100644 --- a/lib/dvb/epgcache.cpp +++ b/lib/dvb/epgcache.cpp @@ -177,12 +177,11 @@ eEPGCache::eEPGCache() void eEPGCache::timeUpdated() { - if ( !thread_running() ) + if (!sync()) { eDebug("[EPGC] time updated.. start EPG Mainloop"); run(); - } - else + } else messages.send(Message(Message::timeChanged)); } @@ -692,6 +691,7 @@ void eEPGCache::gotMessage( const Message &msg ) void eEPGCache::thread() { + hasStarted(); nice(4); load(); cleanLoop(); @@ -910,7 +910,7 @@ bool eEPGCache::channel_data::finishEPG() { if (!isRunning) // epg ready { - eDebug("[EPGC] stop caching events(%d)", time(0)+eDVBLocalTimeHandler::getInstance()->difference()); + eDebug("[EPGC] stop caching events(%ld)", time(0)+eDVBLocalTimeHandler::getInstance()->difference()); zapTimer.start(UPDATE_INTERVAL, 1); eDebug("[EPGC] next update in %i min", UPDATE_INTERVAL / 60000); for (int i=0; i < 3; ++i) @@ -931,7 +931,7 @@ bool eEPGCache::channel_data::finishEPG() void eEPGCache::channel_data::startEPG() { - eDebug("[EPGC] start caching events(%d)", eDVBLocalTimeHandler::getInstance()->difference()+time(0)); + eDebug("[EPGC] start caching events(%ld)", eDVBLocalTimeHandler::getInstance()->difference()+time(0)); state=0; haveData=0; can_delete=0; @@ -1118,7 +1118,7 @@ void eEPGCache::channel_data::readData( const __u8 *data) break; default: eDebugNoNewLine("unknown");break; } - eDebug(" finished(%d)", time(0)+eDVBLocalTimeHandler::getInstance()->difference()); + eDebug(" finished(%ld)", time(0)+eDVBLocalTimeHandler::getInstance()->difference()); if ( reader ) reader->stop(); isRunning &= ~source; @@ -1532,6 +1532,7 @@ PyObject *eEPGCache::lookupEvent(PyObject *list, PyObject *convertFunc) PyObject *item=PyList_GET_ITEM(list, listIt++); // borrowed reference! if (PyTuple_Check(item)) { + bool service_changed=false; int type=0; long event_id=-1; time_t stime=-1; @@ -1579,6 +1580,24 @@ PyObject *eEPGCache::lookupEvent(PyObject *list, PyObject *convertFunc) eDebug("service reference for epg query is not valid"); continue; } + + // redirect subservice querys to parent service + eServiceReferenceDVB &dvb_ref = (eServiceReferenceDVB&)ref; + if (dvb_ref.getParentTransportStreamID().get()) // linkage subservice + { + eServiceCenterPtr service_center; + if (!eServiceCenter::getPrivInstance(service_center)) + { + dvb_ref.setTransportStreamID( dvb_ref.getParentTransportStreamID() ); + dvb_ref.setServiceID( dvb_ref.getParentServiceID() ); + dvb_ref.setParentTransportStreamID(eTransportStreamID(0)); + dvb_ref.setParentServiceID(eServiceID(0)); + dvb_ref.name=""; + service = PyString_FromString(dvb_ref.toString().c_str()); + service_changed = true; + } + } + PyObject *service_name=NULL; if (must_get_service_name) { @@ -1628,6 +1647,8 @@ PyObject *eEPGCache::lookupEvent(PyObject *list, PyObject *convertFunc) if (ret) return ret; } + if (service_changed) + Py_DECREF(service); if (service_name) Py_DECREF(service_name); } @@ -1713,7 +1734,7 @@ void fillTuple2(PyObject *tuple, const char *argstring, int argcount, eventData // 1 = search events with exactly title name (EXAKT_TITLE_SEARCH) // 2 = search events with text in title name (PARTIAL_TITLE_SEARCH) // when type is 0 (SIMILAR_BROADCASTINGS_SEARCH) -// the fourth is the servicereference tring +// the fourth is the servicereference string // the fifth is the eventid // when type is 1 or 2 (EXAKT_TITLE_SEARCH or PARTIAL_TITLE_SEARCH) // the fourth is the search text @@ -1728,6 +1749,7 @@ PyObject *eEPGCache::search(PyObject *arg) __u32 descr[512]; int eventid = -1; const char *argstring=0; + char *refstr=0; int argcount=0; int querytype=-1; bool needServiceEvent=false; @@ -1772,7 +1794,7 @@ PyObject *eEPGCache::search(PyObject *arg) PyObject *obj = PyTuple_GET_ITEM(arg, 3); if (PyString_Check(obj)) { - const char *refstr = PyString_AS_STRING(obj); + refstr = PyString_AS_STRING(obj); eServiceReferenceDVB ref(refstr); if (ref.valid()) { @@ -1929,22 +1951,32 @@ PyObject *eEPGCache::search(PyObject *arg) if (descridx > -1) { int maxcount=maxmatches; + eServiceReferenceDVB ref(refstr?refstr:""); + // ref is only valid in SIMILAR_BROADCASTING_SEARCH + // in this case we start searching with the base service + bool first = ref.valid() ? true : false; singleLock s(cache_lock); - // check all services - for( eventCache::iterator cit(eventDB.begin()); cit != eventDB.end() && maxcount; ++cit) + eventCache::iterator cit(ref.valid() ? eventDB.find(ref) : eventDB.begin()); + while(cit != eventDB.end() && maxcount) { + if ( ref.valid() && !first && cit->first == ref ) + { + // do not scan base service twice ( only in SIMILAR BROADCASTING SEARCH ) + ++cit; + continue; + } PyObject *service_name=0; PyObject *service_reference=0; - eventMap &evmap = cit->second.first; + timeMap &evmap = cit->second.second; // check all events - for (eventMap::iterator evit(evmap.begin()); evit != evmap.end() && maxcount; ++evit) + for (timeMap::iterator evit(evmap.begin()); evit != evmap.end() && maxcount; ++evit) { + if (evit->second->getEventID() == eventid) + continue; __u8 *data = evit->second->EITdata; int tmp = evit->second->ByteSize-12; __u32 *p = (__u32*)(data+12); // check if any of our descriptor used by this event -// if (evit->first == eventid ) -// continue; int cnt=-1; while(tmp>0) { @@ -2012,6 +2044,14 @@ PyObject *eEPGCache::search(PyObject *arg) Py_DECREF(service_name); if (service_reference) Py_DECREF(service_reference); + if (first) + { + // now start at first service in epgcache database ( only in SIMILAR BROADCASTING SEARCH ) + first=false; + cit=eventDB.begin(); + } + else + ++cit; } } @@ -2078,7 +2118,7 @@ void eEPGCache::PMTready(eDVBServicePMTHandler *pmthandler) if (tmp==3) { eServiceReferenceDVB ref; - if (!pmthandler->getService(ref)) + if (!pmthandler->getServiceReference(ref)) { int pid = (*es)->getPid(); messages.send(Message(Message::got_private_pid, ref, pid)); @@ -2176,6 +2216,14 @@ void eEPGCache::privateSectionRead(const uniqueEPGKey ¤t_service, const __ onid |= data[ptr++]; int sid = data[ptr++] << 8; sid |= data[ptr++]; + +// WORKAROUND for wrong transmitted epg data + if ( onid == 0x85 && tsid == 0x11 && sid == 0xd3 ) // premiere sends wrong tsid here + tsid = 0x1; + else if ( onid == 0x85 && tsid == 0x3 && sid == 0xf5 ) // premiere sends wrong sid here + sid = 0xdc; +//////////////////////////////////////////// + uniqueEPGKey service( sid, onid, tsid ); descr_len -= 6; while( descr_len > 0 )