Merge branch 'bug_245_record_playback_fixes'
authorghost <andreas.monzner@multimedia-labs.de>
Tue, 22 Dec 2009 15:02:20 +0000 (16:02 +0100)
committerghost <andreas.monzner@multimedia-labs.de>
Tue, 22 Dec 2009 15:02:20 +0000 (16:02 +0100)
1  2 
lib/dvb/tstools.cpp
lib/python/Screens/InfoBarGenerics.py

diff --combined lib/dvb/tstools.cpp
@@@ -134,7 -134,7 +134,7 @@@ int eDVBTSTools::getPTS(off_t &offset, 
                                        pts |= ((unsigned long long)(packet[ 9]&0xFF)) << 1;
                                        pts |= ((unsigned long long)(packet[10]&0x80)) >> 7;
                                        offset -= 188;
 -                                      eDebug("PCR  found at %llx: %16llx", offset, pts);
 +                                      eDebug("PCR %16llx found at %lld pid %02x (%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x)", pts, offset, pid, packet[0], packet[1], packet[2], packet[3], packet[4], packet[5], packet[6], packet[7], packet[8], packet[9], packet[10]);
                                        if (fixed && fixupPTS(offset, pts))
                                                return -1;
                                        return 0;
                        pts |= ((unsigned long long)(payload[13]&0xFE)) >> 1;
                        offset -= 188;
  
 -//                    eDebug("found pts %08llx at %08llx pid %02x stream: %02x", pts, offset, pid, payload[3]);
 -                      
 +                      eDebug("PTS %16llx found at %lld pid %02x stream: %02x", pts, offset, pid, payload[3]);
 +
                                /* convert to zero-based */
                        if (fixed && fixupPTS(offset, pts))
 -                                      return -1;
 +                              return -1;
                        return 0;
                }
        }
