X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/05eefccc9e20d520d173156ab5dffbcc90f4351f..8948b15a69b1f155389107ac0ff73a65cc0b7337:/lib/dvb/pmt.cpp diff --git a/lib/dvb/pmt.cpp b/lib/dvb/pmt.cpp index 5a1b7c5c..8c56589c 100644 --- a/lib/dvb/pmt.cpp +++ b/lib/dvb/pmt.cpp @@ -4,24 +4,23 @@ #include #include #include +#include #include #include #include -#include +#include -eDVBServicePMTHandler::eDVBServicePMTHandler(int record) +eDVBServicePMTHandler::eDVBServicePMTHandler() :m_ca_servicePtr(0) { - m_record = record; + m_use_decode_demux = 0; eDVBResourceManager::getInstance(m_resourceManager); CONNECT(m_PMT.tableReady, eDVBServicePMTHandler::PMTready); CONNECT(m_PAT.tableReady, eDVBServicePMTHandler::PATready); - eDebug("new PMT handler record: %d", m_record); } eDVBServicePMTHandler::~eDVBServicePMTHandler() { - eDebug("delete PMT handler record: %d", m_record); if (m_ca_servicePtr) { eDebug("unregister caservice"); @@ -43,7 +42,7 @@ void eDVBServicePMTHandler::channelStateChanged(iDVBChannel *channel) && (state == iDVBChannel::state_ok) && (!m_demux)) { if (m_channel) - if (m_channel->getDemux(m_demux, m_record ? 0 : iDVBChannel::capDecode)) + if (m_channel->getDemux(m_demux, (!m_use_decode_demux) ? 0 : iDVBChannel::capDecode)) eDebug("Allocating a demux for now tuned-in channel failed."); serviceEvent(eventTuned); @@ -52,8 +51,6 @@ void eDVBServicePMTHandler::channelStateChanged(iDVBChannel *channel) { eDebug("ok ... now we start!!"); - /* emit */ m_resourceManager->m_channelRunning(channel); - m_PAT.begin(eApp, eDVBPATSpec(), m_demux); if ( m_service && !m_service->cacheEmpty() ) @@ -74,6 +71,7 @@ void eDVBServicePMTHandler::PMTready(int error) else { serviceEvent(eventNewProgramInfo); + eEPGCache::getInstance()->PMTready(this); if (!m_pvr_channel) { if(!m_ca_servicePtr) // don't send campmt to camd.socket for playbacked services @@ -98,7 +96,6 @@ void eDVBServicePMTHandler::PMTready(int error) void eDVBServicePMTHandler::PATready(int) { - eDebug("got PAT"); ePtr > ptr; if (!m_PAT.getCurrent(ptr)) { @@ -127,9 +124,20 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program) program.videoStreams.clear(); program.audioStreams.clear(); program.pcrPid = -1; + program.isCrypted = false; + program.pmtPid = -1; if (!m_PMT.getCurrent(ptr)) { + int cached_apid_ac3 = -1; + int cached_apid_mpeg = -1; + int cached_vpid = -1; + if ( m_service && !m_service->cacheEmpty() ) + { + cached_vpid = m_service->getCachePID(eDVBService::cVPID); + cached_apid_mpeg = m_service->getCachePID(eDVBService::cAC3PID); + cached_apid_ac3 = m_service->getCachePID(eDVBService::cAPID); + } eDVBTableSpec table_spec; ptr->getSpec(table_spec); program.pmtPid = table_spec.pid < 0x1fff ? table_spec.pid : -1; @@ -142,24 +150,29 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program) ElementaryStreamInfoConstIterator es; for (es = pmt.getEsInfo()->begin(); es != pmt.getEsInfo()->end(); ++es) { - int isaudio = 0, isvideo = 0; + int isaudio = 0, isvideo = 0, cadescriptors = 0; videoStream video; audioStream audio; - + audio.component_tag=-1; + video.component_tag=-1; + video.pid = (*es)->getPid(); audio.pid = (*es)->getPid(); - + switch ((*es)->getType()) { case 0x01: // MPEG 1 video case 0x02: // MPEG 2 video isvideo = 1; - break; + //break; fall through !!! case 0x03: // MPEG 1 audio case 0x04: // MPEG 2 audio: - isaudio = 1; - audio.type = audioStream::atMPEG; - break; + if (!isvideo) + { + isaudio = 1; + audio.type = audioStream::atMPEG; + } + //break; fall through !!! case 0x06: // PES Private /* PES private can contain AC-3, DTS or lots of other stuff. check descriptors to get the exact type. */ @@ -169,8 +182,28 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program) switch ((*desc)->getTag()) { case AC3_DESCRIPTOR: - isaudio = 1; - audio.type = audioStream::atAC3; + if (!isvideo) + { + isaudio = 1; + audio.type = audioStream::atAC3; + } + break; + case ISO_639_LANGUAGE_DESCRIPTOR: + if (!isvideo) + { + const Iso639LanguageList *languages = ((Iso639LanguageDescriptor*)*desc)->getIso639Languages(); + /* use last language code */ + for (Iso639LanguageConstIterator i(languages->begin()); i != languages->end(); ++i) + audio.language_code = (*i)->getIso639LanguageCode(); + } + break; + case STREAM_IDENTIFIER_DESCRIPTOR: + audio.component_tag = + video.component_tag = + ((StreamIdentifierDescriptor*)*desc)->getComponentTag(); + break; + case CA_DESCRIPTOR: + ++cadescriptors; break; } } @@ -178,40 +211,51 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program) } if (isaudio) { - for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin(); - desc != (*es)->getDescriptors()->end(); ++desc) + if ( !program.audioStreams.empty() && + ( audio.pid == cached_apid_ac3 || audio.pid == cached_apid_mpeg) ) { - switch ((*desc)->getTag()) - { - case ISO_639_LANGUAGE_DESCRIPTOR: - { - const Iso639LanguageList *languages = ((Iso639LanguageDescriptor*)*desc)->getIso639Languages(); - - /* use last language code */ - for (Iso639LanguageConstIterator i(languages->begin()); i != languages->end(); ++i) - audio.language_code = (*i)->getIso639LanguageCode(); - - break; - } - case COMPONENT_DESCRIPTOR: - audio.component_tag = ((ComponentDescriptor*)*desc)->getComponentTag(); - break; - } + program.audioStreams.push_back(program.audioStreams[0]); + program.audioStreams[0] = audio; } - - program.audioStreams.push_back(audio); + else + program.audioStreams.push_back(audio); } - if (isvideo) - program.videoStreams.push_back(video); + else if (isvideo) + { + 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 + continue; + if ( cadescriptors > 0 ) + program.isCrypted=true; + } + if ( !program.isCrypted ) + { + for (DescriptorConstIterator desc = pmt.getDescriptors()->begin(); + desc != pmt.getDescriptors()->end(); ++desc) + { + switch ((*desc)->getTag()) + { + case CA_DESCRIPTOR: + program.isCrypted=true; + break; + } + } + break; } } return 0; - } - else if ( m_service && !m_service->cacheEmpty() ) + } else if ( m_service && !m_service->cacheEmpty() ) { int vpid = m_service->getCachePID(eDVBService::cVPID), - apid_ac3 = m_service->getCachePID(eDVBService::cAPID), - apid_mpeg = m_service->getCachePID(eDVBService::cAC3PID), + apid_ac3 = m_service->getCachePID(eDVBService::cAC3PID), + apid_mpeg = m_service->getCachePID(eDVBService::cAPID), pcrpid = m_service->getCachePID(eDVBService::cPCRPID), cnt=0; if ( vpid != -1 ) @@ -257,7 +301,7 @@ int eDVBServicePMTHandler::getChannel(eUsePtr &channel) return -1; } -int eDVBServicePMTHandler::getDemux(ePtr &demux) +int eDVBServicePMTHandler::getDataDemux(ePtr &demux) { demux = m_demux; if (demux) @@ -266,6 +310,19 @@ int eDVBServicePMTHandler::getDemux(ePtr &demux) return -1; } +int eDVBServicePMTHandler::getDecodeDemux(ePtr &demux) +{ + /* if we're using the decoding demux as data source + (for example in pvr playbacks), return that one. */ + if (m_use_decode_demux) + { + demux = m_demux; + return 0; + } + + return m_channel->getDemux(demux, iDVBChannel::capDecode); +} + int eDVBServicePMTHandler::getPVRChannel(ePtr &pvr_channel) { pvr_channel = m_pvr_channel; @@ -275,11 +332,13 @@ int eDVBServicePMTHandler::getPVRChannel(ePtr &pvr_channel) return -1; } -int eDVBServicePMTHandler::tune(eServiceReferenceDVB &ref) +int eDVBServicePMTHandler::tune(eServiceReferenceDVB &ref, int use_decode_demux) { RESULT res; m_reference = ref; + m_use_decode_demux = use_decode_demux; + /* is this a normal (non PVR) channel? */ if (ref.path.empty()) { @@ -327,6 +386,16 @@ int eDVBServicePMTHandler::tune(eServiceReferenceDVB &ref) return res; } +void eDVBServicePMTHandler::free() +{ + m_PMT.stop(); + m_PAT.stop(); + m_service = 0; + m_channel = 0; + m_pvr_channel = 0; + m_demux = 0; +} + std::map eDVBCAService::exist; eDVBCAService::eDVBCAService() @@ -352,7 +421,7 @@ RESULT eDVBCAService::register_service( const eServiceReferenceDVB &ref, int dem { caservice = (exist[ref]=new eDVBCAService()); caservice->m_service = ref; - eDebug("[eDVBCAHandler] new service %s", ref.toString().c_str() ); + eDebug("[eDVBCAService] new service %s", ref.toString().c_str() ); } // search free demux entry int iter=0, max_demux_slots = sizeof(caservice->m_used_demux); @@ -363,11 +432,11 @@ RESULT eDVBCAService::register_service( const eServiceReferenceDVB &ref, int dem if ( iter < max_demux_slots ) { caservice->m_used_demux[iter] = demux_num & 0xFF; - eDebug("[eDVBCAHandler] add demux %d to slot %d service %s", demux_num, iter, ref.toString().c_str()); + eDebug("[eDVBCAService] add demux %d to slot %d service %s", demux_num, iter, ref.toString().c_str()); } else { - eDebug("[eDVBCAHandler] no more demux slots free for service %s!!", ref.toString().c_str()); + eDebug("[eDVBCAService] no more demux slots free for service %s!!", ref.toString().c_str()); return -1; } return 0; @@ -378,7 +447,7 @@ RESULT eDVBCAService::unregister_service( const eServiceReferenceDVB &ref, int d CAServiceMap::iterator it = exist.find(ref); if ( it == exist.end() ) { - eDebug("[eDVBCAHandler] try to unregister non registered %s", ref.toString().c_str()); + eDebug("[eDVBCAService] try to unregister non registered %s", ref.toString().c_str()); return -1; } else @@ -418,7 +487,7 @@ RESULT eDVBCAService::unregister_service( const eServiceReferenceDVB &ref, int d if (ptr) it->second->buildCAPMT(ptr); else - eDebug("[eDVBCAHandler] can not send updated demux info"); + eDebug("[eDVBCAService] can not send updated demux info"); } } return 0; @@ -561,7 +630,7 @@ void eDVBCAService::sendCAPMT() if ( write(m_sock, m_capmt, wp) == wp ) { m_sendstate=0xFFFFFFFF; - eDebug("[eDVBCAHandler] send %d bytes",wp); + eDebug("[eDVBCAService] send %d bytes",wp); #if 1 for(int i=0;i