Example #1
0
RESULT eDVBScan::nextChannel()
{
	ePtr<iDVBFrontend> fe;

	m_SDT = 0; m_PAT = 0; m_BAT = 0; m_NIT = 0, m_PMT = 0;

	m_ready = 0;

	m_pat_tsid = eTransportStreamID();

		/* check what we need */
	m_ready_all = readySDT;

	if (m_flags & scanNetworkSearch)
		m_ready_all |= readyNIT;

	if (m_flags & scanSearchBAT)
		m_ready_all |= readyBAT;

	if (m_usePAT)
		m_ready_all |= readyPAT;

	if (!m_ch_blindscan.empty())
	{
		/* keep iterating with the same 'channel' till we get a tune failure */
		SCAN_eDebug("[eDVBScan] blindscan channel iteration");
		m_ch_current = m_ch_blindscan.front();
	}
	else
	{
		m_ch_blindscan_result = NULL;
		if (m_ch_toScan.empty())
		{
			SCAN_eDebug("[eDVBScan] no channels left: %zd scanned, %zd unavailable, %zd database.",
				m_ch_scanned.size(), m_ch_unavailable.size(), m_new_channels.size());
			m_event(evtFinish);
			return -ENOENT;
		}

		m_ch_current = m_ch_toScan.front();

		m_ch_toScan.pop_front();
	}

	if (m_channel->getFrontend(fe))
	{
		m_event(evtFail);
		return -ENOTSUP;
	}

	m_chid_current = eDVBChannelID();

	m_channel_state = iDVBChannel::state_idle;

	if (fe->tune(*m_ch_current, !m_ch_blindscan.empty()))
		return nextChannel();

	m_event(evtUpdate);
	return 0;
}
Example #2
0
RESULT eDVBScan::nextChannel()
{
	ePtr<iDVBFrontend> fe;

	m_SDT = 0; m_PAT = 0; m_BAT = 0; m_NIT = 0, m_PMT = 0;

	m_ready = 0;

	m_pat_tsid = eTransportStreamID();

		/* check what we need */
	m_ready_all = readySDT;

	if (m_flags & scanNetworkSearch)
		m_ready_all |= readyNIT;

	if (m_flags & scanSearchBAT)
		m_ready_all |= readyBAT;

	if (m_usePAT)
		m_ready_all |= readyPAT;

	if (m_ch_toScan.empty())
	{
		SCAN_eDebug("[eDVBScan] no channels left to scan.");
		SCAN_eDebug("[eDVBScan] %zd channels scanned, %zd were unavailable.",
				m_ch_scanned.size(), m_ch_unavailable.size());
		SCAN_eDebug("[eDVBScan] %zd channels in database.", m_new_channels.size());
		m_event(evtFinish);
		return -ENOENT;
	}

	m_ch_current = m_ch_toScan.front();

	m_ch_toScan.pop_front();

	if (m_channel->getFrontend(fe))
	{
		m_event(evtFail);
		return -ENOTSUP;
	}

	m_chid_current = eDVBChannelID();

	m_channel_state = iDVBChannel::state_idle;

	if (fe->tune(*m_ch_current))
		return nextChannel();

	m_event(evtUpdate);
	return 0;
}
Example #3
0
void eDVBScan::VCTready(int err)
{
	SCAN_eDebug("[eDVBScan] got vct %d", err);
	m_ready |= readySDT;
	if (!err)
		m_ready |= validVCT;
	channelDone();
}
Example #4
0
void eDVBScan::PATready(int err)
{
	SCAN_eDebug("[eDVBScan] got pat, err %d", err);
	m_ready |= readyPAT;
	if (!err)
		m_ready |= validPAT;
	startFilter(); // for starting the SDT filter
}
Example #5
0
void eDVBScan::BATready(int err)
{
	SCAN_eDebug("[eDVBScan] got bat, err %d", err);
	m_ready |= readyBAT;
	if (!err)
		m_ready |= validBAT;
	channelDone();
}
Example #6
0
void eDVBScan::NITready(int err)
{
	SCAN_eDebug("[eDVBScan] got nit, err %d", err);
	m_ready |= readyNIT;
	if (!err)
		m_ready |= validNIT;
	channelDone();
}
Example #7
0
eDVBScan::eDVBScan(iDVBChannel *channel, bool usePAT, bool debug)
	:m_channel(channel)
	,m_channel_state(iDVBChannel::state_idle)
	,m_ready(0)
	,m_ready_all(usePAT ? (readySDT|readyPAT) : readySDT)
	,m_pmt_running(false)
	,m_abort_current_pmt(false)
	,m_flags(0)
	,m_usePAT(usePAT)
	,m_scan_debug(debug)
{
	if (m_channel->getDemux(m_demux))
		SCAN_eDebug("[eDVBScan] failed to allocate demux!");
	m_channel->connectStateChange(sigc::mem_fun(*this, &eDVBScan::stateChange), m_stateChanged_connection);
}
Example #8
0
void eDVBScan::PMTready(int err)
{
	SCAN_eDebug("[eDVBScan] got pmt %d", err);
	if (!err)
	{
		bool scrambled = false;
		bool have_audio = false;
		bool have_video = false;
		unsigned short pcrpid = 0xFFFF;
		std::vector<ProgramMapSection*>::const_iterator i;

		for (i = m_PMT->getSections().begin(); i != m_PMT->getSections().end(); ++i)
		{
			const ProgramMapSection &pmt = **i;
			if (pcrpid == 0xFFFF)
				pcrpid = pmt.getPcrPid();
			else
				SCAN_eDebug("[eDVBScan]   already have a pcrpid %04x %04x", pcrpid, pmt.getPcrPid());
			ElementaryStreamInfoConstIterator es;
			for (es = pmt.getEsInfo()->begin(); es != pmt.getEsInfo()->end(); ++es)
			{
				int isaudio = 0, isvideo = 0, is_scrambled = 0, forced_audio = 0, forced_video = 0;
				switch ((*es)->getType())
				{
				case 0x1b: // AVC Video Stream (MPEG4 H264)
				case 0x24: // H265 HEVC
				case 0x10: // MPEG 4 Part 2
				case 0x01: // MPEG 1 video
				case 0x02: // MPEG 2 video
					isvideo = 1;
					forced_video = 1;
					//break; fall through !!!
				case 0x03: // MPEG 1 audio
				case 0x04: // MPEG 2 audio
				case 0x0f: // MPEG 2 AAC
				case 0x11: // MPEG 4 AAC
					if (!isvideo)
					{
						forced_audio = 1;
						isaudio = 1;
					}
				case 0x06: // PES Private
				case 0x81: // user private
				case 0xEA: // TS_PSI_ST_SMPTE_VC1
					for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin();
							desc != (*es)->getDescriptors()->end(); ++desc)
					{
						uint8_t tag = (*desc)->getTag();
						/* PES private can contain AC-3, DTS or lots of other stuff.
						   check descriptors to get the exakt type. */
						if (!forced_video && !forced_audio)
						{
							switch (tag)
							{
							case 0x1C: // TS_PSI_DT_MPEG4_Audio
							case 0x2B: // TS_PSI_DT_MPEG2_AAC
							case AAC_DESCRIPTOR:
							case AC3_DESCRIPTOR:
							case DTS_DESCRIPTOR:
							case AUDIO_STREAM_DESCRIPTOR:
								isaudio = 1;
								break;
							case 0x28: // TS_PSI_DT_AVC
							case 0x1B: // TS_PSI_DT_MPEG4_Video
							case VIDEO_STREAM_DESCRIPTOR:
								isvideo = 1;
								break;
							case REGISTRATION_DESCRIPTOR: /* some services don't have a separate AC3 descriptor */
							{
								RegistrationDescriptor *d = (RegistrationDescriptor*)(*desc);
								switch (d->getFormatIdentifier())
								{
								case 0x44545331 ... 0x44545333: // DTS1/DTS2/DTS3
								case 0x41432d33: // == 'AC-3'
								case 0x42535344: // == 'BSSD' (LPCM)
									isaudio = 1;
									break;
								case 0x56432d31: // == 'VC-1'
									isvideo = 1;
									break;
								default:
									break;
								}
							}
							default:
								break;
							}
						}
						if (tag == CA_DESCRIPTOR)
							is_scrambled = 1;
					}
				default:
					break;
				}
				if (isvideo)
					have_video = true;
				else if (isaudio)
					have_audio = true;
				else
					continue;
				if (is_scrambled)
					scrambled = true;
			}
			for (DescriptorConstIterator desc = pmt.getDescriptors()->begin();
				desc != pmt.getDescriptors()->end(); ++desc)
			{
				if ((*desc)->getTag() == CA_DESCRIPTOR)
					scrambled = true;
			}
		}
		m_pmt_in_progress->second.scrambled = scrambled;
		if ( have_video )
			m_pmt_in_progress->second.serviceType = 1;
		else if ( have_audio )
			m_pmt_in_progress->second.serviceType = 2;
		else
			m_pmt_in_progress->second.serviceType = 100;
	}
