Merge branch 'bug_570_playback_skip_fixes_and_cleanup_ml_aholst' into experimental
authorghost <andreas.monzner@multimedia-labs.de>
Wed, 24 Nov 2010 23:12:59 +0000 (00:12 +0100)
committerghost <andreas.monzner@multimedia-labs.de>
Wed, 24 Nov 2010 23:12:59 +0000 (00:12 +0100)
1  2 
data/setup.xml
lib/dvb/tstools.cpp
lib/python/Components/UsageConfig.py
lib/python/Plugins/Extensions/DVDPlayer/plugin.py
lib/python/Screens/InfoBarGenerics.py

diff --combined data/setup.xml
index f5dea73,fa8ff3f..c5eb07f
mode 100755,100644..100755
                        <item level="1" text="Change bouquets in quickzap">config.usage.quickzap_bouquet_change</item>
                        <item level="1" text="Alternative radio mode">config.usage.e1like_radio_mode</item>
                        <item level="1" text="Action on long powerbutton press">config.usage.on_long_powerpress</item>
 +                      <item level="1" text="Action on short powerbutton press">config.usage.on_short_powerpress</item>
                        <item level="0" text="Infobar timeout">config.usage.infobar_timeout</item>
                        <item level="1" text="12V output" requires="12V_Output">config.usage.output_12V</item>
 +                      <item level="0" text="Show event-progress in channel selection">config.usage.show_event_progress_in_servicelist</item>
                        <item level="2" text="Show infobar on channel change">config.usage.show_infobar_on_zap</item>
                        <item level="2" text="Show infobar on skip forward/backward">config.usage.show_infobar_on_skip</item>
                        <item level="2" text="Show infobar on event change">config.usage.show_infobar_on_event_change</item>
                        <item level="2" text="Fast Forward speeds">config.seek.speeds_forward</item>
                        <item level="2" text="Rewind speeds">config.seek.speeds_backward</item>
                        <item level="2" text="Slow Motion speeds">config.seek.speeds_slowmotion</item>
- <!-- TRANSLATORS: Note that "Enter" in the two strings below should *not*
-      be interpreted as "Give speed as input". The intended meaning is
-      instead "Initial speed when starting winding", i.e. the speed at
-      which "winding mode" is entered when first pressing "rewind" or
-      "fast forward". -->  
-                       <item level="2" text="Enter Fast Forward at speed">config.seek.enter_forward</item>
-                       <item level="2" text="Enter Rewind at speed">config.seek.enter_backward</item>
- <!-- TRANSLATORS: The effect of "Non-smooth winding" is that rather
-      than using ordinary "continuous" or "smooth" winding, a fast
-      sequence of stills is shown when winding at high speeds. This
-      makes it much easier too follow when almost each frame comes from
-      a new scene. The effect is achieved by repeating each shown frame
-      a couple of times. The settings control both at which speed this
-      winding mode sets in, and how many times each frame should be
-      repeated. This was previously called "Discontinuous playback"
-      which was incomprehensible. "Non-smooth winding" may be a better
-      term, but note that there is nothing irregular about it. Synonyms
-      better suited for translation to other languages may be "stepwise
-      winding/playback", or "winding/playback using stills". -->
-                       <item level="2" text="Use non-smooth winding at speeds above">config.seek.stepwise_minspeed</item>
-                       <item level="2" text="Frame repeat count during non-smooth winding">config.seek.stepwise_repeat</item>
+ <!-- TRANSLATORS: The following is the speed you get on the first press on fast-forward.
+      It was previously called "enter fast forward at speed" which was easily misunderstood. -->  
+                       <item level="2" text="Initial Fast Forward speed">config.seek.enter_forward</item>
+                       <item level="2" text="Initial Rewind speed">config.seek.enter_backward</item>
                        <item level="2" text="Behavior of 'pause' when paused">config.seek.on_pause</item>
                        <item level="2" text="Behavior of 0 key in PiP-mode">config.usage.pip_zero_button</item>
                        <item level="2" text="Alternative services tuner priority">config.usage.alternatives_priority</item>
                        <item level="2" text="Limited character set for recording filenames">config.recording.ascii_filenames</item>
 +                      <item level="2" text="Composition of the recording filenames">config.recording.filename_composition</item>
                </setup>
                <setup key="harddisk" title="Harddisk setup" >
                        <item level="0" text="Harddisk standby after">config.usage.hdd_standby</item>
