Merge branch 'master' of git.opendreambox.org:/git/enigma2
authorFelix Domke <felix.domke@multimedia-labs.de>
Thu, 16 Jul 2009 21:41:52 +0000 (23:41 +0200)
committerFelix Domke <felix.domke@multimedia-labs.de>
Thu, 16 Jul 2009 21:41:52 +0000 (23:41 +0200)
12 files changed:
data/defaults/Dream/userbouquet.favourites.tv
lib/base/encoding.cpp
lib/base/rawfile.cpp
lib/dvb/db.cpp
lib/dvb/demux.cpp
lib/dvb/pmt.cpp
lib/dvb/scan.cpp
lib/dvb/specs.h
lib/python/Components/Harddisk.py
lib/python/Plugins/SystemPlugins/NFIFlash/downloader.py
lib/service/servicemp3.cpp
lib/service/servicemp3.h

index 7efaccd..f1adaf9 100644 (file)
@@ -12,6 +12,7 @@
 #SERVICE 1:0:1:2F1C:441:1:C00000:0:0:0:\r
 #SERVICE 1:0:1:7005:436:1:C00000:0:0:0:\r
 #SERVICE 1:0:1:2FC:5:85:C00000:0:0:0:\r
+#SERVICE 1:0:1:F98:454:1:C00000:0:0:0:\r
 #SERVICE 1:0:1:7034:41B:1:C00000:0:0:0:\r
 #SERVICE 1:0:1:6D67:437:1:C00000:0:0:0:\r
 #SERVICE 1:0:1:7031:41B:1:C00000:0:0:0:\r
 #SERVICE 1:0:1:6D6E:437:1:C00000:0:0:0:\r
 #SERVICE 1:0:1:6D6B:437:1:C00000:0:0:0:\r
 #SERVICE 1:0:1:2775:444:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:202:7:85:C00000:0:0:0:\r
 #SERVICE 1:0:1:293:5:85:C00000:0:0:0:\r
 #SERVICE 1:0:1:3138:459:1:C00000:0:0:0:\r
 #SERVICE 1:0:1:6D70:437:1:C00000:0:0:0:\r
 #SERVICE 1:0:1:277B:444:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:332D:45B:1:C00000:0:0:0:\r
 #SERVICE 1:0:1:3139:459:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:F1CC:421:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:2F5A:454:1:C00000:0:0:0:\r
 #SERVICE 1:64:A:0:0:0:0:0:0:0::Sport\r
 #DESCRIPTION Sport\r
 #SERVICE 1:0:1:384:21:85:C00000:0:0:0:\r
@@ -50,8 +51,8 @@
 #SERVICE 1:0:1:2F3A:441:1:C00000:0:0:0:\r
 #SERVICE 1:0:1:445F:453:1:C00000:0:0:0:\r
 #SERVICE 1:0:1:79F4:443:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:2753:402:1:C00000:0:0:0:\r
 #SERVICE 1:0:1:7035:41B:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:2F80:454:1:C00000:0:0:0:\r
 #SERVICE 1:64:3:0:0:0:0:0:0:0::Regional\r
 #DESCRIPTION Regional\r
 #SERVICE 1:0:1:3146:459:1:C00000:0:0:0:\r
 #SERVICE 1:64:5:0:0:0:0:0:0:0::Reisen\r
 #DESCRIPTION Reisen\r
 #SERVICE 1:0:1:20:21:85:C00000:0:0:0:\r
-#SERVICE 1:0:1:301:7:85:C00000:0:0:0:\r
-#SERVICE 1:0:1:27A8:444:1:C00000:0:0:0:\r
 #SERVICE 1:0:1:3339:45B:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:27B9:444:1:C00000:0:0:0:\r
 #SERVICE 1:64:9:0:0:0:0:0:0:0::Beratung\r
 #DESCRIPTION Beratung\r
 #SERVICE 1:0:1:295:21:85:C00000:0:0:0:\r
 #SERVICE 1:64:6:0:0:0:0:0:0:0::Einkaufen\r
 #DESCRIPTION Einkaufen\r
-#SERVICE 1:0:1:2F30:441:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:301:7:85:C00000:0:0:0:\r
 #SERVICE 1:0:1:28:21:85:C00000:0:0:0:\r
 #SERVICE 1:0:1:79EA:443:1:C00000:0:0:0:\r
 #SERVICE 1:0:1:2F44:454:1:C00000:0:0:0:\r
 #SERVICE 1:0:1:3148:459:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:332D:45B:1:C00000:0:0:0:\r
 #SERVICE 1:0:1:36:7:85:C00000:0:0:0:\r
 #SERVICE 1:0:1:307:7:85:C00000:0:0:0:\r
 #SERVICE 1:0:1:296:5:85:C00000:0:0:0:\r
 #SERVICE 1:0:1:2791:444:1:C00000:0:0:0:\r
 #SERVICE 1:0:1:383:21:85:C00000:0:0:0:\r
 #SERVICE 1:0:1:313C:459:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:278C:444:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:3159:459:1:C00000:0:0:0:\r
 #SERVICE 1:0:1:2E:21:85:C00000:0:0:0:\r
 #SERVICE 1:0:1:381:21:85:C00000:0:0:0:\r
 #SERVICE 1:64:7:0:0:0:0:0:0:0::High Definition\r
 #DESCRIPTION High Definition\r
-#SERVICE 1:0:19:1324:3EF:1:C00000:0:0:0:\r
+#SERVICE 1:0:19:2B5C:3F3:1:C00000:0:0:0:\r
+#SERVICE 1:0:19:2B66:3F3:1:C00000:0:0:0:\r
 #SERVICE 1:0:19:2B70:3F3:1:C00000:0:0:0:\r
-#SERVICE 1:0:19:2B84:3F3:1:C00000:0:0:0:\r
 #SERVICE 1:0:19:6EEC:4B1:1:C00000:0:0:0:\r
+#SERVICE 1:0:19:1324:3EF:1:C00000:0:0:0:\r
 #SERVICE 1:0:19:1325:3EF:1:C00000:0:0:0:\r
+#SERVICE 1:0:19:2B84:3F3:1:C00000:0:0:0:\r
 #SERVICE 1:64:0:0:0:0:0:0:0:0::Alternativen\r
 #DESCRIPTION Alternativen\r
 #SERVICE 1:0:1:6DCB:44D:1:C00000:0:0:0:\r
index 6a997cf..831de84 100644 (file)
@@ -1,3 +1,4 @@
+#include <cstdio>
 #include <cstdlib>
 #include <lib/base/encoding.h>
 #include <lib/base/eerror.h>
index e444ba9..d7f2a65 100644 (file)
@@ -1,3 +1,4 @@
+#include <cstdio>
 #include <unistd.h>
 #include <fcntl.h>
 #include <lib/base/rawfile.h>
index ffc62f6..109d6a6 100644 (file)
@@ -175,7 +175,10 @@ int eDVBService::checkFilter(const eServiceReferenceDVB &ref, const eDVBChannelQ
                res = m_service_name_sort == query.m_string;
                break;
        case eDVBChannelQuery::tProvider:
-               res = m_provider_name == query.m_string;
+               if (query.m_string == "Unknown" && m_provider_name.empty())
+                       res = 1;
+               else
+                       res = m_provider_name == query.m_string;
                break;
        case eDVBChannelQuery::tType:
                res = ref.getServiceType() == query.m_int;
index 1146518..6d92540 100644 (file)
 #define HAVE_ADD_PID
 
 #ifdef HAVE_ADD_PID
+
+#if HAVE_DVB_API_VERSION > 3
+#ifndef DMX_ADD_PID
+#define DMX_ADD_PID            _IOW('o', 51, __u16)
+#define DMX_REMOVE_PID         _IOW('o', 52, __u16)
+#endif
+#else
 #define DMX_ADD_PID              _IO('o', 51)
 #define DMX_REMOVE_PID           _IO('o', 52)
 
@@ -42,6 +49,7 @@ typedef enum {
        DMX_TAP_TS = 0,
        DMX_TAP_PES = DMX_PES_OTHER, /* for backward binary compat. */
 } dmx_tap_type_t;
+#endif
 
 #endif
 
@@ -493,12 +501,17 @@ eDVBTSRecorder::~eDVBTSRecorder()
 
 RESULT eDVBTSRecorder::start()
 {
+       std::map<int,int>::iterator i(m_pids.begin());
+
        if (m_running)
                return -1;
        
        if (m_target_fd == -1)
                return -2;
 
+       if (i == m_pids.end())
+               return -3;
+
        char filename[128];
 #ifndef HAVE_ADD_PID
 #if HAVE_DVB_API_VERSION < 3
@@ -527,10 +540,16 @@ RESULT eDVBTSRecorder::start()
        ::ioctl(m_source_fd, DMX_SET_BUFFER_SIZE, 1024*1024);
 
        dmx_pes_filter_params flt;
+#if HAVE_DVB_API_VERSION > 3
+       flt.pes_type = DMX_PES_OTHER;
+       flt.output  = DMX_OUT_TSDEMUX_TAP;
+#else
        flt.pes_type = (dmx_pes_type_t)DMX_TAP_TS;
-       flt.pid     = (__u16)-1;
-       flt.input   = DMX_IN_FRONTEND;
        flt.output  = DMX_OUT_TAP;
+#endif
+       flt.pid     = i->first;
+       ++i;
+       flt.input   = DMX_IN_FRONTEND;
        flt.flags   = 0;
        int res = ::ioctl(m_source_fd, DMX_SET_PES_FILTER, &flt);
        if (res)
@@ -549,10 +568,12 @@ RESULT eDVBTSRecorder::start()
        
        m_thread->start(m_source_fd, m_target_fd);
        m_running = 1;
-       
-       for (std::map<int,int>::iterator i(m_pids.begin()); i != m_pids.end(); ++i)
+
+       while (i != m_pids.end()) {
                startPID(i->first);
-       
+               ++i;
+       }
+
        return 0;
 }
 
@@ -675,7 +696,12 @@ RESULT eDVBTSRecorder::startPID(int pid)
        m_pids[pid] = fd;
 #else
        while(true) {
+#if HAVE_DVB_API_VERSION > 3
+               __u16 p = pid;
+               if (::ioctl(m_source_fd, DMX_ADD_PID, &p) < 0) {
+#else
                if (::ioctl(m_source_fd, DMX_ADD_PID, pid) < 0) {
+#endif
                        perror("DMX_ADD_PID");
                        if (errno == EAGAIN || errno == EINTR) {
                                eDebug("retry!");
@@ -698,7 +724,12 @@ void eDVBTSRecorder::stopPID(int pid)
        if (m_pids[pid] != -1)
        {
                while(true) {
+#if HAVE_DVB_API_VERSION > 3
+                       __u16 p = pid;
+                       if (::ioctl(m_source_fd, DMX_REMOVE_PID, &p) < 0) {
+#else
                        if (::ioctl(m_source_fd, DMX_REMOVE_PID, pid) < 0) {
+#endif
                                perror("DMX_REMOVE_PID");
                                if (errno == EAGAIN || errno == EINTR) {
                                        eDebug("retry!");
index 13ed6b9..e1aa096 100644 (file)
@@ -17,6 +17,7 @@
 #include <dvbsi++/subtitling_descriptor.h>
 #include <dvbsi++/teletext_descriptor.h>
 #include <dvbsi++/video_stream_descriptor.h>
+#include <dvbsi++/registration_descriptor.h>
 
 eDVBServicePMTHandler::eDVBServicePMTHandler()
        :m_ca_servicePtr(0), m_dvb_scan(0), m_decode_demux_num(0xFF)
@@ -209,11 +210,11 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program)
                        {
                                const ProgramMapSection &pmt = **i;
                                program.pcrPid = pmt.getPcrPid();
-                       
+
                                ElementaryStreamInfoConstIterator es;
                                for (es = pmt.getEsInfo()->begin(); es != pmt.getEsInfo()->end(); ++es)
                                {
-                                       int isaudio = 0, isvideo = 0;
+                                       int isaudio = 0, isvideo = 0, issubtitle = 0, forced_video = 0, forced_audio = 0;
                                        videoStream video;
                                        audioStream audio;
                                        audio.component_tag=video.component_tag=-1;
@@ -239,17 +240,21 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program)
                                                //break; fall through !!!
                                        case 0x02: // MPEG 2 video
                                                isvideo = 1;
+                                               forced_video = 1;
                                                //break; fall through !!!
                                        case 0x03: // MPEG 1 audio
                                        case 0x04: // MPEG 2 audio:
-                                               if (!isvideo)
+                                               if (!isvideo) {
                                                        isaudio = 1;
+                                                       forced_audio = 1;
+                                               }
                                                //break; fall through !!!
                                        case 0x0f: // MPEG 2 AAC
                                                if (!isvideo && !isaudio)
                                                {
                                                        isaudio = 1;
                                                        audio.type = audioStream::atAAC;
+                                                       forced_audio = 1;
                                                }
                                                //break; fall through !!!
                                        case 0x11: // MPEG 4 AAC
@@ -257,6 +262,7 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program)
                                                {
                                                        isaudio = 1;
                                                        audio.type = audioStream::atAACHE;
+                                                       forced_audio = 1;
                                                }
                                        case 0x80: // user private ... but blueray LPCM
                                                if (!isvideo && !isaudio)
@@ -280,13 +286,12 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program)
                                        case 0x06: // PES Private
                                        case 0xEA: // TS_PSI_ST_SMPTE_VC1
                                                for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin();
-                                                               desc != (*es)->getDescriptors()->end(); ++desc)
+                                                       desc != (*es)->getDescriptors()->end(); ++desc)
                                                {
                                                        uint8_t tag = (*desc)->getTag();
-                                                       if (!isaudio && !isvideo)
+                                                       /* check descriptors to get the exakt stream type. */
+                                                       if (!forced_video && !forced_audio)
                                                        {
-                                                               /* PES private can contain AC-3, DTS or lots of other stuff.
-                                                                  check descriptors to get the exakt type. */
                                                                switch (tag)
                                                                {
                                                                case AUDIO_STREAM_DESCRIPTOR:
@@ -325,6 +330,7 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program)
                                                                                s.language_code = (*it)->getIso639LanguageCode();
 //                                                                             eDebug("add dvb subtitle %s PID %04x, type %d, composition page %d, ancillary_page %d",
 //                                                                                     s.language_code.c_str(), s.pid, s.subtitling_type, s.composition_page_id, s.ancillary_page_id);
+                                                                               issubtitle=1;
                                                                                program.subtitleStreams.push_back(s);
                                                                        }
                                                                        break;
@@ -349,6 +355,8 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program)
 //                                                                                             eDebug("add teletext subtitle %s PID %04x, page number %d, magazine number %d",
 //                                                                                                     s.language_code.c_str(), s.pid, s.teletext_page_number, s.teletext_magazine_number);
                                                                                                program.subtitleStreams.push_back(s);
+                                                                                               issubtitle=1;
+                                                                                       default:
                                                                                                break;
                                                                                        }
                                                                                }
@@ -373,13 +381,8 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program)
                                                                        break;
                                                                case REGISTRATION_DESCRIPTOR: /* some services don't have a separate AC3 descriptor */
                                                                {
-                                                                               /* libdvbsi++ doesn't yet support this descriptor type, so work around. */
-                                                                       if ((*desc)->getLength() < 4)
-                                                                               break;
-                                                                       unsigned char descr[6];
-                                                                       (*desc)->writeToBuffer(descr);
-                                                                       int format_identifier = (descr[2] << 24) | (descr[3] << 16) | (descr[4] << 8) | (descr[5]);
-                                                                       switch (format_identifier)
+                                                                       RegistrationDescriptor *d = (RegistrationDescriptor*)(*desc);
+                                                                       switch (d->getFormatIdentifier())
                                                                        {
                                                                        case 0x44545331 ... 0x44545333: // DTS1/DTS2/DTS3
                                                                                isaudio = 1;
@@ -394,15 +397,17 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program)
                                                                                audio.type = audioStream::atLPCM;
                                                                                break;
                                                                        case 0x56432d31: // == 'VC-1'
-                                                                               if (descr[6] == 0x01) // subdescriptor tag
+                                                                       {
+                                                                               const AdditionalIdentificationInfoVector *vec = d->getAdditionalIdentificationInfo();
+                                                                               if (vec->size() > 1 && (*vec)[1] == 0x01) // subdescriptor tag
                                                                                {
-                                                                                       if (descr[7] >= 0x90) // profile_level
+                                                                                       if ((*vec)[2] >= 0x90) // profile_level
                                                                                                video.type = videoStream::vtVC1; // advanced profile
                                                                                        else
                                                                                                video.type = videoStream::vtVC1_SM; // simple main
                                                                                        isvideo = 1;
                                                                                }
-                                                                               break;
+                                                                       }
                                                                        default:
                                                                                break;
                                                                        }
@@ -422,39 +427,57 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program)
                                                        }
                                                        switch (tag)
                                                        {
-                                                               case ISO_639_LANGUAGE_DESCRIPTOR:
-                                                                       if (!isvideo)
+                                                       case ISO_639_LANGUAGE_DESCRIPTOR:
+                                                               if (!isvideo)
+                                                               {
+                                                                       int cnt=0;
+                                                                       const Iso639LanguageList *languages = ((Iso639LanguageDescriptor*)*desc)->getIso639Languages();
+                                                                               /* use last language code */
+                                                                       for (Iso639LanguageConstIterator i(languages->begin()); i != languages->end(); ++i, ++cnt)
                                                                        {
-                                                                               int cnt=0;
-                                                                               const Iso639LanguageList *languages = ((Iso639LanguageDescriptor*)*desc)->getIso639Languages();
-                                                                                       /* use last language code */
-                                                                               for (Iso639LanguageConstIterator i(languages->begin()); i != languages->end(); ++i, ++cnt)
-                                                                               {
-                                                                                       if (cnt == 0)
-                                                                                               audio.language_code = (*i)->getIso639LanguageCode();
-                                                                                       else
-                                                                                               audio.language_code += "/" + (*i)->getIso639LanguageCode();
-                                                                               }
+                                                                               if (cnt == 0)
+                                                                                       audio.language_code = (*i)->getIso639LanguageCode();
+                                                                               else
+                                                                                       audio.language_code += "/" + (*i)->getIso639LanguageCode();
                                                                        }
-                                                                       break;
-                                                               case STREAM_IDENTIFIER_DESCRIPTOR:
-                                                                       audio.component_tag =
-                                                                               video.component_tag =
-                                                                                       ((StreamIdentifierDescriptor*)*desc)->getComponentTag();
-                                                                       break;
-                                                               case CA_DESCRIPTOR:
-                                                               {
-                                                                       CaDescriptor *descr = (CaDescriptor*)(*desc);
-                                                                       program.caids.insert(descr->getCaSystemId());
-                                                                       break;
                                                                }
-                                                               default:
-                                                                       break;
+                                                               break;
+                                                       case STREAM_IDENTIFIER_DESCRIPTOR:
+                                                               audio.component_tag =
+                                                                       video.component_tag =
+                                                                               ((StreamIdentifierDescriptor*)*desc)->getComponentTag();
+                                                               break;
+                                                       case CA_DESCRIPTOR:
+                                                       {
+                                                               CaDescriptor *descr = (CaDescriptor*)(*desc);
+                                                               program.caids.insert(descr->getCaSystemId());
+                                                               break;
+                                                       }
+                                                       default:
+                                                               break;
                                                        }
                                                }
+                                       default:
                                                break;
                                        }
