Merge branch 'bug_124_m2ts_support' into experimental
authorghost <andreas.monzner@multimedia-labs.de>
Tue, 21 Dec 2010 10:47:08 +0000 (11:47 +0100)
committerghost <andreas.monzner@multimedia-labs.de>
Tue, 21 Dec 2010 10:47:08 +0000 (11:47 +0100)
1  2 
lib/dvb/pmt.cpp
lib/dvb/pmt.h

diff --combined lib/dvb/pmt.cpp
  #include <dvbsi++/registration_descriptor.h>
  
  eDVBServicePMTHandler::eDVBServicePMTHandler()
-       :m_ca_servicePtr(0), m_dvb_scan(0), m_decode_demux_num(0xFF)
+       :m_ca_servicePtr(0), m_dvb_scan(0), m_decode_demux_num(0xFF), m_no_pat_entry_delay(eTimer::create())
  {
        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);
+       CONNECT(m_no_pat_entry_delay->timeout, eDVBServicePMTHandler::sendEventNoPatEntry);
  }
  
  eDVBServicePMTHandler::~eDVBServicePMTHandler()
@@@ -126,14 -127,21 +127,21 @@@ void eDVBServicePMTHandler::PMTready(in
        }
  }
  
+ void eDVBServicePMTHandler::sendEventNoPatEntry()
+ {
+       serviceEvent(eventNoPATEntry);
+ }
  void eDVBServicePMTHandler::PATready(int)
  {
+       eDebug("PATready");
        ePtr<eTable<ProgramAssociationSection> > ptr;
        if (!m_PAT.getCurrent(ptr))
        {
                int service_id_single = -1;
                int pmtpid_single = -1;
                int pmtpid = -1;
+               int cnt=0;
                std::vector<ProgramAssociationSection*>::const_iterator i;
                for (i = ptr->getSections().begin(); pmtpid == -1 && i != ptr->getSections().end(); ++i)
                {
                        ProgramAssociationConstIterator program;
                        for (program = pat.getPrograms()->begin(); pmtpid == -1 && program != pat.getPrograms()->end(); ++program)
                        {
+                               ++cnt;
                                if (eServiceID((*program)->getProgramNumber()) == m_reference.getServiceID())
                                        pmtpid = (*program)->getProgramMapPid();
-                               if (pmtpid_single == -1 && pmtpid == -1)
+                               if (++cnt == 1 && pmtpid_single == -1 && pmtpid == -1)
                                {
                                        pmtpid_single = (*program)->getProgramMapPid();
                                        service_id_single = (*program)->getProgramNumber();
                                        pmtpid_single = service_id_single = -1;
                        }
                }
-               if (pmtpid_single != -1) // only one PAT entry .. so we use this one
+               if (pmtpid_single != -1) // only one PAT entry .. and not valid pmtpid found
                {
+                       eDebug("use single pat entry!");
                        m_reference.setServiceID(eServiceID(service_id_single));
                        pmtpid = pmtpid_single;
                }
-               if (pmtpid == -1)
-                       serviceEvent(eventNoPATEntry);
-               else
+               if (pmtpid == -1) {
+                       eDebug("no PAT entry found.. start delay");
+                       m_no_pat_entry_delay->start(1000, true);
+               }
+               else {
+                       eDebug("use pmtpid %04x for service_id %04x", pmtpid, m_reference.getServiceID().get());
+                       m_no_pat_entry_delay->stop();
                        m_PMT.begin(eApp, eDVBPMTSpec(pmtpid, m_reference.getServiceID().get()), m_demux);
+               }
        } else
                serviceEvent(eventNoPAT);
  }
  
 -PyObject *eDVBServicePMTHandler::getCaIds()
 +PyObject *eDVBServicePMTHandler::getCaIds(bool pair)
  {
        ePyObject ret;
  
  
        if ( !getProgramInfo(prog) )
        {
 -              int cnt=prog.caids.size();
 -              if (cnt)
 +              if (pair)
                {
 +                      int cnt=prog.caids.size();
 +                      if (cnt)
 +                      {
 +                              ret=PyList_New(cnt);
 +                              std::list<program::capid_pair>::iterator it(prog.caids.begin());
 +                              while(cnt--)
 +                              {
 +                                      ePyObject tuple = PyTuple_New(2);
 +                                      PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(it->caid));
 +                                      PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong((it++)->capid));
 +                                      PyList_SET_ITEM(ret, cnt, tuple);
 +                              }
 +                      }
 +              }
 +              else
 +              {
 +                      std::set<program::capid_pair> set(prog.caids.begin(), prog.caids.end());
 +                      std::set<program::capid_pair>::iterator it(set.begin());
 +                      int cnt=set.size();
                        ret=PyList_New(cnt);
 -                      std::set<uint16_t>::iterator it(prog.caids.begin());
                        while(cnt--)
 -                              PyList_SET_ITEM(ret, cnt, PyInt_FromLong(*it++));
 +                              PyList_SET_ITEM(ret, cnt, PyInt_FromLong((it++)->caid));
                }
        }
  
        return ret ? (PyObject*)ret : (PyObject*)PyList_New(0);
  }
  
 -int eDVBServicePMTHandler::getProgramInfo(struct program &program)
 +int eDVBServicePMTHandler::getProgramInfo(program &program)
  {
        ePtr<eTable<ProgramMapSection> > ptr;
        int cached_apid_ac3 = -1;
                                        if ((*desc)->getTag() == CA_DESCRIPTOR)
                                        {
                                                CaDescriptor *descr = (CaDescriptor*)(*desc);
 -                                              program.caids.insert(descr->getCaSystemId());
 +                                              program::capid_pair pair;
 +                                              pair.caid = descr->getCaSystemId();
 +                                              pair.capid = descr->getCaPid();
 +                                              program.caids.push_back(pair);
                                        }
                                        else if ((*desc)->getTag() == REGISTRATION_DESCRIPTOR)
                                        {
                                                        case CA_DESCRIPTOR:
                                                        {
                                                                CaDescriptor *descr = (CaDescriptor*)(*desc);
 -                                                              program.caids.insert(descr->getCaSystemId());
 +                                                              program::capid_pair pair;
 +                                                              pair.caid = descr->getCaSystemId();
 +                                                              pair.capid = descr->getCaPid();
 +                                                              program.caids.push_back(pair);
                                                                break;
                                                        }
                                                        default:
                        program.textPid = cached_tpid;
                }
                CAID_LIST &caids = m_service->m_ca;
 -              for (CAID_LIST::iterator it(caids.begin()); it != caids.end(); ++it)
 -                      program.caids.insert(*it);
 +              for (CAID_LIST::iterator it(caids.begin()); it != caids.end(); ++it) {
 +                      program::capid_pair pair;
 +                      pair.caid = *it;
 +                      pair.capid = -1; // not known yet
 +                      program.caids.push_back(pair);
 +              }
                if ( cnt )
                        ret = 0;
        }