diff --combined lib/dvb/tstools.cpp
@@@ -7,6 -7,7 +7,6 @@@
  #include <stdio.h>
  
  eDVBTSTools::eDVBTSTools()
 -      :m_file_lock(true)
  {
        m_pid = -1;
        m_maxrange = 256*1024;
        m_futile = 0;
  }
  
 +void eDVBTSTools::closeSource()
 +{
 +      m_source = NULL;
 +}
 +
  eDVBTSTools::~eDVBTSTools()
  {
 -      closeFile();
 +      closeSource();
  }
  
  int eDVBTSTools::openFile(const char *filename, int nostreaminfo)
  {
 +      eRawFile *f = new eRawFile();
 +      ePtr<iTsSource> src = f;
 +
 +      if (f->open(filename, 1) < 0)
 +              return -1;
 +
 +      setSource(src, filename);
 +
 +      return 0;
 +}
 +
 +void eDVBTSTools::setSource(ePtr<iTsSource> &source, const char *stream_info_filename)
 +{
        closeFile();
 -      
 -      if (!nostreaminfo)
 +
 +      m_source = source;
 +
 +      if (stream_info_filename)
        {
 -              eDebug("loading streaminfo for %s", filename);
 -              m_streaminfo.load(filename);
 +              eDebug("loading streaminfo for %s", stream_info_filename);
 +              m_streaminfo.load(stream_info_filename);
        }
        
        if (!m_streaminfo.empty())
  //            eDebug("no recorded stream information available");
                m_use_streaminfo = 0;
        }
 -      
 -      m_samples_taken = 0;
  
 -      eSingleLocker l(m_file_lock);
 -      if (m_file.open(filename, 1) < 0)
 -              return -1;
 -      return 0;
 +      m_samples_taken = 0;
  }
  
  void eDVBTSTools::closeFile()
  {
 -      eSingleLocker l(m_file_lock);
 -      m_file.close();
 +      if (m_source)
 +              closeSource();
  }
  
  void eDVBTSTools::setSyncPID(int pid)
