#include <lib/dvb/metaparser.h>
#include <lib/dvb_ci/dvbci.h>
#include <lib/dvb/epgcache.h>
+#include <lib/dvb/scan.h>
+#include <dvbsi++/ca_descriptor.h>
#include <dvbsi++/ca_program_map_section.h>
#include <dvbsi++/teletext_descriptor.h>
#include <dvbsi++/descriptor_tag.h>
#include <dvbsi++/stream_identifier_descriptor.h>
eDVBServicePMTHandler::eDVBServicePMTHandler()
- :m_ca_servicePtr(0), m_decode_demux_num(0xFF)
+ :m_ca_servicePtr(0), m_dvb_scan(0), m_decode_demux_num(0xFF)
{
m_use_decode_demux = 0;
m_pmt_pid = -1;
{
if (m_channel)
if (m_channel->getDemux(m_demux, (!m_use_decode_demux) ? 0 : iDVBChannel::capDecode))
- eDebug("Allocating a demux for now tuned-in channel failed.");
+ eDebug("Allocating %s-decoding a demux for now tuned-in channel failed.", m_use_decode_demux ? "" : "non-");
serviceEvent(eventTuned);
serviceEvent(eventNoPAT);
}
+PyObject *eDVBServicePMTHandler::getCaIds()
+{
+ PyObject *ret=0;
+
+ ePtr<eTable<ProgramMapSection> > ptr;
+
+ if ( ((m_service && m_service->usePMT()) || !m_service) && !m_PMT.getCurrent(ptr))
+ {
+ uint16_t caids[255];
+ memset(caids, 0, sizeof(caids));
+ std::vector<ProgramMapSection*>::const_iterator i = ptr->getSections().begin();
+ for (; i != ptr->getSections().end(); ++i)
+ {
+ const ProgramMapSection &pmt = **i;
+ ElementaryStreamInfoConstIterator es = pmt.getEsInfo()->begin();
+ for (; es != pmt.getEsInfo()->end(); ++es)
+ {
+ for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin();
+ desc != (*es)->getDescriptors()->end(); ++desc)
+ {
+ switch ((*desc)->getTag())
+ {
+ case CA_DESCRIPTOR:
+ {
+ const CaDescriptor *cadescr = (const CaDescriptor*)*desc;
+ uint16_t caid = cadescr->getCaSystemId();
+ int idx=0;
+ while (caids[idx] && caids[idx] != caid)
+ ++idx;
+ caids[idx]=caid;
+ break;
+ }
+ }
+ }
+ }
+ for (DescriptorConstIterator desc = pmt.getDescriptors()->begin();
+ desc != pmt.getDescriptors()->end(); ++desc)
+ {
+ switch ((*desc)->getTag())
+ {
+ case CA_DESCRIPTOR:
+ {
+ const CaDescriptor *cadescr = (const CaDescriptor*)*desc;
+ uint16_t caid = cadescr->getCaSystemId();
+ int idx=0;
+ while (caids[idx] && caids[idx] != caid)
+ ++idx;
+ caids[idx]=caid;
+ break;
+ }
+ }
+ }
+ }
+ int cnt=0;
+ while (caids[cnt])
+ ++cnt;
+ if (cnt)
+ {
+ ret=PyList_New(cnt);
+ while(cnt--)
+ PyList_SET_ITEM(ret, cnt, PyInt_FromLong(caids[cnt]));
+ }
+ }
+
+ if (!ret)
+ ret=PyList_New(0);
+
+ return ret;
+}
+
int eDVBServicePMTHandler::getProgramInfo(struct program &program)
{
ePtr<eTable<ProgramMapSection> > ptr;
video.pid = (*es)->getPid();
audio.pid = (*es)->getPid();
+ video.type = videoStream::vtMPEG2;
switch ((*es)->getType())
{
+ case 0x1b: // AVC Video Stream (MPEG4 H264)
+ video.type = videoStream::vtMPEG4_H264;
case 0x01: // MPEG 1 video
case 0x02: // MPEG 2 video
isvideo = 1;
if ( program.textPid == -1 || (*es)->getPid() == cached_tpid )
program.textPid = (*es)->getPid();
break;
+ case DTS_DESCRIPTOR:
+ if (!isvideo)
+ {
+ isaudio = 1;
+ audio.type = audioStream::atDTS;
+ }
+ break;
case AC3_DESCRIPTOR:
if (!isvideo)
{
apid_mpeg = m_service->getCachePID(eDVBService::cAPID),
pcrpid = m_service->getCachePID(eDVBService::cPCRPID),
tpid = m_service->getCachePID(eDVBService::cTPID),
+ vpidtype = m_service->getCachePID(eDVBService::cVTYPE),
cnt=0;
+ if ( vpidtype == -1 )
+ vpidtype = videoStream::vtMPEG2;
if ( vpid != -1 )
{
videoStream s;
s.pid = vpid;
+ s.type = vpidtype;
program.videoStreams.push_back(s);
++cnt;
}
return -1;
}
+void eDVBServicePMTHandler::SDTScanEvent(int event)
+{
+ switch (event)
+ {
+ case eDVBScan::evtFinish:
+ {
+ ePtr<iDVBChannelList> db;
+ if (m_resourceManager->getChannelList(db) != 0)
+ eDebug("no channel list");
+ else
+ {
+ m_dvb_scan->insertInto(db);
+ eDebug("sdt update done!");
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
int eDVBServicePMTHandler::tune(eServiceReferenceDVB &ref, int use_decode_demux, eCueSheet *cue)
{
RESULT res;
m_channel->connectEvent(
slot(*this, &eDVBServicePMTHandler::channelEvent),
m_channelEvent_connection);
+
+ if (ref.path.empty())
+ {
+ delete m_dvb_scan;
+ m_dvb_scan = new eDVBScan(m_channel);
+ m_dvb_scan->connectEvent(slot(*this, &eDVBServicePMTHandler::SDTScanEvent), m_scan_event_connection);
+ }
} else
{
serviceEvent(eventTuneFailed);
void eDVBServicePMTHandler::free()
{
+ eDVBScan *tmp = m_dvb_scan; // do a copy on stack (recursive call of free()) !!!
+ m_dvb_scan = 0;
+ delete m_dvb_scan;
+
if (m_ca_servicePtr)
{
int demuxes[2] = {0,0};