By Anders Holst:
authorFelix Domke <felix.domke@multimedia-labs.de>
Thu, 29 Oct 2009 00:47:49 +0000 (01:47 +0100)
committerFelix Domke <felix.domke@multimedia-labs.de>
Thu, 29 Oct 2009 00:56:31 +0000 (01:56 +0100)
* My previous code for "slow rewind" (aka "SeekBackHack") is not
  required any more. Indeed, since the change in "decoder states"
  some time ago my code stopped working and is now only destructively
  interfering with the new winding approach, effectively ruining the
  speed accuracy for slow rewind. Similarly, the "non-smooth winding"
  code ruins the accuracy for high winding speeds. The patch below
  removes the "SeekBackHack", and temporarily disables the
  "non-smooth winding" code until we know whether the decoder states
  will allow simultaneous repeat and skip rates
  again. (InfoBarGenerics.py)

* Due to a bug in 'eDVBTSTools::findNextPicture', rewind was always
  at the required speed minus one. (The frame just played was counted
  as one when skipping backwards.) Fixed below. (tstools.cpp)

* A piece of code to apparently increase precision in seeking, by
  always aligning to an i-frame start, had exactly the opposite
  effect: GOP single-stepping fails completely on DM7025 and gets
  highly unreliable on DM800. The piece of code is removed.
  (It destructively interferes with previous code by me to hit frames
  somewhat before the GOP start. As an alternative, my previous code
  can be removed instead, and the currently removed piece of code
  adjusted to work. But then it has to be done differently on the two
  platforms.) (dvb.cpp)

* By some reason eDVBVideo::getPTS only returns even numbers on DM800
  even when it should be odd. This ruins GOP single stepping in 50%
  of the cases. This is easy to compensate for by adding a margin of
  1 in getAccessPoint. (pvrparse.cpp)

* After the above, when GOP single-stepping works reliable on both
  platforms and on SD/HD, the correct step lengths can be
  used. (InfoBarGenerics.py)

lib/dvb/dvb.cpp
lib/dvb/pvrparse.cpp
lib/dvb/tstools.cpp
lib/python/Screens/InfoBarGenerics.py

index 894287e84f18845b6e06d39a467033a1d62688fa..a8dfb193e9f30a9a2a989e62f0efe5ab274a3cad 100644 (file)
@@ -1462,12 +1462,7 @@ void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off
                        continue;
                }
                
-               size_t iframe_len;
-                       /* try to align to iframe */
-               int direction = pts < 0 ? -1 : 1;
-               m_tstools.findFrame(offset, iframe_len, direction);
-
-               eDebug("ok, resolved skip (rel: %d, diff %lld), now at %08llx (skipped additional %d frames due to iframe re-align)", relative, pts, offset, direction);
+               eDebug("ok, resolved skip (rel: %d, diff %lld), now at %08llx", relative, pts, offset);
                current_offset = align(offset, blocksize); /* in case tstools return non-aligned offset */
        }
 
index 1393bf77847a6ec384bba54b0bf31cd4fc8cd25a..5cdecbd610095ec2172b811454f0b71ec1013ed6 100644 (file)
@@ -244,6 +244,7 @@ off_t eMPEGStreamInformation::getAccessPoint(pts_t ts, int marg)
        off_t last = 0;
        off_t last2 = 0;
        pts_t lastc = 0;
+       ts += 1; // Add rounding error margin
        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);
