Merge branch 'master' of /home/tmbinc/enigma2-git into tmbinc/FixTimingBugs
authorFelix Domke <tmbinc@elitedvb.net>
Thu, 12 Feb 2009 15:49:17 +0000 (16:49 +0100)
committerFelix Domke <tmbinc@elitedvb.net>
Thu, 12 Feb 2009 15:49:17 +0000 (16:49 +0100)
15 files changed:
lib/base/filepush.cpp
lib/dvb/decoder.cpp
lib/dvb/decoder.h
lib/dvb/dvb.cpp
lib/dvb/idvb.h
lib/dvb/pvrparse.cpp
lib/dvb/pvrparse.h
lib/dvb/tstools.cpp
lib/dvb/tstools.h
lib/python/Components/Network.py
lib/python/Components/Renderer/FrontpanelLed.py
lib/python/Screens/InfoBarGenerics.py
lib/service/iservice.h
lib/service/servicedvb.cpp
lib/service/servicedvb.h

index 1999707..e99e956 100644 (file)
@@ -260,12 +260,9 @@ void eFilePushThread::stop()
        // fixmee.. here we need a better solution to ensure
        // that the thread context take notice of the signal
        // even when no syscall is in progress
-       while(!sendSignal(SIGUSR1))
-       {
-               eDebug("send SIGUSR1 to thread context");
-               usleep(5000); // wait msek
-       }
-       kill();
+       eDebug("if enigma hangs here, the filepush thread is non-responsive. FIX THAT DAMN THREAD.");
+       sendSignal(SIGUSR1);
+       kill(0);
 }
 
 void eFilePushThread::pause()
index 065a49c..f73dbdd 100644 (file)
@@ -39,7 +39,7 @@
 DEFINE_REF(eDVBAudio);
 
 eDVBAudio::eDVBAudio(eDVBDemux *demux, int dev)
-       :m_demux(demux), m_dev(dev), m_is_freezed(0)
+       :m_demux(demux), m_dev(dev)
 {
        char filename[128];
 #if HAVE_DVB_API_VERSION < 3
@@ -198,7 +198,7 @@ int eDVBAudio::startPid(int pid, int type)
                break;
        }
 
-       eDebugNoNewLine("AUDIO_SET_BYPASS - ");
+       eDebugNoNewLine("AUDIO_SET_BYPASS(%d) - ", bypass);
        if (::ioctl(m_fd, AUDIO_SET_BYPASS_MODE, bypass) < 0)
                eDebug("failed (%m)");
        else
@@ -244,28 +244,20 @@ void eDVBAudio::flush()
 
 void eDVBAudio::freeze()
 {
-       if (!m_is_freezed)
-       {
-               eDebugNoNewLine("AUDIO_PAUSE - ");
-               if (::ioctl(m_fd, AUDIO_PAUSE) < 0)
-                       eDebug("failed (%m)");
-               else
-                       eDebug("ok");
-               m_is_freezed=1;
-       }
+       eDebugNoNewLine("AUDIO_PAUSE - ");
+       if (::ioctl(m_fd, AUDIO_PAUSE) < 0)
+               eDebug("failed (%m)");
+       else
+               eDebug("ok");
 }
 
 void eDVBAudio::unfreeze()
 {
-       if (m_is_freezed)
-       {
-               eDebugNoNewLine("AUDIO_CONTINUE - ");
-               if (::ioctl(m_fd, AUDIO_CONTINUE) < 0)
-                       eDebug("failed (%m)");
-               else
-                       eDebug("ok");
-               m_is_freezed=0;
-       }
+       eDebugNoNewLine("AUDIO_CONTINUE - ");
+       if (::ioctl(m_fd, AUDIO_CONTINUE) < 0)
+               eDebug("failed (%m)");
+       else
+               eDebug("ok");
 }
 
 void eDVBAudio::setChannel(int channel)
@@ -303,8 +295,9 @@ eDVBAudio::~eDVBAudio()
 DEFINE_REF(eDVBVideo);
 
 eDVBVideo::eDVBVideo(eDVBDemux *demux, int dev)