-                                       if (isaudio)
+                                       if (issubtitle && (isaudio || isvideo))
+                                               eDebug("ambiguous streamtype for PID %04x detected.. forced as subtitle!", (*es)->getPid());
+                                       else if (isaudio && isvideo)
+                                               eDebug("ambiguous streamtype for PID %04x detected.. forced as video!", (*es)->getPid());
+                                       if (issubtitle)
+                                               continue;
+                                       else if (isvideo)
+                                       {
+                                               video.pid = (*es)->getPid();
+                                               if ( !program.videoStreams.empty() && video.pid == cached_vpid )
+                                               {
+                                                       program.videoStreams.push_back(program.videoStreams[0]);
+                                                       program.videoStreams[0] = video;
+                                               }
+                                               else
+                                                       program.videoStreams.push_back(video);
+                                       }
+                                       else if (isaudio)
                                        {
                                                audio.pid = (*es)->getPid();
 
@@ -468,17 +491,6 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program)
 
                                                program.audioStreams.push_back(audio);
                                        }
-                                       else if (isvideo)
-                                       {
-                                               video.pid = (*es)->getPid();
-                                               if ( !program.videoStreams.empty() && video.pid == cached_vpid )
-                                               {
-                                                       program.videoStreams.push_back(program.videoStreams[0]);
-                                                       program.videoStreams[0] = video;
-                                               }
-                                               else
-                                                       program.videoStreams.push_back(video);
-                                       }
                                        else
                                                continue;
                                }
@@ -494,7 +506,6 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program)
                        }
                        ret = 0;
 
