X-Git-Url: http://code.vuplus.com/gitweb/?p=vuplus_dvbapp;a=blobdiff_plain;f=lib%2Fdvb%2Fpmt.cpp;h=fbd9b8f815285b0f8f8ebc6e3dd16812007433a9;hp=74f896fa11f714eaeffe891a82731810408386ff;hb=eb510064c67c19fec47fd04ea03017c17569e3c5;hpb=993ff2fb9432e8e0edf3a3cf341c5f343461ccf6 diff --git a/lib/dvb/pmt.cpp b/lib/dvb/pmt.cpp index 74f896f..fbd9b8f 100644 --- a/lib/dvb/pmt.cpp +++ b/lib/dvb/pmt.cpp @@ -32,7 +32,10 @@ eDVBServicePMTHandler::eDVBServicePMTHandler() m_use_decode_demux = 0; m_pmt_pid = -1; m_dsmcc_pid = -1; - m_isstreamclient = false; + m_service_type = livetv; + m_descramble = true; + m_ca_disabled = false; + m_pmt_ready = false; eDVBResourceManager::getInstance(m_resourceManager); CONNECT(m_PMT.tableReady, eDVBServicePMTHandler::PMTready); CONNECT(m_PAT.tableReady, eDVBServicePMTHandler::PATready); @@ -104,36 +107,54 @@ void eDVBServicePMTHandler::channelEvent(iDVBChannel *channel, int event) case iDVBChannel::evtSOF: serviceEvent(eventSOF); break; + case iDVBChannel::evtFailed+3: + serviceEvent(eventNoDiskSpace); + break; default: break; } } +void eDVBServicePMTHandler::registerCAService() +{ + int demuxes[2] = {0,0}; + uint8_t demuxid; + m_demux->getCADemuxID(demuxid); + demuxes[0]=demuxid; + if (m_decode_demux_num != 0xFF) + demuxes[1]=m_decode_demux_num; + else + demuxes[1]=demuxes[0]; + eDVBCAService::register_service(m_reference, demuxes, m_ca_servicePtr); +} + void eDVBServicePMTHandler::PMTready(int error) { if (error) serviceEvent(eventNoPMT); else { + m_pmt_ready = true; m_have_cached_program = false; serviceEvent(eventNewProgramInfo); - if (!m_pvr_channel) // don't send campmt to camd.socket for playbacked services + + mDemuxId = m_decode_demux_num; + if (!m_pvr_channel) { eEPGCache::getInstance()->PMTready(this); - if(!m_ca_servicePtr && !m_isstreamclient) + } + + if (m_descramble) + { + if(!m_ca_servicePtr) + { + registerCAService(); + } + if (!m_ca_disabled) { - int demuxes[2] = {0,0}; - uint8_t tmp; - m_demux->getCADemuxID(tmp); - demuxes[0]=tmp; - if (m_decode_demux_num != 0xFF) - demuxes[1]=m_decode_demux_num; - else - demuxes[1]=demuxes[0]; - eDVBCAService::register_service(m_reference, demuxes, m_ca_servicePtr); eDVBCIInterfaces::getInstance()->recheckPMTHandlers(); + eDVBCIInterfaces::getInstance()->gotPMT(this); } - eDVBCIInterfaces::getInstance()->gotPMT(this); } if (m_ca_servicePtr) { @@ -143,6 +164,9 @@ void eDVBServicePMTHandler::PMTready(int error) else eDebug("eDVBServicePMTHandler cannot call buildCAPMT"); } + + if (m_service_type == pvrDescramble) + serviceEvent(eventStartPvrDescramble); } } @@ -213,6 +237,16 @@ void saveData(int orgid, unsigned char* data, int sectionLength) int fd = 0, rc = 0; char fileName[255] = {0}; sprintf(fileName, "/tmp/ait.%d", orgid); + + if (data[6] > 0) { + eDebug("section_number %d > 0", data[6]); + data[6] = 0; + } + if (data[7] > data[6]) { + eDebug("last_section_number %d > section_number %d", data[7], data[6]); + data[7] = data[6]; + } + if((fd = open(fileName, O_RDWR|O_CREAT|O_TRUNC)) < 0) { eDebug("Fail to save a AIT Data."); @@ -225,6 +259,7 @@ void saveData(int orgid, unsigned char* data, int sectionLength) #include #include +#include #define PACK_VERSION(major,minor,micro) (((major) << 16) + ((minor) << 8) + (micro)) #define UNPACK_VERSION(version,major,minor,micro) { \ major = (version)&0xff; \ @@ -243,23 +278,26 @@ void eDVBServicePMTHandler::AITready(int error) eraseHbbTVApplications(&m_HbbTVApplications); - memcpy(m_AITData, ptr->getBufferData(), 4096); - int sectionLength = 0; for (std::vector::const_iterator it = ptr->getSections().begin(); it != ptr->getSections().end(); ++it) { std::list::const_iterator i = (*it)->getApplicationInformation()->begin(); - sectionLength += (*it)->getSectionLength(); + memcpy(m_AITData, ptr->getBufferData(), 4096); + sectionLength = (*it)->getSectionLength() + 3; eDebug("Section Length : %d, Total Section Length : %d", (*it)->getSectionLength(), sectionLength); for (; i != (*it)->getApplicationInformation()->end(); ++i) { std::string hbbtvUrl = "", applicaionName = ""; - + std::string boundaryExtension = ""; + int controlCode = (*i)->getApplicationControlCode(); - ApplicationIdentifier * applicationIdentifier = (*i)->getApplicationIdentifier(); + const ApplicationIdentifier * applicationIdentifier = (*i)->getApplicationIdentifier(); + profilecode = 0; orgid = applicationIdentifier->getOrganisationId(); appid = applicationIdentifier->getApplicationId(); eDebug("found applicaions ids >> pid : %x, orgid : %d, appid : %d", m_ait_pid, orgid, appid); + if (controlCode == 1) + saveData(orgid, m_AITData, sectionLength); if (controlCode == 1 || controlCode == 2) /* 1:AUTOSTART, 2:ETC */ { for (DescriptorConstIterator desc = (*i)->getDescriptors()->begin(); @@ -270,7 +308,7 @@ void eDVBServicePMTHandler::AITready(int error) case APPLICATION_DESCRIPTOR: { ApplicationDescriptor* applicationDescriptor = (ApplicationDescriptor*)(*desc); - ApplicationProfileList* applicationProfiles = applicationDescriptor->getApplicationProfiles(); + const ApplicationProfileList* applicationProfiles = applicationDescriptor->getApplicationProfiles(); ApplicationProfileConstIterator interactionit = applicationProfiles->begin(); for(; interactionit != applicationProfiles->end(); ++interactionit) { @@ -314,7 +352,6 @@ void eDVBServicePMTHandler::AITready(int error) for(; interactionit != transport->getInteractionTransports()->end(); ++interactionit) { hbbtvUrl = (*interactionit)->getUrlBase()->getUrl(); - if(controlCode == 1) m_HBBTVUrl = hbbtvUrl; break; } break; @@ -339,9 +376,10 @@ void eDVBServicePMTHandler::AITready(int error) } if(!hbbtvUrl.empty()) { - char* uu = hbbtvUrl.c_str(); + const char* uu = hbbtvUrl.c_str(); if(!strncmp(uu, "http://", 7) || !strncmp(uu, "dvb://", 6) || !strncmp(uu, "https://", 8)) { + if(controlCode == 1) m_HBBTVUrl = hbbtvUrl; switch(profileVersion) { case 65793: @@ -355,16 +393,40 @@ void eDVBServicePMTHandler::AITready(int error) break; } } + else if (!boundaryExtension.empty()) { + if(boundaryExtension.at(boundaryExtension.length()-1) != '/') { + boundaryExtension += "/"; + } + boundaryExtension += hbbtvUrl; + if(controlCode == 1) m_HBBTVUrl = boundaryExtension; + switch(profileVersion) + { + case 65793: + case 66049: + m_HbbTVApplications.push_back(new HbbTVApplicationInfo(controlCode, orgid, appid, boundaryExtension, applicaionName, profilecode)); + break; + case 1280: + case 65538: + default: + m_HbbTVApplications.push_back(new HbbTVApplicationInfo((-1)*controlCode, orgid, appid, boundaryExtension, applicaionName, profilecode)); + break; + } + } } } } if (m_HbbTVApplications.size()) { - saveData(orgid, m_AITData, sectionLength);//4096); for(HbbTVApplicationInfoListConstIterator infoiter = m_HbbTVApplications.begin() ; infoiter != m_HbbTVApplications.end() ; ++infoiter) + { + char fileName[255] = {0}; + sprintf(fileName, "/tmp/ait.%d", (*infoiter)->m_OrgId); + if (access(fileName, 0) < 0) + saveData((*infoiter)->m_OrgId, m_AITData, sectionLength); eDebug("Found : control[%d], name[%s], url[%s]", (*infoiter)->m_ControlCode, (*infoiter)->m_ApplicationName.c_str(), (*infoiter)->m_HbbTVUrl.c_str()); + } serviceEvent(eventHBBTVInfo); } else eDebug("No found anything."); @@ -381,7 +443,7 @@ void eDVBServicePMTHandler::OCready(int error) { for (std::vector::const_iterator it = ptr->getSections().begin(); it != ptr->getSections().end(); ++it) { - unsigned char* sectionData = (*it)->getData(); + unsigned char* sectionData = (unsigned char*)(*it)->getData(); } } /* for now, do not keep listening for table updates */ @@ -451,7 +513,10 @@ int eDVBServicePMTHandler::getProgramInfo(program &program) { ePtr > 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_vpid = -1; int cached_tpid = -1; int ret = -1; @@ -462,6 +527,8 @@ int eDVBServicePMTHandler::getProgramInfo(program &program) program.pmtPid = -1; program.textPid = -1; program.aitPid = -1; + program.isCached = false; + program.pmtVersion = -1; int first_ac3 = -1; program.defaultAudioStream = 0; @@ -470,8 +537,11 @@ int eDVBServicePMTHandler::getProgramInfo(program &program) if ( m_service && !m_service->cacheEmpty() ) { cached_vpid = m_service->getCacheEntry(eDVBService::cVPID); - cached_apid_mpeg = m_service->getCacheEntry(eDVBService::cAPID); + 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_tpid = m_service->getCacheEntry(eDVBService::cTPID); } @@ -487,6 +557,7 @@ int eDVBServicePMTHandler::getProgramInfo(program &program) eDVBTableSpec table_spec; ptr->getSpec(table_spec); program.pmtPid = table_spec.pid < 0x1fff ? table_spec.pid : -1; + program.pmtVersion = table_spec.version; std::vector::const_iterator i; for (i = ptr->getSections().begin(); i != ptr->getSections().end(); ++i) { @@ -532,6 +603,13 @@ int eDVBServicePMTHandler::getProgramInfo(program &program) video.type = videoStream::vtMPEG4_H264; isvideo = 1; //break; fall through !!! + case 0x24: // H265 HEVC + if (!isvideo) + { + video.type = videoStream::vtH265_HEVC; + isvideo = 1; + } + //break; fall through !!! case 0x10: // MPEG 4 Part 2 if (!isvideo) { @@ -866,11 +944,11 @@ int eDVBServicePMTHandler::getProgramInfo(program &program) 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) + if (audio.pid == cached_apid_ac3 || audio.pid == cached_apid_ddp || audio.pid == cached_apid_mpeg || audio.pid == cached_apid_aache || audio.pid == cached_apid_aac) program.defaultAudioStream = 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))) + if ((audio.type != audioStream::atMPEG) && ((first_ac3 == -1) || (audio.pid == cached_apid_ac3) || (audio.pid == cached_apid_ddp))) first_ac3 = program.audioStreams.size(); program.audioStreams.push_back(audio); @@ -903,6 +981,9 @@ int eDVBServicePMTHandler::getProgramInfo(program &program) int cached_pcrpid = m_service->getCacheEntry(eDVBService::cPCRPID), vpidtype = m_service->getCacheEntry(eDVBService::cVTYPE), cnt=0; + + program.isCached = true; + if ( vpidtype == -1 ) vpidtype = videoStream::vtMPEG2; if ( cached_vpid != -1 ) @@ -922,6 +1003,33 @@ int eDVBServicePMTHandler::getProgramInfo(program &program) 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_mpeg != -1 ) { audioStream s; @@ -1030,19 +1138,20 @@ void eDVBServicePMTHandler::SDTScanEvent(int event) } } -int eDVBServicePMTHandler::tune(eServiceReferenceDVB &ref, int use_decode_demux, eCueSheet *cue, bool simulate, eDVBService *service) +int eDVBServicePMTHandler::tune(eServiceReferenceDVB &ref, int use_decode_demux, eCueSheet *cue, bool simulate, eDVBService *service, serviceType type, bool descramble) { ePtr s; - return tuneExt(ref, use_decode_demux, s, NULL, cue, simulate, service); + return tuneExt(ref, use_decode_demux, s, NULL, cue, simulate, service, type, descramble); } -int eDVBServicePMTHandler::tuneExt(eServiceReferenceDVB &ref, int use_decode_demux, ePtr &source, const char *streaminfo_file, eCueSheet *cue, bool simulate, eDVBService *service, bool isstreamclient) +int eDVBServicePMTHandler::tuneExt(eServiceReferenceDVB &ref, int use_decode_demux, ePtr &source, const char *streaminfo_file, eCueSheet *cue, bool simulate, eDVBService *service, serviceType type, bool descramble) { RESULT res=0; m_reference = ref; m_use_decode_demux = use_decode_demux; m_no_pat_entry_delay->stop(); - m_isstreamclient = isstreamclient; + m_service_type = type; + m_descramble = descramble; /* use given service as backup. This is used for timeshift where we want to clone the live stream using the cache, but in fact have a PVR channel */ m_service = service; @@ -1056,11 +1165,14 @@ int eDVBServicePMTHandler::tuneExt(eServiceReferenceDVB &ref, int use_decode_dem if (!simulate) eDebug("allocate Channel: res %d", res); + if (!res) + serviceEvent(eventChannelAllocated); + ePtr db; if (!m_resourceManager->getChannelList(db)) db->getService((eServiceReferenceDVB&)m_reference, m_service); - if (!res && !simulate) + if (!res && !simulate && m_descramble && !m_ca_disabled) eDVBCIInterfaces::getInstance()->addPMTHandler(this); } else if (!simulate) // no simulation of playback services { @@ -1087,10 +1199,16 @@ int eDVBServicePMTHandler::tuneExt(eServiceReferenceDVB &ref, int use_decode_dem eDebug("alloc PVR"); /* allocate PVR */ eDVBChannelID chid; - if (m_isstreamclient) ref.getChannelID(chid); + if (m_service_type == streamclient) ref.getChannelID(chid); res = m_resourceManager->allocatePVRChannel(chid, m_pvr_channel); if (res) + { eDebug("allocatePVRChannel failed!\n"); + } + else if (descramble) + { + eDVBCIInterfaces::getInstance()->addPMTHandler(this); + } m_channel = m_pvr_channel; } @@ -1128,15 +1246,7 @@ int eDVBServicePMTHandler::tuneExt(eServiceReferenceDVB &ref, int use_decode_dem m_pvr_channel->setCueSheet(cue); if (m_pvr_channel->getDemux(m_pvr_demux_tmp, (!m_use_decode_demux) ? 0 : iDVBChannel::capDecode)) - { - if (m_isstreamclient) - { - eDebug("Allocating %s-decoding a demux for http channel failed.", m_use_decode_demux ? "" : "non-"); - return -2; - } - else - eDebug("Allocating %s-decoding a demux for PVR channel failed.", m_use_decode_demux ? "" : "non-"); - } + eDebug("[eDVBServicePMTHandler] Allocating %s-decoding a demux for PVR channel failed.", m_use_decode_demux ? "" : "non-"); else if (source) m_pvr_channel->playSource(source, streaminfo_file); else @@ -1187,6 +1297,32 @@ void eDVBServicePMTHandler::free() m_demux = 0; } +void eDVBServicePMTHandler::addCaHandler() +{ + m_ca_disabled = false; + if (m_channel) + { + eDVBCIInterfaces::getInstance()->addPMTHandler(this); + if (m_pmt_ready) + { + eDVBCIInterfaces::getInstance()->recheckPMTHandlers(); + eDVBCIInterfaces::getInstance()->gotPMT(this); + } + } +} + +void eDVBServicePMTHandler::removeCaHandler() +{ + m_ca_disabled = true; + if (m_channel) + eDVBCIInterfaces::getInstance()->removePMTHandler(this); +} + +bool eDVBServicePMTHandler::isCiConnected() +{ + eDVBCIInterfaces::getInstance()->isCiConnected(this); +} + CAServiceMap eDVBCAService::exist; ChannelMap eDVBCAService::exist_channels; ePtr eDVBCAService::m_chanAddedConn;