-       :m_demux(demux), m_dev(dev), m_is_slow_motion(0), m_is_fast_forward(0), m_is_freezed(0)
-       ,m_width(-1), m_height(-1), m_framerate(-1), m_aspect(-1), m_progressive(-1)
+<<<<<<< HEAD:lib/dvb/decoder.cpp
+       : m_demux(demux), m_dev(dev),
+       m_width(-1), m_height(-1), m_framerate(-1), m_aspect(-1), m_progressive(-1)
 {
        char filename[128];
 #if HAVE_DVB_API_VERSION < 3
@@ -493,34 +486,25 @@ void eDVBVideo::flush()
 
 void eDVBVideo::freeze()
 {
-       if (!m_is_freezed)
-       {
-               eDebugNoNewLine("VIDEO_FREEZE - ");
-               if (::ioctl(m_fd, VIDEO_FREEZE) < 0)
-                       eDebug("failed (%m)");
-               else
-                       eDebug("ok");
-               m_is_freezed=1;
-       }
+       eDebugNoNewLine("VIDEO_FREEZE - ");
+       if (::ioctl(m_fd, VIDEO_FREEZE) < 0)
+               eDebug("failed (%m)");
+       else
+               eDebug("ok");
 }
 
 void eDVBVideo::unfreeze()
 {
-       if (m_is_freezed)
-       {
-               eDebugNoNewLine("VIDEO_CONTINUE - ");
-               if (::ioctl(m_fd, VIDEO_CONTINUE) < 0)
-                       eDebug("failed (%m)");
-               else
-                       eDebug("ok");
-               m_is_freezed=0;
-       }
+       eDebugNoNewLine("VIDEO_CONTINUE - ");
+       if (::ioctl(m_fd, VIDEO_CONTINUE) < 0)
+               eDebug("failed (%m)");
+       else
+               eDebug("ok");
 }
 
 int eDVBVideo::setSlowMotion(int repeat)
 {
-       eDebugNoNewLine("VIDEO_SLOWMOTION - ");
-       m_is_slow_motion = repeat;
+       eDebugNoNewLine("VIDEO_SLOWMOTION(%d) - ", repeat);
        int ret = ::ioctl(m_fd, VIDEO_SLOWMOTION, repeat);
        if (ret < 0)
                eDebug("failed(%m)");
@@ -531,8 +515,7 @@ int eDVBVideo::setSlowMotion(int repeat)
 
 int eDVBVideo::setFastForward(int skip)
 {
-       eDebugNoNewLine("VIDEO_FAST_FORWARD - ");
-       m_is_fast_forward = skip;
+       eDebugNoNewLine("VIDEO_FAST_FORWARD(%d) - ", skip);
        int ret = ::ioctl(m_fd, VIDEO_FAST_FORWARD, skip);
        if (ret < 0)
                eDebug("failed(%m)");
@@ -559,11 +542,6 @@ int eDVBVideo::getPTS(pts_t &now)
 
 eDVBVideo::~eDVBVideo()
 {
-       if (m_is_slow_motion)
-               setSlowMotion(0);
-       if (m_is_fast_forward)
-               setFastForward(0);
-       unfreeze();
        if (m_fd >= 0)
                ::close(m_fd);
        if (m_fd_demux >= 0)
@@ -869,14 +847,14 @@ int eTSMPEGDecoder::setState()
 {
        int res = 0;
 
-       int noaudio = m_is_sm || m_is_ff || m_is_trickmode;
+       int noaudio = (m_state != statePlay) && (m_state != statePause);
        int nott = noaudio; /* actually same conditions */
 
        if ((noaudio && m_audio) || (!m_audio && !noaudio))
-               m_changed |= changeAudio;
+               m_changed |= changeAudio | changeState;
 
        if ((nott && m_text) || (!m_text && !nott))
-               m_changed |= changeText;
+               m_changed |= changeText | changeState;
 
        bool changed = !!m_changed;
 #if HAVE_DVB_API_VERSION < 3
@@ -1019,6 +997,39 @@ int eTSMPEGDecoder::setState()
                m_changed &= ~changeText;
        }
 #endif
+
+       if (m_changed & changeState)
+       {
+                                       /* play, slowmotion, fast-forward */
+               int state_table[6][4] = 
+                       {
+                               /* [stateStop] =                 */ {0, 0, 0},
+                               /* [statePause] =                */ {0, 0, 0},
+                               /* [statePlay] =                 */ {1, 0, 0},
+                               /* [stateDecoderFastForward] =   */ {1, 0, m_ff_sm_ratio},
+                               /* [stateHighspeedFastForward] = */ {1, 0, 1},
+                               /* [stateSlowMotion] =           */ {1, m_ff_sm_ratio, 0}
+                       };
+               int *s = state_table[m_state];
+               if (m_video)
+               {
+                       m_video->setSlowMotion(s[1]);
+                       m_video->setFastForward(s[2]);
+                       if (s[0])
+                               m_video->unfreeze();
+                       else
+                               m_video->freeze();
+               }
+               if (m_audio)
+               {
+                       if (s[0])
+                               m_audio->unfreeze();
+                       else
+                               m_audio->freeze();
+               }
+               m_changed &= ~changeState;
+       }
+
        if (changed && !m_video && m_audio && m_radio_pic.length())
                showSinglePic(m_radio_pic.c_str());
 
@@ -1065,7 +1076,7 @@ eTSMPEGDecoder::eTSMPEGDecoder(eDVBDemux *demux, int decoder)
 {
        demux->connectEvent(slot(*this, &eTSMPEGDecoder::demux_event), m_demux_event_conn);
        CONNECT(m_showSinglePicTimer->timeout, eTSMPEGDecoder::finishShowSinglePic);
-       m_is_ff = m_is_sm = m_is_trickmode = 0;
+       m_state = stateStop;
 }
 
 eTSMPEGDecoder::~eTSMPEGDecoder()
@@ -1147,82 +1158,61 @@ RESULT eTSMPEGDecoder::setSyncMaster(int who)
        return -1;
 }
 
-RESULT eTSMPEGDecoder::start()
-{
-       RESULT r;
-       r = setState();
-       if (r)
-               return r;
-       return unfreeze();
-}
-
-       /* preroll is start in freezed mode. */
-RESULT eTSMPEGDecoder::preroll()
+RESULT eTSMPEGDecoder::set()
 {
        return setState();
 }
 
-RESULT eTSMPEGDecoder::freeze(int cont)
-{
-       if (m_video)
-               m_video->freeze();
-
-       if (m_audio)
-               m_audio->freeze();
-
-       return 0;
-}
-
-RESULT eTSMPEGDecoder::unfreeze()
+RESULT eTSMPEGDecoder::play()
 {
-       if (m_video)
-               m_video->unfreeze();
-
-       if (m_audio)
-               m_audio->unfreeze();
-
-       return 0;
-}
-
-RESULT eTSMPEGDecoder::setSinglePictureMode(int when)
-{
-       return -1;
+       if (m_state == statePlay)
+               return 0;
+       m_state = statePlay;
+       m_changed |= changeState;
+       return setState();
 }
 
-RESULT eTSMPEGDecoder::setPictureSkipMode(int what)
+RESULT eTSMPEGDecoder::pause()
 {
-       return -1;
+       if (m_state == statePause)
+               return 0;
+       m_state = statePause;
+       m_changed |= changeState;
+       return setState();
 }
 
 RESULT eTSMPEGDecoder::setFastForward(int frames_to_skip)
 {
-       m_is_ff = frames_to_skip != 0;
+       if ((m_state == stateDecoderFastForward) && (m_ff_sm_ratio == frames_to_skip))
+               return 0;
 
-       setState();
-       unfreeze(); // audio might be restarted and still in preroll (freezed) state.
+       m_state = stateDecoderFastForward;
+       m_ff_sm_ratio = frames_to_skip;
+       m_changed |= changeState;
+       return setState();
 
-       if (m_video)
-               return m_video->setFastForward(frames_to_skip);
-       else
-               return -1;
+//             return m_video->setFastForward(frames_to_skip);
 }
 
 RESULT eTSMPEGDecoder::setSlowMotion(int repeat)
 {
-       m_is_sm = repeat != 0;
-
-       setState();
-       unfreeze(); // audio might be restarted and still in preroll (freezed) state.
+       if ((m_state == stateSlowMotion) && (m_ff_sm_ratio == repeat))
+               return 0;
 
-       if (m_video)
-               return m_video->setSlowMotion(repeat);
-       else
-               return -1;
+       m_state = stateSlowMotion;
+       m_ff_sm_ratio = repeat;
+       m_changed |= changeState;
+       return setState();
 }
 
-RESULT eTSMPEGDecoder::setZoom(int what)
+RESULT eTSMPEGDecoder::setTrickmode()
 {
-       return -1;
+       if (m_state == stateTrickmode)
+               return 0;
+
+       m_state = stateTrickmode;
+       m_changed |= changeState;
+       return setState();
 }
 
 RESULT eTSMPEGDecoder::flush()
@@ -1246,13 +1236,6 @@ void eTSMPEGDecoder::demux_event(int event)
        }
 }
 
-RESULT eTSMPEGDecoder::setTrickmode(int what)
-{
-       m_is_trickmode = what;
-       setState();
-       return 0;
-}
-
 RESULT eTSMPEGDecoder::getPTS(int what, pts_t &pts)
 {
        if (what == 0) /* auto */
index f2e10bb..51be514 100644 (file)
@@ -125,10 +125,12 @@ private:
                changeVideo = 1, 
                changeAudio = 2, 
                changePCR   = 4,
-               changeText  = 8
+               changeText  = 8,
+               changeState = 16,
        };
        int m_changed, m_decoder;
-       int m_is_ff, m_is_sm, m_is_trickmode;
+       int m_state;
+       int m_ff_sm_ratio;
        int setState();
        ePtr<eConnection> m_demux_event_conn;
        ePtr<eConnection> m_video_event_conn;
@@ -154,17 +156,33 @@ public:
        RESULT setSyncPCR(int pcrpid);
        RESULT setTextPID(int textpid);
        RESULT setSyncMaster(int who);
-       RESULT start();
-       RESULT preroll();
-       RESULT freeze(int cont);
-       RESULT unfreeze();
-       RESULT setSinglePictureMode(int when);
-       RESULT setPictureSkipMode(int what);
-       RESULT setFastForward(int frames_to_skip);
-       RESULT setSlowMotion(int repeat);
-       RESULT setZoom(int what);
+       
+               /*
+               The following states exist:
+               
+                - stop: data source closed, no playback
+                - pause: data source active, decoder paused
+                - play: data source active, decoder consuming
+                - decoder fast forward: data source linear, decoder drops frames
+                - trickmode, highspeed reverse: data source fast forwards / reverses, decoder just displays frames as fast as it can
+                - slow motion: decoder displays frames multiple times
+               */
+       enum {
+               stateStop,
+               statePause,
+               statePlay,
+               stateDecoderFastForward,
+               stateTrickmode,
+               stateSlowMotion
+       };
+       RESULT set(); /* just apply settings, keep state */
+       RESULT play(); /* -> play */
+       RESULT pause(); /* -> pause */
+       RESULT setFastForward(int frames_to_skip); /* -> decoder fast forward */
+       RESULT setSlowMotion(int repeat); /* -> slow motion **/
+       RESULT setTrickmode(); /* -> highspeed fast forward */
+
        RESULT flush();
-       RESULT setTrickmode(int what);
        RESULT showSinglePic(const char *filename);
        RESULT setRadioPic(const std::string &filename);
                /* what 0=auto, 1=video, 2=audio. */
index 2460943..c320fc7 100644 (file)
@@ -974,7 +974,7 @@ int eDVBChannelFilePush::filterRecordData(const unsigned char *_data, int len, s
        }
 #endif
 
-#if 1 /* not yet */
+#if 1 /* This codepath is required on Broadcom-based Dreamboxes (DM800, DM8000) and strips away non-I-frames. */
        if (!m_iframe_search)
                return len;
 
@@ -990,9 +990,9 @@ int eDVBChannelFilePush::filterRecordData(const unsigned char *_data, int len, s
                unsigned char *ts = data + ts_offset;
                int pid = ((ts[1] << 8) | ts[2]) & 0x1FFF;
 
-               if ((d[3] == 0) && (m_pid == pid))  /* picture start */
+               if ((d[3] == 0 || d[3] == 0x09 && d[-1] == 0 && (ts[1] & 0x40)) && (m_pid == pid))  /* picture start */
                {
-                       int picture_type = (d[5] >> 3) & 7;
+                       int picture_type = (d[3]==0 ? (d[5] >> 3) & 7 : (d[4] >> 5) + 1);
                        d += 4;
 
 //                     eDebug("%d-frame at %d, offset in TS packet: %d, pid=%04x", picture_type, offset, offset % 188, pid);
@@ -1036,16 +1036,25 @@ int eDVBChannelFilePush::filterRecordData(const unsigned char *_data, int len, s
                        }
                } else if ((d[3] & 0xF0) == 0xE0) /* video stream */
                {
-                       if (m_pid != pid)
+                               /* verify that this is actually a PES header, not just some ES data */
+                       if (ts[1] & 0x40) /* PUSI set */
                        {
-                               eDebug("now locked to pid %04x", pid);
-                               m_pid = pid;
+                               int payload_start = 4;
+                               if (ts[3] & 0x20) /* adaptation field present */
+                                       payload_start += ts[4] + 1; /* skip AF */
+                               if (payload_start == (offset%188)) /* the 00 00 01 should be directly at the payload start, otherwise it's not a PES header */
+                               {
+                                       if (m_pid != pid)
+                                       {
+                                               eDebug("now locked to pid %04x (%02x %02x %02x %02x)", pid, ts[0], ts[1], ts[2], ts[3]);
+                                               m_pid = pid;
+                                       }
+                               }
                        }
 //                     m_pid = 0x6e;
                        d += 4;
                } else
                        d += 4; /* ignore */
-
        }
 
        if (m_iframe_state == 1)
@@ -1200,7 +1209,7 @@ void eDVBChannel::cueSheetEvent(int event)
                {
                        off_t offset_in, offset_out;
                        pts_t pts_in = i->first, pts_out = i->second;
-                       if (m_tstools.getOffset(offset_in, pts_in) || m_tstools.getOffset(offset_out, pts_out))
+                       if (m_tstools.getOffset(offset_in, pts_in, -1) || m_tstools.getOffset(offset_out, pts_out, 1))
                        {
                                eDebug("span translation failed.\n");
                                continue;
@@ -1328,13 +1337,13 @@ void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off
                                eDebug("AP relative seeking failed!");
                        } else
                        {
-                               eDebug("next ap is %llx\n", pts);
                                pts = nextap;
+                               eDebug("next ap is %llx\n", pts);
                        }
                }
 
                off_t offset = 0;
-               if (m_tstools.getOffset(offset, pts))
+               if (m_tstools.getOffset(offset, pts, -1))
                {
                        eDebug("get offset for pts=%lld failed!", pts);
                        continue;
@@ -1408,16 +1417,29 @@ void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off
                }
        }
 
-       if ((current_offset < -m_skipmode_m) && (m_skipmode_m < 0))
-       {
-               eDebug("reached SOF");
-               m_skipmode_m = 0;
-               m_pvr_thread->sendEvent(eFilePushThread::evtUser);
+       if (m_source_span.empty()) {
+               if ((current_offset < -m_skipmode_m) && (m_skipmode_m < 0))
+               {
+                       eDebug("reached SOF");
+                       m_skipmode_m = 0;
+                       m_pvr_thread->sendEvent(eFilePushThread::evtUser);
+               }
+               start = current_offset;
+               size = max;
+       } else {
+               off_t tmp2, tmp = align(m_source_span.rbegin()->second, blocksize);
+               pts_t len;
+               getLength(len);
+               m_tstools.getOffset(tmp2, len, 1);
+               if (current_offset == tmp || current_offset == tmp2) {
+                       start = tmp2;
+                       size = max;
+               } else {
+                       start = tmp - align(512*1024, blocksize);
+                       size = align(512*1024, blocksize);
+               }
        }
 
-       start = current_offset;
-       size = max;
-
        eDebug("END OF CUESHEET. (%08llx, %d)", start, size);
        return;
 }
index ec016d6..cfa98ec 100644 (file)
@@ -664,37 +664,24 @@ public:
                /** Set Sync mode to either audio or video master */
        virtual RESULT setSyncMaster(int who)=0;
 
-               /** Apply settings with starting video */
-       virtual RESULT start()=0;
-               /** Apply settings but don't start yet */
-       virtual RESULT preroll()=0;
+               /** Apply settings but don't change state */
+       virtual RESULT set()=0;
+               /* all those apply settings, then transition to the given state */
 
-               /** Freeze frame. Either continue decoding (without display) or halt. */
-       virtual RESULT freeze(int cont)=0;
-               /** Continue after freeze. */
-       virtual RESULT unfreeze()=0;
+               /** play */
+       virtual RESULT play()=0;
+               /** Freeze frame. */
+       virtual RESULT pause()=0;
 
                /** fast forward by skipping frames. 0 is disabled, 2 is twice-the-speed, ... */
        virtual RESULT setFastForward(int skip=0)=0;
 
-               // stop on .. Picture
-       enum { spm_I, spm_Ref, spm_Any };
-               /** Stop on specific decoded picture. For I-Frame display. */
-       virtual RESULT setSinglePictureMode(int when)=0;
-
-       enum { pkm_B, pkm_PB };
-               /** Fast forward by skipping either B or P/B pictures */
-       virtual RESULT setPictureSkipMode(int what)=0;
-
                /** Slow Motion by repeating pictures */
        virtual RESULT setSlowMotion(int repeat)=0;
