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; }
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; }
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; }