@@@ -212,13 -212,10 +212,13 @@@ int eDVBTSTools::fixupPTS(const off_t &
                        now -= pos;
                return 0;
        }
 +      eDebug("eDVBTSTools::fixupPTS failed!");
 +      return -1;
  }
  
  int eDVBTSTools::getOffset(off_t &offset, pts_t &pts, int marg)
  {
 +      eDebug("getOffset for pts 0x%llx", pts);
        if (m_use_streaminfo)
        {
                if (pts >= m_pts_end && marg > 0 && m_end_valid)
@@@ -443,8 -440,6 +443,8 @@@ void eDVBTSTools::takeSamples(
        m_samples_taken = 1;
        m_samples.clear();
        pts_t dummy;
 +      int retries=2;
 +
        if (calcLen(dummy) == -1)
                return;
        
                bytes_per_sample = 40*1024*1024;
  
        bytes_per_sample -= bytes_per_sample % 188;
 -      
 -      for (off_t offset = m_offset_begin; offset < m_offset_end; offset += bytes_per_sample)
 +
 +      eDebug("samples step %lld, pts begin %llx, pts end %llx, offs begin %lld, offs end %lld:",
 +              bytes_per_sample, m_pts_begin, m_pts_end, m_offset_begin, m_offset_end);
 +
 +      for (off_t offset = m_offset_begin; offset < m_offset_end;)
        {
                pts_t p;
 -              takeSample(offset, p);
 +              if (takeSample(offset, p) && retries--)
 +                      continue;
 +              retries = 2;
 +              offset += bytes_per_sample;
        }
        m_samples[0] = m_offset_begin;
        m_samples[m_pts_end - m_pts_begin] = m_offset_end;
 -      
 -//    eDebug("begin, end: %llx %llx", m_offset_begin, m_offset_end); 
  }
  
        /* returns 0 when a sample was taken. */
  int eDVBTSTools::takeSample(off_t off, pts_t &p)
  {
 +      off_t offset_org = off;
 +
        if (!eDVBTSTools::getPTS(off, p, 1))
        {
                        /* as we are happily mixing PTS and PCR values (no comment, please), we might
                        {
                                if ((l->second > off) || (u->second < off))
                                {
 -                                      eDebug("ignoring sample %llx %llx %llx (%lld %lld %lld)",
 +                                      eDebug("ignoring sample %lld %lld %lld (%llx %llx %llx)",
                                                l->second, off, u->second, l->first, p, u->first);
                                        return 1;
                                }
                        }
                }
  
 -              
 +              eDebug("adding sample %lld: pts 0x%llx -> pos %lld (diff %lld bytes)", offset_org, p, off, off-offset_org);
                m_samples[p] = off;
                return 0;
        }
 -      return 1;
 +      return -1;
  }
  
  int eDVBTSTools::findPMT(int &pmt_pid, int &service_id)
@@@ -663,18 -652,23 +663,23 @@@ int eDVBTSTools::findFrame(off_t &_offs
  
  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;
                
  //            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
                }
        }
  
@@@ -691,8 -691,6 +691,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)
                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):
                        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
                        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]:
@@@ -1212,10 -1205,7 +1205,7 @@@ class InfoBarTimeshift
                        self.setSeekState(self.SEEK_STATE_PAUSE)
  
                if back:
-                       self.doSeek(-5) # seek some gops before end
                        self.ts_rewind_timer.start(200, 1)
-               else:
-                       self.doSeek(-1) # seek 1 gop before end
  
        def rewindService(self):
                self.setSeekState(self.makeStateBackward(int(config.seek.enter_backward.value)))
@@@ -1669,46 -1659,17 +1659,46 @@@ class InfoBarAudioSelection
                                else:
                                        break
  
 +                      availableKeys = []
 +                      usedKeys = []
 +
                        if SystemInfo["CanDownmixAC3"]:
 -                              tlist = [(_("AC3 downmix") + " - " +(_("Off"), _("On"))[config.av.downmix_ac3.value and 1 or 0], "CALLFUNC", self.changeAC3Downmix),
 -                                      ((_("Left"), _("Stereo"), _("Right"))[self.audioChannel.getCurrentChannel()], "mode"),
 -                                      ("--", "")] + tlist
 -                              keys = [ "red", "green", "", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0"] + [""]*n
 -                              selection += 3
 -                      else:
 -                              tlist = [((_("Left"), _("Stereo"), _("Right"))[self.audioChannel.getCurrentChannel()], "mode"), ("--", "")] + tlist
 -                              keys = [ "red", "", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0"] + [""]*n
 +                              flist = [(_("AC3 downmix") + " - " +(_("Off"), _("On"))[config.av.downmix_ac3.value and 1 or 0], "CALLFUNC", self.changeAC3Downmix),
 +                                      ((_("Left"), _("Stereo"), _("Right"))[self.audioChannel.getCurrentChannel()], "mode")]
 +                              usedKeys.extend(["red", "green"])
 +                              availableKeys.extend(["yellow", "blue"])
                                selection += 2
 -                      self.session.openWithCallback(self.audioSelected, ChoiceBox, title=_("Select audio track"), list = tlist, selection = selection, keys = keys, skin_name = "AudioTrackSelection")
 +                      else:
 +                              flist = [((_("Left"), _("Stereo"), _("Right"))[self.audioChannel.getCurrentChannel()], "mode")]
 +                              usedKeys.extend(["red"])
 +                              availableKeys.extend(["green", "yellow", "blue"])
 +                              selection += 1
 +
 +                      if hasattr(self, "runPlugin"):
 +                              class PluginCaller:
 +                                      def __init__(self, fnc, *args):
 +                                              self.fnc = fnc
 +                                              self.args = args
 +                                      def __call__(self, *args, **kwargs):
 +                                              self.fnc(*self.args)
 +
 +                              Plugins = [ (p.name, PluginCaller(self.runPlugin, p)) for p in plugins.getPlugins(where = PluginDescriptor.WHERE_AUDIOMENU) ]
 +
 +                              for p in Plugins:
 +                                      selection += 1
 +                                      flist.append((p[0], "CALLFUNC", p[1]))
 +                                      if availableKeys:
 +                                              usedKeys.append(availableKeys[0])
 +                                              del availableKeys[0]
 +                                      else:
 +                                              usedKeys.append("")
 +
 +                      flist.append(("--", ""))
 +                      usedKeys.append("")
 +                      selection += 1
 +
 +                      keys = usedKeys + [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "0" ] + [""] * n
 +                      self.session.openWithCallback(self.audioSelected, ChoiceBox, title=_("Select audio track"), list = flist + tlist, selection = selection, keys = keys, skin_name = "AudioTrackSelection")
                else:
                        del self.audioTracks