void eDVBServiceController::leaveService( const eServiceReferenceDVB &service) { if (!service) return; std::map<eServiceReferenceDVB,int>::iterator it = CIServices.find(service); if ( it != CIServices.end() ) { // eDebug("[eDVBCIHandler] leave service %s", service.toString().c_str() ); CIServices.erase(it); if ( DVBCI ) DVBCI->messages.send(eDVBCI::eDVBCIMessage(eDVBCI::eDVBCIMessage::PMTflush, service.getServiceID().get() )); if ( DVBCI2 ) DVBCI2->messages.send(eDVBCI::eDVBCIMessage(eDVBCI::eDVBCIMessage::PMTflush, service.getServiceID().get() )); } }
void eChannelInfo::getServiceInfo( const eServiceReferenceDVB& service ) { closeEIT(); delete eit; eit=0; // eService *service=eServiceInterface::getInstance()->addRef(service); if (!service.path.size()) { DescriptionForEPGSearch = ""; cdescr.show(); cname.setFlags(RS_FADE); cname.resize( eSize( clientrect.width()/8*7-4, clientrect.height()/3) ); int opos=service.getDVBNamespace().get()>>16; if ( eSystemInfo::getInstance()->getFEType() == eSystemInfo::feSatellite ) copos.setText(eString().sprintf("%d.%d\xC2\xB0%c", abs(opos / 10), abs(opos % 10), opos>0?'E':'W') ); EITEvent *e = 0; e = eEPGCache::getInstance()->lookupEvent(service); if (e && eListBoxEntryService::nownextEPG) { time_t t = e->start_time+e->duration+61; delete e; e = eEPGCache::getInstance()->lookupEvent((const eServiceReferenceDVB&)service,t); } if (e) // data is in cache... { ParseEITInfo(e); delete e; } else // we parse the eit... { cname.setText(_("no data for this service avail")); eDVBServiceController *sapi=eDVB::getInstance()->getServiceAPI(); if (!sapi) return; eServiceReferenceDVB &ref = sapi->service; int type = ((service.getTransportStreamID()==ref.getTransportStreamID()) && (service.getOriginalNetworkID()==ref.getOriginalNetworkID())) ? EIT::tsActual:EIT::tsOther; eit = new EIT( EIT::typeNowNext, service.getServiceID().get(), type ); CONNECT( eit->tableReady, eChannelInfo::EITready ); eit->start(); } } else
int eDVBServicePMTHandler::tuneExt(eServiceReferenceDVB &ref, int use_decode_demux, ePtr<iTsSource> &source, const char *streaminfo_file, eCueSheet *cue, bool simulate, eDVBService *service, serviceType type, bool descramble) { RESULT res=0; m_reference = ref; m_use_decode_demux = use_decode_demux; m_no_pat_entry_delay->stop(); m_service_type = type; doDescramble = descramble; /* use given service as backup. This is used for timeshift where we want to clone the live stream using the cache, but in fact have a PVR channel */ m_service = service; /* is this a normal (non PVR) channel? */ if (ref.path.empty()) { eDVBChannelID chid; ref.getChannelID(chid); res = m_resourceManager->allocateChannel(chid, m_channel, simulate); if (!simulate) eDebug("allocate Channel: res %d", res); ePtr<iDVBChannelList> db; if (!m_resourceManager->getChannelList(db)) db->getService((eServiceReferenceDVB&)m_reference, m_service); if (!res && !simulate) eDVBCIInterfaces::getInstance()->addPMTHandler(this); } else if (!simulate) // no simulation of playback services { if (!ref.getServiceID().get() /* incorrect sid in meta file or recordings.epl*/ ) { eDVBTSTools tstools; bool b = source || !tstools.openFile(ref.path.c_str(), 1); eWarning("no .meta file found, trying to find PMT pid"); if (source) tstools.setSource(source, NULL); if (b) { eDVBPMTParser::program program; if (!tstools.findPMT(program)) { m_pmt_pid = program.pmtPid; eDebug("PMT pid found on pid %04x, service id %d", m_pmt_pid, program.serviceId); m_reference.setServiceID(program.serviceId); } } else eWarning("no valid source to find PMT pid!"); } eDebug("alloc PVR"); /* allocate PVR */ eDVBChannelID chid; if (m_service_type == streamclient) ref.getChannelID(chid); res = m_resourceManager->allocatePVRChannel(chid, m_pvr_channel); if (res) eDebug("allocatePVRChannel failed!\n"); m_channel = m_pvr_channel; } if (!simulate) { if (m_channel) { m_channel->connectStateChange( slot(*this, &eDVBServicePMTHandler::channelStateChanged), m_channelStateChanged_connection); m_last_channel_state = -1; channelStateChanged(m_channel); m_channel->connectEvent( slot(*this, &eDVBServicePMTHandler::channelEvent), m_channelEvent_connection); if (ref.path.empty()) { m_dvb_scan = new eDVBScan(m_channel, true, false); if (!eConfigManager::getConfigBoolValue("config.misc.disable_background_scan")) { /* * not starting a dvb scan triggers what appears to be a * refcount bug (channel?/demux?), so we always start a scan, * but ignore the results when background scanning is disabled */ m_dvb_scan->connectEvent(slot(*this, &eDVBServicePMTHandler::SDTScanEvent), m_scan_event_connection); } } } else { if (res == eDVBResourceManager::errAllSourcesBusy) serviceEvent(eventNoResources); else /* errChidNotFound, errNoChannelList, errChannelNotInList, errNoSourceFound */ serviceEvent(eventMisconfiguration); return res; } if (m_pvr_channel) { m_pvr_channel->setCueSheet(cue); if (m_pvr_channel->getDemux(m_pvr_demux_tmp, (!m_use_decode_demux) ? 0 : iDVBChannel::capDecode)) eDebug("Allocating %s-decoding a demux for PVR channel failed.", m_use_decode_demux ? "" : "non-"); else if (source) m_pvr_channel->playSource(source, streaminfo_file); else m_pvr_channel->playFile(ref.path.c_str()); if (m_service_type == offline) { m_pvr_channel->setOfflineDecodeMode(eConfigManager::getConfigIntValue("config.recording.offline_decode_delay")); } } } return res; }
std::string eRTSPStreamClient::searchServiceRef(int sys, int freq, int pol, int orbital_position, int sid) { eDebug("start %s", __FUNCTION__); eDVBFrontendParametersSatellite sat1; eDVBFrontendParametersTerrestrial ter1; eDVBFrontendParametersCable cab1; int found = 0; memset(&sat, 0, sizeof(sat)); memset(&ter, 0, sizeof(ter)); memset(&cab, 0, sizeof(cab)); const eServiceReferenceDVB *srvc = NULL; for (std::map<eServiceReferenceDVB, ePtr<eDVBService>>::iterator i(m_dvbdb->m_services.begin()); i != m_dvbdb->m_services.end(); ++i) { found = 0; unsigned int flags = 0; eDVBChannelID chid; ePtr<iDVBFrontendParameters> p; const eServiceReferenceDVB &s = i->first; s.getChannelID(chid); m_dvbdb->getChannelFrontendData(chid, p); flags = i->second->m_flags; if (!p) continue; if (!p->getDVBS(sat1) && ((sys == SYS_DVBS) || (sys == SYS_DVBS2))) { // eDebug("freq = %d, sat.freq %d, OP %d, SOP %d, pol %d pol %d", freq, sat1.frequency, orbital_position, sat1.orbital_position, pol, sat1.polarisation); if ((absdiff(sat1.frequency, freq) < 2000) && sat1.polarisation == pol && orbital_position == sat1.orbital_position) { sat = sat1; eDebug("Adding %s to the list for frequency %d (%s) f:%x", s.toString().c_str(), sat.frequency, i->second->m_service_name.c_str(), flags); srvc = &i->first; found = 1; } } if (!p->getDVBT(ter1) && ((sys == SYS_DVBT) || (sys == SYS_DVBT2))) { if ((absdiff(ter1.frequency / 1000, freq) < 2000)) { ter = ter1; eDebug("Adding %s to the list (%s) f:%x", s.toString().c_str(), i->second->m_service_name.c_str(), flags); srvc = &i->first; found = 1; } } #ifdef SYS_DVBC_ANNEX_A if (!p->getDVBC(cab1) && ((sys == SYS_DVBC_ANNEX_A) || (sys == SYS_DVBC2))) #else if (!p->getDVBC(cab1) && ((sys == SYS_DVBC_ANNEX_AC) || (sys == SYS_DVBC2))) #endif { if ((absdiff(cab1.frequency, freq) < 2000)) { cab = cab1; eDebug("Adding %s to the list (%s) f:%x", s.toString().c_str(), i->second->m_service_name.c_str(), flags); srvc = &i->first; found = 1; } } std::set<eServiceReferenceDVB>::iterator it = processed_sr.find(s); int not_available = (it == processed_sr.end()); if (found) { if (addCachedPids(i->second, s)) { if (not_available) { eDebug("SR %s does not have cached pids", s.toString().c_str()); not_cached_sr.insert(s); } else eDebug("SR %s was already attempted and does not have cached pids, not adding", s.toString().c_str()); } } } if (srvc) { // return srvc->toString(); const eServiceReferenceDVB srv(srvc->getDVBNamespace(), srvc->getTransportStreamID(), srvc->getOriginalNetworkID(), eServiceID(sid), srvc->getServiceType(), srvc->getSourceID()); return srv.toString(); } eDebug("end %s", __FUNCTION__); return ""; }
void eDVB::recBegin(const char *filename, eServiceReferenceDVB service) { if (recorder) recEnd(); PMT *pmt=getPMT(); PAT *pat=tPAT.ready()?tPAT.getCurrent():0; recorder=new eDVBRecorder(pmt, pat); if ( pat ) pat->unlock(); recorder->recRef=(eServiceReferenceDVB&)eServiceInterface::getInstance()->service; eServiceHandler *handler = eServiceInterface::getInstance()->getService(); recorder->scrambled = handler->getFlags() & eServiceHandler::flagIsScrambled; recorder->open(filename); CONNECT(recorder->recMessage, eDVB::recMessage); // recorder->addNewPID(0); // PAT // if (Decoder::parms.pmtpid != -1) // recorder->addNewPID(Decoder::parms.pmtpid); if (!pmt) { if (Decoder::parms.apid != -1) recorder->addNewPID(Decoder::parms.apid); if (Decoder::parms.vpid != -1) recorder->addNewPID(Decoder::parms.vpid); if (Decoder::parms.tpid != -1) recorder->addNewPID(Decoder::parms.tpid); if (Decoder::parms.pcrpid != -1) recorder->addNewPID(Decoder::parms.pcrpid); } else { recorder->addNewPID(pmt->PCR_PID); #ifdef RECORD_ECM for (ePtrList<Descriptor>::iterator i(pmt->program_info.begin()); i != pmt->program_info.end(); ++i) if (i->Tag() == 9) recorder->addNewPID(((CADescriptor*)*i)->CA_PID); #endif for (ePtrList<PMTEntry>::iterator i(pmt->streams); i != pmt->streams.end(); ++i) { int record=0; int isUndocumentedNA = 0; switch (i->stream_type) { case 1: // video.. case 2: record=1; break; case 3: // audio.. case 4: record=1; break; case 0x80: case 0x81: case 0x82: case 0x83: isUndocumentedNA = 1; case 6: for (ePtrList<Descriptor>::iterator it(i->ES_info); it != i->ES_info.end(); ++it) { switch (it->Tag()) { case DESCR_AC3: { int norecord=0; eConfig::getInstance()->getKey("/enigma/noac3recording", norecord); if (!norecord) record=1; break; } case DESCR_ISO639_LANGUAGE: if (isUndocumentedNA) { record = 1; } break; #ifdef RECORD_TELETEXT case DESCR_TELETEXT: { int norecord=0; eConfig::getInstance()->getKey("/enigma/nottxrecording", norecord); if (!norecord) record=2; // low bitrate break; } #endif #ifdef RECORD_SUBTITLES case DESCR_SUBTITLING: { record=2; // low bitrate break; } #endif } } break; } if (record) recorder->addNewPID(i->elementary_PID, record==2?DMX_LOW_BITRATE:0); #ifdef RECORD_ECM for (ePtrList<Descriptor>::iterator it(i->ES_info); it != i->ES_info.end(); ++it) if (it->Tag() == 9) recorder->addNewPID(((CADescriptor*)*it)->CA_PID); #endif } pmt->unlock(); } // build SMI table. // build SIT: __u8 sit[4096]; int pos=0; sit[pos++]=0x7F; // TID sit[pos++]=0x80; // section_syntax_indicator, length sit[pos++]=0; // length sit[pos++]=0; sit[pos++]=0; // reserved sit[pos++]=1; // reserved, version number, current/next indicator sit[pos++]=0; // section number sit[pos++]=0; // last section number sit[pos++]=0; // loop length sit[pos++]=0; // " " int loop_pos=pos; // TODO: build Partitial Transport Stream descriptor containing valid values about rate sit[loop_pos-2]|=(pos-loop_pos)>>8; sit[loop_pos-1]|=(pos-loop_pos)&0xFF; // create one single entry: our service... sit[pos++]=service.getServiceID().get()>>8; sit[pos++]=service.getServiceID().get()&0xFF; sit[pos++]=3<<4; // running state sit[pos++]=0; loop_pos=pos; // create our special descriptor: sit[pos++]=0x80; // private sit[pos++]=0; int descr_pos=pos; memcpy(sit+pos, "ENIGMA", 6); pos+=6; if (Decoder::parms.vpid != -1) { sit[pos++]=eServiceDVB::cVPID; sit[pos++]=2; sit[pos++]=Decoder::parms.vpid>>8; sit[pos++]=Decoder::parms.vpid&0xFF; }
static int searchforEvent(EITEvent *ev, const eString &search, eString &titlefound, eServiceReferenceDVB &new_ref, int intExactMatch, int intCaseSensitive, int genre) { eString title; eString sFind; int intFound = 0; // Genre Suchkriterium schlägt immer Titelsuche ;) if ( genre != 0) { int Range = 0; switch (genre) { case 32: Range = 36; break; case 48: Range = 51; break; case 64: Range = 75; break; case 80: Range = 85; break; case 96: Range = 102; break; case 112: Range = 123; break; case 128: Range = 131; break; case 144: Range = 151; break; case 160: Range = 167; break; case 176: Range = 179; break; default: break; } for (ePtrList<Descriptor>::iterator d(ev->descriptor); d != ev->descriptor.end(); ++d) { Descriptor *descriptor=*d; if(descriptor->Tag()==DESCR_CONTENT) { ContentDescriptor *cod=(ContentDescriptor*)descriptor; for(ePtrList<descr_content_entry_struct>::iterator ce(cod->contentList.begin()); ce != cod->contentList.end(); ++ce) { if ( genre < 32 ) { if (genre == ce->content_nibble_level_1*16+ce->content_nibble_level_2) intFound = 1; } else { int genreID = ce->content_nibble_level_1*16+ce->content_nibble_level_2; if ( (genreID >= genre) && (genreID <= Range)) intFound = 1; } } } } if (intFound) { LocalEventData led; led.getLocalData(ev, &title, 0); titlefound = title; } } else { if (search != "") { LocalEventData led; led.getLocalData(ev, &title, 0); titlefound = title; if (intExactMatch || intCaseSensitive) sFind = title; else sFind = title.upper(); if (!intExactMatch) { if (sFind.find(search) != eString::npos) intFound = 1; } else { if (!strcmp(search.c_str(),sFind.c_str())) intFound = 1; } } } if (intFound) { for (ePtrList<Descriptor>::iterator d(ev->descriptor); d != ev->descriptor.end(); ++d) { Descriptor *descriptor=*d; if (descriptor->Tag() == DESCR_LINKAGE) { LinkageDescriptor *ld=(LinkageDescriptor*)descriptor; if (ld->linkage_type==0xB0) { eServiceReferenceDVB MySubService(new_ref.getDVBNamespace(), eTransportStreamID(ld->transport_stream_id), eOriginalNetworkID(ld->original_network_id), eServiceID(ld->service_id), 7); new_ref = MySubService; break; } } } } return intFound; }
int eDVBServiceController::switchService(const eServiceReferenceDVB &newservice) { if (newservice == service) { eDebug("is same service.."); return 0; } Decoder::Flush(1); #ifndef DISABLE_FILE eServiceReferenceDVB recRef = dvb.recorder && dvb.recorder->recRef ? dvb.recorder->recRef : eServiceReferenceDVB(); recRef.data[0] = service.getServiceType(); #endif if ( service #ifndef DISABLE_FILE // && !service.path && Decoder::locked != 2 // leave service for (timer) zap in Background && service != recRef #endif ) { // must replace faked service types.. for capmt handlers eServiceReferenceDVB ref=service; switch(ref.getServiceType()) { case 4: case 7: ref.data[0]=1; // TV break; } eDVBCaPMTClientHandler::distribute_leaveService(ref); // capmt handler call.. } /*emit*/ dvb.leaveService(service); // Linkage service handling.. if ( newservice.getServiceType()==7 && prevservice ) { parentservice = prevservice; prevservice = eServiceReferenceDVB(); } if ( !newservice ) { if ( service.getServiceType() != 7 ) prevservice=service; // save currentservice // when in 15 seconds no other dvb service is running disable frontend disableFrontendTimer.start(15*1000, true); } ///////////////////////////////// service=newservice; dvb.tEIT.start(0); // clear eit dvb.tPAT.start(0); // clear tables. dvb.tPMT.start(0); dvb.tSDT.start(0); if (service) { if ( service && !service.path ) eDVBCaPMTClientHandler::distribute_enterService(service); // capmt handler call.. dvb.event(eDVBServiceEvent(eDVBServiceEvent::eventServiceSwitch)); } switch(newservice.getServiceType()) { case 1: // tv service case 2: // radio service case 4: // nvod parent service case 7: // linkage service delete dvb.parentEIT; dvb.parentEIT = 0; break; case 5: // nvod ref service // send Parent EIT .. for osd text.. dvb.gotEIT(0,0); break; } return 1; }