Example #9
0
void eDVBScan::stateChange(iDVBChannel *ch)
{
	int state;
	if (ch->getState(state))
		return;
	if (m_channel_state == state)
		return;

	if (state == iDVBChannel::state_ok)
	{
		if (m_ch_current && m_channel)
		{
			int type;
			m_ch_current->getSystem(type);
			if (type == iDVBFrontend::feTerrestrial)
			{
				eDVBFrontendParametersTerrestrial parm;
				m_ch_current->getDVBT(parm);
				if (parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T_T2)
				{
					/* we have a lock, this is a valid DVB-T transponder, set our system parameter */
					parm.system = eDVBFrontendParametersTerrestrial::System_DVB_T;
					m_ch_current->setDVBT(parm);
				}
			}
		}
		if (!m_ch_blindscan.empty())
		{
			/* update current blindscan iteration channel with scanned parameters */
			if (m_ch_current && m_channel)
			{
				ePtr<iDVBFrontend> fe;
				m_channel->getFrontend(fe);
				if (fe)
				{
					ePtr<iDVBTransponderData> tp;
					fe->getTransponderData(tp, false);
					if (tp)
					{
						ePtr<eDVBFrontendParameters> feparm = new eDVBFrontendParameters;
						int type;
						m_ch_current->getSystem(type);
						switch (type)
						{
						case iDVBFrontend::feSatellite:
						{
							eDVBFrontendParametersSatellite parm;
							m_ch_current->getDVBS(parm);
							parm.system = tp->getSystem();
							parm.frequency = tp->getFrequency();
							parm.symbol_rate = tp->getSymbolRate();
							parm.modulation = tp->getModulation();
							feparm->setDVBS(parm);
							break;
						}
						case iDVBFrontend::feCable:
						{
							eDVBFrontendParametersCable parm;
							m_ch_current->getDVBC(parm);
							parm.system = tp->getSystem();
							parm.frequency = tp->getFrequency();
							parm.symbol_rate = tp->getSymbolRate();
							parm.modulation = tp->getModulation();
							feparm->setDVBC(parm);
							break;
						}
						case iDVBFrontend::feTerrestrial:
						{
							eDVBFrontendParametersTerrestrial parm;
							m_ch_current->getDVBT(parm);
							parm.system = tp->getSystem();
							parm.frequency = tp->getFrequency();
							parm.bandwidth = tp->getBandwidth();
							parm.modulation = tp->getConstellation();
							feparm->setDVBT(parm);
							break;
						}
						case iDVBFrontend::feATSC:
						{
							eDVBFrontendParametersATSC parm;
							m_ch_current->getATSC(parm);
							parm.system = tp->getSystem();
							parm.frequency = tp->getFrequency();
							feparm->setATSC(parm);
							break;
						}
						}
						m_ch_current = m_ch_blindscan_result = feparm;
					}
				}
			}
		}
		startFilter();
		m_channel_state = state;
	} else if (state == iDVBChannel::state_failed)
	{
		if (m_ch_current && m_channel)
		{
			int type;
			m_ch_current->getSystem(type);
			m_ch_unavailable.push_back(m_ch_current);
			if (type == iDVBFrontend::feTerrestrial)
			{
				eDVBFrontendParametersTerrestrial parm;
				m_ch_current->getDVBT(parm);
				if (parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T_T2)
				{
					/* we have to scan T2 as well as T */
					ePtr<iDVBFrontend> fe;
					eDVBFrontendParameters eparm;
					parm.system = eDVBFrontendParametersTerrestrial::System_DVB_T2;
					eparm.setDVBT(parm);
					m_channel->getFrontend(fe);
					if (fe)
					{
						ePtr<iDVBFrontendParameters> feparm = new eDVBFrontendParameters(eparm);
						/* but only if the frontend supports T2 */
						if (fe->isCompatibleWith(feparm))
						{
							addChannelToScan(feparm);
						}
					}
				}
			}
		}
		if (!m_ch_blindscan.empty())
		{
			/* tune failure, this means the blindscan channel iteration run has completed */
			SCAN_eDebug("[eDVBScan] blindscan channel completed");
			m_ch_blindscan.pop_front();
		}
		nextChannel();
	}
			/* unavailable will timeout, anyway. */
}