Merge branch 'bug_124_m2ts_support'
authorghost <andreas.monzner@multimedia-labs.de>
Wed, 16 Feb 2011 13:31:31 +0000 (14:31 +0100)
committerghost <andreas.monzner@multimedia-labs.de>
Wed, 16 Feb 2011 13:31:31 +0000 (14:31 +0100)
Conflicts:
lib/dvb/pmt.cpp
lib/service/Makefile.am

1  2 
lib/dvb/esection.h
lib/dvb/pmt.cpp
lib/dvb/pmt.h
lib/dvb/tstools.cpp
lib/python/Plugins/Extensions/MediaPlayer/plugin.py
lib/service/Makefile.am
lib/service/servicedvb.cpp

diff --combined lib/dvb/esection.h
@@@ -63,7 -63,7 +63,7 @@@ protected
                        else
                                TABLE_eDebugNoNewLine("-");
                                
 -              TABLE_eDebug(" %d/%d TID %02x", avail.size(), max, data[0]);
 +              TABLE_eDebug(" %zd/%d TID %02x", avail.size(), max, data[0]);
  
                if (avail.size() == max)
                {
@@@ -100,6 -100,10 +100,10 @@@ class eAUTable: public eAUGTabl
        int first;
        ePtr<iDVBDemux> m_demux;
        eMainloop *ml;
+       /* needed to detect broken table version handling (seen on some m2ts files) */
+       struct timespec m_prev_table_update;
+       int m_table_cnt;
  public:
  
        eAUTable()
        
        int begin(eMainloop *m, const eDVBTableSpec &spec, ePtr<iDVBDemux> demux)
        {
+               m_table_cnt = 0;
                ml = m;
                m_demux = demux;
                first= 1;
  
                if (current && (!current->getSpec(spec)))
                {
+                       /* detect broken table version handling (seen on some m2ts files) */
+                       if (m_table_cnt)
+                       {
+                               if (abs(timeout_usec(m_prev_table_update)) > 500000)
+                                       m_table_cnt = -1;
+                               else if (m_table_cnt > 1) // two pmt update within one second
+                               {
+                                       eDebug("Seen two consecutive table version changes within 500ms. "
+                                           "This seems broken, so auto update for pid %04x, table %02x is now disabled!!",
+                                           spec.pid, spec.tid);
+                                       m_table_cnt = 0;
+                                       return;
+                               }
+                       }
+                       ++m_table_cnt;
+                       clock_gettime(CLOCK_MONOTONIC, &m_prev_table_update);
                        next = new Table();
                        CONNECT(next->tableReady, eAUTable::slotTableReady);
                        spec.flags &= ~(eDVBTableSpec::tfAnyVersion|eDVBTableSpec::tfThisVersion|eDVBTableSpec::tfHaveTimeout);
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,30 -127,60 +127,60 @@@ 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)
                {
                        const ProgramAssociationSection &pat = **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 (++cnt == 1 && pmtpid_single == -1 && pmtpid == -1)
+                               {
+                                       pmtpid_single = (*program)->getProgramMapPid();
+                                       service_id_single = (*program)->getProgramNumber();
+                               }
+                               else
+                                       pmtpid_single = service_id_single = -1;
+                       }
                }
-               if (pmtpid == -1)
-                       serviceEvent(eventNoPATEntry);
-               else
+               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) {
+                       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;
                        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.push_back(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.push_back(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.push_back(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.push_back(pair);
 +              }
                if ( cnt )
                        ret = 0;
        }
@@@ -710,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;
        {
                if (!ref.getServiceID().get() /* incorrect sid in meta file or recordings.epl*/ )
                {
-                       eWarning("no .meta file found, trying to find PMT pid");
                        eDVBTSTools tstools;
+                       bool b = source || !tstools.openFile(ref.path.c_str(), 1);
+                       eWarning("no .meta file found, trying to find PMT pid");
                        if (source)
-                               tstools.setSource(source, streaminfo_file ? streaminfo_file : ref.path.c_str());
-                       else if (tstools.openFile(ref.path.c_str()))
-                               eWarning("failed to open file");
-                       else
+                               tstools.setSource(source, NULL);
+                       if (b)
                        {
                                int service_id, pmt_pid;
                                if (!tstools.findPMT(pmt_pid, service_id))
                                        m_pmt_pid = pmt_pid;
                                }
                        }
+                       else
+                               eWarning("no valid source to find PMT pid!");
                }
                eDebug("alloc PVR");
                        /* allocate PVR */
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();
@@@ -144,7 -145,7 +145,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) 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);
diff --combined lib/dvb/tstools.cpp
@@@ -40,7 -40,7 +40,7 @@@ int eDVBTSTools::openFile(const char *f
        if (f->open(filename, 1) < 0)
                return -1;
  
 -      setSource(src, filename);
 +      setSource(src, nostreaminfo ? NULL : filename);
  
        return 0;
  }
