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);
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)
{
else
eDebug("eDVBServicePMTHandler cannot call buildCAPMT");
}
+
+ if (m_service_type == pvrDescramble)
+ serviceEvent(eventStartPvrDescramble);
}
}
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.");
#include <dvbsi++/application_profile.h>
#include <dvbsi++/application_descriptor.h>
+#include <dvbsi++/simple_application_boundary_descriptor.h>
#define PACK_VERSION(major,minor,micro) (((major) << 16) + ((minor) << 8) + (micro))
#define UNPACK_VERSION(version,major,minor,micro) { \
major = (version)&0xff; \
eraseHbbTVApplications(&m_HbbTVApplications);
- memcpy(m_AITData, ptr->getBufferData(), 4096);
-
int sectionLength = 0;
for (std::vector<ApplicationInformationSection*>::const_iterator it = ptr->getSections().begin(); it != ptr->getSections().end(); ++it)
{
std::list<ApplicationInformation *>::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();
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)
{
for(; interactionit != transport->getInteractionTransports()->end(); ++interactionit)
{
hbbtvUrl = (*interactionit)->getUrlBase()->getUrl();
- if(controlCode == 1) m_HBBTVUrl = hbbtvUrl;
break;
}
break;
}
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:
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.");
{
for (std::vector<OCSection*>::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 */
{
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_vpid = -1;
int cached_tpid = -1;
int ret = -1;
program.pmtPid = -1;
program.textPid = -1;
program.aitPid = -1;
+ program.isCached = false;
+ program.pmtVersion = -1;
int first_ac3 = -1;
program.defaultAudioStream = 0;
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);
}
eDVBTableSpec table_spec;
ptr->getSpec(table_spec);
program.pmtPid = table_spec.pid < 0x1fff ? table_spec.pid : -1;
+ program.pmtVersion = table_spec.version;
std::vector<ProgramMapSection*>::const_iterator i;
for (i = ptr->getSections().begin(); i != ptr->getSections().end(); ++i)
{
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)
{
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);
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 )
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;
}
}
-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<iTsSource> 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<iTsSource> &source, const char *streaminfo_file, eCueSheet *cue, bool simulate, eDVBService *service, bool isstreamclient)
+int eDVBServicePMTHandler::tuneExt(eServiceReferenceDVB &ref, int use_decode_demux, ePtr<iTsSource> &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;
if (!simulate)
eDebug("allocate Channel: res %d", res);
+ if (!res)
+ serviceEvent(eventChannelAllocated);
+
ePtr<iDVBChannelList> 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
{
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;
}
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
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<eConnection> eDVBCAService::m_chanAddedConn;