#include <lib/dvb/metaparser.h>
#include <lib/dvb_ci/dvbci.h>
#include <lib/dvb/epgcache.h>
+#include <dvbsi++/ca_descriptor.h>
#include <dvbsi++/ca_program_map_section.h>
#include <dvbsi++/teletext_descriptor.h>
#include <dvbsi++/descriptor_tag.h>
:m_ca_servicePtr(0), m_decode_demux_num(0xFF)
{
m_use_decode_demux = 0;
+ m_pmt_pid = -1;
eDVBResourceManager::getInstance(m_resourceManager);
CONNECT(m_PMT.tableReady, eDVBServicePMTHandler::PMTready);
CONNECT(m_PAT.tableReady, eDVBServicePMTHandler::PATready);
eDVBServicePMTHandler::~eDVBServicePMTHandler()
{
- if (m_ca_servicePtr)
- {
- eDebug("unregister caservice");
- 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];
- ePtr<eTable<ProgramMapSection> > ptr;
- m_PMT.getCurrent(ptr);
- eDVBCAService::unregister_service(m_reference, demuxes, ptr);
- eDVBCIInterfaces::getInstance()->removePMTHandler(this);
- }
+ free();
}
void eDVBServicePMTHandler::channelStateChanged(iDVBChannel *channel)
{
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);
{
eDebug("ok ... now we start!!");
- m_PAT.begin(eApp, eDVBPATSpec(), m_demux);
+ if (m_pmt_pid == -1)
+ m_PAT.begin(eApp, eDVBPATSpec(), m_demux);
+ else
+ m_PMT.begin(eApp, eDVBPMTSpec(m_pmt_pid, m_reference.getServiceID().get()), m_demux);
if ( m_service && !m_service->cacheEmpty() )
serviceEvent(eventNewProgramInfo);
case iDVBChannel::evtEOF:
serviceEvent(eventEOF);
break;
+ case iDVBChannel::evtSOF:
+ serviceEvent(eventSOF);
+ break;
default:
break;
}
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;
program.pmtPid = -1;
program.textPid = -1;
- if (!m_PMT.getCurrent(ptr))
+ if ( ((m_service && m_service->usePMT()) || !m_service) && !m_PMT.getCurrent(ptr))
{
int cached_apid_ac3 = -1;
int cached_apid_mpeg = -1;
demux = m_demux;
return ret;
}
+
+ ASSERT(m_channel); /* calling without a previous ::tune is certainly bad. */
ret = m_channel->getDemux(demux, iDVBChannel::capDecode);
if (!ret)
return -1;
}
-int eDVBServicePMTHandler::tune(eServiceReferenceDVB &ref, int use_decode_demux)
+int eDVBServicePMTHandler::tune(eServiceReferenceDVB &ref, int use_decode_demux, eCueSheet *cue)
{
RESULT res;
m_reference = ref;
eDVBMetaParser parser;
if (parser.parseFile(ref.path))
- eWarning("no .meta file found, trying original service ref.");
- else
+ {
+ eWarning("no .meta file found, trying to find PMT pid");
+ eDVBTSTools tstools;
+ if (tstools.openFile(ref.path.c_str()))
+ eWarning("failed to open file");
+ else
+ {
+ int service_id, pmt_pid;
+ if (!tstools.findPMT(pmt_pid, service_id))
+ {
+ eDebug("PMT pid found on pid %04x, service id %d", pmt_pid, service_id);
+ m_reference.setServiceID(service_id);
+ m_pmt_pid = pmt_pid;
+ }
+ }
+ } else
m_reference = parser.m_ref;
eDebug("alloc PVR");
eDebug("allocatePVRChannel failed!\n");
m_channel = m_pvr_channel;
}
-
+
+ ePtr<iDVBChannelList> db;
+ if (!m_resourceManager->getChannelList(db))
+ db->getService((eServiceReferenceDVB&)m_reference, m_service);
+
if (m_channel)
{
m_channel->connectStateChange(
}
if (m_pvr_channel)
+ {
+ m_pvr_channel->setCueSheet(cue);
m_pvr_channel->playFile(ref.path.c_str());
-
- ePtr<iDVBChannelList> db;
- if (!m_resourceManager->getChannelList(db))
- db->getService((eServiceReferenceDVB&)m_reference, m_service);
+ }
return res;
}
void eDVBServicePMTHandler::free()
{
+ if (m_ca_servicePtr)
+ {
+ 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];
+ ePtr<eTable<ProgramMapSection> > ptr;
+ m_PMT.getCurrent(ptr);
+ eDVBCAService::unregister_service(m_reference, demuxes, ptr);
+ eDVBCIInterfaces::getInstance()->removePMTHandler(this);
+ m_ca_servicePtr = 0;
+ }
+
+ if (m_pvr_channel)
+ {
+ m_pvr_channel->stopFile();
+ m_pvr_channel->setCueSheet(0);
+ }
m_PMT.stop();
m_PAT.stop();
m_service = 0;