-       
-       enum { zoom_Normal, zoom_PanScan, zoom_Letterbox, zoom_Fullscreen };
-               /** Set Zoom. mode *must* be fitting. */
-       virtual RESULT setZoom(int what)=0;
-
-       virtual RESULT setTrickmode(int what) = 0;
 
+               /** Display any complete data as fast as possible */
+       virtual RESULT setTrickmode()=0;
+       
        virtual RESULT getPTS(int what, pts_t &pts) = 0;
 
        virtual RESULT showSinglePic(const char *filename) = 0;
index 5931366..71cbd60 100644 (file)
@@ -36,8 +36,6 @@ int eMPEGStreamInformation::load(const char *filename)
                return -1;
        m_access_points.clear();
        m_pts_to_offset.clear();
-       pts_t last = -(1LL<<62);
-       int loaded = 0, skipped = 0;
        while (1)
        {
                unsigned long long d[2];
@@ -48,16 +46,9 @@ int eMPEGStreamInformation::load(const char *filename)
                d[0] = bswap_64(d[0]);
                d[1] = bswap_64(d[1]);
 #endif
-               if ((d[1] - last) > 90000/2)
-               {
-                       m_access_points[d[0]] = d[1];
-                       m_pts_to_offset.insert(std::pair<pts_t,off_t>(d[1], d[0]));
-                       last = d[1];
-                       loaded++;
-               } else
-                       skipped++;
+               m_access_points[d[0]] = d[1];
+               m_pts_to_offset.insert(std::pair<pts_t,off_t>(d[1], d[0]));
        }
-       eDebug("loaded %d, skipped %d", loaded, skipped);
        fclose(f);
        fixupDiscontinuties();
        return 0;
@@ -216,30 +207,45 @@ pts_t eMPEGStreamInformation::getInterpolated(off_t offset)
        return before_ts + diff;
 }
  
-off_t eMPEGStreamInformation::getAccessPoint(pts_t ts)
+off_t eMPEGStreamInformation::getAccessPoint(pts_t ts, int marg)
 {
                /* FIXME: more efficient implementation */
        off_t last = 0;
+       off_t last2 = 0;
+       pts_t lastc = 0;
        for (std::map<off_t, pts_t>::const_iterator i(m_access_points.begin()); i != m_access_points.end(); ++i)
        {
                pts_t delta = getDelta(i->first);
                pts_t c = i->second - delta;
-               if (c > ts)
-                       break;
+               if (c > ts) {
+                       if (marg > 0)
+                               return (last + i->first)/376*188;
+                       else if (marg < 0)
+                               return (last + last2)/376*188;
+                       else
+                               return last;
+               }
+               lastc = c;
+               last2 = last;
                last = i->first;
        }
-       return last;
+       if (marg < 0)
+               return (last + last2)/376*188;
+       else
+               return last;
 }
 
 int eMPEGStreamInformation::getNextAccessPoint(pts_t &ts, const pts_t &start, int direction)
 {
        off_t offset = getAccessPoint(start);
+       pts_t c1, c2;
        std::map<off_t, pts_t>::const_iterator i = m_access_points.find(offset);
        if (i == m_access_points.end())
        {
                eDebug("getNextAccessPoint: initial AP not found");
                return -1;
        }
+       c1 = i->second - getDelta(i->first);
        while (direction)
        {
                if (direction > 0)
@@ -247,6 +253,12 @@ int eMPEGStreamInformation::getNextAccessPoint(pts_t &ts, const pts_t &start, in
                        if (i == m_access_points.end())
                                return -1;
                        ++i;
+                       c2 = i->second - getDelta(i->first);
+                       if (c1 == c2) { // Discontinuity
+                               ++i;
+                               c2 = i->second - getDelta(i->first);
+                       }
+                       c1 = c2;
                        direction--;
                }
                if (direction < 0)
@@ -257,6 +269,12 @@ int eMPEGStreamInformation::getNextAccessPoint(pts_t &ts, const pts_t &start, in
                                return -1;
                        }
                        --i;
+                       c2 = i->second - getDelta(i->first);
+                       if (c1 == c2) { // Discontinuity
+                               --i;
+                               c2 = i->second - getDelta(i->first);
+                       }
+                       c1 = c2;
                        direction++;
                }
        }
@@ -355,7 +373,8 @@ int eMPEGStreamParserTS::processPacket(const unsigned char *pkt, off_t offset)
                                /*eDebug("Sequence header but no valid PTS value.")*/;
                }
 
