Example #1
0
int eDVBServicePMTHandler::getProgramInfo(program &program)
{
	ePtr<eTable<ProgramMapSection> > ptr;
	int cached_apid_ac3 = -1;
	int cached_apid_ddp = -1;
	int cached_apid_mpeg = -1;
	int cached_apid_aache = -1;
	int cached_apid_aac = -1;
	int cached_apid_dra = -1;
	int cached_vpid = -1;
	int cached_tpid = -1;
	int ret = -1;
	uint8_t adapter, demux;

	if (m_have_cached_program)
	{
		program = m_cached_program;
		return 0;
	}

	eDVBPMTParser::clearProgramInfo(program);

	if ( m_service && !m_service->cacheEmpty() )
	{
		cached_vpid = m_service->getCacheEntry(eDVBService::cVPID);
		cached_apid_mpeg = m_service->getCacheEntry(eDVBService::cMPEGAPID);
		cached_apid_ac3 = m_service->getCacheEntry(eDVBService::cAC3PID);
		cached_apid_ddp = m_service->getCacheEntry(eDVBService::cDDPPID);
		cached_apid_aache = m_service->getCacheEntry(eDVBService::cAACHEAPID);
		cached_apid_aac = m_service->getCacheEntry(eDVBService::cAACAPID);
		cached_apid_dra = m_service->getCacheEntry(eDVBService::cDRAAPID);
		cached_tpid = m_service->getCacheEntry(eDVBService::cTPID);
	}

	if ( ((m_service && m_service->usePMT()) || !m_service) && eDVBPMTParser::getProgramInfo(program) >= 0)
	{
		unsigned int i;
		int first_non_mpeg = -1;
		int audio_cached = -1;
		int autoaudio_mpeg = -1;
		int autoaudio_ac3 = -1;
		int autoaudio_ddp = -1;
		int autoaudio_aache = -1;
		int autoaudio_aac = -1;
		int autoaudio_dra = -1;
		int autoaudio_level = 4;

		std::string configvalue;
		std::vector<std::string> autoaudio_languages;
		configvalue = eConfigManager::getConfigValue("config.autolanguage.audio_autoselect1");
		if (configvalue != "")
			autoaudio_languages.push_back(configvalue);
		configvalue = eConfigManager::getConfigValue("config.autolanguage.audio_autoselect2");
		if (configvalue != "")
			autoaudio_languages.push_back(configvalue);
		configvalue = eConfigManager::getConfigValue("config.autolanguage.audio_autoselect3");
		if (configvalue != "")
			autoaudio_languages.push_back(configvalue);
		configvalue = eConfigManager::getConfigValue("config.autolanguage.audio_autoselect4");
		if (configvalue != "")
			autoaudio_languages.push_back(configvalue);

		int autosub_txt_normal = -1;
		int autosub_txt_hearing = -1;
		int autosub_dvb_normal = -1;
		int autosub_dvb_hearing = -1;
		int autosub_level =4;

		std::vector<std::string> autosub_languages;
		configvalue = eConfigManager::getConfigValue("config.autolanguage.subtitle_autoselect1");
		if (configvalue != "")
			autosub_languages.push_back(configvalue);
		configvalue = eConfigManager::getConfigValue("config.autolanguage.subtitle_autoselect2");
		if (configvalue != "")
			autosub_languages.push_back(configvalue);
		configvalue = eConfigManager::getConfigValue("config.autolanguage.subtitle_autoselect3");
		if (configvalue != "")
			autosub_languages.push_back(configvalue);
		configvalue = eConfigManager::getConfigValue("config.autolanguage.subtitle_autoselect4");
		if (configvalue != "")
			autosub_languages.push_back(configvalue);

		m_dsmcc_pid = program.dsmccPid;
		if (program.aitPid >= 0)
		{
			m_AIT.begin(eApp, eDVBAITSpec(program.aitPid), m_demux);
		}

		for (i = 0; i < program.videoStreams.size(); i++)
		{
			if (program.videoStreams[i].pid == cached_vpid)
			{
				/* put cached vpid at the front of the videoStreams vector */
				if (i > 0)
				{
					videoStream tmp = program.videoStreams[i];
					program.videoStreams[i] = program.videoStreams[0];
					program.videoStreams[0] = tmp;
				}
				break;
			}
		}
		for (i = 0; i < program.audioStreams.size(); i++)
		{
			if (program.audioStreams[i].pid == cached_apid_ac3
			 || program.audioStreams[i].pid == cached_apid_ddp
			 || program.audioStreams[i].pid == cached_apid_mpeg
			 || program.audioStreams[i].pid == cached_apid_aache
			 || program.audioStreams[i].pid == cached_apid_aac
			 || program.audioStreams[i].pid == cached_apid_dra)
			{
				/* if we find the cached pids, this will be our default stream */
				audio_cached = i;
			}
			/* also, we need to know the first non-mpeg (i.e. "ac3"/dts/...) stream */
			if ((program.audioStreams[i].type != audioStream::atMPEG) && ((first_non_mpeg == -1)
				|| (program.audioStreams[i].pid == cached_apid_ac3)
				|| (program.audioStreams[i].pid == cached_apid_ddp)
				|| (program.audioStreams[i].pid == cached_apid_aache)
				|| (program.audioStreams[i].pid == cached_apid_aac)
				|| (program.audioStreams[i].pid == cached_apid_dra)))
			{
				first_non_mpeg = i;
			}
			if (!program.audioStreams[i].language_code.empty())
			{
				int x = 1;
				for (std::vector<std::string>::iterator it = autoaudio_languages.begin();x <= autoaudio_level && it != autoaudio_languages.end();x++,it++)
				{
					bool languageFound = false;
					size_t pos = 0;
					char delimiter = '/';
					std::string audioStreamLanguages = program.audioStreams[i].language_code;
					audioStreamLanguages += delimiter;
					while ((pos = audioStreamLanguages.find(delimiter)) != std::string::npos)
					{
						if ((*it).find(audioStreamLanguages.substr(0, pos)) != std::string::npos)
						{
							if (program.audioStreams[i].type == audioStream::atMPEG && (autoaudio_level > x || autoaudio_mpeg == -1))
								autoaudio_mpeg = i;
							else if (program.audioStreams[i].type == audioStream::atAC3 && (autoaudio_level > x || autoaudio_ac3 == -1))
								autoaudio_ac3 = i;
							else if (program.audioStreams[i].type == audioStream::atDDP && (autoaudio_level > x || autoaudio_ddp == -1))
								autoaudio_ddp = i;
							else if (program.audioStreams[i].type == audioStream::atAACHE && (autoaudio_level > x || autoaudio_aache == -1))
								autoaudio_aache = i;
							else if (program.audioStreams[i].type == audioStream::atAAC && (autoaudio_level > x || autoaudio_aac == -1))
								autoaudio_aac = i;
							else if (program.audioStreams[i].type == audioStream::atDRA && (autoaudio_level > x || autoaudio_dra == -1))
								autoaudio_dra = i;
							autoaudio_level = x;
							languageFound = true;
							break;
						}
						audioStreamLanguages.erase(0, pos + 1);
					}
					if (languageFound)
						break;
				}
			}
		}
		for (i = 0; i < program.subtitleStreams.size(); i++)
		{
			if (!program.subtitleStreams[i].language_code.empty())
			{
				int x = 1;
				for (std::vector<std::string>::iterator it2 = autosub_languages.begin();x <= autosub_level && it2 != autosub_languages.end();x++,it2++)
				{
					if ((*it2).find(program.subtitleStreams[i].language_code) != std::string::npos)
					{
						autosub_level = x;
						if (program.subtitleStreams[i].subtitling_type >= 0x10)
						{
							/* DVB subs */
							if (program.subtitleStreams[i].subtitling_type >= 0x20)
								autosub_dvb_hearing = i;
							else
								autosub_dvb_normal = i;
						}
						else
						{
							/* TXT subs */
							if (program.subtitleStreams[i].subtitling_type == 0x05)
								autosub_txt_hearing = i;
							else
								autosub_txt_normal = i;
						}
						break;
					}
				}
			}
		}

		bool defaultac3 = eConfigManager::getConfigBoolValue("config.autolanguage.audio_defaultac3");
		bool defaultddp = eConfigManager::getConfigBoolValue("config.autolanguage.audio_defaultddp");
		bool useaudio_cache = eConfigManager::getConfigBoolValue("config.autolanguage.audio_usecache");

		if (useaudio_cache && audio_cached != -1)
			program.defaultAudioStream = audio_cached;
		else if (defaultac3 && autoaudio_ac3 != -1)
			program.defaultAudioStream = autoaudio_ac3;
		else if (defaultddp && autoaudio_ddp != -1)
			program.defaultAudioStream = autoaudio_ddp;
		else
		{
			if (autoaudio_mpeg != -1)
				program.defaultAudioStream = autoaudio_mpeg;
			else if (autoaudio_ac3 != -1)
				program.defaultAudioStream = autoaudio_ac3;
			else if (autoaudio_ddp != -1)
				program.defaultAudioStream = autoaudio_ddp;
			else if (autoaudio_aache != -1)
				program.defaultAudioStream = autoaudio_aache;
			else if (autoaudio_aac != -1)
				program.defaultAudioStream = autoaudio_aac;
			else if (first_non_mpeg != -1 && (defaultac3 || defaultddp))
				program.defaultAudioStream = first_non_mpeg;
		}

		bool allow_hearingimpaired = eConfigManager::getConfigBoolValue("config.autolanguage.subtitle_hearingimpaired");
		bool default_hearingimpaired = eConfigManager::getConfigBoolValue("config.autolanguage.subtitle_defaultimpaired");
		bool defaultdvb = eConfigManager::getConfigBoolValue("config.autolanguage.subtitle_defaultdvb");
		int equallanguagemask = eConfigManager::getConfigIntValue("config.autolanguage.equal_languages");

		if (defaultdvb)
		{
			if (allow_hearingimpaired && default_hearingimpaired && autosub_dvb_hearing != -1)
				program.defaultSubtitleStream = autosub_dvb_hearing;
			else if (autosub_dvb_normal != -1)
				program.defaultSubtitleStream = autosub_dvb_normal;
			else if (allow_hearingimpaired && autosub_dvb_hearing != -1)
				program.defaultSubtitleStream = autosub_dvb_hearing;
			else if (allow_hearingimpaired && default_hearingimpaired && autosub_txt_hearing != -1)
				program.defaultSubtitleStream = autosub_txt_hearing;
			else if (autosub_txt_normal != -1)
				program.defaultSubtitleStream = autosub_txt_normal;
			else if (allow_hearingimpaired && autosub_txt_hearing != -1)
				program.defaultSubtitleStream = autosub_txt_hearing;
		}
		else
		{
			if (allow_hearingimpaired && default_hearingimpaired && autosub_txt_hearing != -1)
				program.defaultSubtitleStream = autosub_txt_hearing;
			else if (autosub_txt_normal != -1)
				program.defaultSubtitleStream = autosub_txt_normal;
			else if (allow_hearingimpaired && autosub_txt_hearing != -1)
				program.defaultSubtitleStream = autosub_txt_hearing;
			else if (allow_hearingimpaired && default_hearingimpaired && autosub_dvb_hearing != -1)
				program.defaultSubtitleStream = autosub_dvb_hearing;
			else if (autosub_dvb_normal != -1)
				program.defaultSubtitleStream = autosub_dvb_normal;
			else if (allow_hearingimpaired && autosub_dvb_hearing != -1)
				program.defaultSubtitleStream = autosub_dvb_hearing;
		}
		if (program.defaultSubtitleStream != -1 && (equallanguagemask & (1<<(autosub_level-1))) == 0 && program.subtitleStreams[program.defaultSubtitleStream].language_code.compare(program.audioStreams[program.defaultAudioStream].language_code) == 0 )
			program.defaultSubtitleStream = -1;

		ret = 0;
	}
	else if ( m_service && !m_service->cacheEmpty() )
	{
		int cached_pcrpid = m_service->getCacheEntry(eDVBService::cPCRPID),
			vpidtype = m_service->getCacheEntry(eDVBService::cVTYPE),
			pmtpid = m_service->getCacheEntry(eDVBService::cPMTPID),
			subpid = m_service->getCacheEntry(eDVBService::cSUBTITLE),
			cnt=0;
		if (pmtpid > 0)
		{
			program.pmtPid = pmtpid;
		}
		if ( vpidtype == -1 )
			vpidtype = videoStream::vtMPEG2;
		if ( cached_vpid != -1 )
		{
			videoStream s;
			s.pid = cached_vpid;
			s.type = vpidtype;
			program.videoStreams.push_back(s);
			++cnt;
		}
		if ( cached_apid_ac3 != -1 )
		{
			audioStream s;
			s.type = audioStream::atAC3;
			s.pid = cached_apid_ac3;
			s.rdsPid = -1;
			program.audioStreams.push_back(s);
			++cnt;
		}
		if ( cached_apid_ddp != -1 )
		{
			audioStream s;
			s.type = audioStream::atDDP;
			s.pid = cached_apid_ddp;
			s.rdsPid = -1;
			program.audioStreams.push_back(s);
			++cnt;
		}
		if ( cached_apid_aache != -1 )
		{
			audioStream s;
			s.type = audioStream::atAACHE;
			s.pid = cached_apid_aache;
			s.rdsPid = -1;
			program.audioStreams.push_back(s);
			++cnt;
		}
		if ( cached_apid_aac != -1 )
		{
			audioStream s;
			s.type = audioStream::atAAC;
			s.pid = cached_apid_aac;
			s.rdsPid = -1;
			program.audioStreams.push_back(s);
			++cnt;
		}
		if ( cached_apid_dra != -1 )
		{
			audioStream s;
			s.type = audioStream::atDRA;
			s.pid = cached_apid_dra;
			s.rdsPid = -1;
			program.audioStreams.push_back(s);
			++cnt;
		}
		if ( cached_apid_mpeg != -1 )
		{
			audioStream s;
			s.type = audioStream::atMPEG;
			s.pid = cached_apid_mpeg;
			s.rdsPid = -1;
			program.audioStreams.push_back(s);
			++cnt;
		}
		if ( cached_pcrpid != -1 )
		{
			++cnt;
			program.pcrPid = cached_pcrpid;
		}
		if ( cached_tpid != -1 )
		{
			++cnt;
			program.textPid = cached_tpid;
		}
		if (subpid > 0)
		{
			subtitleStream s;
			s.pid = (subpid & 0xffff0000) >> 16;
			if (s.pid != program.textPid)
			{
				s.subtitling_type = 0x10;
				s.composition_page_id = (subpid >> 8) & 0xff;
				s.ancillary_page_id = subpid & 0xff;
				program.subtitleStreams.push_back(s);
				++cnt;
			}
Example #2
0
int eDVBServicePMTHandler::getProgramInfo(program &program)
{
	ePtr<eTable<ProgramMapSection> > ptr;
	int cached_apid_ac3 = -1;
	int cached_apid_mpeg = -1;
	int cached_apid_aache = -1;
	int cached_vpid = -1;
	int cached_tpid = -1;
	int ret = -1;
	uint8_t adapter, demux;

	if (m_have_cached_program)
	{
		program = m_cached_program;
		return 0;
	}

	eDVBPMTParser::clearProgramInfo(program);

	if ( m_service && !m_service->cacheEmpty() )
	{
		cached_vpid = m_service->getCacheEntry(eDVBService::cVPID);
		cached_apid_mpeg = m_service->getCacheEntry(eDVBService::cMPEGAPID);
		cached_apid_ac3 = m_service->getCacheEntry(eDVBService::cAC3PID);
		cached_apid_aache = m_service->getCacheEntry(eDVBService::cAACHEAPID);
		cached_tpid = m_service->getCacheEntry(eDVBService::cTPID);
	}

	if ( ((m_service && m_service->usePMT()) || !m_service) && eDVBPMTParser::getProgramInfo(program) >= 0)
	{
		unsigned int i;
		int first_non_mpeg = -1;
		int audio_cached = -1;
		int autoaudio_mpeg = -1;
		int autoaudio_ac3 = -1;
		int autoaudio_aache = -1;
		int autoaudio_level = 4;

		std::string configvalue;
		std::vector<std::string> autoaudio_languages;
		configvalue = eConfigManager::getConfigValue("config.autolanguage.audio_autoselect1");
		if (configvalue != "" && configvalue != "None")
			autoaudio_languages.push_back(configvalue);
		configvalue = eConfigManager::getConfigValue("config.autolanguage.audio_autoselect2");
		if (configvalue != "" && configvalue != "None")
			autoaudio_languages.push_back(configvalue);
		configvalue = eConfigManager::getConfigValue("config.autolanguage.audio_autoselect3");
		if (configvalue != "" && configvalue != "None")
			autoaudio_languages.push_back(configvalue);
		configvalue = eConfigManager::getConfigValue("config.autolanguage.audio_autoselect4");
		if (configvalue != "" && configvalue != "None")
			autoaudio_languages.push_back(configvalue);

		int autosub_txt_normal = -1;
		int autosub_txt_hearing = -1;
		int autosub_dvb_normal = -1;
		int autosub_dvb_hearing = -1;
		int autosub_level =4;

		std::vector<std::string> autosub_languages;
		configvalue = eConfigManager::getConfigValue("config.autolanguage.subtitle_autoselect1");
		if (configvalue != "" && configvalue != "None")
			autosub_languages.push_back(configvalue);
		configvalue = eConfigManager::getConfigValue("config.autolanguage.subtitle_autoselect2");
		if (configvalue != "" && configvalue != "None")
			autosub_languages.push_back(configvalue);
		configvalue = eConfigManager::getConfigValue("config.autolanguage.subtitle_autoselect3");
		if (configvalue != "" && configvalue != "None")
			autosub_languages.push_back(configvalue);
		configvalue = eConfigManager::getConfigValue("config.autolanguage.subtitle_autoselect4");
		if (configvalue != "" && configvalue != "None")
			autosub_languages.push_back(configvalue);

		m_dsmcc_pid = program.dsmccPid;
		if (program.aitPid >= 0)
		{
			m_AIT.begin(eApp, eDVBAITSpec(program.aitPid), m_demux);
		}

		for (i = 0; i < program.videoStreams.size(); i++)
		{
			if (program.videoStreams[i].pid == cached_vpid)
			{
				/* put cached vpid at the front of the videoStreams vector */
				if (i > 0)
				{
					videoStream tmp = program.videoStreams[i];
					program.videoStreams[i] = program.videoStreams[0];
					program.videoStreams[0] = tmp;
				}
				break;
			}
		}
		for (i = 0; i < program.audioStreams.size(); i++)
		{
			if (program.audioStreams[i].pid == cached_apid_ac3 || program.audioStreams[i].pid == cached_apid_mpeg || program.audioStreams[i].pid == cached_apid_aache)
			{
				/* if we find the cached pids, this will be our default stream */
				audio_cached = i;
			}
			/* also, we need to know the first non-mpeg (i.e. "ac3"/dts/...) stream */
			if ((program.audioStreams[i].type != audioStream::atMPEG) && ((first_non_mpeg == -1) || (program.audioStreams[i].pid == cached_apid_ac3) || (program.audioStreams[i].pid == cached_apid_aache)))
			{
				first_non_mpeg = i;
			}
			if (!program.audioStreams[i].language_code.empty())
			{
				int x = 1;
				for (std::vector<std::string>::iterator it = autoaudio_languages.begin();x <= autoaudio_level && it != autoaudio_languages.end();x++,it++)
				{
					if ((*it).find(program.audioStreams[i].language_code) != std::string::npos)
					{
						if (program.audioStreams[i].type == audioStream::atMPEG && (autoaudio_level > x || autoaudio_mpeg == -1)) 
							autoaudio_mpeg = i;
						else if (program.audioStreams[i].type == audioStream::atAC3 && (autoaudio_level > x || autoaudio_ac3 == -1))
							autoaudio_ac3 = i;
						else if (program.audioStreams[i].type == audioStream::atAACHE && (autoaudio_level > x || autoaudio_aache == -1))
							autoaudio_aache = i;
						autoaudio_level = x;
						break;
					}
				}
			}
		}
		for (i = 0; i < program.subtitleStreams.size(); i++)
		{
			if (!program.subtitleStreams[i].language_code.empty())
			{
				int x = 1;
				for (std::vector<std::string>::iterator it2 = autosub_languages.begin();x <= autosub_level && it2 != autosub_languages.end();x++,it2++)
				{
					if ((*it2).find(program.subtitleStreams[i].language_code) != std::string::npos)
					{
						autosub_level = x;
						if (program.subtitleStreams[i].subtitling_type >= 0x10)
						{
							/* DVB subs */
							if (program.subtitleStreams[i].subtitling_type >= 0x20)
								autosub_dvb_hearing = i;
							else
								autosub_dvb_normal = i;
						}
						else
						{
							/* TXT subs */
							if (program.subtitleStreams[i].subtitling_type == 0x05)
								autosub_txt_hearing = i;
							else
								autosub_txt_normal = i;
						}
						break;
					}
				}
			}
		}

		bool defaultac3 = eConfigManager::getConfigBoolValue("config.autolanguage.audio_defaultac3");
		bool useaudio_cache = eConfigManager::getConfigBoolValue("config.autolanguage.audio_usecache");

		if (useaudio_cache && audio_cached != -1)
			program.defaultAudioStream = audio_cached;
		else if ( defaultac3 )
		{
			if ( autoaudio_ac3 != -1 )
				program.defaultAudioStream = autoaudio_ac3;
			else if ( autoaudio_mpeg != -1 )
				program.defaultAudioStream = autoaudio_mpeg;
			else if ( first_non_mpeg != -1 )
				program.defaultAudioStream = first_non_mpeg;
		}
		else
		{
			if ( autoaudio_mpeg != -1 )
				program.defaultAudioStream = autoaudio_mpeg;
			else if ( autoaudio_ac3 != -1 )
				program.defaultAudioStream = autoaudio_ac3;
			else if ( autoaudio_aache != -1 )
				program.defaultAudioStream = autoaudio_aache;
		}

		bool allow_hearingimpaired = eConfigManager::getConfigBoolValue("config.autolanguage.subtitle_hearingimpaired");
		bool default_hearingimpaired = eConfigManager::getConfigBoolValue("config.autolanguage.subtitle_defaultimpaired");
		bool defaultdvb = eConfigManager::getConfigBoolValue("config.autolanguage.subtitle_defaultdvb");
		int equallanguagemask = eConfigManager::getConfigIntValue("config.autolanguage.equal_languages");

		if (defaultdvb)
		{
			if (allow_hearingimpaired && default_hearingimpaired && autosub_dvb_hearing != -1)
				program.defaultSubtitleStream = autosub_dvb_hearing;
			else if (autosub_dvb_normal != -1)
				program.defaultSubtitleStream = autosub_dvb_normal;
			else if (allow_hearingimpaired && autosub_dvb_hearing != -1)
				program.defaultSubtitleStream = autosub_dvb_hearing;
			else if (allow_hearingimpaired && default_hearingimpaired && autosub_txt_hearing != -1)
				program.defaultSubtitleStream = autosub_txt_hearing;
			else if (autosub_txt_normal != -1)
				program.defaultSubtitleStream = autosub_txt_normal;
			else if (allow_hearingimpaired && autosub_txt_hearing != -1)
				program.defaultSubtitleStream = autosub_txt_hearing;
		}
		else
		{
			if (allow_hearingimpaired && default_hearingimpaired && autosub_txt_hearing != -1)
				program.defaultSubtitleStream = autosub_txt_hearing;
			else if (autosub_txt_normal != -1)
				program.defaultSubtitleStream = autosub_txt_normal;
			else if (allow_hearingimpaired && autosub_txt_hearing != -1)
				program.defaultSubtitleStream = autosub_txt_hearing;
			else if (allow_hearingimpaired && default_hearingimpaired && autosub_dvb_hearing != -1)
				program.defaultSubtitleStream = autosub_dvb_hearing;
			else if (autosub_dvb_normal != -1)
				program.defaultSubtitleStream = autosub_dvb_normal;
			else if (allow_hearingimpaired && autosub_dvb_hearing != -1)
				program.defaultSubtitleStream = autosub_dvb_hearing;
		}
		if (program.defaultSubtitleStream != -1 && (equallanguagemask & (1<<(autosub_level-1))) == 0 && program.subtitleStreams[program.defaultSubtitleStream].language_code.compare(program.audioStreams[program.defaultAudioStream].language_code) == 0 )
			program.defaultSubtitleStream = -1;

		ret = 0;
	}
	else if ( m_service && !m_service->cacheEmpty() )
	{
		int cached_pcrpid = m_service->getCacheEntry(eDVBService::cPCRPID),
			vpidtype = m_service->getCacheEntry(eDVBService::cVTYPE),
			cnt=0;
		if ( vpidtype == -1 )
			vpidtype = videoStream::vtMPEG2;
		if ( cached_vpid != -1 )
		{
			videoStream s;
			s.pid = cached_vpid;
			s.type = vpidtype;
			program.videoStreams.push_back(s);
			++cnt;
		}
		if ( cached_apid_ac3 != -1 )
		{
			audioStream s;
			s.type = audioStream::atAC3;
			s.pid = cached_apid_ac3;
			s.rdsPid = -1;
			program.audioStreams.push_back(s);
			++cnt;
		}
		if ( cached_apid_aache != -1 )
		{
			audioStream s;
			s.type = audioStream::atAACHE;
			s.pid = cached_apid_aache;
			s.rdsPid = -1;
			program.audioStreams.push_back(s);
			++cnt;
		}
		if ( cached_apid_mpeg != -1 )
		{
			audioStream s;
			s.type = audioStream::atMPEG;
			s.pid = cached_apid_mpeg;
			s.rdsPid = -1;
			program.audioStreams.push_back(s);
			++cnt;
		}
		if ( cached_pcrpid != -1 )
		{
			++cnt;
			program.pcrPid = cached_pcrpid;
		}
		if ( cached_tpid != -1 )
		{
			++cnt;
			program.textPid = cached_tpid;
		}
		CAID_LIST &caids = m_service->m_ca;
		for (CAID_LIST::iterator it(caids.begin()); it != caids.end(); ++it) {
			program::capid_pair pair;
			pair.caid = *it;
			pair.capid = -1; // not known yet
			program.caids.push_back(pair);
		}
		if ( cnt )
			ret = 0;
	}

	if (m_demux)
	{
		m_demux->getCAAdapterID(adapter);
		program.adapterId = adapter;
		m_demux->getCADemuxID(demux);
		program.demuxId = demux;
	}

	m_cached_program = program;
	m_have_cached_program = true;
	return ret;
}
Example #3
0
int eDVBServicePMTHandler::getProgramInfo(program &program)
{
	ePtr<eTable<ProgramMapSection> > ptr;
	int cached_apid_ac3 = -1;
	int cached_apid_mpeg = -1;
	int cached_vpid = -1;
	int cached_tpid = -1;
	int ret = -1;

	if (m_have_cached_program)
	{
		program = m_cached_program;
		return 0;
	}

	program.videoStreams.clear();
	program.audioStreams.clear();
	program.subtitleStreams.clear();
	program.pcrPid = -1;
	program.pmtPid = -1;
	program.textPid = -1;
	program.aitPid = -1;

	program.defaultAudioStream = 0;
	program.defaultSubtitleStream = -1;

	if ( m_service && !m_service->cacheEmpty() )
	{
		cached_vpid = m_service->getCacheEntry(eDVBService::cVPID);
		cached_apid_mpeg = m_service->getCacheEntry(eDVBService::cAPID);
		cached_apid_ac3 = m_service->getCacheEntry(eDVBService::cAC3PID);
		cached_tpid = m_service->getCacheEntry(eDVBService::cTPID);
	}

	if ( ((m_service && m_service->usePMT()) || !m_service) && !m_PMT.getCurrent(ptr))
	{
		int first_ac3 = -1;
		int audio_cached = -1;
		int autoaudio_mpeg = -1;
		int autoaudio_ac3 = -1;
		int autoaudio_level = 4;

		std::string configvalue;
		std::vector<std::string> autoaudio_languages;
		if (!ePythonConfigQuery::getConfigValue("config.autolanguage.audio_autoselect1", configvalue) && configvalue != "None")
			autoaudio_languages.push_back(configvalue);
		if (!ePythonConfigQuery::getConfigValue("config.autolanguage.audio_autoselect2", configvalue) && configvalue != "None")
			autoaudio_languages.push_back(configvalue);
		if (!ePythonConfigQuery::getConfigValue("config.autolanguage.audio_autoselect3", configvalue) && configvalue != "None")
			autoaudio_languages.push_back(configvalue);
		if (!ePythonConfigQuery::getConfigValue("config.autolanguage.audio_autoselect4", configvalue) && configvalue != "None")
			autoaudio_languages.push_back(configvalue);

		audioStream *prev_audio = 0;

		int autosub_txt_normal = -1;
		int autosub_txt_hearing = -1;
		int autosub_dvb_normal = -1;
		int autosub_dvb_hearing = -1;
		int autosub_level =4;

		std::vector<std::string> autosub_languages;
		if (!ePythonConfigQuery::getConfigValue("config.autolanguage.subtitle_autoselect1", configvalue) && configvalue != "None")
			autosub_languages.push_back(configvalue);
		if (!ePythonConfigQuery::getConfigValue("config.autolanguage.subtitle_autoselect2", configvalue) && configvalue != "None")
			autosub_languages.push_back(configvalue);
		if (!ePythonConfigQuery::getConfigValue("config.autolanguage.subtitle_autoselect3", configvalue) && configvalue != "None")
			autosub_languages.push_back(configvalue);
		if (!ePythonConfigQuery::getConfigValue("config.autolanguage.subtitle_autoselect4", configvalue) && configvalue != "None")
			autosub_languages.push_back(configvalue);

		eDVBTableSpec table_spec;
		ptr->getSpec(table_spec);
		program.pmtPid = table_spec.pid < 0x1fff ? table_spec.pid : -1;
		std::vector<ProgramMapSection*>::const_iterator i;
		for (i = ptr->getSections().begin(); i != ptr->getSections().end(); ++i)
		{
			const ProgramMapSection &pmt = **i;
			int is_hdmv = 0;

			program.pcrPid = pmt.getPcrPid();

			for (DescriptorConstIterator desc = pmt.getDescriptors()->begin();
				desc != pmt.getDescriptors()->end(); ++desc)
			{
				if ((*desc)->getTag() == CA_DESCRIPTOR)
				{
					CaDescriptor *descr = (CaDescriptor*)(*desc);
					program::capid_pair pair;
					pair.caid = descr->getCaSystemId();
					pair.capid = descr->getCaPid();
					program.caids.push_back(pair);
				}
				else if ((*desc)->getTag() == REGISTRATION_DESCRIPTOR)
				{
					RegistrationDescriptor *d = (RegistrationDescriptor*)(*desc);
					if (d->getFormatIdentifier() == 0x48444d56) // HDMV
						is_hdmv = 1;
				}
			}

			ElementaryStreamInfoConstIterator es;
			for (es = pmt.getEsInfo()->begin(); es != pmt.getEsInfo()->end(); ++es)
			{
				int isaudio = 0, isvideo = 0, issubtitle = 0, forced_video = 0, forced_audio = 0, isteletext = 0;
				int streamtype = (*es)->getType();
				videoStream video;
				audioStream audio;
				audio.component_tag=video.component_tag=-1;
				video.type = videoStream::vtMPEG2;
				audio.type = audioStream::atMPEG;
				audio.rdsPid = -1;

				switch (streamtype)
				{
				case 0x1b: // AVC Video Stream (MPEG4 H264)
					video.type = videoStream::vtMPEG4_H264;
					isvideo = 1;
					//break; fall through !!!
				case 0x10: // MPEG 4 Part 2
					if (!isvideo)
					{
						video.type = videoStream::vtMPEG4_Part2;
						isvideo = 1;
					}
					//break; fall through !!!
				case 0x01: // MPEG 1 video
					if (!isvideo)
						video.type = videoStream::vtMPEG1;
					//break; fall through !!!
				case 0x02: // MPEG 2 video
					isvideo = 1;
					forced_video = 1;
					//break; fall through !!!
				case 0x03: // MPEG 1 audio
				case 0x04: // MPEG 2 audio:
					if (!isvideo) {
						isaudio = 1;
						forced_audio = 1;
					}
					//break; fall through !!!
				case 0x0f: // MPEG 2 AAC
					if (!isvideo && !isaudio)
					{
						isaudio = 1;
						audio.type = audioStream::atAAC;
						forced_audio = 1;
					}
					//break; fall through !!!
				case 0x11: // MPEG 4 AAC
					if (!isvideo && !isaudio)
					{
						isaudio = 1;
						audio.type = audioStream::atAACHE;
						forced_audio = 1;
					}
				case 0x80: // user private ... but bluray LPCM
				case 0xA0: // bluray secondary LPCM
					if (!isvideo && !isaudio && is_hdmv)
					{
						isaudio = 1;
						audio.type = audioStream::atLPCM;
					}
				case 0x81: // user private ... but bluray AC3
				case 0xA1: // bluray secondary AC3
					if (!isvideo && !isaudio)
					{
						isaudio = 1;
						audio.type = audioStream::atAC3;
					}
				case 0x82: // bluray DTS (dvb user private...)
				case 0xA2: // bluray secondary DTS
					if (!isvideo && !isaudio && is_hdmv)
					{
						isaudio = 1;
						audio.type = audioStream::atDTS;
					}
				case 0x86: // bluray DTS-HD (dvb user private...)
				case 0xA6: // bluray secondary DTS-HD
					if (!isvideo && !isaudio && is_hdmv)
					{
						isaudio = 1;
						audio.type = audioStream::atDTSHD;
					}
				case 0x06: // PES Private
				case 0xEA: // TS_PSI_ST_SMPTE_VC1
				{
					int num_descriptors = 0;
					for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin();
						desc != (*es)->getDescriptors()->end(); ++desc)
					{
						uint8_t tag = (*desc)->getTag();
						/* check descriptors to get the exakt stream type. */
						++num_descriptors;
						if (!forced_video && !forced_audio)
						{
							switch (tag)
							{
							case AUDIO_STREAM_DESCRIPTOR:
								isaudio = 1;
								break;
							case VIDEO_STREAM_DESCRIPTOR:
							{
								isvideo = 1;
								VideoStreamDescriptor *d = (VideoStreamDescriptor*)(*desc);
								if (d->getMpeg1OnlyFlag())
									video.type = videoStream::vtMPEG1;
								break;
							}
							case SUBTITLING_DESCRIPTOR:
							{
								SubtitlingDescriptor *d = (SubtitlingDescriptor*)(*desc);
								const SubtitlingList *list = d->getSubtitlings();
								subtitleStream s;
								s.pid = (*es)->getPid();
								for (SubtitlingConstIterator it(list->begin()); it != list->end(); ++it)
								{
									s.subtitling_type = (*it)->getSubtitlingType();
									switch(s.subtitling_type)
									{
									case 0x10 ... 0x13: // dvb subtitles normal
									case 0x20 ... 0x23: // dvb subtitles hearing impaired
										break;
									default:
										eDebug("dvb subtitle %s PID %04x with wrong subtitling type (%02x)... force 0x10!!",
										s.language_code.c_str(), s.pid, s.subtitling_type);
										s.subtitling_type = 0x10;
										break;
									}
									s.composition_page_id = (*it)->getCompositionPageId();
									s.ancillary_page_id = (*it)->getAncillaryPageId();
									std::string language = (*it)->getIso639LanguageCode();
									s.language_code = language;
//								eDebug("add dvb subtitle %s PID %04x, type %d, composition page %d, ancillary_page %d", s.language_code.c_str(), s.pid, s.subtitling_type, s.composition_page_id, s.ancillary_page_id);

									if (!language.empty())
									{
										int x = 1;
										for (std::vector<std::string>::iterator it2 = autosub_languages.begin();x <= autosub_level && it2 != autosub_languages.end();x++,it2++)
										{
											if ((*it2).find(language) != std::string::npos)
											{
												autosub_level = x;
												if (s.subtitling_type >= 0x20)
													autosub_dvb_hearing = program.subtitleStreams.size();
												else
													autosub_dvb_normal = program.subtitleStreams.size();
												break;
											}
										}
									}
									issubtitle = 1;
									program.subtitleStreams.push_back(s);
								}
								break;
							}
							case TELETEXT_DESCRIPTOR:
								if ( program.textPid == -1 || (*es)->getPid() == cached_tpid )
								{
									subtitleStream s;
									s.subtitling_type = 0x01; // EBU TELETEXT SUBTITLES
									s.pid = program.textPid = (*es)->getPid();
									TeletextDescriptor *d = (TeletextDescriptor*)(*desc);
									isteletext = 1;
									const VbiTeletextList *list = d->getVbiTeletexts();
									std::string language;
									for (VbiTeletextConstIterator it(list->begin()); it != list->end(); ++it)
									{
										switch((*it)->getTeletextType())
										{
										case 0x02: // Teletext subtitle page
										case 0x05: // Teletext subtitle page for hearing impaired pepople
											language = (*it)->getIso639LanguageCode();
											s.language_code = language;
											s.teletext_page_number = (*it)->getTeletextPageNumber();
											s.teletext_magazine_number = (*it)->getTeletextMagazineNumber();
//										eDebug("add teletext subtitle %s PID %04x, page number %d, magazine number %d", s.language_code.c_str(), s.pid, s.teletext_page_number, s.teletext_magazine_number);
											if (!language.empty())
											{
												int x = 1;
												for (std::vector<std::string>::iterator it2 = autosub_languages.begin();x <= autosub_level && it2 != autosub_languages.end();x++,it2++)
												{
													if ((*it2).find(language) != std::string::npos)
													{
														autosub_level = x;
														if (s.subtitling_type == 0x05)
															autosub_txt_hearing = program.subtitleStreams.size();
														else
															autosub_txt_normal = program.subtitleStreams.size();
														break;
													}
												}
											}
											program.subtitleStreams.push_back(s);
											issubtitle=1;
										default:
											break;
										}
									}
								}
								break;
							case DTS_DESCRIPTOR:
								isaudio = 1;
								audio.type = audioStream::atDTS;
								break;
							case 0x2B: // TS_PSI_DT_MPEG2_AAC
								isaudio = 1;
								audio.type = audioStream::atAAC; // MPEG2-AAC
								break;
							case 0x1C: // TS_PSI_DT_MPEG4_Audio
							case AAC_DESCRIPTOR:
								isaudio = 1;
								audio.type = audioStream::atAACHE; // MPEG4-AAC
								break;
							case AC3_DESCRIPTOR:
								isaudio = 1;
								audio.type = audioStream::atAC3;
								break;
							case ENHANCED_AC3_DESCRIPTOR:
								isaudio = 1;
								audio.type = audioStream::atDDP;
								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
									isaudio = 1;
									audio.type = audioStream::atDTS;
									break;
								case 0x41432d33: // == 'AC-3'
									isaudio = 1;
									audio.type = audioStream::atAC3;
									break;
								case 0x42535344: // == 'BSSD' (LPCM)
									isaudio = 1;
									audio.type = audioStream::atLPCM;
									break;
								case 0x56432d31: // == 'VC-1'
								{
									const AdditionalIdentificationInfoVector *vec = d->getAdditionalIdentificationInfo();
									if (vec->size() > 1 && (*vec)[0] == 0x01) // subdescriptor tag
									{
										if ((*vec)[1] >= 0x90) // profile_level
											video.type = videoStream::vtVC1; // advanced profile
										else
											video.type = videoStream::vtVC1_SM; // simple main
										isvideo = 1;
									}
								}
								default:
									break;
								}
								break;
							}
							case 0x28: // TS_PSI_DT_AVC
								isvideo = 1;
								video.type = videoStream::vtMPEG4_H264;
								break;
							case 0x1B: // TS_PSI_DT_MPEG4_Video
								isvideo = 1;
								video.type = videoStream::vtMPEG4_Part2;
								break;
							default:
								break;
							}
						}
						switch (tag)
						{
						case ISO_639_LANGUAGE_DESCRIPTOR:
							if (!isvideo)
							{
								const Iso639LanguageList *languages = ((Iso639LanguageDescriptor*)*desc)->getIso639Languages();
								/* use last language code */
								int cnt=0;
								for (Iso639LanguageConstIterator i=languages->begin(); i != languages->end(); ++i)
								{
									std::string language=(*i)->getIso639LanguageCode();
									if ( cnt==0 )
										audio.language_code = language;
									else
										audio.language_code += "/" + language;
									cnt++;
										
									if (!language.empty())
									{
										int x = 1;
										for (std::vector<std::string>::iterator it = autoaudio_languages.begin();x <= autoaudio_level && it != autoaudio_languages.end();x++,it++)
										{
											if ((*it).find(language) != std::string::npos)
											{
												if (audio.type == audioStream::atMPEG && (autoaudio_level > x || autoaudio_mpeg == -1)) 
													autoaudio_mpeg = program.audioStreams.size();
												else if (audio.type != audioStream::atMPEG && (autoaudio_level > x || autoaudio_ac3 == -1))
													autoaudio_ac3 = program.audioStreams.size();
												autoaudio_level = x;
												break;
											}
										}
									}
								}
							}
							break;
						case STREAM_IDENTIFIER_DESCRIPTOR:
							audio.component_tag =
								video.component_tag =
									((StreamIdentifierDescriptor*)*desc)->getComponentTag();
							break;
						case CA_DESCRIPTOR:
						{
							CaDescriptor *descr = (CaDescriptor*)(*desc);
							program::capid_pair pair;
							pair.caid = descr->getCaSystemId();
							pair.capid = descr->getCaPid();
							program.caids.push_back(pair);
							break;
						}
						default:
							break;
						}
					}
					if (!num_descriptors && streamtype == 0x06 && prev_audio)
					{
						prev_audio->rdsPid = (*es)->getPid();
						eDebug("Rds PID %04x detected ? ! ?", prev_audio->rdsPid);
					}
					prev_audio = 0;
					break;
				}
				case 0x05: /* ITU-T Rec. H.222.0 | ISO/IEC 13818-1 private sections */
				{
					for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin();
						desc != (*es)->getDescriptors()->end(); ++desc)
					{
						switch ((*desc)->getTag())
						{
						case APPLICATION_SIGNALLING_DESCRIPTOR:
							program.aitPid = (*es)->getPid();
							m_AIT.begin(eApp, eDVBAITSpec(program.aitPid), m_demux);
							break;
						}
					}
					break;
				}
				case 0x0b: /* ISO/IEC 13818-6 DSM-CC U-N Messages */
				{
					for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin();
						desc != (*es)->getDescriptors()->end(); ++desc)
					{
						switch ((*desc)->getTag())
						{
						case CAROUSEL_IDENTIFIER_DESCRIPTOR:
							m_dsmcc_pid = (*es)->getPid();
							break;
						case STREAM_IDENTIFIER_DESCRIPTOR:
							break;
						}
					}
					break;
				}
				default:
					break;
				}
				if (isteletext && (isaudio || isvideo))
				{
					eDebug("ambiguous streamtype for PID %04x detected.. forced as teletext!", (*es)->getPid());
					continue; // continue with next PID
				}
				else if (issubtitle && (isaudio || isvideo))
					eDebug("ambiguous streamtype for PID %04x detected.. forced as subtitle!", (*es)->getPid());
				else if (isaudio && isvideo)
					eDebug("ambiguous streamtype for PID %04x detected.. forced as video!", (*es)->getPid());
				if (issubtitle) // continue with next PID
					continue;
				else if (isvideo)
				{
					video.pid = (*es)->getPid();
					if ( !program.videoStreams.empty() && video.pid == cached_vpid )
					{
						program.videoStreams.push_back(program.videoStreams[0]);
						program.videoStreams[0] = video;
					}
					else
						program.videoStreams.push_back(video);
				}
				else if (isaudio)
				{
					audio.pid = (*es)->getPid();

					/* if we find the cached pids, this will be our default stream */
					if (audio.pid == cached_apid_ac3 || audio.pid == cached_apid_mpeg)
						audio_cached = program.audioStreams.size();

					/* also, we need to know the first non-mpeg (i.e. "ac3"/dts/...) stream */
					if ((audio.type != audioStream::atMPEG) && ((first_ac3 == -1) || (audio.pid == cached_apid_ac3)))
						first_ac3 = program.audioStreams.size();

					program.audioStreams.push_back(audio);
					prev_audio = &program.audioStreams.back();
				}
				else
					continue;
			}
		}
		ret = 0;

		bool defaultac3 = false;
		bool useaudio_cache = false;

		if (!ePythonConfigQuery::getConfigValue("config.autolanguage.audio_defaultac3", configvalue))
			defaultac3 = configvalue == "True";
		if (!ePythonConfigQuery::getConfigValue("config.autolanguage.audio_usecache", configvalue))
			useaudio_cache = configvalue == "True";

		if (useaudio_cache && audio_cached != -1)
			program.defaultAudioStream = audio_cached;
		else if ( defaultac3 )
		{
			if ( autoaudio_ac3 != -1 )
				program.defaultAudioStream = autoaudio_ac3;
			else if ( autoaudio_mpeg != -1 )
				program.defaultAudioStream = autoaudio_mpeg;
			else if ( first_ac3 != -1 )
				program.defaultAudioStream = first_ac3;
		}
		else
		{
			if ( autoaudio_mpeg != -1 )
				program.defaultAudioStream = autoaudio_mpeg;
			else if ( autoaudio_ac3 != -1 )
				program.defaultAudioStream = autoaudio_ac3;
		}

		bool allow_hearingimpaired = false;
		bool default_hearingimpaired = false;
		bool defaultdvb = false;
		int equallanguagemask = false;

		if (!ePythonConfigQuery::getConfigValue("config.autolanguage.subtitle_hearingimpaired", configvalue))
			allow_hearingimpaired = configvalue == "True";
		if (!ePythonConfigQuery::getConfigValue("config.autolanguage.subtitle_defaultimpaired", configvalue))
			default_hearingimpaired = configvalue == "True";
		if (!ePythonConfigQuery::getConfigValue("config.autolanguage.subtitle_defaultdvb", configvalue))
			defaultdvb = configvalue == "True";
		if (!ePythonConfigQuery::getConfigValue("config.autolanguage.equal_languages", configvalue))
			equallanguagemask = atoi(configvalue.c_str());

		if (defaultdvb)
		{
			if (allow_hearingimpaired && default_hearingimpaired && autosub_dvb_hearing != -1)
				program.defaultSubtitleStream = autosub_dvb_hearing;
			else if (autosub_dvb_normal != -1)
				program.defaultSubtitleStream = autosub_dvb_normal;
			else if (allow_hearingimpaired && autosub_dvb_hearing != -1)
				program.defaultSubtitleStream = autosub_dvb_hearing;
			else if (allow_hearingimpaired && default_hearingimpaired && autosub_txt_hearing != -1)
				program.defaultSubtitleStream = autosub_txt_hearing;
			else if (autosub_txt_normal != -1)
				program.defaultSubtitleStream = autosub_txt_normal;
			else if (allow_hearingimpaired && autosub_dvb_hearing != -1)
				program.defaultSubtitleStream = autosub_txt_hearing;
		}
		else
		{
			if (allow_hearingimpaired && default_hearingimpaired && autosub_txt_hearing != -1)
				program.defaultSubtitleStream = autosub_txt_hearing;
			else if (autosub_txt_normal != -1)
				program.defaultSubtitleStream = autosub_txt_normal;
			else if (allow_hearingimpaired && autosub_txt_hearing != -1)
				program.defaultSubtitleStream = autosub_txt_hearing;
			else if (allow_hearingimpaired && default_hearingimpaired && autosub_dvb_hearing != -1)
				program.defaultSubtitleStream = autosub_dvb_hearing;
			else if (autosub_dvb_normal != -1)
				program.defaultSubtitleStream = autosub_dvb_normal;
			else if (allow_hearingimpaired && autosub_dvb_hearing != -1)
				program.defaultSubtitleStream = autosub_dvb_hearing;
		}
		if (program.defaultSubtitleStream != -1 && (equallanguagemask & (1<<(autosub_level-1))) == 0 && program.subtitleStreams[program.defaultSubtitleStream].language_code.compare(program.audioStreams[program.defaultAudioStream].language_code) == 0 )
			program.defaultSubtitleStream = -1;
	}