Ticket #8631: seek_honors_cutlist_v11.patch

File seek_honors_cutlist_v11.patch, 27.8 KB (added by Jim Stichnoth <stichnot@…>, 18 months ago)
  • mythtv/libs/libmythtv/bdringbuffer.cpp

    diff --git a/mythtv/libs/libmythtv/bdringbuffer.cpp b/mythtv/libs/libmythtv/bdringbuffer.cpp
    index 8028527..bd7fc9f 100644
    a b bool BDRingBuffer::HandleAction(const QStringList &actions, int64_t pts) 
    199199        PressButton(BD_VK_DOWN, pts); 
    200200    } 
    201201    else if (actions.contains(ACTION_LEFT) || 
     202             actions.contains(ACTION_SEEKRWNDNOCUTLIST) || 
    202203             actions.contains(ACTION_SEEKRWND)) 
    203204    { 
    204205        PressButton(BD_VK_LEFT, pts); 
    205206    } 
    206207    else if (actions.contains(ACTION_RIGHT) || 
     208             actions.contains(ACTION_SEEKFFWDNOCUTLIST) || 
    207209             actions.contains(ACTION_SEEKFFWD)) 
    208210    { 
    209211        PressButton(BD_VK_RIGHT, pts); 
  • mythtv/libs/libmythtv/deletemap.cpp

    diff --git a/mythtv/libs/libmythtv/deletemap.cpp b/mythtv/libs/libmythtv/deletemap.cpp
    index 0a1ac66..955dbe3 100644
    a b void DeleteMap::UpdateSeekAmount(int change, double framerate) 
    127127    } 
    128128} 
    129129 
    130 /** 
     130static QString createTimeString(uint64_t frame, uint64_t total, 
     131                                double frame_rate, bool full_resolution) 
     132{ 
     133    int secs   = (int)(frame / frame_rate); 
     134    int frames = frame - (int)(secs * frame_rate); 
     135    int totalSecs = (int)(total / frame_rate); 
     136    QString timestr; 
     137    if (totalSecs >= 3600) 
     138        timestr = QString::number(secs / 3600) + ":"; 
     139    timestr += QString("%1").arg((secs / 60) % 60, 2, 10, QChar(48)) + 
     140        QString(":%1").arg(secs % 60, 2, 10, QChar(48)); 
     141    if (full_resolution) 
     142        timestr += QString(".%1").arg(frames, 2, 10, QChar(48)); 
     143    return timestr; 
     144} 
     145 
     146 /** 
    131147 * \brief Show and update the edit mode On Screen Display. The cut regions 
    132148 *        are only refreshed if the deleteMap has been updated. 
    133149 */ 
    void DeleteMap::UpdateOSD(uint64_t frame, uint64_t total, double frame_rate, 
    145161    infoMap.detach(); 
    146162    ctx->UnlockPlayingInfo(__FILE__, __LINE__); 
    147163 
    148     int secs   = (int)(frame / frame_rate); 
    149     int frames = frame - (int)(secs * frame_rate); 
    150     QString timestr = QString::number(secs / 3600) + 
    151                       QString(":%1").arg((secs / 60) % 60, 2, 10, QChar(48)) + 
    152                       QString(":%1").arg(secs % 60, 2, 10, QChar(48)) + 
    153                       QString(".%1").arg(frames, 2, 10, QChar(48)); 
    154  
    155164    QString cutmarker = " "; 
    156165    if (IsInDelete(frame)) 
    157166        cutmarker = QObject::tr("cut"); 
    158167 
     168    QString timestr = createTimeString(frame, total, frame_rate, true); 
     169    uint64_t relTotal = TranslatePositionAbsToRel(total); 
     170    QString relTimeDisplay = createTimeString(TranslatePositionAbsToRel(frame), 
     171                                              relTotal, frame_rate, false); 
     172    QString relLengthDisplay = createTimeString(relTotal, 
     173                                                relTotal, frame_rate, false); 
    159174    infoMap["timedisplay"]  = timestr; 
    160175    infoMap["framedisplay"] = QString::number(frame); 
    161176    infoMap["cutindicator"] = cutmarker; 
    162177    infoMap["title"]        = QObject::tr("Edit"); 
    163178    infoMap["seekamount"]   = m_seekText;; 
     179    infoMap["reltimedisplay"] = relTimeDisplay; 
     180    infoMap["rellengthdisplay"] = relLengthDisplay; 
     181    infoMap["fulltimedisplay"] = timestr + " (" + 
     182        QObject::tr("%1 of %2").arg(relTimeDisplay).arg(relLengthDisplay) + ")"; 
    164183 
    165184    QHash<QString,float> posMap; 
    166185    posMap.insert("position", (float)((double)frame/(double)total)); 
    bool DeleteMap::IsSaved(PlayerContext *ctx) 
    819838 
    820839    return currentMap == savedMap; 
    821840} 
     841 
     842uint64_t DeleteMap::TranslatePositionAbsToRel(const frm_dir_map_t &deleteMap, 
     843                                              uint64_t absPosition) 
     844{ 
     845    uint64_t subtraction = 0; 
     846    uint64_t startOfCutRegion = 0; 
     847    frm_dir_map_t::const_iterator i; 
     848    bool withinCut = false; 
     849    bool first = true; 
     850    for (i = deleteMap.constBegin(); 
     851         i != deleteMap.constEnd() && i.key() <= absPosition; 
     852         i++) 
     853    { 
     854        if (first) 
     855            withinCut = (i.value() == MARK_CUT_END); 
     856        first = false; 
     857        if (i.value() == MARK_CUT_START && !withinCut) 
     858        { 
     859            withinCut = true; 
     860            startOfCutRegion = i.key(); 
     861        } 
     862        else if (i.value() == MARK_CUT_END && withinCut) 
     863        { 
     864            withinCut = false; 
     865            subtraction += (i.key() - startOfCutRegion); 
     866        } 
     867    } 
     868    if (withinCut) 
     869        subtraction += (absPosition - startOfCutRegion); 
     870    return absPosition - subtraction; 
     871} 
     872 
     873uint64_t DeleteMap::TranslatePositionRelToAbs(const frm_dir_map_t &deleteMap, 
     874                                              uint64_t relPosition) 
     875{ 
     876    uint64_t addition = 0; 
     877    uint64_t startOfCutRegion = 0; 
     878    frm_dir_map_t::const_iterator i; 
     879    bool withinCut = false; 
     880    bool first = true; 
     881    for (i = deleteMap.constBegin(); i != deleteMap.constEnd(); i++) 
     882    { 
     883        if (first) 
     884            withinCut = (i.value() == MARK_CUT_END); 
     885        first = false; 
     886        if (i.value() == MARK_CUT_START && !withinCut) 
     887        { 
     888            withinCut = true; 
     889            startOfCutRegion = i.key(); 
     890            if (relPosition + addition <= startOfCutRegion) 
     891                break; 
     892        } 
     893        else if (i.value() == MARK_CUT_END && withinCut) 
     894        { 
     895            withinCut = false; 
     896            addition += (i.key() - startOfCutRegion); 
     897        } 
     898    } 
     899    return relPosition + addition; 
     900} 
  • mythtv/libs/libmythtv/deletemap.h

    diff --git a/mythtv/libs/libmythtv/deletemap.h b/mythtv/libs/libmythtv/deletemap.h
    index 2dfa190..ffdb2d0 100644
    a b class DeleteMap 
    5959    bool     IsTemporaryMark(uint64_t frame); 
    6060    bool     HasTemporaryMark(void); 
    6161    uint64_t GetLastFrame(uint64_t total); 
     62    uint64_t TranslatePositionAbsToRel(uint64_t absPosition) { 
     63        return TranslatePositionAbsToRel(m_deleteMap, absPosition); 
     64    } 
     65    uint64_t TranslatePositionRelToAbs(uint64_t relPosition) { 
     66        return TranslatePositionRelToAbs(m_deleteMap, relPosition); 
     67    } 
     68    static uint64_t TranslatePositionAbsToRel(const frm_dir_map_t &deleteMap, 
     69                                              uint64_t absPosition); 
     70    static uint64_t TranslatePositionRelToAbs(const frm_dir_map_t &deleteMap, 
     71                                              uint64_t relPosition); 
    6272 
    6373    void TrackerReset(uint64_t frame, uint64_t total); 
    6474    bool TrackerWantsToJump(uint64_t frame, uint64_t total, uint64_t &to); 
  • mythtv/libs/libmythtv/dvdringbuffer.cpp

    diff --git a/mythtv/libs/libmythtv/dvdringbuffer.cpp b/mythtv/libs/libmythtv/dvdringbuffer.cpp
    index 318f8f8..fd20394 100644
    a b bool DVDRingBuffer::HandleAction(const QStringList &actions, int64_t pts) 
    11431143        MoveButtonDown(); 
    11441144    } 
    11451145    else if (actions.contains(ACTION_LEFT) || 
     1146             actions.contains(ACTION_SEEKRWNDNOCUTLIST) || 
    11461147             actions.contains(ACTION_SEEKRWND)) 
    11471148    { 
    11481149        MoveButtonLeft(); 
    11491150    } 
    11501151    else if (actions.contains(ACTION_RIGHT) || 
     1152             actions.contains(ACTION_SEEKFFWDNOCUTLIST) || 
    11511153             actions.contains(ACTION_SEEKFFWD)) 
    11521154    { 
    11531155        MoveButtonRight(); 
  • mythtv/libs/libmythtv/mythplayer.cpp

    diff --git a/mythtv/libs/libmythtv/mythplayer.cpp b/mythtv/libs/libmythtv/mythplayer.cpp
    index 0682907..6b7151e 100644
    a b void MythPlayer::calcSliderPos(osdInfo &info, bool paddedFields) 
    46054605    playbackLen = max(playbackLen, 1); 
    46064606    secsplayed  = min((float)playbackLen, max(secsplayed, 0.0f)); 
    46074607 
    4608     info.values.insert("secondsplayed", (int)secsplayed); 
    4609     info.values.insert("totalseconds", playbackLen); 
    4610     info.values["position"] = (int)(1000.0f * (secsplayed / (float)playbackLen)); 
     4608    // Set the raw values, followed by the translated values. 
     4609    for (int i = 0; i < 2 ; ++i) 
     4610    { 
     4611        QString rawPrefix = (i == 0 ? "raw" : ""); 
     4612        if (i > 0) 
     4613        { 
     4614            playbackLen = deleteMap.TranslatePositionAbsToRel(playbackLen * video_frame_rate) / 
     4615                video_frame_rate; 
     4616            secsplayed = deleteMap.TranslatePositionAbsToRel(secsplayed * video_frame_rate) / 
     4617                video_frame_rate; 
     4618        } 
     4619 
     4620    info.values.insert(rawPrefix + "secondsplayed", (int)secsplayed); 
     4621    info.values.insert(rawPrefix + "totalseconds", playbackLen); 
     4622    info.values[rawPrefix + "position"] = (int)(1000.0f * (secsplayed / (float)playbackLen)); 
    46114623 
    46124624    int phours = (int)secsplayed / 3600; 
    46134625    int pmins = ((int)secsplayed - phours * 3600) / 60; 
    void MythPlayer::calcSliderPos(osdInfo &info, bool paddedFields) 
    46564668        } 
    46574669    } 
    46584670 
    4659     info.text["description"] = QObject::tr("%1 of %2").arg(text1).arg(text2); 
    4660     info.text["playedtime"] = text1; 
    4661     info.text["totaltime"] = text2; 
    4662     info.text["remainingtime"] = islive ? QString() : text3; 
    4663     info.text["behindtime"] = islive ? text3 : QString(); 
     4671    info.text[rawPrefix + "description"] = QObject::tr("%1 of %2").arg(text1).arg(text2); 
     4672    info.text[rawPrefix + "playedtime"] = text1; 
     4673    info.text[rawPrefix + "totaltime"] = text2; 
     4674    info.text[rawPrefix + "remainingtime"] = islive ? QString() : text3; 
     4675    info.text[rawPrefix + "behindtime"] = islive ? text3 : QString(); 
     4676    } 
    46644677} 
    46654678 
    46664679int MythPlayer::GetNumChapters() 
  • mythtv/libs/libmythtv/mythplayer.h

    diff --git a/mythtv/libs/libmythtv/mythplayer.h b/mythtv/libs/libmythtv/mythplayer.h
    index 56ddc01..dd8a296 100644
    a b class MTV_PUBLIC MythPlayer 
    353353    virtual long long CalcMaxFFTime(long long ff, bool setjump = true) const; 
    354354    long long CalcRWTime(long long rw) const; 
    355355    virtual void calcSliderPos(osdInfo &info, bool paddedFields = false); 
     356    uint64_t TranslatePositionAbsToRel(uint64_t absPosition) { 
     357        return deleteMap.TranslatePositionAbsToRel(absPosition); 
     358    } 
     359    uint64_t TranslatePositionRelToAbs(uint64_t relPosition) { 
     360        return deleteMap.TranslatePositionRelToAbs(relPosition); 
     361    } 
    356362 
    357363    // Commercial stuff 
    358364    void SetAutoCommercialSkip(CommSkipMode autoskip) 
  • mythtv/libs/libmythtv/osd.cpp

    diff --git a/mythtv/libs/libmythtv/osd.cpp b/mythtv/libs/libmythtv/osd.cpp
    index 56d6611..68ca122 100644
    a b void OSD::SetValues(const QString &window, QHash<QString,int> &map, 
    344344            found = true; 
    345345        } 
    346346    } 
     347    if (map.contains("rawposition")) 
     348    { 
     349        MythUIProgressBar *bar = dynamic_cast<MythUIProgressBar *> (win->GetChild("rawposition")); 
     350        if (bar) 
     351        { 
     352            bar->SetVisible(true); 
     353            bar->SetStart(0); 
     354            bar->SetTotal(1000); 
     355            bar->SetUsed(map.value("rawposition")); 
     356            found = true; 
     357        } 
     358    } 
    347359 
    348360    if (found) 
    349361        SetExpiry(window, timeout); 
  • mythtv/libs/libmythtv/tv_actions.h

    diff --git a/mythtv/libs/libmythtv/tv_actions.h b/mythtv/libs/libmythtv/tv_actions.h
    index 5826438..8f40f17 100644
    a b  
    3636#define ACTION_JUMPFFWD             "JUMPFFWD" 
    3737#define ACTION_JUMPRWND             "JUMPRWND" 
    3838#define ACTION_JUMPBKMRK            "JUMPBKMRK" 
     39#define ACTION_SEEKRWNDNOCUTLIST    "SEEKRWNDNOCUTLIST" 
     40#define ACTION_SEEKFFWDNOCUTLIST    "SEEKFFWDNOCUTLIST" 
     41#define ACTION_JUMPRWNDNOCUTLIST    "JUMPRWNDNOCUTLIST" 
     42#define ACTION_JUMPFFWDNOCUTLIST    "JUMPFFWDNOCUTLIST" 
    3943#define ACTION_JUMPSTART            "JUMPSTART" 
    4044#define ACTION_JUMPTODVDROOTMENU    "JUMPTODVDROOTMENU" 
    4145#define ACTION_JUMPTOPOPUPMENU      "JUMPTOPOPUPMENU" 
  • mythtv/libs/libmythtv/tv_play.cpp

    diff --git a/mythtv/libs/libmythtv/tv_play.cpp b/mythtv/libs/libmythtv/tv_play.cpp
    index 299ca17..0576e82 100644
    a b void TV::InitKeys(void) 
    505505            "Pause"), "P"); 
    506506    REG_KEY("TV Playback", ACTION_SEEKFFWD, QT_TRANSLATE_NOOP("MythControls", 
    507507            "Fast Forward"), "Right"); 
     508    REG_KEY("TV Playback", ACTION_SEEKFFWDNOCUTLIST, QT_TRANSLATE_NOOP("MythControls", 
     509            "Fast Forward ignoring cutlist"), ""); 
    508510    REG_KEY("TV Playback", ACTION_SEEKRWND, QT_TRANSLATE_NOOP("MythControls", 
    509511            "Rewind"), "Left"); 
     512    REG_KEY("TV Playback", ACTION_SEEKRWNDNOCUTLIST, QT_TRANSLATE_NOOP("MythControls", 
     513            "Rewind ignoring cutlist"), ""); 
    510514    REG_KEY("TV Playback", "ARBSEEK", QT_TRANSLATE_NOOP("MythControls", 
    511515            "Arbitrary Seek"), "*"); 
     516    REG_KEY("TV Playback", "ARBSEEKNOCUTLIST", QT_TRANSLATE_NOOP("MythControls", 
     517            "Arbitrary Seek ignoring cutlist"), ""); 
    512518    REG_KEY("TV Playback", ACTION_CHANNELUP, QT_TRANSLATE_NOOP("MythControls", 
    513519            "Channel up"), "Up"); 
    514520    REG_KEY("TV Playback", ACTION_CHANNELDOWN, QT_TRANSLATE_NOOP("MythControls", 
    void TV::InitKeys(void) 
    519525            "Switch to the previous channel"), "H"); 
    520526    REG_KEY("TV Playback", ACTION_JUMPFFWD, QT_TRANSLATE_NOOP("MythControls", 
    521527            "Jump ahead"), "PgDown"); 
     528    REG_KEY("TV Playback", ACTION_JUMPFFWDNOCUTLIST, QT_TRANSLATE_NOOP("MythControls", 
     529            "Jump ahead ignoring cutlist"), ""); 
    522530    REG_KEY("TV Playback", ACTION_JUMPRWND, QT_TRANSLATE_NOOP("MythControls", 
    523531            "Jump back"), "PgUp"); 
     532    REG_KEY("TV Playback", ACTION_JUMPRWNDNOCUTLIST, QT_TRANSLATE_NOOP("MythControls", 
     533            "Jump back ignoring cutlist"), ""); 
     534    REG_KEY("TV Playback", "INFONOCUTLIST", QT_TRANSLATE_NOOP("MythControls", 
     535            "Info ignoring cutlist"), ""); 
    524536    REG_KEY("TV Playback", ACTION_JUMPBKMRK, QT_TRANSLATE_NOOP("MythControls", 
    525537            "Jump to bookmark"), "K"); 
    526538    REG_KEY("TV Playback", "FFWDSTICKY", QT_TRANSLATE_NOOP("MythControls", 
    bool TV::ActiveHandleAction(PlayerContext *ctx, 
    39904002        } 
    39914003    } 
    39924004    else if (has_action(ACTION_JUMPRWND, actions)) 
    3993         DoJumpRWND(ctx); 
     4005        DoJumpRWND(ctx, true); 
     4006    else if (has_action(ACTION_JUMPRWNDNOCUTLIST, actions)) 
     4007        DoJumpRWND(ctx, false); 
    39944008    else if (has_action(ACTION_JUMPFFWD, actions)) 
    3995         DoJumpFFWD(ctx); 
     4009        DoJumpFFWD(ctx, true); 
     4010    else if (has_action(ACTION_JUMPFFWDNOCUTLIST, actions)) 
     4011        DoJumpFFWD(ctx, false); 
    39964012    else if (has_action(ACTION_JUMPBKMRK, actions)) 
    39974013    { 
    39984014        ctx->LockDeletePlayer(__FILE__, __LINE__); 
    3999         long long bookmark = ctx->player->GetBookmark(); 
    4000         long long curloc   = ctx->player->GetFramesPlayed(); 
     4015        uint64_t bookmark  = ctx->player->GetBookmark(); 
    40014016        float     rate     = ctx->player->GetFrameRate(); 
    4002         long long seekloc = (long long) ((bookmark - curloc) / rate); 
     4017        float seekloc = ctx->player->TranslatePositionAbsToRel(bookmark) / rate; 
    40034018        ctx->UnlockDeletePlayer(__FILE__, __LINE__); 
    40044019 
    40054020        if (bookmark > rate) 
    4006             DoSeek(ctx, seekloc, tr("Jump to Bookmark")); 
     4021            DoSeek(ctx, seekloc, tr("Jump to Bookmark"), false); 
    40074022    } 
    40084023    else if (has_action(ACTION_JUMPSTART,actions)) 
    40094024    { 
    4010         long long seekloc = +1; 
    4011         ctx->LockDeletePlayer(__FILE__, __LINE__); 
    4012         seekloc = (int64_t) (-1.0 * ctx->player->GetFramesPlayed() / 
    4013                              ctx->player->GetFrameRate()); 
    4014         ctx->UnlockDeletePlayer(__FILE__, __LINE__); 
    4015  
    4016         if (seekloc <= 0) 
    4017             DoSeek(ctx, seekloc, tr("Jump to Beginning")); 
     4025        DoSeek(ctx, 0, tr("Jump to Beginning"), false); 
    40184026    } 
    40194027    else if (has_action(ACTION_CLEAROSD, actions)) 
    40204028    { 
    bool TV::ActiveHandleAction(PlayerContext *ctx, 
    41684176        ChangeTimeStretch(ctx, -1); 
    41694177    else if (has_action("MENU", actions)) 
    41704178        ShowOSDMenu(ctx); 
    4171     else if (has_action("INFO", actions)) 
     4179    else if (has_action("INFO", actions) || has_action("INFONOCUTLIST", actions)) 
    41724180    { 
    41734181        if (HasQueuedInput()) 
    41744182        { 
    4175             DoArbSeek(ctx, ARBSEEK_SET); 
     4183            DoArbSeek(ctx, ARBSEEK_SET, !has_action("INFONOCUTLIST", actions)); 
    41764184        } 
    41774185        else 
    41784186            ToggleOSD(ctx, true); 
    bool TV::ActivePostQHandleAction(PlayerContext *ctx, const QStringList &actions) 
    44104418                ChangeChannel(ctx, CHANNEL_DIRECTION_UP); 
    44114419        } 
    44124420        else 
    4413             DoJumpRWND(ctx); 
     4421            DoJumpRWND(ctx, true); 
    44144422    } 
    44154423    else if (has_action(ACTION_CHANNELDOWN, actions)) 
    44164424    { 
    bool TV::ActivePostQHandleAction(PlayerContext *ctx, const QStringList &actions) 
    44224430                ChangeChannel(ctx, CHANNEL_DIRECTION_DOWN); 
    44234431        } 
    44244432        else 
    4425             DoJumpFFWD(ctx); 
     4433            DoJumpFFWD(ctx, true); 
    44264434    } 
    44274435    else if (has_action("DELETE", actions) && !islivetv) 
    44284436    { 
    void TV::ProcessNetworkControlCommand(PlayerContext *ctx, 
    46514659        ctx->UnlockDeletePlayer(__FILE__, __LINE__); 
    46524660 
    46534661        if (tokens[2] == "BEGINNING") 
    4654             DoSeek(ctx, -fplay, tr("Jump to Beginning")); 
    4655         else if (tokens[2] == "FORWARD") 
    4656             DoSeek(ctx, ctx->fftime, tr("Skip Ahead")); 
    4657         else if (tokens[2] == "BACKWARD") 
    4658             DoSeek(ctx, -ctx->rewtime, tr("Skip Back")); 
    4659         else if ((tokens[2] == "POSITION") && (tokens.size() == 4) && 
     4662            DoSeek(ctx, 0, tr("Jump to Beginning"), false); 
     4663        else if (tokens[2] == "FORWARD" || tokens[2] == "FORWARDNOCUTLIST") 
     4664            DoSeek(ctx, ctx->fftime, tr("Skip Ahead"), true, tokens[2] == "FORWARD"); 
     4665        else if (tokens[2] == "BACKWARD" || tokens[2] == "BACKWARDNOCUTLIST") 
     4666            DoSeek(ctx, -ctx->rewtime, tr("Skip Back"), true, tokens[2] == "BACKWARD"); 
     4667        else if ((tokens[2] == "POSITION" || 
     4668                  tokens[2] == "POSITIONNOCUTLIST") && 
     4669                 (tokens.size() == 4) && 
    46604670                 (tokens[3].contains(QRegExp("^\\d+$")))) 
    46614671        { 
    46624672            long long rel_frame = tokens[3].toInt(); 
    4663             rel_frame -= (long long) (fplay * (1.0 / 
    4664                                       ctx->player->GetFrameRate())); 
    4665             DoSeek(ctx, rel_frame, tr("Jump To")); 
     4673            DoSeek(ctx, rel_frame / ctx->player->GetFrameRate(), tr("Jump To"), 
     4674                   false, tokens[2] == "POSITION"); 
    46664675        } 
    46674676    } 
    46684677    else if (tokens.size() >= 3 && tokens[1] == "VOLUME") 
    bool TV::SeekHandleAction(PlayerContext *actx, const QStringList &actions, 
    56965705                          const bool isDVD) 
    56975706{ 
    56985707    const int kRewind = 4, kForward = 8, kSticky = 16, kSlippery = 32, 
    5699               kRelative = 64, kAbsolute = 128, kWhenceMask = 3; 
     5708              kRelative = 64, kAbsolute = 128, kIgnoreCutlist = 256, 
     5709              kWhenceMask = 3; 
    57005710    int flags = 0; 
    57015711    if (has_action(ACTION_SEEKFFWD, actions)) 
    57025712        flags = ARBSEEK_FORWARD | kForward | kSlippery | kRelative; 
     5713    else if (has_action(ACTION_SEEKFFWDNOCUTLIST, actions)) 
     5714        flags = ARBSEEK_FORWARD | kForward | kSlippery | kRelative | kIgnoreCutlist; 
    57035715    else if (has_action("FFWDSTICKY", actions)) 
    57045716        flags = ARBSEEK_END     | kForward | kSticky   | kAbsolute; 
    57055717    else if (has_action(ACTION_RIGHT, actions)) 
    57065718        flags = ARBSEEK_FORWARD | kForward | kSticky   | kRelative; 
    57075719    else if (has_action(ACTION_SEEKRWND, actions)) 
    57085720        flags = ARBSEEK_REWIND  | kRewind  | kSlippery | kRelative; 
     5721    else if (has_action(ACTION_SEEKRWNDNOCUTLIST, actions)) 
     5722        flags = ARBSEEK_REWIND  | kRewind  | kSlippery | kRelative | kIgnoreCutlist; 
    57095723    else if (has_action("RWNDSTICKY", actions)) 
    57105724        flags = ARBSEEK_SET     | kRewind  | kSticky   | kAbsolute; 
    57115725    else if (has_action(ACTION_LEFT, actions)) 
    bool TV::SeekHandleAction(PlayerContext *actx, const QStringList &actions, 
    57165730    int direction = (flags & kRewind) ? -1 : 1; 
    57175731    if (HasQueuedInput()) 
    57185732    { 
    5719         DoArbSeek(actx, static_cast<ArbSeekWhence>(flags & kWhenceMask)); 
     5733        DoArbSeek(actx, static_cast<ArbSeekWhence>(flags & kWhenceMask), 
     5734                  !(flags & kIgnoreCutlist)); 
    57205735    } 
    57215736    else if (ContextIsPaused(actx, __FILE__, __LINE__)) 
    57225737    { 
    bool TV::SeekHandleAction(PlayerContext *actx, const QStringList &actions, 
    57315746                             direction * (1.001 / rate); 
    57325747            QString message = (flags & kRewind) ? QString(tr("Rewind")) : 
    57335748                                                 QString(tr("Forward")); 
    5734             DoSeek(actx, time, message); 
     5749            DoSeek(actx, time, message, true, !(flags & kIgnoreCutlist)); 
    57355750        } 
    57365751    } 
    57375752    else if (flags & kSticky) 
    bool TV::SeekHandleAction(PlayerContext *actx, const QStringList &actions, 
    57425757    { 
    57435758            if (smartForward) 
    57445759                doSmartForward = true; 
    5745             DoSeek(actx, -actx->rewtime, tr("Skip Back")); 
     5760            DoSeek(actx, -actx->rewtime, tr("Skip Back"), 
     5761                   true, !(flags & kIgnoreCutlist)); 
    57465762    } 
    57475763    else 
    57485764    { 
    57495765        if (smartForward & doSmartForward) 
    5750             DoSeek(actx, actx->rewtime, tr("Skip Ahead")); 
     5766            DoSeek(actx, actx->rewtime, tr("Skip Ahead"), 
     5767                   true, !(flags & kIgnoreCutlist)); 
    57515768        else 
    5752             DoSeek(actx, actx->fftime, tr("Skip Ahead")); 
     5769            DoSeek(actx, actx->fftime, tr("Skip Ahead"), 
     5770                   true, !(flags & kIgnoreCutlist)); 
    57535771    } 
    57545772    return true; 
    57555773} 
    57565774 
    5757 void TV::DoSeek(PlayerContext *ctx, float time, const QString &mesg) 
     5775void TV::DoSeek(PlayerContext *ctx, float time, const QString &mesg, 
     5776                bool timeIsOffset, bool honorCutlist) 
    57585777{ 
    57595778    bool limitkeys = false; 
    57605779 
    void TV::DoSeek(PlayerContext *ctx, float time, const QString &mesg) 
    57685787        keyRepeatTimer.start(); 
    57695788        NormalSpeed(ctx); 
    57705789        time += StopFFRew(ctx); 
     5790        float framerate = ctx->player->GetFrameRate(); 
     5791        uint64_t currentFrameAbs = ctx->player->GetFramesPlayed(); 
     5792        uint64_t currentFrameRel = honorCutlist ? 
     5793            ctx->player->TranslatePositionAbsToRel(currentFrameAbs) : 
     5794            currentFrameAbs; 
     5795        int64_t desiredFrameRel = (timeIsOffset ? currentFrameRel : 0) + 
     5796            time * framerate + 0.5; 
     5797        if (desiredFrameRel < 0) 
     5798            desiredFrameRel = 0; 
     5799        uint64_t desiredFrameAbs = honorCutlist ? 
     5800            ctx->player->TranslatePositionRelToAbs(desiredFrameRel) : 
     5801            desiredFrameRel; 
     5802        time = ((int64_t)desiredFrameAbs - (int64_t)currentFrameAbs) / framerate; 
    57715803        DoPlayerSeek(ctx, time); 
    57725804        UpdateOSDSeekMessage(ctx, mesg, kOSDTimeout_Med); 
    57735805    } 
    57745806} 
    57755807 
    5776 void TV::DoArbSeek(PlayerContext *ctx, ArbSeekWhence whence) 
     5808void TV::DoArbSeek(PlayerContext *ctx, ArbSeekWhence whence, bool honorCutlist) 
    57775809{ 
    57785810    bool ok = false; 
    57795811    int seek = GetQueuedInputAsInt(&ok); 
    void TV::DoArbSeek(PlayerContext *ctx, ArbSeekWhence whence) 
    57845816    float time = ((seek / 100) * 3600) + ((seek % 100) * 60); 
    57855817 
    57865818    if (whence == ARBSEEK_FORWARD) 
    5787         DoSeek(ctx, time, tr("Jump Ahead")); 
     5819        DoSeek(ctx, time, tr("Jump Ahead"), true, honorCutlist); 
    57885820    else if (whence == ARBSEEK_REWIND) 
    5789         DoSeek(ctx, -time, tr("Jump Back")); 
     5821        DoSeek(ctx, -time, tr("Jump Back"), true, honorCutlist); 
    57905822    else 
    57915823    { 
    57925824        ctx->LockDeletePlayer(__FILE__, __LINE__); 
    void TV::DoArbSeek(PlayerContext *ctx, ArbSeekWhence whence) 
    57985830        if (whence == ARBSEEK_END) 
    57995831            time = (ctx->player->CalcMaxFFTime(LONG_MAX, false) / 
    58005832                    ctx->player->GetFrameRate()) - time; 
    5801         else 
    5802             time = time - (ctx->player->GetFramesPlayed() - 1) / 
    5803                     ctx->player->GetFrameRate(); 
    58045833        ctx->UnlockDeletePlayer(__FILE__, __LINE__); 
    5805         DoSeek(ctx, time, tr("Jump To")); 
     5834        DoSeek(ctx, time, tr("Jump To"), (whence != ARBSEEK_SET), honorCutlist); 
    58065835    } 
    58075836} 
    58085837 
    bool TV::CommitQueuedInput(PlayerContext *ctx) 
    67286757    { 
    67296758        commited = true; 
    67306759        if (HasQueuedInput()) 
     6760            // XXX Should the cutlist be honored? 
    67316761            DoArbSeek(ctx, ARBSEEK_FORWARD); 
    67326762    } 
    67336763    else if (StateIsLiveTV(GetState(ctx))) 
    void TV::OSDDialogEvent(int result, QString text, QString action) 
    97589788        SetExitPlayer(true, true); 
    97599789    } 
    97609790    else if (action == ACTION_JUMPFFWD) 
    9761         DoJumpFFWD(actx); 
     9791        DoJumpFFWD(actx, true); 
     9792    else if (action == ACTION_JUMPFFWDNOCUTLIST) 
     9793        DoJumpFFWD(actx, false); 
    97629794    else if (action == ACTION_JUMPRWND) 
    9763         DoJumpRWND(actx); 
     9795        DoJumpRWND(actx, true); 
     9796    else if (action == ACTION_JUMPRWNDNOCUTLIST) 
     9797        DoJumpRWND(actx, false); 
    97649798    else if (action.startsWith("DEINTERLACER")) 
    97659799        HandleDeinterlacer(actx, action); 
    97669800    else if (action == ACTION_TOGGLEOSDDEBUG) 
    void TV::ITVRestart(PlayerContext *ctx, bool isLive) 
    1156111595    ctx->UnlockDeletePlayer(__FILE__, __LINE__); 
    1156211596} 
    1156311597 
    11564 void TV::DoJumpFFWD(PlayerContext *ctx) 
     11598void TV::DoJumpFFWD(PlayerContext *ctx, bool honorCutlist) 
    1156511599{ 
    1156611600    if (GetState(ctx) == kState_WatchingDVD) 
    1156711601        DVDJumpForward(ctx); 
    1156811602    else if (GetNumChapters(ctx) > 0) 
    1156911603        DoJumpChapter(ctx, 9999); 
    1157011604    else 
    11571         DoSeek(ctx, ctx->jumptime * 60, tr("Jump Ahead")); 
     11605        DoSeek(ctx, ctx->jumptime * 60, tr("Jump Ahead"), true, honorCutlist); 
    1157211606} 
    1157311607 
    11574 void TV::DoJumpRWND(PlayerContext *ctx) 
     11608void TV::DoJumpRWND(PlayerContext *ctx, bool honorCutlist) 
    1157511609{ 
    1157611610    if (GetState(ctx) == kState_WatchingDVD) 
    1157711611        DVDJumpBack(ctx); 
    1157811612    else if (GetNumChapters(ctx) > 0) 
    1157911613        DoJumpChapter(ctx, -1); 
    1158011614    else 
    11581         DoSeek(ctx, -ctx->jumptime * 60, tr("Jump Back")); 
     11615        DoSeek(ctx, -ctx->jumptime * 60, tr("Jump Back"), true, honorCutlist); 
    1158211616} 
    1158311617 
    1158411618/*  \fn TV::DVDJumpBack(PlayerContext*) 
    void TV::DVDJumpBack(PlayerContext *ctx) 
    1160411638        uint chapterLength = dvdrb->GetChapterLength(); 
    1160511639        if ((titleLength == chapterLength) && chapterLength > 300) 
    1160611640        { 
    11607             DoSeek(ctx, -ctx->jumptime * 60, tr("Jump Back")); 
     11641            DoSeek(ctx, -ctx->jumptime * 60, tr("Jump Back"), true); 
    1160811642        } 
    1160911643        else 
    1161011644        { 
    void TV::DVDJumpForward(PlayerContext *ctx) 
    1164711681             (currentTime < (chapterLength - (ctx->jumptime * 60))) && 
    1164811682             chapterLength > 300) 
    1164911683        { 
    11650             DoSeek(ctx, ctx->jumptime * 60, tr("Jump Ahead")); 
     11684            DoSeek(ctx, ctx->jumptime * 60, tr("Jump Ahead"), true); 
    1165111685        } 
    1165211686        else 
    1165311687        { 
  • mythtv/libs/libmythtv/tv_play.h

    diff --git a/mythtv/libs/libmythtv/tv_play.h b/mythtv/libs/libmythtv/tv_play.h
    index bd9d176..b4a9a99 100644
    a b class MTV_PUBLIC TV : public QObject 
    386386 
    387387    bool SeekHandleAction(PlayerContext *actx, const QStringList &actions, 
    388388                          const bool isDVD); 
    389     void DoSeek(PlayerContext*, float time, const QString &mesg); 
     389    void DoSeek(PlayerContext*, float time, const QString &mesg, 
     390                bool timeIsOffset, bool honorCutlist=true); 
    390391    bool DoPlayerSeek(PlayerContext*, float time); 
    391392    enum ArbSeekWhence { 
    392393        ARBSEEK_SET = 0, 
    class MTV_PUBLIC TV : public QObject 
    394395        ARBSEEK_FORWARD, 
    395396        ARBSEEK_END 
    396397    }; 
    397     void DoArbSeek(PlayerContext*, ArbSeekWhence whence); 
    398     void DoJumpFFWD(PlayerContext *ctx); 
    399     void DoJumpRWND(PlayerContext *ctx); 
     398    void DoArbSeek(PlayerContext*, ArbSeekWhence whence, bool honorCutlist=true); 
     399    void DoJumpFFWD(PlayerContext *ctx, bool honorCutlist); 
     400    void DoJumpRWND(PlayerContext *ctx, bool honorCutlist); 
    400401    void NormalSpeed(PlayerContext*); 
    401402    void ChangeSpeed(PlayerContext*, int direction); 
    402403    void ToggleTimeStretch(PlayerContext*); 
  • mythtv/themes/default-wide/osd.xml

    diff --git a/mythtv/themes/default-wide/osd.xml b/mythtv/themes/default-wide/osd.xml
    index b711a3c..6f60e2e 100644
    a b  
    519519            <area>770,10,300,30</area> 
    520520            <align>right,top</align> 
    521521        </textarea> 
    522         <textarea name="timedisplay" from="title"> 
     522        <textarea name="fulltimedisplay" from="title"> 
    523523            <area>10,50,1060,30</area> 
    524524            <align>hcenter,bottom</align> 
    525525        </textarea>