-
                        /* finally some fixup: if our default audio stream is an MPEG audio stream, 
                           and we have 'defaultac3' set, use the first available ac3 stream instead.
                           (note: if an ac3 audio stream was selected before, this will be also stored
index 1c8e4d2..19c1086 100644 (file)
@@ -5,6 +5,7 @@
 #include <dvbsi++/terrestrial_delivery_system_descriptor.h>
 #include <dvbsi++/cable_delivery_system_descriptor.h>
 #include <dvbsi++/ca_identifier_descriptor.h>
+#include <dvbsi++/registration_descriptor.h>
 #include <lib/dvb/specs.h>
 #include <lib/dvb/esection.h>
 #include <lib/dvb/scan.h>
@@ -292,32 +293,36 @@ void eDVBScan::PMTready(int err)
                        ElementaryStreamInfoConstIterator es;
                        for (es = pmt.getEsInfo()->begin(); es != pmt.getEsInfo()->end(); ++es)
                        {
-                               int isaudio = 0, isvideo = 0, is_scrambled = 0;
+                               int isaudio = 0, isvideo = 0, is_scrambled = 0, forced_audio = 0, forced_video = 0;
                                switch ((*es)->getType())
                                {
-                               case 0xEA: // TS_PSI_ST_SMPTE_VC1
                                case 0x1b: // AVC Video Stream (MPEG4 H264)
                                case 0x10: // MPEG 4 Part 2
                                case 0x01: // MPEG 1 video
                                case 0x02: // MPEG 2 video
                                        isvideo = 1;
+                                       forced_video = 1;
                                        //break; fall through !!!
                                case 0x03: // MPEG 1 audio
                                case 0x04: // MPEG 2 audio
                                case 0x0f: // MPEG 2 AAC
                                case 0x11: // MPEG 4 AAC
-                                       if (!isvideo)
+                                       if (!isvideo) 
+                                       {
+                                               forced_audio = 1;
                                                isaudio = 1;
+                                       }
                                case 0x06: // PES Private
                                case 0x81: // user private
+                               case 0xEA: // TS_PSI_ST_SMPTE_VC1
                                        for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin();
                                                        desc != (*es)->getDescriptors()->end(); ++desc)
                                        {
                                                uint8_t tag = (*desc)->getTag();
-                                               if (!isaudio && !isvideo)
+                                               /* PES private can contain AC-3, DTS or lots of other stuff.
+                                                  check descriptors to get the exakt type. */
+                                               if (!forced_video && !forced_audio)
                                                {
-                                                       /* PES private can contain AC-3, DTS or lots of other stuff.
-                                                          check descriptors to get the exakt type. */
                                                        switch (tag)
                                                        {
                                                        case 0x1C: // TS_PSI_DT_MPEG4_Audio
@@ -335,16 +340,11 @@ void eDVBScan::PMTready(int err)
                                                                break;
                                                        case REGISTRATION_DESCRIPTOR: /* some services don't have a separate AC3 descriptor */
                                                        {
-                                                               /* libdvbsi++ doesn't yet support this descriptor type, so work around. */
-                                                               if ((*desc)->getLength() < 4)
-                                                                       break;
-                                                               unsigned char descr[6];
-                                                               (*desc)->writeToBuffer(descr);
-                                                               int format_identifier = (descr[2] << 24) | (descr[3] << 16) | (descr[4] << 8) | (descr[5]);
-                                                               switch (format_identifier)
+                                                               RegistrationDescriptor *d = (RegistrationDescriptor*)(*desc);
+                                                               switch (d->getFormatIdentifier())
                                                                {
-                                                               case 0x41432d33: // == 'AC-3'
                                                                case 0x44545331 ... 0x44545333: // DTS1/DTS2/DTS3
+                                                               case 0x41432d33: // == 'AC-3'
                                                                case 0x42535344: // == 'BSSD' (LPCM)
                                                                        isaudio = 1;
                                                                        break;
@@ -362,12 +362,13 @@ void eDVBScan::PMTready(int err)
                                                if (tag == CA_DESCRIPTOR)
                                                        is_scrambled = 1;
                                        }
+                               default:
                                        break;
                                }
-                               if (isaudio)
-                                       have_audio = true;
-                               else if (isvideo)
+                               if (isvideo)
                                        have_video = true;
+                               else if (isaudio)
+                                       have_audio = true;
                                else
                                        continue;
                                if (is_scrambled)
index fdbaea1..6be938c 100644 (file)
@@ -48,7 +48,7 @@ public:
                m_spec.pid     = ServiceDescriptionSection::PID;
                m_spec.tid     = ServiceDescriptionSection::TID;
                m_spec.tidext  = tsid;
-               m_spec.timeout = 20000; // ServiceDescriptionSection::TIMEOUT;
+               m_spec.timeout = 60000; // ServiceDescriptionSection::TIMEOUT;
                m_spec.flags   = eDVBTableSpec::tfAnyVersion |
                        eDVBTableSpec::tfHaveTID | eDVBTableSpec::tfCheckCRC |
                        eDVBTableSpec::tfHaveTIDExt | eDVBTableSpec::tfHaveTimeout;
index 637c889..2efdb68 100755 (executable)
@@ -6,11 +6,7 @@ import time
 from Components.Console import Console
 
 def readFile(filename):
-       try:
-               file = open(filename)
-       except IOError:
-               return ""
-
+       file = open(filename)
        data = file.read().strip()
        file.close()
        return data
index 6d404cf..6292a46 100644 (file)
@@ -494,7 +494,7 @@ class NFIDownload(Screen):
                        self.taskstring = ""
                        self.container.appClosed.append(self.fdisk_finished)
                        self.container.execute("fdisk " + self.stickdevice + "/disc")
-                       self.container.write("d\nn\np\n1\n\n\nt\n6\nw\n")
+                       self.container.write("d\n4\nd\n3\nd\n2\nd\nn\np\n1\n\n\nt\n6\nw\n")
                        self.delayTimer = eTimer()
                        self.delayTimer.callback.append(self.progress_increment)
                        self.delayTimer.start(105, False)
index 3a61011..3e6de28 100644 (file)
@@ -198,6 +198,7 @@ eServiceMP3::eServiceMP3(eServiceReference ref)
        m_currentSubtitleStream = 0;
        m_subtitle_widget = 0;
        m_currentTrickRatio = 0;
+       m_subs_to_pull = 0;
        m_buffer_size = 1*1024*1024;
        CONNECT(m_seekTimeout->timeout, eServiceMP3::seekTimeoutCB);
        CONNECT(m_subtitle_sync_timer->timeout, eServiceMP3::pushSubtitles);
@@ -301,7 +302,6 @@ eServiceMP3::eServiceMP3(eServiceReference ref)
                eDebug("eServiceMP3::sorry, can't play: missing gst-plugin-appsink");
        else
        {
-               g_object_set (G_OBJECT (subsink), "emit-signals", TRUE, NULL);
                g_signal_connect (subsink, "new-buffer", G_CALLBACK (gstCBsubtitleAvail), this);
                g_object_set (G_OBJECT (m_gst_playbin), "text-sink", subsink, NULL);
        }
@@ -488,8 +488,6 @@ RESULT eServiceMP3::getLength(pts_t &pts)
 
 RESULT eServiceMP3::seekTo(pts_t to)
 {
-       m_subtitle_pages.clear();
-
        if (!m_gst_playbin)
                return -1;
 
@@ -502,6 +500,11 @@ RESULT eServiceMP3::seekTo(pts_t to)
                eDebug("eServiceMP3::seekTo failed");
                return -1;
        }
+
+       m_subtitle_pages.clear();
+       eSingleLocker l(m_subs_to_pull_lock);
+       m_subs_to_pull = 0;
+
        return 0;
 }
 
@@ -564,19 +567,40 @@ RESULT eServiceMP3::seekRelative(int direction, pts_t to)
 
 RESULT eServiceMP3::getPlayPosition(pts_t &pts)
 {
+       GstFormat fmt = GST_FORMAT_TIME;
+       gint64 pos;
+       GstElement *sink;
+       pts = 0;
+
        if (!m_gst_playbin)
                return -1;
        if (m_state != stRunning)
                return -1;
 
-       GstFormat fmt = GST_FORMAT_TIME;
-       gint64 len;
-       
-       if (!gst_element_query_position(m_gst_playbin, &fmt, &len))
+       g_object_get (G_OBJECT (m_gst_playbin), "audio-sink", &sink, NULL);
+
+       if (!sink)
+               g_object_get (G_OBJECT (m_gst_playbin), "video-sink", &sink, NULL);
+
+       if (!sink)
                return -1;
 
-               /* len is in nanoseconds. we have 90 000 pts per second. */
-       pts = len / 11111;
+       gchar *name = gst_element_get_name(sink);
+       gboolean use_get_decoder_time = strstr(name, "dvbaudiosink") || strstr(name, "dvbvideosink");
+       g_free(name);
+
+       if (use_get_decoder_time)
+               g_signal_emit_by_name(sink, "get-decoder-time", &pos);
+
+       gst_object_unref(sink);
+
+       if (!use_get_decoder_time && !gst_element_query_position(m_gst_playbin, &fmt, &pos)) {
+               eDebug("gst_element_query_position failed in getPlayPosition");
+               return -1;
+       }
+
+       /* pos is in nanoseconds. we have 90 000 pts per second. */
+       pts = pos / 11111;
        return 0;
 }
 
@@ -1011,13 +1035,13 @@ void eServiceMP3::gstBusCall(GstBus *bus, GstMessage *msg)
                case GST_MESSAGE_STATE_CHANGED:
                {
                        if(GST_MESSAGE_SRC(msg) != GST_OBJECT(m_gst_playbin))
-                       return;
+                               break;
 
                        GstState old_state, new_state;
                        gst_message_parse_state_changed(msg, &old_state, &new_state, NULL);
                
                        if(old_state == new_state)
-                               return;
+                               break;
        
                        eDebug("eServiceMP3::state transition %s -> %s", gst_element_state_get_name(old_state), gst_element_state_get_name(new_state));
        
@@ -1030,6 +1054,16 @@ void eServiceMP3::gstBusCall(GstBus *bus, GstMessage *msg)
                                }       break;
                                case GST_STATE_CHANGE_READY_TO_PAUSED:
                                {
+                                       GstElement *sink;
+                                       g_object_get (G_OBJECT (m_gst_playbin), "text-sink", &sink, NULL);
+                                       if (sink)
+                                       {
+                                               g_object_set (G_OBJECT (sink), "max-buffers", 2, NULL);
+                                               g_object_set (G_OBJECT (sink), "sync", FALSE, NULL);
+                                               g_object_set (G_OBJECT (sink), "async", FALSE, NULL);
+                                               g_object_set (G_OBJECT (sink), "emit-signals", TRUE, NULL);
+                                               gst_object_unref(sink);
+                                       }
                                }       break;
                                case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
                                {
@@ -1050,12 +1084,12 @@ void eServiceMP3::gstBusCall(GstBus *bus, GstMessage *msg)
                {
                        gchar *debug;
                        GError *err;
-       
                        gst_message_parse_error (msg, &err, &debug);
                        g_free (debug);
                        eWarning("Gstreamer error: %s (%i) from %s", err->message, err->code, sourceName );
                        if ( err->domain == GST_STREAM_ERROR )
                        {
+                               eDebug("err->code %d", err->code);
                                if ( err->code == GST_STREAM_ERROR_CODEC_NOT_FOUND )
                                {
                                        if ( g_strrstr(sourceName, "videosink") )
@@ -1112,6 +1146,9 @@ void eServiceMP3::gstBusCall(GstBus *bus, GstMessage *msg)
                }
                case GST_MESSAGE_ASYNC_DONE:
                {
+                       if(GST_MESSAGE_SRC(msg) != GST_OBJECT(m_gst_playbin))
+                               break;
+
                        GstTagList *tags;
                        gint i, active_idx, n_video = 0, n_audio = 0, n_text = 0;
 
@@ -1218,7 +1255,6 @@ void eServiceMP3::gstBusCall(GstBus *bus, GstMessage *msg)
                                                if (strstr(eventname, "Changed"))
                                                        m_event((iPlayableService*)this, evVideoProgressiveChanged);
                                        }
-                                       g_free(eventname);
                                }
                        }
                        break;
@@ -1251,12 +1287,12 @@ audiotype_t eServiceMP3::gstCheckAudioPad(GstStructure* structure)
 
        if ( gst_structure_has_name (structure, "audio/mpeg"))
        {
-               gint mpegversion, layer = -1;
+               gint mpegversion, layer = -1;
                if (!gst_structure_get_int (structure, "mpegversion", &mpegversion))
                        return atUnknown;
 
                switch (mpegversion) {
-                       case 1:
+                       case 1:
                                {
                                        gst_structure_get_int (structure, "layer", &layer);
                                        if ( layer == 3 )
@@ -1284,7 +1320,7 @@ audiotype_t eServiceMP3::gstCheckAudioPad(GstStructure* structure)
        return atUnknown;
 }
 
-void eServiceMP3::gstPoll(const int&)
+void eServiceMP3::gstPoll(const int &msg)
 {
                /* ok, we have a serious problem here. gstBusSyncHandler sends 
                   us the wakup signal, but likely before it was posted.
@@ -1292,15 +1328,19 @@ void eServiceMP3::gstPoll(const int&)
                   
                   I need to understand the API a bit more to make this work 
                   proplerly. */
-       usleep(1);
-       
-       GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (m_gst_playbin));
-       GstMessage *message;
-       while ((message = gst_bus_pop (bus)))
+       if (msg == 1)
        {
-               gstBusCall(bus, message);
-               gst_message_unref (message);
+               GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (m_gst_playbin));
+               GstMessage *message;
+               usleep(1);
+               while ((message = gst_bus_pop (bus)))
+               {
+                       gstBusCall(bus, message);
+                       gst_message_unref (message);
+               }
        }
+       else
+               pullSubtitle();
 }
 
 eAutoInitPtr<eServiceFactoryMP3> init_eServiceFactoryMP3(eAutoInitNumbers::service+1, "eServiceFactoryMP3");
@@ -1308,62 +1348,96 @@ eAutoInitPtr<eServiceFactoryMP3> init_eServiceFactoryMP3(eAutoInitNumbers::servi
 void eServiceMP3::gstCBsubtitleAvail(GstElement *appsink, gpointer user_data)
 {
        eServiceMP3 *_this = (eServiceMP3*)user_data;
-       GstBuffer *buffer;
-       g_signal_emit_by_name (appsink, "pull-buffer", &buffer);
-       if (buffer)
+       eSingleLocker l(_this->m_subs_to_pull_lock);
+       ++_this->m_subs_to_pull;
+       _this->m_pump.send(2);
+}
+
+void eServiceMP3::pullSubtitle()
+{
+       GstElement *sink;
+       g_object_get (G_OBJECT (m_gst_playbin), "text-sink", &sink, NULL);
+       if (sink)
        {
-               GstFormat fmt = GST_FORMAT_TIME;
-               gint64 buf_pos = GST_BUFFER_TIMESTAMP(buffer);
-               gint64 duration_ns = GST_BUFFER_DURATION(buffer);
-               size_t len = GST_BUFFER_SIZE(buffer);
-               unsigned char line[len+1];
-               memcpy(line, GST_BUFFER_DATA(buffer), len);
-               line[len] = 0;
-//             eDebug("got new subtitle @ buf_pos = %lld ns (in pts=%lld): '%s' ", buf_pos, buf_pos/11111, line);
-               if ( _this->m_subtitle_widget )
+               while (m_subs_to_pull && m_subtitle_pages.size() < 2)
                {
-                       ePangoSubtitlePage page;
-                       gRGB rgbcol(0xD0,0xD0,0xD0);
-                       page.m_elements.push_back(ePangoSubtitlePageElement(rgbcol, (const char*)line));
-                       page.show_pts = buf_pos / 11111L;
-                       page.m_timeout = duration_ns / 1000000;
-                       _this->m_subtitle_pages.push_back(page);
-                       _this->pushSubtitles();
+                       GstBuffer *buffer;
+                       {
+                               eSingleLocker l(m_subs_to_pull_lock);
+                               --m_subs_to_pull;
+                       }
+                       g_signal_emit_by_name (sink, "pull-buffer", &buffer);
+                       if (buffer)
+                       {
+                               gint64 buf_pos = GST_BUFFER_TIMESTAMP(buffer);
+                               gint64 duration_ns = GST_BUFFER_DURATION(buffer);
+                               size_t len = GST_BUFFER_SIZE(buffer);
+                               unsigned char line[len+1];
+                               memcpy(line, GST_BUFFER_DATA(buffer), len);
+                               line[len] = 0;
+                               eDebug("got new subtitle @ buf_pos = %lld ns (in pts=%lld): '%s' ", buf_pos, buf_pos/11111, line);
+                               ePangoSubtitlePage page;
+                               gRGB rgbcol(0xD0,0xD0,0xD0);
+                               page.m_elements.push_back(ePangoSubtitlePageElement(rgbcol, (const char*)line));
+                               page.show_pts = buf_pos / 11111L;
+                               page.m_timeout = duration_ns / 1000000;
+                               m_subtitle_pages.push_back(page);
+                               pushSubtitles();
+                               gst_buffer_unref(buffer);
+                       }
                }
+               gst_object_unref(sink);
        }
+       else
+               eDebug("no subtitle sink!");
 }
 
 void eServiceMP3::pushSubtitles()
 {
        ePangoSubtitlePage page;
-       GstClockTime base_time;
        pts_t running_pts;
-       GstElement *syncsink;
-       g_object_get (G_OBJECT (m_gst_playbin), "audio-sink", &syncsink, NULL);
-       GstClock *clock;
-       clock = gst_element_get_clock (syncsink);
        while ( !m_subtitle_pages.empty() )
        {
+               getPlayPosition(running_pts);
                page = m_subtitle_pages.front();
-
-               base_time = gst_element_get_base_time (syncsink);
-               running_pts = gst_clock_get_time (clock) / 11111L;
                gint64 diff_ms = ( page.show_pts - running_pts ) / 90;
-//             eDebug("eServiceMP3::pushSubtitles show_pts = %lld  running_pts = %lld  diff = %lld", page.show_pts, running_pts, diff_ms);
-               if ( diff_ms > 20 )
+               eDebug("eServiceMP3::pushSubtitles show_pts = %lld  running_pts = %lld  diff = %lld", page.show_pts, running_pts, diff_ms);
+               if (diff_ms < -100)
                {
-//                     eDebug("m_subtitle_sync_timer->start(%lld,1)", diff_ms);
-                       m_subtitle_sync_timer->start(diff_ms, 1);
+                       GstFormat fmt = GST_FORMAT_TIME;
+                       gint64 now;
+                       if (gst_element_query_position(m_gst_playbin, &fmt, &now) != -1)
+                       {
+                               now /= 11111;
+                               diff_ms = abs((now - running_pts) / 90);
+                               eDebug("diff < -100ms check decoder/pipeline diff: decoder: %lld, pipeline: %lld, diff: %lld", running_pts, now, diff_ms);
+                               if (diff_ms > 100000)
+                               {
+                                       eDebug("high decoder/pipeline difference.. assume decoder has now started yet.. check again in 1sec");
+                                       m_subtitle_sync_timer->start(1000, true);
+                                       break;
+                               }
+                       }
+                       else
+                               eDebug("query position for decoder/pipeline check failed!");
+                       eDebug("subtitle to late... drop");
+                       m_subtitle_pages.pop_front();
+               }
+               else if ( diff_ms > 20 )
+               {
+//                     eDebug("start recheck timer");
+                       m_subtitle_sync_timer->start(diff_ms > 1000 ? 1000 : diff_ms, true);
                        break;
                }
-               else
+               else // immediate show
                {
-                       m_subtitle_widget->setPage(page);
+                       if (m_subtitle_widget)
+                               m_subtitle_widget->setPage(page);
                        m_subtitle_pages.pop_front();
                }
        }
-       gst_object_unref (clock);
-       gst_object_unref (syncsink);
+       if (m_subtitle_pages.empty())
+               pullSubtitle();
 }
 
 RESULT eServiceMP3::enableSubtitles(eWidget *parent, ePyObject tuple)
@@ -1386,16 +1460,23 @@ RESULT eServiceMP3::enableSubtitles(eWidget *parent, ePyObject tuple)
                goto error_out;
        type = PyInt_AsLong(entry);
 
-       g_object_set (G_OBJECT (m_gst_playbin), "current-text", pid, NULL);
-       m_currentSubtitleStream = pid;
+       if (m_currentSubtitleStream != pid)
+       {
+               g_object_set (G_OBJECT (m_gst_playbin), "current-text", pid, NULL);
+               m_currentSubtitleStream = pid;
+               eSingleLocker l(m_subs_to_pull_lock);
+               m_subs_to_pull = 0;
+               m_subtitle_pages.clear();
+       }
 
+       m_subtitle_widget = 0;
        m_subtitle_widget = new eSubtitleWidget(parent);
        m_subtitle_widget->resize(parent->size()); /* full size */
 
        g_object_get (G_OBJECT (m_gst_playbin), "current-text", &text_pid, NULL);
 
        eDebug ("eServiceMP3::switched to subtitle stream %i", text_pid);
-       m_subtitle_pages.clear();
+
 
        return 0;
 
index ee06064..29c1d43 100644 (file)
@@ -201,6 +201,9 @@ private:
        std::list<ePangoSubtitlePage> m_subtitle_pages;
        ePtr<eTimer> m_subtitle_sync_timer;
        void pushSubtitles();
+       void pullSubtitle();
+       int m_subs_to_pull;
+       eSingleLock m_subs_to_pull_lock;
 
        gint m_aspect, m_width, m_height, m_framerate, m_progressive;
        RESULT trickSeek(gdouble ratio);