@@@ -91,24 -77,31 +91,24 @@@ int eDVBTSTools::getPTS(off_t &offset, 
                if (!m_streaminfo.getPTS(offset, pts))
                        return 0;
        
 -      if (!m_file.valid())
 +      if (!m_source || !m_source->valid())
                return -1;
  
        offset -= offset % 188;
  
 -      eSingleLocker l(m_file_lock);
 -      if (m_file.lseek(offset, SEEK_SET) < 0)
 -      {
 -              eDebug("lseek failed");
 -              return -1;
 -      }
 -      
        int left = m_maxrange;
        
        while (left >= 188)
        {
                unsigned char packet[188];
 -              if (m_file.read(packet, 188) != 188)
 +              if (m_source->read(offset, packet, 188) != 188)
                {
                        eDebug("read error");
                        break;
                }
                left -= 188;
                offset += 188;
 -              
 +
                if (packet[0] != 0x47)
                {
                        eDebug("resync");
                                if (packet[i] == 0x47)
                                        break;
                                ++i;
 +                              --offset;
                        }
 -                      offset = m_file.lseek(i - 188, SEEK_CUR);
                        continue;
                }
                
@@@ -411,7 -404,7 +411,7 @@@ int eDVBTSTools::getNextAccessPoint(pts
  
  void eDVBTSTools::calcBegin()
  {
 -      if (!m_file.valid())
 +      if (!m_source || !m_source->valid())
                return;
  
        if (!(m_begin_valid || m_futile))
  
  void eDVBTSTools::calcEnd()
  {
 -      if (!m_file.valid())
 +      if (!m_source || !m_source->valid())
                return;
  
 -      eSingleLocker l(m_file_lock);
 -      off_t end = m_file.lseek(0, SEEK_END);
 +      off_t end = m_source->lseek(0, SEEK_END);
        
        if (llabs(end - m_last_filelength) > 1*1024*1024)
        {
@@@ -579,28 -573,31 +579,28 @@@ int eDVBTSTools::takeSample(off_t off, 
  int eDVBTSTools::findPMT(int &pmt_pid, int &service_id)
  {
                /* FIXME: this will be factored out soon! */
 -      if (!m_file.valid())
 +      if (!m_source || !m_source->valid())
        {
                eDebug(" file not valid");
                return -1;
        }
  
 -      eSingleLocker l(m_file_lock);
 -      if (m_file.lseek(0, SEEK_SET) < 0)
 -      {
 -              eDebug("seek failed");
 -              return -1;
 -      }
 +      off_t position=0;
  
        int left = 5*1024*1024;
        
        while (left >= 188)
        {
                unsigned char packet[188];
 -              if (m_file.read(packet, 188) != 188)
 +              int ret = m_source->read(position, packet, 188);
 +              if (ret != 188)
                {
                        eDebug("read error");
                        break;
                }
                left -= 188;
 -              
 +              position += 188;
 +
                if (packet[0] != 0x47)
                {
                        int i = 0;
                        {
                                if (packet[i] == 0x47)
                                        break;
 +                              --position;
                                ++i;
                        }
 -                      m_file.lseek(i - 188, SEEK_CUR);
                        continue;
                }
 -              
                int pid = ((packet[1] << 8) | packet[2]) & 0x1FFF;
                
                int pusi = !!(packet[1] & 0x40);
@@@ -700,9 -698,23 +700,23 @@@ int eDVBTSTools::findFrame(off_t &_offs
                else if (direction == +1)
                        direction = 0;
        }
-                       /* let's find the next frame after the given offset */
        off_t start = offset;
  
+                       /* backtrack to find the previous sequence start, in case of MPEG2 */
+       if ((data & 0xFF) == 0x00) {
+               do {
+                       --start;
+                       if (m_streaminfo.getStructureEntry(start, data, 0))
+                       {
+                               eDebug("get previous failed");
+                               return -1;
+                       }
+               } while (((data & 0xFF) != 9) && ((data & 0xFF) != 0x00) && ((data & 0xFF) != 0xB3)); /* sequence start or previous frame */
+               if ((data & 0xFF) != 0xB3)
+                       start = offset;  /* Failed to find corresponding sequence start, so never mind */
+       }
+                       /* let's find the next frame after the given offset */
        do {
                if (m_streaminfo.getStructureEntry(offset, data, 1))
                {
        } while (((data & 0xFF) != 9) && ((data & 0xFF) != 0x00)); /* next frame */
  
                        /* align to TS pkt start */
//    start = start - (start % 188);
//    offset = offset - (offset % 188);
      start = start - (start % 188);
      offset = offset - (offset % 188);
  
        len = offset - start;
        _offset = start;
@@@ -1,7 -1,7 +1,7 @@@
  from Components.Harddisk import harddiskmanager
  from config import ConfigSubsection, ConfigYesNo, config, ConfigSelection, ConfigText, ConfigNumber, ConfigSet, ConfigLocations
  from Tools.Directories import resolveFilename, SCOPE_HDD
 -from enigma import Misc_Options, setTunerTypePriorityOrder;
 +from enigma import Misc_Options, setTunerTypePriorityOrder, eEnv;
  from SystemInfo import SystemInfo
  import os
  
@@@ -51,14 -51,7 +51,14 @@@ def InitUsageConfig()
  
        config.usage.on_long_powerpress = ConfigSelection(default = "show_menu", choices = [
                ("show_menu", _("show shutdown menu")),
 -              ("shutdown", _("immediate shutdown")) ] )
 +              ("shutdown", _("immediate shutdown")),
 +              ("standby", _("Standby")) ] )
 +      
 +      config.usage.on_short_powerpress = ConfigSelection(default = "standby", choices = [
 +              ("show_menu", _("show shutdown menu")),
 +              ("shutdown", _("immediate shutdown")),
 +              ("standby", _("Standby")) ] )
 +
  
        config.usage.alternatives_priority = ConfigSelection(default = "0", choices = [
                ("0", "DVB-S/-C/-T"),
@@@ -68,8 -61,6 +68,8 @@@
                ("4", "DVB-T/-C/-S"),
                ("5", "DVB-T/-S/-C") ])
  
 +      config.usage.show_event_progress_in_servicelist = ConfigYesNo(default = False)
 +
        config.usage.blinking_display_clock_during_recording = ConfigYesNo(default = False)
  
        config.usage.show_message_when_recording_starts = ConfigYesNo(default = True)
@@@ -94,7 -85,7 +94,7 @@@
  
        SystemInfo["12V_Output"] = Misc_Options.getInstance().detected_12V_output()
  
 -      config.usage.keymap = ConfigText(default = "/usr/share/enigma2/keymap.xml")
 +      config.usage.keymap = ConfigText(default = eEnv.resolve("${datadir}/enigma2/keymap.xml"))
  
        config.seek = ConfigSubsection()
        config.seek.selfdefined_13 = ConfigNumber(default=15)
        config.seek.selfdefined_79 = ConfigNumber(default=300)
  
        config.seek.speeds_forward = ConfigSet(default=[2, 4, 8, 16, 32, 64, 128], choices=[2, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128])
-       config.seek.speeds_backward = ConfigSet(default=[8, 16, 32, 64, 128], choices=[1, 2, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128])
+       config.seek.speeds_backward = ConfigSet(default=[2, 4, 8, 16, 32, 64, 128], choices=[1, 2, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128])
        config.seek.speeds_slowmotion = ConfigSet(default=[2, 4, 8], choices=[2, 4, 6, 8, 12, 16, 25])
  
        config.seek.enter_forward = ConfigSelection(default = "2", choices = ["2", "4", "6", "8", "12", "16", "24", "32", "48", "64", "96", "128"])
        config.seek.enter_backward = ConfigSelection(default = "1", choices = ["1", "2", "4", "6", "8", "12", "16", "24", "32", "48", "64", "96", "128"])
-       config.seek.stepwise_minspeed = ConfigSelection(default = "16", choices = ["Never", "2", "4", "6", "8", "12", "16", "24", "32", "48", "64", "96", "128"])
-       config.seek.stepwise_repeat = ConfigSelection(default = "3", choices = ["2", "3", "4", "5", "6"])
  
        config.seek.on_pause = ConfigSelection(default = "play", choices = [
                ("play", _("Play")),
@@@ -88,8 -88,8 +88,8 @@@ class FileBrowser(Screen)
                self.close(None)
  
  class DVDSummary(Screen):
 -      skin = """
 -      <screen position="0,0" size="132,64">
 +      skin = (
 +      """<screen name="DVDSummary" position="0,0" size="132,64" id="1">
                <widget source="session.CurrentService" render="Label" position="5,4" size="120,28" font="Regular;12" transparent="1" >
                        <convert type="ServiceName">Name</convert>
                </widget>
                <widget source="session.CurrentService" render="Progress" position="6,46" size="60,18" borderWidth="1" >
                        <convert type="ServicePosition">Position</convert>
                </widget>
 -      </screen>"""
 +      </screen>""",
 +      """<screen name="DVDSummary" position="0,0" size="96,64" id="2">
 +              <widget source="session.CurrentService" render="Label" position="0,0" size="96,25" font="Regular;12" transparent="1" >
 +                      <convert type="ServiceName">Name</convert>
 +              </widget>
 +              <widget name="DVDPlayer" position="0,26" size="96,12" font="Regular;10" transparent="1" />
 +              <widget name="Chapter" position="0,40" size="66,12" font="Regular;10" transparent="1" halign="left" />
 +              <widget source="session.CurrentService" render="Label" position="66,40" size="30,12" font="Regular;10" transparent="1" halign="right" >
 +                      <convert type="ServicePosition">Position</convert>
 +              </widget>
 +              <widget source="session.CurrentService" render="Progress" position="0,52" size="96,12" borderWidth="1" >
 +                      <convert type="ServicePosition">Position</convert>
 +              </widget>
 +      </screen>""")
  
        def __init__(self, session, parent):
                Screen.__init__(self, session, parent)
@@@ -235,8 -222,6 +235,6 @@@ class DVDPlayer(Screen, InfoBarBase, In
                self.saved_config_speeds_backward = config.seek.speeds_backward.value
                self.saved_config_enter_forward = config.seek.enter_forward.value
                self.saved_config_enter_backward = config.seek.enter_backward.value
-               self.saved_config_seek_stepwise_minspeed = config.seek.stepwise_minspeed.value
-               self.saved_config_seek_stepwise_repeat = config.seek.stepwise_repeat.value
                self.saved_config_seek_on_pause = config.seek.on_pause.value
                self.saved_config_seek_speeds_slowmotion = config.seek.speeds_slowmotion.value
  
                config.seek.speeds_slowmotion.value = [ ]
                config.seek.enter_forward.value = "2"
                config.seek.enter_backward.value = "2"
-               config.seek.stepwise_minspeed.value = "Never"
-               config.seek.stepwise_repeat.value = "3"
                config.seek.on_pause.value = "play"
  
        def restore_infobar_seek_config(self):
                config.seek.speeds_slowmotion.value = self.saved_config_seek_speeds_slowmotion
                config.seek.enter_forward.value = self.saved_config_enter_forward
                config.seek.enter_backward.value = self.saved_config_enter_backward
-               config.seek.stepwise_minspeed.value = self.saved_config_seek_stepwise_minspeed
-               config.seek.stepwise_repeat.value = self.saved_config_seek_stepwise_repeat
                config.seek.on_pause.value = self.saved_config_seek_on_pause
  
        def __init__(self, session, dvd_device = None, dvd_filelist = [ ], args = None):
                HelpableScreen.__init__(self)
                self.save_infobar_seek_config()
                self.change_infobar_seek_config()
-               InfoBarSeek.__init__(self, useSeekBackHack=False)
+               InfoBarSeek.__init__(self)
                InfoBarPVRState.__init__(self)
                self.dvdScreen = self.session.instantiateDialog(DVDOverlay)
  
@@@ -598,7 -598,6 +598,7 @@@ class InfoBarEPG
  
                if list:
                        list.append((_("show single service EPG..."), self.openSingleServiceEPG))
 +                      list.append((_("Multi EPG"), self.openMultiServiceEPG))
                        self.session.openWithCallback(self.EventInfoPluginChosen, ChoiceBox, title=_("Please choose an extension..."), list = list, skin_name = "EPGExtensionsList")
                else:
                        self.openSingleServiceEPG()
@@@ -717,7 -716,7 +717,7 @@@ class InfoBarSeek
        SEEK_STATE_PAUSE = (1, 0, 0, "||")
        SEEK_STATE_EOF = (1, 0, 0, "END")
  
-       def __init__(self, actionmap = "InfobarSeekActions", useSeekBackHack=True):
+       def __init__(self, actionmap = "InfobarSeekActions"):
                self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
                        {
                                iPlayableService.evSeekableStatusChanged: self.__seekableStatusChanged,
                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:
-                       return (0, n, 0, ">> %dx" % n)
+               return (0, n, 0, ">> %dx" % n)
  
        def makeStateBackward(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:
-                       return (0, -n, 0, "<< %dx" % n)
+               return (0, -n, 0, "<< %dx" % n)
  
        def makeStateSlowMotion(self, n):
                return (0, 0, n, "/%d" % n)
@@@ -1673,11 -1662,126 +1663,11 @@@ class InfoBarAudioSelection
                        })
  
        def audioSelection(self):
 -              service = self.session.nav.getCurrentService()
 -              self.audioTracks = audio = service and service.audioTracks()
 -              n = audio and audio.getNumberOfTracks() or 0
 -              tlist = []
 -              if n > 0:
 -                      self.audioChannel = service.audioChannel()
 -
 -                      idx = 0
 -                      while idx < n:
 -                              cnt = 0
 -                              i = audio.getTrackInfo(idx)
 -                              languages = i.getLanguage().split('/')
 -                              description = i.getDescription()
 -                              language = ""
 -
 -                              for lang in languages:
 -                                      if cnt:
 -                                              language += ' / '
 -                                      if LanguageCodes.has_key(lang):
 -                                              language += LanguageCodes[lang][0]
 -                                      else:
 -                                              language += lang
 -                                      cnt += 1
 -
 -                              if len(description):
 -                                      description += " (" + language + ")"
 -                              else:
 -                                      description = language
 -
 -                              tlist.append((description, idx))
 -                              idx += 1
 -
 -                      tlist.sort(key=lambda x: x[0])
 -
 -                      selectedAudio = self.audioTracks.getCurrentTrack()
 -
 -                      selection = 0
 -
 -                      for x in tlist:
 -                              if x[1] != selectedAudio:
 -                                      selection += 1
 -                              else:
 -                                      break
 -
 -                      availableKeys = []
 -                      usedKeys = []
 -
 -                      if SystemInfo["CanDownmixAC3"]:
 -                              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
 -                      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
 -
 -      def changeAC3Downmix(self, arg):
 -              choicelist = self.session.current_dialog["list"]
 -              list = choicelist.list
 -              t = list[0][1]
 -              list[0][1]=(t[0], t[1], t[2], t[3], t[4], t[5], t[6],
 -                      _("AC3 downmix") + " - " + (_("On"), _("Off"))[config.av.downmix_ac3.value and 1 or 0])
 -              choicelist.setList(list)
 -              if config.av.downmix_ac3.value:
 -                      config.av.downmix_ac3.value = False
 -              else:
 -                      config.av.downmix_ac3.value = True
 -              config.av.downmix_ac3.save()
 -
 -      def audioSelected(self, audio):
 -              if audio is not None:
 -                      if isinstance(audio[1], str):
 -                              if audio[1] == "mode":
 -                                      keys = ["red", "green", "yellow"]
 -                                      selection = self.audioChannel.getCurrentChannel()
 -                                      tlist = ((_("left"), 0), (_("stereo"), 1), (_("right"), 2))
 -                                      self.session.openWithCallback(self.modeSelected, ChoiceBox, title=_("Select audio mode"), list = tlist, selection = selection, keys = keys, skin_name ="AudioModeSelection")
 -                      else:
 -                              del self.audioChannel
 -                              if self.session.nav.getCurrentService().audioTracks().getNumberOfTracks() > audio[1]:
 -                                      self.audioTracks.selectTrack(audio[1])
 -              else:
 -                      del self.audioChannel
 -              del self.audioTracks
 -
 -      def modeSelected(self, mode):
 -              if mode is not None:
 -                      self.audioChannel.selectChannel(mode[1])
 -              del self.audioChannel
 +              from Screens.AudioSelection import AudioSelection
 +              self.session.openWithCallback(self.audioSelected, AudioSelection, infobar=self)
 +              
 +      def audioSelected(self, ret=None):
 +              print "[infobar::audioSelected]", ret
  
  class InfoBarSubserviceSelection:
        def __init__(self):
@@@ -1970,20 -2074,21 +1960,21 @@@ class InfoBarCueSheetSupport
                return True
  
        def jumpPreviousMark(self):
-               # we add 2 seconds, so if the play position is <2s after
+               # we add 5 seconds, so if the play position is <5s after
                # the mark, the mark before will be used
                self.jumpPreviousNextMark(lambda x: -x-5*90000, start=True)
  
        def jumpNextMark(self):
-               if not self.jumpPreviousNextMark(lambda x: x):
+               if not self.jumpPreviousNextMark(lambda x: x-90000):
                        self.doSeek(-1)
  
        def getNearestCutPoint(self, pts, cmp=abs, start=False):
                # can be optimized
-               beforecut = False
+               beforecut = True
                nearest = None
+               bestdiff = -1
+               instate = True
                if start:
-                       beforecut = True
                        bestdiff = cmp(0 - pts)
                        if bestdiff >= 0:
                                nearest = [0, False]
                                beforecut = False
                                if cp[1] == self.CUT_TYPE_IN:  # Start is here, disregard previous marks
                                        diff = cmp(cp[0] - pts)
-                                       if diff >= 0:
+                                       if start and diff >= 0:
                                                nearest = cp
                                                bestdiff = diff
                                        else:
                                                nearest = None
-                       if cp[1] in (self.CUT_TYPE_MARK, self.CUT_TYPE_LAST):
+                                               bestdiff = -1
+                       if cp[1] == self.CUT_TYPE_IN:
+                               instate = True
+                       elif cp[1] == self.CUT_TYPE_OUT:
+                               instate = False
+                       elif cp[1] in (self.CUT_TYPE_MARK, self.CUT_TYPE_LAST):
                                diff = cmp(cp[0] - pts)
-                               if diff >= 0 and (nearest is None or bestdiff > diff):
+                               if instate and diff >= 0 and (nearest is None or bestdiff > diff):
                                        nearest = cp
                                        bestdiff = diff
                return nearest