Esempio n. 1
0
void eDVBServicePMTHandler::channelStateChanged(iDVBChannel *channel)
{
	int state;
	channel->getState(state);

	if ((m_last_channel_state != iDVBChannel::state_ok)
		&& (state == iDVBChannel::state_ok))
	{
		if (!m_demux && m_channel)
		{
			if (m_pvr_demux_tmp)
			{
				m_demux = m_pvr_demux_tmp;
				m_pvr_demux_tmp = NULL;
			}
			else if (m_channel->getDemux(m_demux, (!m_use_decode_demux) ? 0 : iDVBChannel::capDecode))
				eDebug("[eDVBServicePMTHandler] Allocating %s-decoding a demux for now tuned-in channel failed.", m_use_decode_demux ? "" : "non-");
		}

		if (m_demux)
		{
			eDebug("[eDVBServicePMTHandler] ok ... now we start!!");
			m_have_cached_program = false;

			if (m_service && !m_service->cacheEmpty())
			{
				serviceEvent(eventNewProgramInfo);
				if (m_use_decode_demux)
				{
					if (!m_ca_servicePtr)
					{
						registerCAService();
					}
					if (m_ca_servicePtr && !m_service->usePMT())
					{
						eDebug("[eDVBServicePMTHandler] create cached caPMT");
						eDVBCAHandler::getInstance()->handlePMT(m_reference, m_service);
					}
				}
			}

			if (!m_service || m_service->usePMT())
			{
				if (m_pmt_pid == -1)
					m_PAT.begin(eApp, eDVBPATSpec(), m_demux);
				else
					m_PMT.begin(eApp, eDVBPMTSpec(m_pmt_pid, m_reference.getServiceID().get()), m_demux);
			}

			serviceEvent(eventTuned);
		}
	} else if ((m_last_channel_state != iDVBChannel::state_failed) &&
			(state == iDVBChannel::state_failed))
	{
		eDebug("[eDVBServicePMTHandler] tune failed.");
		serviceEvent(eventTuneFailed);
	}
}
Esempio n. 2
0
void eDVBServicePMTHandler::PMTready(int error)
{
	if (error)
		serviceEvent(eventNoPMT);
	else
	{
		m_have_cached_program = false;
		serviceEvent(eventNewProgramInfo);
		switch (m_service_type)
		{
		case livetv:
		case recording:
		case scrambled_recording:
		case timeshift_recording:
		case scrambled_timeshift_recording:
		case streamserver:
		case scrambled_streamserver:
		case streamclient:
			eEPGCache::getInstance()->PMTready(this);
			break;
		default:
			/* do not start epg caching for other types of services */
			break;
		}
		if (doDescramble)
		{
			if (!m_ca_servicePtr)
			{
				int demuxes[2] = {0,0};
				uint8_t demuxid;
				uint8_t adapterid;
				m_demux->getCADemuxID(demuxid);
				m_demux->getCAAdapterID(adapterid);
				demuxes[0]=demuxid;
				if (m_decode_demux_num != 0xFF)
					demuxes[1]=m_decode_demux_num;
				else
					demuxes[1]=demuxes[0];
				eDVBCAHandler::getInstance()->registerService(m_reference, adapterid, demuxes, (int)m_service_type, m_ca_servicePtr);
				eDVBCIInterfaces::getInstance()->recheckPMTHandlers();
			}
			eDVBCIInterfaces::getInstance()->gotPMT(this);
		}
		if (m_ca_servicePtr)
		{
			ePtr<eTable<ProgramMapSection> > ptr;
			if (!m_PMT.getCurrent(ptr))
				eDVBCAHandler::getInstance()->handlePMT(m_reference, ptr);
			else
				eDebug("eDVBServicePMTHandler cannot call buildCAPMT");
		}
	}
}
Esempio n. 3
0
void eServiceHandlerDVB::switchedService(const eServiceReferenceDVB &s, int err)
{
	if ( !s )
		return;
	int oldstate=state;
	error = err;
	if (error)
		state=stateError;
	else
		state=statePlaying;

	if (state != oldstate)
		serviceEvent(eServiceEvent(eServiceEvent::evtStateChanged));

	serviceEvent(eServiceEvent(eServiceEvent::evtStart));
}
Esempio n. 4
0
File: pmt.cpp Progetto: ambrosa/test
void eDVBServicePMTHandler::channelEvent(iDVBChannel *channel, int event)
{
	switch (event)
	{
	case iDVBChannel::evtPreStart:
		serviceEvent(eventPreStart);
		break;
	case iDVBChannel::evtEOF:
		serviceEvent(eventEOF);
		break;
	case iDVBChannel::evtSOF:
		serviceEvent(eventSOF);
		break;
	default:
		break;
	}
}
Esempio n. 5
0
void eServiceHandlerDVB::handleDVBEvent( const eDVBEvent & e )
{
	switch ( e.type )
	{
		case eDVBEvent::eventRecordWriteError:
			serviceEvent(eServiceEvent(eServiceEvent::evtRecordFailed));
		break;
	}
}
Esempio n. 6
0
void eServiceHandlerDVB::gotPMT(PMT *)
{
	serviceEvent(eServiceEvent(eServiceEvent::evtGotPMT));
	if ( decoder )
	{
		eDVBServiceController *sapi=eDVB::getInstance()->getServiceAPI();
		if ( sapi )
			decoder->messages.send(eDVRPlayerThread::eDVRPlayerThreadMessage(eDVRPlayerThread::eDVRPlayerThreadMessage::updateAudioTracks, sapi->audioStreams.size()));
	}
}
Esempio n. 7
0
void eDVBServicePMTHandler::PMTready(int error)
{
	if (error)
		serviceEvent(eventNoPMT);
	else
	{
		m_have_cached_program = false;
		serviceEvent(eventNewProgramInfo);
		switch (m_service_type)
		{
		case livetv:
		case recording:
		case scrambled_recording:
		case timeshift_recording:
		case scrambled_timeshift_recording:
		case streamserver:
		case scrambled_streamserver:
		case streamclient:
			eEPGCache::getInstance()->PMTready(this);
			break;
		default:
			/* do not start epg caching for other types of services */
			break;
		}
		if (doDescramble)
		{
			if (!m_ca_servicePtr)
			{
				registerCAService();
			}
			eDVBCIInterfaces::getInstance()->recheckPMTHandlers();
			eDVBCIInterfaces::getInstance()->gotPMT(this);
		}
		if (m_ca_servicePtr)
		{
			ePtr<eTable<ProgramMapSection> > ptr;
			if (!m_PMT.getCurrent(ptr))
				eDVBCAHandler::getInstance()->handlePMT(m_reference, ptr);
			else
				eDebug("eDVBServicePMTHandler cannot call buildCAPMT");
		}
	}
}
Esempio n. 8
0
void eServiceHandlerDVB::gotMessage(const eDVRPlayerThreadMessage &message)
{
	if (message.type == eDVRPlayerThreadMessage::done)
	{
		state=stateStopped;
		serviceEvent(eServiceEvent(eServiceEvent::evtEnd));
	}
	else if (message.type == eDVRPlayerThreadMessage::liveeof)
		stopPlayback(1);
}
Esempio n. 9
0
void eServiceHandlerDVB::scrambledStatusChanged(bool scrambled)
{
	int oldflags=flags;

	if (scrambled)
		flags |= flagIsScrambled;
	else
		flags &= ~flagIsScrambled;

	if (oldflags != flags)
		serviceEvent(eServiceEvent(eServiceEvent::evtFlagsChanged) );
}
Esempio n. 10
0
void eServiceHandlerDVB::stopPlayback( int waslivemode )
{
	if (decoder)
	{
			// reenable pcrpid
		Decoder::parms.pcrpid = pcrpid;
		Decoder::Set();
		flags&=~(flagIsSeekable|flagSupportPosition);
		serviceEvent(eServiceEvent(eServiceEvent::evtFlagsChanged) );
		delete decoder;
		decoder=0;
	}
}
Esempio n. 11
0
File: pmt.cpp Progetto: ambrosa/test
void eDVBServicePMTHandler::PMTready(int error)
{
	if (error)
		serviceEvent(eventNoPMT);
	else
	{
		m_have_cached_program = false;
		serviceEvent(eventNewProgramInfo);
		if (!m_pvr_channel) // don't send campmt to camd.socket for playbacked services
		{
			eEPGCache::getInstance()->PMTready(this);
			if(!m_ca_servicePtr)
			{
				int demuxes[2] = {0,0};
				uint8_t demuxid;
				uint8_t adapterid;
				m_demux->getCADemuxID(demuxid);
				m_demux->getCAAdapterID(adapterid);
				demuxes[0]=demuxid;
				if (m_decode_demux_num != 0xFF)
					demuxes[1]=m_decode_demux_num;
				else
					demuxes[1]=demuxes[0];
				eDVBCAHandler::getInstance()->registerService(m_reference, adapterid, demuxes, m_ca_servicePtr);
				eDVBCIInterfaces::getInstance()->recheckPMTHandlers();
			}
			eDVBCIInterfaces::getInstance()->gotPMT(this);
		}
		if (m_ca_servicePtr)
		{
			ePtr<eTable<ProgramMapSection> > ptr;
			if (!m_PMT.getCurrent(ptr))
				eDVBCAHandler::getInstance()->handlePMT(m_reference, ptr);
			else
				eDebug("eDVBServicePMTHandler cannot call buildCAPMT");
		}
	}
}
Esempio n. 12
0
void eDVBServicePMTHandler::PATready(int)
{
	eDebug("PATready");
	ePtr<eTable<ProgramAssociationSection> > ptr;
	if (!m_PAT.getCurrent(ptr))
	{
		int service_id_single = -1;
		int pmtpid_single = -1;
		int pmtpid = -1;
		int cnt=0;
		int tsid=-1;
		std::vector<ProgramAssociationSection*>::const_iterator i = ptr->getSections().begin();
		tsid = (*i)->getTableIdExtension(); // in PAT this is the transport stream id
		eDebug("PAT TSID: 0x%04x (%d)", tsid, tsid);
		for (i = ptr->getSections().begin(); pmtpid == -1 && i != ptr->getSections().end(); ++i)
		{
			const ProgramAssociationSection &pat = **i;
			ProgramAssociationConstIterator program;
			for (program = pat.getPrograms()->begin(); pmtpid == -1 && program != pat.getPrograms()->end(); ++program)
			{
				if (eServiceID((*program)->getProgramNumber()) == m_reference.getServiceID())
					pmtpid = (*program)->getProgramMapPid();
				if (++cnt == 1 && pmtpid_single == -1 && pmtpid == -1)
				{
					pmtpid_single = (*program)->getProgramMapPid();
					service_id_single = (*program)->getProgramNumber();
				}
				else
					pmtpid_single = service_id_single = -1;
			}
		}
		if (pmtpid_single != -1) // only one PAT entry .. and not valid pmtpid found
		{
			eDebug("use single pat entry!");
			m_reference.setServiceID(eServiceID(service_id_single));
			pmtpid = pmtpid_single;
		}
		if (pmtpid == -1) {
			eDebug("no PAT entry found.. start delay");
			m_no_pat_entry_delay->start(1000, true);
		}
		else {
			eDebug("use pmtpid %04x for service_id %04x", pmtpid, m_reference.getServiceID().get());
			m_no_pat_entry_delay->stop();
			m_PMT.begin(eApp, eDVBPMTSpec(pmtpid, m_reference.getServiceID().get()), m_demux);
		}
	} else
		serviceEvent(eventNoPAT);
}
Esempio n. 13
0
int eServiceHandlerDVB::play(const eServiceReference &service, int workaround )
{
	eDVBServiceController *sapi=eDVB::getInstance()->getServiceAPI();
	if (service.type != eServiceReference::idDVB)
		return -1;
#ifndef DISABLE_FILE
	if ( !workaround )
		decoder=0;

	if (service.path.length())
	{
		if ( !workaround )
		{
			struct stat64 s;
			if (::stat64(service.path.c_str(), &s))
			{
				eDebug("file %s not exist.. don't play", service.path.c_str() );
				return -1;
			}
			if ( eDVB::getInstance()->recorder &&
				service.path == eDVB::getInstance()->recorder->getFilename() )
				startPlayback(service.path, 2);
			else
				startPlayback(service.path, 0);
		}
		else
			flags |= (flagIsSeekable|flagSupportPosition);
	}
	else
#endif
	{
		flags &= ~(flagIsSeekable|flagSupportPosition);
		serviceEvent(eServiceEvent(eServiceEvent::evtFlagsChanged) );
	}

	if (sapi)
		return sapi->switchService((const eServiceReferenceDVB&)service);

	return -1;
}
Esempio n. 14
0
void eServiceHandlerDVB::startPlayback(const eString &filename, int livemode, bool startpaused)
{
	stopPlayback();
	decoder=new eDVRPlayerThread(filename.c_str(), this, livemode,playingPermanentTimeshift);
	if (startpaused)
	{
		decoder->messages.send(eDVRPlayerThread::eDVRPlayerThreadMessage(eDVRPlayerThread::eDVRPlayerThreadMessage::startPaused, livemode));
	}
	else
	{
		decoder->messages.send(eDVRPlayerThread::eDVRPlayerThreadMessage(eDVRPlayerThread::eDVRPlayerThreadMessage::start, livemode));
	}
	flags=flagIsSeekable|flagSupportPosition;
	state= statePlaying;
	if ( livemode )
		flags|=flagStartTimeshift;
	pcrpid = Decoder::current.pcrpid;
		// stop pcrpid
	Decoder::parms.pcrpid = -1;
	Decoder::Set();
	serviceEvent(eServiceEvent(eServiceEvent::evtFlagsChanged) );
	if ( livemode )
		flags&=~flagStartTimeshift;
}
Esempio n. 15
0
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;
}
Esempio n. 16
0
void eDVBServicePMTHandler::AITready(int error)
{
	eDebug("AITready");
	ePtr<eTable<ApplicationInformationSection> > ptr;
	m_aitInfoList.clear();
	if (!m_AIT.getCurrent(ptr))
	{
		m_HBBTVUrl = "";
		for (std::vector<ApplicationInformationSection*>::const_iterator it = ptr->getSections().begin(); it != ptr->getSections().end(); ++it)
		{
			for (std::list<ApplicationInformation *>::const_iterator i = (*it)->getApplicationInformation()->begin(); i != (*it)->getApplicationInformation()->end(); ++i)
			{
				struct aitInfo aitinfo;
				aitinfo.id = ((ApplicationIdentifier*)(*i)->getApplicationIdentifier())->getApplicationId();
				for (DescriptorConstIterator desc = (*i)->getDescriptors()->begin(); desc != (*i)->getDescriptors()->end(); ++desc)
				{
					switch ((*desc)->getTag())
					{
					case APPLICATION_DESCRIPTOR:
						break;
					case APPLICATION_NAME_DESCRIPTOR:
					{
						ApplicationNameDescriptor *appname = (ApplicationNameDescriptor*)(*desc);
						for (ApplicationNameConstIterator appnamesit = appname->getApplicationNames()->begin(); appnamesit != appname->getApplicationNames()->end(); ++appnamesit)
						{
							aitinfo.name = (*appnamesit)->getApplicationName();
						}
						break;
					}
					case TRANSPORT_PROTOCOL_DESCRIPTOR:
					{
						TransportProtocolDescriptor *transport = (TransportProtocolDescriptor*)(*desc);
						switch (transport->getProtocolId())
						{
						case 1: /* object carousel */
							if (m_dsmcc_pid >= 0)
							{
								m_OC.begin(eApp, eDVBDSMCCDLDataSpec(m_dsmcc_pid), m_demux);
							}
							break;
						case 2: /* ip */
							break;
						case 3: /* interaction */
							for (InterActionTransportConstIterator interactionit = transport->getInteractionTransports()->begin(); interactionit != transport->getInteractionTransports()->end(); ++interactionit)
							{
								if ((*i)->getApplicationControlCode() == 0x01) /* AUTOSTART */
								{
									m_HBBTVUrl = (*interactionit)->getUrlBase()->getUrl();
								}
								aitinfo.url = (*interactionit)->getUrlBase()->getUrl();
								break;
							}
							break;
						}
						break;
					}
					case GRAPHICS_CONSTRAINTS_DESCRIPTOR:
						break;
					case SIMPLE_APPLICATION_LOCATION_DESCRIPTOR:
					{
						SimpleApplicationLocationDescriptor *applicationlocation = (SimpleApplicationLocationDescriptor*)(*desc);
						if ((*i)->getApplicationControlCode() == 0x01) /* AUTOSTART */
						{
							m_HBBTVUrl += applicationlocation->getInitialPath();
						}
						aitinfo.url += applicationlocation->getInitialPath();
						m_aitInfoList.push_back(aitinfo);
						break;
					}
					case APPLICATION_USAGE_DESCRIPTOR:
						break;
					case SIMPLE_APPLICATION_BOUNDARY_DESCRIPTOR:
						break;
					}
				}
			}
		}
		if (!m_HBBTVUrl.empty())
		{
			serviceEvent(eventHBBTVInfo);
		}
	}
	/* for now, do not keep listening for table updates */
	m_AIT.stop();
}
Esempio n. 17
0
void eDVBServicePMTHandler::sendEventNoPatEntry()
{
	serviceEvent(eventNoPATEntry);
}
Esempio n. 18
0
void eServiceHandlerDVB::gotEIT(EIT *, int)
{
	serviceEvent(eServiceEvent(eServiceEvent::evtGotEIT));
}
Esempio n. 19
0
void eServiceHandlerDVB::gotSDT(SDT *)
{
	serviceEvent(eServiceEvent(eServiceEvent::evtGotSDT));
}
Esempio n. 20
0
void eServiceHandlerDVB::leaveService(const eServiceReferenceDVB &e)
{
	if ( e )
		serviceEvent(eServiceEvent(eServiceEvent::evtStop));
}
Esempio n. 21
0
void eServiceHandlerDVB::aspectRatioChanged(int isanamorph)
{
	aspect=isanamorph;
	serviceEvent(eServiceEvent(eServiceEvent::evtAspectChanged));
}