Ticket #8631: seek_honors_cutlist_v11.patch

File seek_honors_cutlist_v11.patch, 27.8 KB (added by Jim Stichnoth <stichnot@…>, 10 years 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>