예제 #1
0
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() ));
	}
}
예제 #2
0
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
예제 #3
0
파일: pmt.cpp 프로젝트: pe-tardo/dvbapp
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;
}
예제 #4
0
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 "";
}
예제 #5
0
파일: edvb.cpp 프로젝트: GWARDAR/OpenPLi-1
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;
	}
예제 #6
0
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;
}
예제 #7
0
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;
}