@@@ -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,26 -702,9 +702,26 @@@ 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;
  
 +#if 0
 +                      /* 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 */
 +      }
 +
 +#endif
 +
 +                      /* let's find the next frame after the given offset */
        do {
                if (m_streaminfo.getStructureEntry(offset, data, 1))
                {
  //            eDebug("%08llx@%llx (next)", data, offset);
        } while (((data & 0xFF) != 9) && ((data & 0xFF) != 0x00)); /* next frame */
  
 +#if 0
                        /* align to TS pkt start */
 -//    start = start - (start % 188);
 -//    offset = offset - (offset % 188);
 +      start = start - (start % 188);
 +      offset = offset - (offset % 188);
 +#endif
  
        len = offset - start;
        _offset = start;
index b44a247,d61dbc7..6ff1c5a
mode 100644,100755..100644
@@@ -110,7 -110,7 +110,7 @@@ class MediaPlayer(Screen, InfoBarBase, 
  
                # 'None' is magic to start at the list of mountpoints
                defaultDir = config.mediaplayer.defaultDir.getValue()
-               self.filelist = FileList(defaultDir, matchingPattern = "(?i)^.*\.(mp2|mp3|ogg|ts|wav|wave|m3u|pls|e2pls|mpg|vob|avi|divx|m4v|mkv|mp4|m4a|dat|flac|mov)", useServiceRef = True, additionalExtensions = "4098:m3u 4098:e2pls 4098:pls")
+               self.filelist = FileList(defaultDir, matchingPattern = "(?i)^.*\.(mp2|mp3|ogg|ts|wav|wave|m3u|pls|e2pls|mpg|vob|avi|divx|m4v|mkv|mp4|m4a|dat|flac|mov|m2ts)", useServiceRef = True, additionalExtensions = "4098:m3u 4098:e2pls 4098:pls")
                self["filelist"] = self.filelist
  
                self.playlist = MyPlayList()
@@@ -1041,6 -1041,6 +1041,6 @@@ def filescan(**kwargs)
  from Plugins.Plugin import PluginDescriptor
  def Plugins(**kwargs):
        return [
 -              PluginDescriptor(name = "MediaPlayer", description = "Play back media files", where = PluginDescriptor.WHERE_MENU, fnc = menu),
 -              PluginDescriptor(name = "MediaPlayer", where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan)
 +              PluginDescriptor(name = "MediaPlayer", description = "Play back media files", where = PluginDescriptor.WHERE_MENU, needsRestart = False, fnc = menu),
 +              PluginDescriptor(name = "MediaPlayer", where = PluginDescriptor.WHERE_FILESCAN, needsRestart = False, fnc = filescan)
        ]
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
        {
@@@ -905,7 -903,7 +905,7 @@@ RESULT eServiceFactoryDVB::lookupServic
                /* we are sure to have a ..DVB reference as the info() call was forwarded here according to it's ID. */
                if ((err = db->getService((eServiceReferenceDVB&)ref, service)) != 0)
                {
 -                      eDebug("getService failed!");
 +//                    eDebug("getService failed!");
                        return err;
                }
        }
@@@ -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 = "???";
  
@@@ -2403,7 -2401,7 +2405,7 @@@ void eDVBServicePlay::updateDecoder(boo
                eDebug("getting program info failed.");
        else
        {
 -              eDebugNoNewLine("have %d video stream(s)", program.videoStreams.size());
 +              eDebugNoNewLine("have %zd video stream(s)", program.videoStreams.size());
                if (!program.videoStreams.empty())
                {
                        eDebugNoNewLine(" (");
                        }
                        eDebugNoNewLine(")");
                }
 -              eDebugNoNewLine(", and %d audio stream(s)", program.audioStreams.size());
 +              eDebugNoNewLine(", and %zd audio stream(s)", program.audioStreams.size());
                if (!program.audioStreams.empty())
                {
                        eDebugNoNewLine(" (");
@@@ -2599,7 -2597,7 +2601,7 @@@ void eDVBServicePlay::loadCuesheet(
                        m_cue_entries.insert(cueEntry(where, what));
                }
                fclose(f);
 -              eDebug("%d entries", m_cue_entries.size());
 +              eDebug("%zd entries", m_cue_entries.size());
        } else
                eDebug("cutfile not found!");