Merge branch 'bug_124_m2ts_support' into experimental
authorghost <andreas.monzner@multimedia-labs.de>
Fri, 26 Nov 2010 14:02:25 +0000 (15:02 +0100)
committerghost <andreas.monzner@multimedia-labs.de>
Fri, 26 Nov 2010 14:02:25 +0000 (15:02 +0100)
Conflicts:
lib/dvb/pmt.cpp
lib/service/Makefile.am

1  2 
lib/dvb/pmt.cpp
lib/dvb/pmt.h
lib/dvb/tstools.cpp
lib/service/Makefile.am
lib/service/servicedvb.cpp

diff --combined lib/dvb/pmt.cpp
@@@ -131,6 -131,8 +131,8 @@@ void eDVBServicePMTHandler::PATready(in
        ePtr<eTable<ProgramAssociationSection> > ptr;
        if (!m_PAT.getCurrent(ptr))
        {
+               int service_id_single = -1;
+               int pmtpid_single = -1;
                int pmtpid = -1;
                std::vector<ProgramAssociationSection*>::const_iterator i;
                for (i = ptr->getSections().begin(); pmtpid == -1 && i != ptr->getSections().end(); ++i)
                        const ProgramAssociationSection &pat = **i;
                        ProgramAssociationConstIterator program;
                        for (program = pat.getPrograms()->begin(); pmtpid == -1 && program != pat.getPrograms()->end(); ++program)
+                       {
                                if (eServiceID((*program)->getProgramNumber()) == m_reference.getServiceID())
                                        pmtpid = (*program)->getProgramMapPid();
+                               if (pmtpid_single == -1 && pmtpid == -1)
+                               {
+                                       pmtpid_single = (*program)->getProgramMapPid();
+                                       service_id_single = (*program)->getProgramNumber();
+                               }
+                               else
+                                       pmtpid_single = service_id_single = -1;
+                       }
+               }
+               if (pmtpid_single != -1) // only one PAT entry .. so we use this one
+               {
+                       m_reference.setServiceID(eServiceID(service_id_single));
+                       pmtpid = pmtpid_single;
                }
                if (pmtpid == -1)
                        serviceEvent(eventNoPATEntry);
                serviceEvent(eventNoPAT);
  }
  
 -PyObject *eDVBServicePMTHandler::getCaIds()
 +PyObject *eDVBServicePMTHandler::getCaIds(bool pair)
  {
        ePyObject ret;
  
                if (cnt)
                {
                        ret=PyList_New(cnt);
 -                      std::set<uint16_t>::iterator it(prog.caids.begin());
 -                      while(cnt--)
 -                              PyList_SET_ITEM(ret, cnt, PyInt_FromLong(*it++));
 +                      std::set<program::capid_pair>::iterator it(prog.caids.begin());
 +                      if (pair)
 +                      {
 +                              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
 +                      {
 +                              while(cnt--)
 +                                      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;
                        for (i = ptr->getSections().begin(); i != ptr->getSections().end(); ++i)
                        {
                                const ProgramMapSection &pmt = **i;
+                               int is_hdmv = 0;
                                program.pcrPid = pmt.getPcrPid();
  
 -                                              program.caids.insert(descr->getCaSystemId());
+                               for (DescriptorConstIterator desc = pmt.getDescriptors()->begin();
+                                       desc != pmt.getDescriptors()->end(); ++desc)
+                               {
+                                       if ((*desc)->getTag() == CA_DESCRIPTOR)
+                                       {
+                                               CaDescriptor *descr = (CaDescriptor*)(*desc);
++                                              program::capid_pair pair;
++                                              pair.caid = descr->getCaSystemId();
++                                              pair.capid = descr->getCaPid();
++                                              program.caids.insert(pair);
+                                       }
+                                       else if ((*desc)->getTag() == REGISTRATION_DESCRIPTOR)
+                                       {
+                                               RegistrationDescriptor *d = (RegistrationDescriptor*)(*desc);
+                                               if (d->getFormatIdentifier() == 0x48444d56) // HDMV
+                                                       is_hdmv = 1;
+                                       }
+                               }
                                ElementaryStreamInfoConstIterator es;
                                for (es = pmt.getEsInfo()->begin(); es != pmt.getEsInfo()->end(); ++es)
                                {
                                                        audio.type = audioStream::atAACHE;
                                                        forced_audio = 1;
                                                }
-                                       case 0x80: // user private ... but blueray LPCM
-                                               if (!isvideo && !isaudio)
+                                       case 0x80: // user private ... but bluray LPCM
+                                       case 0xA0: // bluray secondary LPCM
+                                               if (!isvideo && !isaudio && is_hdmv)
                                                {
                                                        isaudio = 1;
                                                        audio.type = audioStream::atLPCM;
                                                }
-                                       case 0x81: // user private ... but blueray AC3
-                                               if (!isvideo && !isaudio)
+                                       case 0x81: // user private ... but bluray AC3
+                                       case 0xA1: // bluray secondary AC3
+                                               if (!isvideo && !isaudio && is_hdmv)
                                                {
                                                        isaudio = 1;
                                                        audio.type = audioStream::atAC3;
                                                }
-                                       case 0x82: // Blueray DTS (dvb user private...)
-                                       case 0xA2: // Blueray secondary DTS
-                                               if (!isvideo && !isaudio)
+                                       case 0x82: // bluray DTS (dvb user private...)
+                                       case 0xA2: // bluray secondary DTS
+                                               if (!isvideo && !isaudio && is_hdmv)
                                                {
                                                        isaudio = 1;
                                                        audio.type = audioStream::atDTS;
                                                }
+                                       case 0x86: // bluray DTS-HD (dvb user private...)
+                                       case 0xA6: // bluray secondary DTS-HD
+                                               if (!isvideo && !isaudio && is_hdmv)
+                                               {
+                                                       isaudio = 1;
+                                                       audio.type = audioStream::atDTSHD;
+                                               }
                                        case 0x06: // PES Private
                                        case 0xEA: // TS_PSI_ST_SMPTE_VC1
                                        {
                                                        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.insert(pair);
                                                                break;
                                                        }
                                                        default:
                                        default:
                                                break;
                                        }
-                                       if (isteletext && (isaudio || isvideo)) 
+                                       if (isteletext && (isaudio || isvideo))
                                        {
-                                               eDebug("ambiguous streamtype for PID %04x detected.. forced as teletext!", (*es)->getPid());                                    
+                                               eDebug("ambiguous streamtype for PID %04x detected.. forced as teletext!", (*es)->getPid());
                                                continue; // continue with next PID
                                        }
                                        else if (issubtitle && (isaudio || isvideo))
                                        else
                                                continue;
                                }
-                               for (DescriptorConstIterator desc = pmt.getDescriptors()->begin();
-                                       desc != pmt.getDescriptors()->end(); ++desc)
-                               {
-                                       if ((*desc)->getTag() == CA_DESCRIPTOR)
-                                       {
-                                               CaDescriptor *descr = (CaDescriptor*)(*desc);
-                                               program::capid_pair pair;
-                                               pair.caid = descr->getCaSystemId();
-                                               pair.capid = descr->getCaPid();
-                                               program.caids.insert(pair);
-                                       }
-                               }
                        }
                        ret = 0;
  
                        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.insert(pair);
 +              }
                if ( cnt )
                        ret = 0;
        }
diff --combined lib/dvb/pmt.h
@@@ -144,7 -144,7 +144,7 @@@ public
        {
                int pid,
                    rdsPid; // hack for some radio services which transmit radiotext on different pid (i.e. harmony fm, HIT RADIO FFH, ...)
-               enum { atMPEG, atAC3, atDTS, atAAC, atAACHE, atLPCM };
+               enum { atMPEG, atAC3, atDTS, atAAC, atAACHE, atLPCM, atDTSHD };
                int type; // mpeg2, ac3, dts, ...
                
                int component_tag;
  
        struct program
        {
 +              struct capid_pair
 +              {
 +                      uint16_t caid;
 +                      int capid;
 +                      bool operator< (const struct capid_pair &t) { return t.caid < caid; }
 +              };
                std::vector<videoStream> videoStreams;
                std::vector<audioStream> audioStreams;
                int defaultAudioStream;
                std::vector<subtitleStream> subtitleStreams;
 -              std::set<uint16_t> caids;
 +              std::set<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; }
diff --combined lib/dvb/tstools.cpp
@@@ -212,6 -212,8 +212,8 @@@ int eDVBTSTools::getPTS(off_t &offset, 
                                                        break;
                                                case 0x71: // AC3 / DTS
                                                        break;
+                                               case 0x72: // DTS - HD
+                                                       break;
                                                default:
                                                        eDebug("skip unknwn stream_id_extension %02x\n", payload[9+offs]);
                                                        continue;
@@@ -700,23 -702,9 +702,23 @@@ int eDVBTSTools::findFrame(off_t &_offs
                else if (direction == +1)
                        direction = 0;
        }
 -                      /* let's find the next frame after the given offset */
        off_t start = offset;
  
 +                      /* backtrack to find the previous sequence start, in case of MPEG2 */
 +      if ((data & 0xFF) == 0x00) {
 +              do {
 +                      --start;
 +                      if (m_streaminfo.getStructureEntry(start, data, 0))
 +                      {
 +                              eDebug("get previous failed");
 +                              return -1;
 +                      }
 +              } while (((data & 0xFF) != 9) && ((data & 0xFF) != 0x00) && ((data & 0xFF) != 0xB3)); /* sequence start or previous frame */
 +              if ((data & 0xFF) != 0xB3)
 +                      start = offset;  /* Failed to find corresponding sequence start, so never mind */
 +      }
 +
 +                      /* let's find the next frame after the given offset */
        do {
                if (m_streaminfo.getStructureEntry(offset, data, 1))
                {
        } while (((data & 0xFF) != 9) && ((data & 0xFF) != 0x00)); /* next frame */
  
                        /* align to TS pkt start */
 -//    start = start - (start % 188);
 -//    offset = offset - (offset % 188);
 +      start = start - (start % 188);
 +      offset = offset - (offset % 188);
  
        len = offset - start;
        _offset = start;
diff --combined lib/service/Makefile.am
@@@ -1,37 -1,8 +1,39 @@@
 -INCLUDES = \
 -      -I$(top_srcdir)/include
 +AM_CPPFLAGS = \
 +      -I$(top_srcdir) \
 +      -I$(top_srcdir)/include \
 +      -include Python.h \
 +      -include $(top_builddir)/enigma2_config.h
 +
 +AM_CXXFLAGS = \
 +      $(LIBXINE_CFLAGS)
  
  noinst_LIBRARIES = libenigma_service.a
  
  libenigma_service_a_SOURCES = \
 -      listboxservice.cpp service.cpp servicemp3.cpp servicedvb.cpp servicefs.cpp \
 -      servicem2ts.cpp event.cpp servicedvbrecord.cpp
 +      event.cpp \
 +      listboxservice.cpp \
 +      service.cpp \
 +      servicedvb.cpp \
 +      servicedvbrecord.cpp \
 +      servicefs.cpp \
-       servicemp3.cpp
++      servicemp3.cpp \
++      servicem2ts.cpp
 +
 +serviceincludedir = $(pkgincludedir)/lib/service
 +serviceinclude_HEADERS = \
 +      event.h \
 +      iservice.h \
 +      listboxservice.h \
 +      service.h \
 +      servicedvb.h \
 +      servicedvbrecord.h \
 +      servicefs.h \
-       servicemp3.h
++      servicemp3.h \
++      servicem2ts.h
 +
 +if HAVE_LIBXINE
 +libenigma_service_a_SOURCES += \
 +      servicexine.cpp
 +serviceinclude_HEADERS += \
 +      servicexine.h
 +endif
@@@ -309,9 -309,7 +309,9 @@@ eStaticServiceDVBPVRInformation::eStati
  RESULT eStaticServiceDVBPVRInformation::getName(const eServiceReference &ref, std::string &name)
  {
        ASSERT(ref == m_ref);
 -      if (m_parser.m_name.size())
 +      if (!ref.name.empty())
 +              name = ref.name;
 +      else if (!m_parser.m_name.empty())
                name = m_parser.m_name;
        else
        {
@@@ -1591,7 -1589,7 +1591,7 @@@ int eDVBServicePlay::getInfo(int w
  {
        eDVBServicePMTHandler::program program;
  
 -      if (w == sCAIDs)
 +      if (w == sCAIDs || w == sCAIDPIDs)
                return resIsPyObject;
  
        eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
@@@ -1732,8 -1730,6 +1732,8 @@@ PyObject *eDVBServicePlay::getInfoObjec
        {
        case sCAIDs:
                return m_service_handler.getCaIds();
 +      case sCAIDPIDs:
 +              return m_service_handler.getCaIds(true);
        case sTransponderData:
                return eStaticServiceDVBInformation().getInfoObject(m_reference, w);
        default:
@@@ -1801,6 -1797,8 +1801,8 @@@ RESULT eDVBServicePlay::getTrackInfo(st
                info.m_description = "AAC-HE";
        else  if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atDTS)
                info.m_description = "DTS";
+       else  if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atDTSHD)
+               info.m_description = "DTS-HD";
        else
                info.m_description = "???";