@@@ -744,8 -732,8 +759,8 @@@ int eDVBServicePMTHandler::tuneExt(eSer
  {
        RESULT res=0;
        m_reference = ref;
-       
        m_use_decode_demux = use_decode_demux;
+       m_no_pat_entry_delay->stop();
  
                /* 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;
diff --combined lib/dvb/pmt.h
@@@ -102,6 -102,7 +102,7 @@@ class eDVBServicePMTHandler: public Obj
        
        int m_use_decode_demux;
        uint8_t m_decode_demux_num;
+       ePtr<eTimer> m_no_pat_entry_delay;
  public:
        eDVBServicePMTHandler();
        ~eDVBServicePMTHandler();
@@@ -181,17 -182,11 +182,17 @@@ public
  
        struct program
        {
 +              struct capid_pair
 +              {
 +                      uint16_t caid;
 +                      int capid;
 +                      bool operator< (const struct capid_pair &t) const { return t.caid < caid; }
 +              };
                std::vector<videoStream> videoStreams;
                std::vector<audioStream> audioStreams;
                int defaultAudioStream;
                std::vector<subtitleStream> subtitleStreams;
 -              std::set<uint16_t> caids;
 +              std::list<capid_pair> caids;
                int pcrPid;
                int pmtPid;
                int textPid;
                PyObject *createPythonObject();
        };
  
 -      int getProgramInfo(struct program &program);
 +      int getProgramInfo(program &program);
        int getDataDemux(ePtr<iDVBDemux> &demux);
        int getDecodeDemux(ePtr<iDVBDemux> &demux);
 -      PyObject *getCaIds();
 +      PyObject *getCaIds(bool pair=false); // caid / ecmpid pair
        
        int getPVRChannel(ePtr<iDVBPVRChannel> &pvr_channel);
        int getServiceReference(eServiceReferenceDVB &service) { service = m_reference; return 0; }
        int getPMT(ePtr<eTable<ProgramMapSection> > &ptr) { return m_PMT.getCurrent(ptr); }
        int getChannel(eUsePtr<iDVBChannel> &channel);
        void resetCachedProgram() { m_have_cached_program = false; }
+       void sendEventNoPatEntry();
  
        /* deprecated interface */
        int tune(eServiceReferenceDVB &ref, int use_decode_demux, eCueSheet *sg=0, bool simulate=false, eDVBService *service = 0);