-               if (pkt[3] == 0x09) /* MPEG4 AVC unit access delimiter */
+               if (pkt[3] == 0x09 &&   /* MPEG4 AVC unit access delimiter */
+                        (pkt[4] >> 5) == 0) /* and I-frame */
                {
                        if (ptsvalid)
                        {
index 94f9f67..20d3347 100644 (file)
@@ -41,7 +41,7 @@ public:
                /* inter/extrapolate timestamp from offset */
        pts_t getInterpolated(off_t offset);
        
-       off_t getAccessPoint(pts_t ts);
+       off_t getAccessPoint(pts_t ts, int marg=0);
        
        int getNextAccessPoint(pts_t &ts, const pts_t &start, int direction);
        
index 5157ef2..bd7ebce 100644 (file)
@@ -209,11 +209,14 @@ int eDVBTSTools::fixupPTS(const off_t &offset, pts_t &now)
        }
 }
 
-int eDVBTSTools::getOffset(off_t &offset, pts_t &pts)
+int eDVBTSTools::getOffset(off_t &offset, pts_t &pts, int marg)
 {
        if (m_use_streaminfo)
        {
-               offset = m_streaminfo.getAccessPoint(pts);
+               if (pts >= m_pts_end && marg > 0 && m_end_valid)
+                       offset = m_offset_end;
+               else
+                       offset = m_streaminfo.getAccessPoint(pts, marg);
                return 0;
        } else
        {
index 1316825..4bc0472 100644 (file)
@@ -40,7 +40,7 @@ public:
        int fixupPTS(const off_t &offset, pts_t &pts);
        
                /* get (approximate) offset corresponding to PTS */
-       int getOffset(off_t &offset, pts_t &pts);
+       int getOffset(off_t &offset, pts_t &pts, int marg=0);
        
        int getNextAccessPoint(pts_t &ts, const pts_t &start, int direction);
        
index f32a648..64b3aa6 100755 (executable)
@@ -203,7 +203,7 @@ class Network:
                                        ifaces[currif]["gateway"] = map(int, split[1].split('.'))
                                        if self.ifaces[currif].has_key("gateway"):
                                                if self.ifaces[currif]["gateway"] != ifaces[currif]["gateway"] and ifaces[currif]["dhcp"] == False:
-                                                       self.ifaces[currif]["gateway"] = map(int, split[1].split('.'))                                  
+                                                       self.ifaces[currif]["gateway"] = map(int, split[1].split('.'))
                                if (split[0] == "pre-up"):
                                        if self.ifaces[currif].has_key("preup"):
                                                self.ifaces[currif]["preup"] = i
index 7bb584e..cd329b5 100644 (file)
@@ -6,15 +6,24 @@ class FrontpanelLed(Element):
                Element.__init__(self)
 
        def changed(self, *args, **kwargs):
-               if self.source.value:
+               if self.source.value or 1:
                        pattern = 0x55555555
+                       pattern_4bit = 0x84fc8c04
                        speed = 20
                else:
                        pattern = 0
+                       pattern_4bit = 0xffffffff
                        speed = 1
 
                try:
                        open("/proc/stb/fp/led0_pattern", "w").write("%08x" % pattern)
+               except IOError:
+                       pass
+               try:
+                       open("/proc/stb/fp/led_pattern", "w").write("%08x" % pattern_4bit)
+               except IOError:
+                       pass
+               try:
                        open("/proc/stb/fp/led_pattern_speed", "w").write("%d" % speed)
                except IOError:
                        pass
index 3404e3f..e64081e 100644 (file)
@@ -779,12 +779,21 @@ class InfoBarSeek:
                        print "not pauseable."
                        state = self.SEEK_STATE_PLAY
 
-               oldstate = self.seekstate
                self.seekstate = state
 
-               for i in range(3):
-                       if oldstate[i] != self.seekstate[i]:
-                               (self.session.nav.pause, pauseable.setFastForward, pauseable.setSlowMotion)[i](self.seekstate[i])
+               if pauseable is not None:
+                       if self.seekstate[0]:
+                               print "resolved to PAUSE"
+                               pauseable.pause()
+                       elif self.seekstate[1]:
+                               print "resolved to FAST FORWARD"
+                               pauseable.setFastForward(self.seekstate[1])
+                       elif self.seekstate[2]:
+                               print "resolved to SLOW MOTION"
+                               pauseable.setSlowMotion(self.seekstate[2])
+                       else:
+                               print "resolved to PLAY"
+                               pauseable.unpause()
 
                for c in self.onPlayStateChanged:
                        c(self.seekstate)
index 02fc450..e27752a 100644 (file)
@@ -392,6 +392,8 @@ class iPauseableService: public iObject
        ~iPausableService();
 #endif
 public:
+
+               /* this will set the *state* directly. So just call a SINGLE function of those at a time. */
        virtual RESULT pause()=0;
        virtual RESULT unpause()=0;
 
index d4a3a56..33cd865 100644 (file)
@@ -1124,6 +1124,9 @@ RESULT eDVBServicePlay::pause(ePtr<iPauseableService> &ptr)
 
 RESULT eDVBServicePlay::setSlowMotion(int ratio)
 {
+       assert(ratio); /* The API changed: instead of calling setSlowMotion(0), call play! */
+       eDebug("eDVBServicePlay::setSlowMotion(%d)", ratio);
+       setFastForward_internal(0);
        if (m_decoder)
                return m_decoder->setSlowMotion(ratio);
        else
@@ -1132,6 +1135,13 @@ RESULT eDVBServicePlay::setSlowMotion(int ratio)
 
 RESULT eDVBServicePlay::setFastForward(int ratio)
 {
+       eDebug("eDVBServicePlay::setFastForward(%d)", ratio);
+       assert(ratio);
+       return setFastForward_internal(ratio);
+}
+
+RESULT eDVBServicePlay::setFastForward_internal(int ratio)
+{
        int skipmode, ffratio;
        
        if (ratio > 8)
@@ -1164,7 +1174,12 @@ RESULT eDVBServicePlay::setFastForward(int ratio)
        if (!m_decoder)
                return -1;
 
-       return m_decoder->setFastForward(ffratio);
+       if (ffratio == 0)
+               return 0;
+       else if (ffratio != 1)
+               return m_decoder->setFastForward(ffratio);
+       else
+               return m_decoder->setTrickmode();
 }
 
 RESULT eDVBServicePlay::seek(ePtr<iSeekableService> &ptr)
@@ -1192,20 +1207,22 @@ RESULT eDVBServicePlay::getLength(pts_t &len)
 
 RESULT eDVBServicePlay::pause()
 {
-       if (!m_is_paused && m_decoder)
+       eDebug("eDVBServicePlay::pause");
+       setFastForward_internal(0);
+       if (m_decoder)
        {
-               m_is_paused = 1;
-               return m_decoder->freeze(0);
+               return m_decoder->pause();
        } else
                return -1;
 }
 
 RESULT eDVBServicePlay::unpause()
 {
-       if (m_is_paused && m_decoder)
+       eDebug("eDVBServicePlay::unpause");
+       setFastForward_internal(0);
+       if (m_decoder)
        {
-               m_is_paused = 0;
-               return m_decoder->unfreeze();
+               return m_decoder->play();
        } else
                return -1;
 }
@@ -1287,9 +1304,8 @@ RESULT eDVBServicePlay::getPlayPosition(pts_t &pos)
 
 RESULT eDVBServicePlay::setTrickmode(int trick)
 {
-       if (m_decoder)
-               m_decoder->setTrickmode(trick);
-       return 0;
+               /* currently unimplemented */
+       return -1;
 }
 
 RESULT eDVBServicePlay::isCurrentlySeekable()
@@ -1575,7 +1591,7 @@ RESULT eDVBServicePlay::selectTrack(unsigned int i)
 {
        int ret = selectAudioStream(i);
 
-       if (m_decoder->start())
+       if (m_decoder->play())
                return -5;
 
        return ret;
@@ -2291,12 +2307,12 @@ void eDVBServicePlay::updateDecoder()
                m_teletext_parser->start(program.textPid);
 
                if (!m_is_primary)
-                       m_decoder->setTrickmode(1);
+                       m_decoder->setTrickmode();
 
                if (m_is_paused)
-                       m_decoder->preroll();
+                       m_decoder->pause();
                else
-                       m_decoder->start();
+                       m_decoder->play();
 
                if (vpid > 0 && vpid < 0x2000)
                        ;
index 56ec89e..43e4690 100644 (file)
@@ -218,6 +218,7 @@ private:
 
        int m_current_audio_stream;
        int selectAudioStream(int n = -1);
+       RESULT setFastForward_internal(int ratio);
        
                /* timeshift */
        ePtr<iDVBTSRecorder> m_record;