index a9eef4067e703bdd3db650f6e16fd8fb078226c5..2e5c5665d9e7a01bb15508078dbc2c5264e55ca6 100644 (file)
@@ -652,18 +652,23 @@ int eDVBTSTools::findFrame(off_t &_offset, size_t &len, int &direction, int fram
 
 int eDVBTSTools::findNextPicture(off_t &offset, size_t &len, int &distance, int frame_types)
 {
-       int nr_frames = 0;
+       int nr_frames, direction;
 //     eDebug("trying to move %d frames at %llx", distance, offset);
        
        frame_types = frametypeI; /* TODO: intelligent "allow IP frames when not crossing an I-Frame */
 
-       int direction = distance > 0 ? 0 : -1;
-       distance = abs(distance);
-       
        off_t new_offset = offset;
        size_t new_len = len;
        int first = 1;
 
+       if (distance > 0) {
+               direction = 0;
+                nr_frames = 0;
+        } else {
+               direction = -1;
+                nr_frames = -1;
+               distance = -distance+1;
+        }      
        while (distance > 0)
        {
                int dir = direction;
@@ -677,12 +682,18 @@ int eDVBTSTools::findNextPicture(off_t &offset, size_t &len, int &distance, int
                
 //             eDebug("we moved %d, %d to go frames (now at %llx)", dir, distance, new_offset);
 
-               if (distance >= 0 || first)
+               if (distance >= 0 || direction == 0)
                {
                        first = 0;
                        offset = new_offset;
                        len = new_len;
                        nr_frames += abs(dir);
+               } 
+               else if (first) {
+                       first = 0;
+                       offset = new_offset;
+                       len = new_len;
+                       nr_frames += abs(dir) + distance; // never jump forward during rewind
                }
        }
 
index 2f8306164ccbe42ed2b8dfca6675372eb77e71bc..5336f9a0192d87d3569de886a086780fd7442475 100644 (file)
@@ -692,8 +692,6 @@ class InfoBarSeek:
                                iPlayableService.evSOF: self.__evSOF,
                        })
 
-               self.minSpeedBackward = useSeekBackHack and 16 or 0
-
                class InfoBarSeekActionMap(HelpableActionMap):
                        def __init__(self, screen, *args, **kwargs):
                                HelpableActionMap.__init__(self, screen, *args, **kwargs)
@@ -740,24 +738,19 @@ class InfoBarSeek:
                self.__seekableStatusChanged()
 
        def makeStateForward(self, n):
-               minspeed = config.seek.stepwise_minspeed.value
-               repeat = int(config.seek.stepwise_repeat.value)
-               if minspeed != "Never" and n >= int(minspeed) and repeat > 1:
-                       return (0, n * repeat, repeat, ">> %dx" % n)
-               else:
+#              minspeed = config.seek.stepwise_minspeed.value
+#              repeat = int(config.seek.stepwise_repeat.value)
+#              if minspeed != "Never" and n >= int(minspeed) and repeat > 1:
+#                      return (0, n * repeat, repeat, ">> %dx" % n)
+#              else:
                        return (0, n, 0, ">> %dx" % n)
 
        def makeStateBackward(self, n):
-               minspeed = config.seek.stepwise_minspeed.value
-               repeat = int(config.seek.stepwise_repeat.value)
-               if self.minSpeedBackward and n < self.minSpeedBackward:
-                       r = (self.minSpeedBackward - 1)/ n + 1
-                       if minspeed != "Never" and n >= int(minspeed) and repeat > 1:
-                               r = max(r, repeat)
-                       return (0, -n * r, r, "<< %dx" % n)
-               elif minspeed != "Never" and n >= int(minspeed) and repeat > 1:
-                       return (0, -n * repeat, repeat, "<< %dx" % n)
-               else:
+#              minspeed = config.seek.stepwise_minspeed.value
+#              repeat = int(config.seek.stepwise_repeat.value)
+#              if minspeed != "Never" and n >= int(minspeed) and repeat > 1:
+#                      return (0, -n * repeat, repeat, "<< %dx" % n)
+#              else:
                        return (0, -n, 0, "<< %dx" % n)
 
        def makeStateSlowMotion(self, n):
@@ -877,7 +870,7 @@ class InfoBarSeek:
                        if config.seek.on_pause.value == "play":
                                self.unPauseService()
                        elif config.seek.on_pause.value == "step":
-                               self.doSeekRelative(0)
+                               self.doSeekRelative(1)
                        elif config.seek.on_pause.value == "last":
                                self.setSeekState(self.lastseekstate)
                                self.lastseekstate = self.SEEK_STATE_PLAY
@@ -950,7 +943,7 @@ class InfoBarSeek:
                        self.setSeekState(self.makeStateBackward(int(config.seek.enter_backward.value)))
                        self.doSeekRelative(-6)
                elif seekstate == self.SEEK_STATE_PAUSE:
-                       self.doSeekRelative(-3)
+                       self.doSeekRelative(-1)
                elif self.isStateForward(seekstate):
                        speed = seekstate[1]
                        if seekstate[2]: