Ticket #8631: seek_honors_cutlist_v8.patch
File seek_honors_cutlist_v8.patch, 28.7 KB (added by , 13 years ago) |
---|
-
mythtv/libs/libmythtv/bdringbuffer.cpp
diff --git a/mythtv/libs/libmythtv/bdringbuffer.cpp b/mythtv/libs/libmythtv/bdringbuffer.cpp index 74c615c..09d2064 100644
a b bool BDRingBuffer::HandleAction(const QStringList &actions, int64_t pts) 198 198 PressButton(BD_VK_DOWN, pts); 199 199 } 200 200 else if (actions.contains(ACTION_LEFT) || 201 actions.contains(ACTION_SEEKRWNDNOCUTLIST) || 201 202 actions.contains(ACTION_SEEKRWND)) 202 203 { 203 204 PressButton(BD_VK_LEFT, pts); 204 205 } 205 206 else if (actions.contains(ACTION_RIGHT) || 207 actions.contains(ACTION_SEEKFFWDNOCUTLIST) || 206 208 actions.contains(ACTION_SEEKFFWD)) 207 209 { 208 210 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 ec934a6..1b177f2 100644
a b void DeleteMap::UpdateSeekAmount(int change, double framerate) 66 66 } 67 67 } 68 68 69 /** 69 static QString createTimeString(uint64_t frame, uint64_t total, 70 double frame_rate, bool full_resolution) 71 { 72 int secs = (int)(frame / frame_rate); 73 int frames = frame - (int)(secs * frame_rate); 74 int totalSecs = (int)(total / frame_rate); 75 QString timestr; 76 if (totalSecs >= 3600) 77 timestr = QString::number(secs / 3600) + ":"; 78 timestr += QString("%1").arg((secs / 60) % 60, 2, 10, QChar(48)) + 79 QString(":%1").arg(secs % 60, 2, 10, QChar(48)); 80 if (full_resolution) 81 timestr += QString(".%1").arg(frames, 2, 10, QChar(48)); 82 return timestr; 83 } 84 85 /** 70 86 * \brief Show and update the edit mode On Screen Display. The cut regions 71 87 * are only refreshed if the deleteMap has been updated. 72 88 */ … … void DeleteMap::UpdateOSD(uint64_t frame, uint64_t total, double frame_rate, 84 100 infoMap.detach(); 85 101 ctx->UnlockPlayingInfo(__FILE__, __LINE__); 86 102 87 int secs = (int)(frame / frame_rate);88 int frames = frame - (int)(secs * frame_rate);89 QString timestr = QString::number(secs / 3600) +90 QString(":%1").arg((secs / 60) % 60, 2, 10, QChar(48)) +91 QString(":%1").arg(secs % 60, 2, 10, QChar(48)) +92 QString(".%1").arg(frames, 2, 10, QChar(48));93 94 103 QString cutmarker = " "; 95 104 if (IsInDelete(frame)) 96 105 cutmarker = QObject::tr("cut"); 97 106 107 QString timestr = createTimeString(frame, total, frame_rate, true); 108 uint64_t relTotal = TranslatePositionAbsToRel(total); 109 QString relTimeDisplay = createTimeString(TranslatePositionAbsToRel(frame), 110 relTotal, frame_rate, false); 111 QString relLengthDisplay = createTimeString(relTotal, 112 relTotal, frame_rate, false); 98 113 infoMap["timedisplay"] = timestr; 99 114 infoMap["framedisplay"] = QString::number(frame); 100 115 infoMap["cutindicator"] = cutmarker; 101 116 infoMap["title"] = QObject::tr("Edit"); 102 117 infoMap["seekamount"] = m_seekText;; 118 infoMap["reltimedisplay"] = relTimeDisplay; 119 infoMap["rellengthdisplay"] = relLengthDisplay; 120 infoMap["fulltimedisplay"] = timestr + " (" + 121 QObject::tr("%1 of %2").arg(relTimeDisplay).arg(relLengthDisplay) + ")"; 103 122 104 123 QHash<QString,float> posMap; 105 124 posMap.insert("position", (float)((double)frame/(double)total)); … … bool DeleteMap::IsSaved(PlayerContext *ctx) 721 740 722 741 return currentMap == savedMap; 723 742 } 743 744 uint64_t DeleteMap::TranslatePositionAbsToRel(const frm_dir_map_t &deleteMap, 745 uint64_t absPosition) 746 { 747 uint64_t subtraction = 0; 748 uint64_t startOfCutRegion = 0; 749 frm_dir_map_t::const_iterator i; 750 bool withinCut = false; 751 bool first = true; 752 for (i = deleteMap.constBegin(); 753 i != deleteMap.constEnd() && i.key() <= absPosition; 754 i++) 755 { 756 if (first) 757 withinCut = (i.value() == MARK_CUT_END); 758 first = false; 759 if (i.value() == MARK_CUT_START && !withinCut) 760 { 761 withinCut = true; 762 startOfCutRegion = i.key(); 763 } 764 else if (i.value() == MARK_CUT_END && withinCut) 765 { 766 withinCut = false; 767 subtraction += (i.key() - startOfCutRegion); 768 } 769 } 770 if (withinCut) 771 subtraction += (absPosition - startOfCutRegion); 772 return absPosition - subtraction; 773 } 774 775 uint64_t DeleteMap::TranslatePositionRelToAbs(const frm_dir_map_t &deleteMap, 776 uint64_t relPosition) 777 { 778 uint64_t addition = 0; 779 uint64_t startOfCutRegion = 0; 780 frm_dir_map_t::const_iterator i; 781 bool withinCut = false; 782 bool first = true; 783 for (i = deleteMap.constBegin(); i != deleteMap.constEnd(); i++) 784 { 785 if (first) 786 withinCut = (i.value() == MARK_CUT_END); 787 first = false; 788 if (i.value() == MARK_CUT_START && !withinCut) 789 { 790 withinCut = true; 791 startOfCutRegion = i.key(); 792 if (relPosition + addition <= startOfCutRegion) 793 break; 794 } 795 else if (i.value() == MARK_CUT_END && withinCut) 796 { 797 withinCut = false; 798 addition += (i.key() - startOfCutRegion); 799 } 800 } 801 return relPosition + addition; 802 } -
mythtv/libs/libmythtv/deletemap.h
diff --git a/mythtv/libs/libmythtv/deletemap.h b/mythtv/libs/libmythtv/deletemap.h index e6a599b..5c4c2d5 100644
a b class DeleteMap 46 46 bool IsTemporaryMark(uint64_t frame); 47 47 bool HasTemporaryMark(void); 48 48 uint64_t GetLastFrame(uint64_t total); 49 uint64_t TranslatePositionAbsToRel(uint64_t absPosition) { 50 return TranslatePositionAbsToRel(m_deleteMap, absPosition); 51 } 52 uint64_t TranslatePositionRelToAbs(uint64_t relPosition) { 53 return TranslatePositionRelToAbs(m_deleteMap, relPosition); 54 } 55 static uint64_t TranslatePositionAbsToRel(const frm_dir_map_t &deleteMap, 56 uint64_t absPosition); 57 static uint64_t TranslatePositionRelToAbs(const frm_dir_map_t &deleteMap, 58 uint64_t relPosition); 49 59 50 60 void TrackerReset(uint64_t frame, uint64_t total); 51 61 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 9647917..97c14e2 100644
a b bool DVDRingBuffer::HandleAction(const QStringList &actions, int64_t pts) 976 976 MoveButtonDown(); 977 977 } 978 978 else if (actions.contains(ACTION_LEFT) || 979 actions.contains(ACTION_SEEKRWNDNOCUTLIST) || 979 980 actions.contains(ACTION_SEEKRWND)) 980 981 { 981 982 MoveButtonLeft(); 982 983 } 983 984 else if (actions.contains(ACTION_RIGHT) || 985 actions.contains(ACTION_SEEKFFWDNOCUTLIST) || 984 986 actions.contains(ACTION_SEEKFFWD)) 985 987 { 986 988 MoveButtonRight(); -
mythtv/libs/libmythtv/mythdvdplayer.cpp
diff --git a/mythtv/libs/libmythtv/mythdvdplayer.cpp b/mythtv/libs/libmythtv/mythdvdplayer.cpp index 42c3e7f..fa64f65 100644
a b void MythDVDPlayer::calcSliderPos(osdInfo &info, bool paddedFields) 426 426 // DVD playing non-functional under windows for now 427 427 secsplayed = 0.0f; 428 428 #endif 429 calcSliderPosPriv(info, paddedFields, playbackLen, secsplayed, islive); 429 calcSliderPosPriv(info, paddedFields, playbackLen, secsplayed, islive, false); 430 calcSliderPosPriv(info, paddedFields, playbackLen, secsplayed, islive, true); 430 431 } 431 432 432 433 void MythDVDPlayer::SeekForScreenGrab(uint64_t &number, uint64_t frameNum, -
mythtv/libs/libmythtv/mythplayer.cpp
diff --git a/mythtv/libs/libmythtv/mythplayer.cpp b/mythtv/libs/libmythtv/mythplayer.cpp index 1a83c92..52aed3c 100644
a b void MythPlayer::calcSliderPos(osdInfo &info, bool paddedFields) 4309 4309 info.values.insert("progbefore", 0); 4310 4310 info.values.insert("progafter", 0); 4311 4311 4312 int playbackLen = totalDuration; 4313 4314 if (totalDuration == 0 || noVideoTracks || decoder->GetCodecDecoderName() == "nuppel") 4315 playbackLen = totalLength; 4312 int rawPlaybackLen = totalDuration; 4313 4314 if (totalDuration == 0 || noVideoTracks || decoder->GetCodecDecoderName() == "nuppel") 4315 rawPlaybackLen = totalLength; 4316 // XXX- Note that the translated playbackLen uses the frame count 4317 // with respect to a fixed frame rate, rather than the ffmpeg 4318 // display timecode. 4319 int playbackLen = deleteMap.TranslatePositionAbsToRel(totalLength * video_frame_rate) / video_frame_rate; 4316 4320 4317 4321 if (livetv && player_ctx->tvchain) 4318 4322 { … … void MythPlayer::calcSliderPos(osdInfo &info, bool paddedFields) 4327 4331 islive = true; 4328 4332 } 4329 4333 4330 float secsplayed = decoder->isCodecMPEG() ? 4331 (float)(disp_timecode / 1000.f) : 4332 (float)(framesPlayed / video_frame_rate); 4333 4334 calcSliderPosPriv(info, paddedFields, playbackLen, secsplayed, islive); 4334 // XXX- Note that the translated secsplayed uses the frame number 4335 // with respect to a fixed frame rate, rather than the ffmpeg 4336 // display timecode. 4337 float secsplayed = ((float)deleteMap.TranslatePositionAbsToRel(framesPlayed) / video_frame_rate); 4338 calcSliderPosPriv(info, paddedFields, playbackLen, secsplayed, islive, false); 4339 float rawSecsplayed = decoder->isCodecMPEG() ? 4340 (float)(disp_timecode / 1000.f) : 4341 (float)(framesPlayed / video_frame_rate); 4342 calcSliderPosPriv(info, paddedFields, rawPlaybackLen, rawSecsplayed, islive, true); 4335 4343 } 4336 4344 4337 4345 void MythPlayer::calcSliderPosPriv(osdInfo &info, bool paddedFields, 4338 4346 int playbackLen, float secsplayed, 4339 bool islive )4347 bool islive, bool isRaw) 4340 4348 { 4349 QString rawPrefix = isRaw ? "raw" : ""; 4341 4350 playbackLen = max(playbackLen, 1); 4342 4351 secsplayed = min((float)playbackLen, max(secsplayed, 0.0f)); 4343 4352 4344 info.values["position"] = (int)(1000.0f * (secsplayed / (float)playbackLen)); 4353 info.values[rawPrefix + "position"] = 4354 (int)(1000.0f * (secsplayed / (float)playbackLen)); 4345 4355 4346 4356 int phours = (int)secsplayed / 3600; 4347 4357 int pmins = ((int)secsplayed - phours * 3600) / 60; … … void MythPlayer::calcSliderPosPriv(osdInfo &info, bool paddedFields, 4387 4398 } 4388 4399 } 4389 4400 4390 info.text[ "description"] = QObject::tr("%1 of %2").arg(text1).arg(text2);4391 info.text[ "playedtime"] = text1;4392 info.text[ "totaltime"] = text2;4393 info.text[ "remainingtime"] = islive ? QString() : text3;4394 info.text[ "behindtime"] = islive ? text3 : QString();4401 info.text[rawPrefix + "description"] = QObject::tr("%1 of %2").arg(text1).arg(text2); 4402 info.text[rawPrefix + "playedtime"] = text1; 4403 info.text[rawPrefix + "totaltime"] = text2; 4404 info.text[rawPrefix + "remainingtime"] = islive ? QString() : text3; 4405 info.text[rawPrefix + "behindtime"] = islive ? text3 : QString(); 4395 4406 } 4396 4407 4397 4408 int MythPlayer::GetNumChapters() -
mythtv/libs/libmythtv/mythplayer.h
diff --git a/mythtv/libs/libmythtv/mythplayer.h b/mythtv/libs/libmythtv/mythplayer.h index cdbf3d5..c6d8a12 100644
a b class MPUBLIC MythPlayer 330 330 virtual long long CalcMaxFFTime(long long ff, bool setjump = true) const; 331 331 long long CalcRWTime(long long rw) const; 332 332 virtual void calcSliderPos(osdInfo &info, bool paddedFields = false); 333 uint64_t TranslatePositionAbsToRel(uint64_t absPosition) { 334 return deleteMap.TranslatePositionAbsToRel(absPosition); 335 } 336 uint64_t TranslatePositionRelToAbs(uint64_t relPosition) { 337 return deleteMap.TranslatePositionRelToAbs(relPosition); 338 } 333 339 334 340 // Commercial stuff 335 341 void SetAutoCommercialSkip(CommSkipMode autoskip) … … class MPUBLIC MythPlayer 509 515 void JumpToProgram(void); 510 516 511 517 void calcSliderPosPriv(osdInfo &info, bool paddedFields, 512 int playbackLen, float secsplayed, bool islive); 518 int playbackLen, float secsplayed, bool islive, 519 bool isRaw); 513 520 514 521 protected: 515 522 DecoderBase *decoder; -
mythtv/libs/libmythtv/osd.cpp
diff --git a/mythtv/libs/libmythtv/osd.cpp b/mythtv/libs/libmythtv/osd.cpp index 6e31132..eea0e84 100644
a b void OSD::SetValues(const QString &window, QHash<QString,int> &map, 339 339 found = true; 340 340 } 341 341 } 342 if (map.contains("rawposition")) 343 { 344 MythUIProgressBar *bar = dynamic_cast<MythUIProgressBar *> (win->GetChild("rawposition")); 345 if (bar) 346 { 347 bar->SetVisible(true); 348 bar->SetStart(0); 349 bar->SetTotal(1000); 350 bar->SetUsed(map.value("rawposition")); 351 found = true; 352 } 353 } 342 354 343 355 if (found) 344 356 SetExpiry(window, timeout); -
mythtv/libs/libmythtv/tv.h
diff --git a/mythtv/libs/libmythtv/tv.h b/mythtv/libs/libmythtv/tv.h index 59ea58a..c1de595 100644
a b 28 28 #define ACTION_CHANNELDOWN "CHANNELDOWN" 29 29 #define ACTION_SEEKRWND "SEEKRWND" 30 30 #define ACTION_SEEKFFWD "SEEKFFWD" 31 #define ACTION_SEEKRWNDNOCUTLIST "SEEKRWNDNOCUTLIST" 32 #define ACTION_SEEKFFWDNOCUTLIST "SEEKFFWDNOCUTLIST" 31 33 32 34 #define ACTION_TOGGLESTUDIOLEVELS "TOGGLESTUDIOLEVELS" 33 35 #define ACTION_TOGGLEUPMIX "TOGGLEUPMIX" -
mythtv/libs/libmythtv/tv_play.cpp
diff --git a/mythtv/libs/libmythtv/tv_play.cpp b/mythtv/libs/libmythtv/tv_play.cpp index 92bf948..7328ace 100644
a b void TV::InitKeys(void) 489 489 "Pause"), "P"); 490 490 REG_KEY("TV Playback", ACTION_SEEKFFWD, QT_TRANSLATE_NOOP("MythControls", 491 491 "Fast Forward"), "Right"); 492 REG_KEY("TV Playback", ACTION_SEEKFFWDNOCUTLIST, QT_TRANSLATE_NOOP("MythControls", 493 "Fast Forward ignoring cutlist"), ""); 492 494 REG_KEY("TV Playback", ACTION_SEEKRWND, QT_TRANSLATE_NOOP("MythControls", 493 495 "Rewind"), "Left"); 496 REG_KEY("TV Playback", ACTION_SEEKRWNDNOCUTLIST, QT_TRANSLATE_NOOP("MythControls", 497 "Rewind ignoring cutlist"), ""); 494 498 REG_KEY("TV Playback", "ARBSEEK", QT_TRANSLATE_NOOP("MythControls", 495 499 "Arbitrary Seek"), "*"); 500 REG_KEY("TV Playback", "ARBSEEKNOCUTLIST", QT_TRANSLATE_NOOP("MythControls", 501 "Arbitrary Seek ignoring cutlist"), ""); 496 502 REG_KEY("TV Playback", ACTION_CHANNELUP, QT_TRANSLATE_NOOP("MythControls", 497 503 "Channel up"), "Up"); 498 504 REG_KEY("TV Playback", ACTION_CHANNELDOWN, QT_TRANSLATE_NOOP("MythControls", … … void TV::InitKeys(void) 503 509 "Switch to the previous channel"), "H"); 504 510 REG_KEY("TV Playback", "JUMPFFWD", QT_TRANSLATE_NOOP("MythControls", 505 511 "Jump ahead"), "PgDown"); 512 REG_KEY("TV Playback", "JUMPFFWDNOCUTLIST", QT_TRANSLATE_NOOP("MythControls", 513 "Jump ahead ignoring cutlist"), ""); 506 514 REG_KEY("TV Playback", "JUMPRWND", QT_TRANSLATE_NOOP("MythControls", 507 515 "Jump back"), "PgUp"); 516 REG_KEY("TV Playback", "JUMPRWNDNOCUTLIST", QT_TRANSLATE_NOOP("MythControls", 517 "Jump back ignoring cutlist"), ""); 518 REG_KEY("TV Playback", "INFONOCUTLIST", QT_TRANSLATE_NOOP("MythControls", 519 "Info ignoring cutlist"), ""); 508 520 REG_KEY("TV Playback", "JUMPBKMRK", QT_TRANSLATE_NOOP("MythControls", 509 521 "Jump to bookmark"), "K"); 510 522 REG_KEY("TV Playback", "FFWDSTICKY", QT_TRANSLATE_NOOP("MythControls", … … bool TV::ActiveHandleAction(PlayerContext *ctx, 3942 3954 } 3943 3955 } 3944 3956 } 3945 else if (has_action("JUMPRWND", actions)) 3957 else if (has_action("JUMPRWND", actions) || 3958 has_action("JUMPRWNDNOCUTLIST", actions)) 3946 3959 { 3947 3960 if (isDVD) 3948 3961 DVDJumpBack(ctx); 3949 3962 else if (GetNumChapters(ctx) > 0) 3950 3963 DoJumpChapter(ctx, -1); 3951 3964 else 3952 DoSeek(ctx, -ctx->jumptime * 60, tr("Jump Back")); 3965 DoSeek(ctx, -ctx->jumptime * 60, tr("Jump Back"), 3966 true, has_action("JUMPRWND", actions)); 3953 3967 } 3954 else if (has_action("JUMPFFWD", actions)) 3968 else if (has_action("JUMPFFWD", actions) || 3969 has_action("JUMPFFWDNOCUTLIST", actions)) 3955 3970 { 3956 3971 if (isDVD) 3957 3972 DVDJumpForward(ctx); 3958 3973 else if (GetNumChapters(ctx) > 0) 3959 3974 DoJumpChapter(ctx, 9999); 3960 3975 else 3961 DoSeek(ctx, ctx->jumptime * 60, tr("Jump Ahead")); 3976 DoSeek(ctx, ctx->jumptime * 60, tr("Jump Ahead"), 3977 true, has_action("JUMPFFWD", actions)); 3962 3978 } 3963 3979 else if (has_action("JUMPBKMRK", actions)) 3964 3980 { 3965 3981 ctx->LockDeletePlayer(__FILE__, __LINE__); 3966 long long bookmark = ctx->player->GetBookmark(); 3967 long long curloc = ctx->player->GetFramesPlayed(); 3982 uint64_t bookmark = ctx->player->GetBookmark(); 3968 3983 float rate = ctx->player->GetFrameRate(); 3969 long long seekloc = (long long) ((bookmark - curloc) / rate);3984 float seekloc = ctx->player->TranslatePositionAbsToRel(bookmark) / rate; 3970 3985 ctx->UnlockDeletePlayer(__FILE__, __LINE__); 3971 3986 3972 3987 if (bookmark > rate) 3973 DoSeek(ctx, seekloc, tr("Jump to Bookmark") );3988 DoSeek(ctx, seekloc, tr("Jump to Bookmark"), false); 3974 3989 } 3975 3990 else if (has_action("JUMPSTART",actions)) 3976 3991 { 3977 long long seekloc = +1; 3978 ctx->LockDeletePlayer(__FILE__, __LINE__); 3979 seekloc = (int64_t) (-1.0 * ctx->player->GetFramesPlayed() / 3980 ctx->player->GetFrameRate()); 3981 ctx->UnlockDeletePlayer(__FILE__, __LINE__); 3982 3983 if (seekloc <= 0) 3984 DoSeek(ctx, seekloc, tr("Jump to Beginning")); 3992 DoSeek(ctx, 0, tr("Jump to Beginning"), false); 3985 3993 } 3986 3994 else if (has_action("CLEAROSD", actions)) 3987 3995 { … … bool TV::ActiveHandleAction(PlayerContext *ctx, 4128 4136 ChangeTimeStretch(ctx, -1); 4129 4137 else if (has_action("MENU", actions)) 4130 4138 ShowOSDMenu(ctx); 4131 else if (has_action("INFO", actions) )4139 else if (has_action("INFO", actions) || has_action("INFONOCUTLIST", actions)) 4132 4140 { 4133 4141 if (HasQueuedInput()) 4134 4142 { 4135 DoArbSeek(ctx, ARBSEEK_SET );4143 DoArbSeek(ctx, ARBSEEK_SET, !has_action("INFONOCUTLIST", actions)); 4136 4144 } 4137 4145 else 4138 4146 ToggleOSD(ctx, true); … … bool TV::ActivePostQHandleAction(PlayerContext *ctx, const QStringList &actions) 4333 4341 else if (GetNumChapters(ctx) > 0) 4334 4342 DoJumpChapter(ctx, -1); 4335 4343 else 4336 DoSeek(ctx, -ctx->jumptime * 60, tr("Jump Back") );4344 DoSeek(ctx, -ctx->jumptime * 60, tr("Jump Back"), true); 4337 4345 } 4338 4346 else if (has_action(ACTION_CHANNELDOWN, actions)) 4339 4347 { … … bool TV::ActivePostQHandleAction(PlayerContext *ctx, const QStringList &actions) 4349 4357 else if (GetNumChapters(ctx) > 0) 4350 4358 DoJumpChapter(ctx, 9999); 4351 4359 else 4352 DoSeek(ctx, ctx->jumptime * 60, tr("Jump Ahead") );4360 DoSeek(ctx, ctx->jumptime * 60, tr("Jump Ahead"), true); 4353 4361 } 4354 4362 else if (has_action("DELETE", actions) && !islivetv) 4355 4363 { … … void TV::ProcessNetworkControlCommand(PlayerContext *ctx, 4581 4589 ctx->UnlockDeletePlayer(__FILE__, __LINE__); 4582 4590 4583 4591 if (tokens[2] == "BEGINNING") 4584 DoSeek(ctx, -fplay, tr("Jump to Beginning")); 4585 else if (tokens[2] == "FORWARD") 4586 DoSeek(ctx, ctx->fftime, tr("Skip Ahead")); 4587 else if (tokens[2] == "BACKWARD") 4588 DoSeek(ctx, -ctx->rewtime, tr("Skip Back")); 4589 else if ((tokens[2] == "POSITION") && (tokens.size() == 4) && 4592 DoSeek(ctx, 0, tr("Jump to Beginning"), false); 4593 else if (tokens[2] == "FORWARD" || tokens[2] == "FORWARDNOCUTLIST") 4594 DoSeek(ctx, ctx->fftime, tr("Skip Ahead"), true, tokens[2] == "FORWARD"); 4595 else if (tokens[2] == "BACKWARD" || tokens[2] == "BACKWARDNOCUTLIST") 4596 DoSeek(ctx, -ctx->rewtime, tr("Skip Back"), true, tokens[2] == "BACKWARD"); 4597 else if ((tokens[2] == "POSITION" || 4598 tokens[2] == "POSITIONNOCUTLIST") && 4599 (tokens.size() == 4) && 4590 4600 (tokens[3].contains(QRegExp("^\\d+$")))) 4591 4601 { 4592 4602 long long rel_frame = tokens[3].toInt(); 4593 rel_frame -= (long long) (fplay * (1.0 / 4594 ctx->player->GetFrameRate())); 4595 DoSeek(ctx, rel_frame, tr("Jump To")); 4603 DoSeek(ctx, rel_frame / ctx->player->GetFrameRate(), tr("Jump To"), 4604 false, tokens[2] == "POSITION"); 4596 4605 } 4597 4606 } 4598 4607 else if (tokens.size() >= 3 && tokens[1] == "VOLUME") … … bool TV::SeekHandleAction(PlayerContext *actx, const QStringList &actions, 5610 5619 const bool isDVD) 5611 5620 { 5612 5621 const int kRewind = 4, kForward = 8, kSticky = 16, kSlippery = 32, 5613 kRelative = 64, kAbsolute = 128, kWhenceMask = 3; 5622 kRelative = 64, kAbsolute = 128, kIgnoreCutlist = 256, 5623 kWhenceMask = 3; 5614 5624 int flags = 0; 5615 5625 if (has_action(ACTION_SEEKFFWD, actions)) 5616 5626 flags = ARBSEEK_FORWARD | kForward | kSlippery | kRelative; 5627 else if (has_action("SEEKFFWDNOCUTLIST", actions)) 5628 flags = ARBSEEK_FORWARD | kForward | kSlippery | kRelative | kIgnoreCutlist; 5617 5629 else if (has_action("FFWDSTICKY", actions)) 5618 5630 flags = ARBSEEK_END | kForward | kSticky | kAbsolute; 5619 5631 else if (has_action(ACTION_RIGHT, actions)) 5620 5632 flags = ARBSEEK_FORWARD | kForward | kSticky | kRelative; 5621 5633 else if (has_action(ACTION_SEEKRWND, actions)) 5622 5634 flags = ARBSEEK_REWIND | kRewind | kSlippery | kRelative; 5635 else if (has_action("SEEKRWNDNOCUTLIST", actions)) 5636 flags = ARBSEEK_REWIND | kRewind | kSlippery | kRelative | kIgnoreCutlist; 5623 5637 else if (has_action("RWNDSTICKY", actions)) 5624 5638 flags = ARBSEEK_SET | kRewind | kSticky | kAbsolute; 5625 5639 else if (has_action(ACTION_LEFT, actions)) … … bool TV::SeekHandleAction(PlayerContext *actx, const QStringList &actions, 5630 5644 int direction = (flags & kRewind) ? -1 : 1; 5631 5645 if (HasQueuedInput()) 5632 5646 { 5633 DoArbSeek(actx, static_cast<ArbSeekWhence>(flags & kWhenceMask)); 5647 DoArbSeek(actx, static_cast<ArbSeekWhence>(flags & kWhenceMask), 5648 !(flags & kIgnoreCutlist)); 5634 5649 } 5635 5650 else if (actx->paused) 5636 5651 { … … bool TV::SeekHandleAction(PlayerContext *actx, const QStringList &actions, 5646 5661 direction * (1.001 / rate); 5647 5662 QString message = (flags & kRewind) ? QString(tr("Rewind")) : 5648 5663 QString(tr("Forward")); 5649 DoSeek(actx, time, message );5664 DoSeek(actx, time, message, true, !(flags & kIgnoreCutlist)); 5650 5665 } 5651 5666 } 5652 5667 else if (flags & kSticky) … … bool TV::SeekHandleAction(PlayerContext *actx, const QStringList &actions, 5657 5672 { 5658 5673 if (smartForward) 5659 5674 doSmartForward = true; 5660 DoSeek(actx, -actx->rewtime, tr("Skip Back")); 5675 DoSeek(actx, -actx->rewtime, tr("Skip Back"), 5676 true, !(flags & kIgnoreCutlist)); 5661 5677 } 5662 5678 else 5663 5679 { 5664 5680 if (smartForward & doSmartForward) 5665 DoSeek(actx, actx->rewtime, tr("Skip Ahead")); 5681 DoSeek(actx, actx->rewtime, tr("Skip Ahead"), 5682 true, !(flags & kIgnoreCutlist)); 5666 5683 else 5667 DoSeek(actx, actx->fftime, tr("Skip Ahead")); 5684 DoSeek(actx, actx->fftime, tr("Skip Ahead"), 5685 true, !(flags & kIgnoreCutlist)); 5668 5686 } 5669 5687 return true; 5670 5688 } 5671 5689 5672 void TV::DoSeek(PlayerContext *ctx, float time, const QString &mesg) 5690 void TV::DoSeek(PlayerContext *ctx, float time, const QString &mesg, 5691 bool timeIsOffset, bool honorCutlist) 5673 5692 { 5674 5693 bool limitkeys = false; 5675 5694 … … void TV::DoSeek(PlayerContext *ctx, float time, const QString &mesg) 5683 5702 keyRepeatTimer.start(); 5684 5703 NormalSpeed(ctx); 5685 5704 time += StopFFRew(ctx); 5705 float framerate = ctx->player->GetFrameRate(); 5706 uint64_t currentFrameAbs = ctx->player->GetFramesPlayed(); 5707 uint64_t currentFrameRel = honorCutlist ? 5708 ctx->player->TranslatePositionAbsToRel(currentFrameAbs) : 5709 currentFrameAbs; 5710 int64_t desiredFrameRel = (timeIsOffset ? currentFrameRel : 0) + 5711 time * framerate + 0.5; 5712 if (desiredFrameRel < 0) 5713 desiredFrameRel = 0; 5714 uint64_t desiredFrameAbs = honorCutlist ? 5715 ctx->player->TranslatePositionRelToAbs(desiredFrameRel) : 5716 desiredFrameRel; 5717 time = ((int64_t)desiredFrameAbs - (int64_t)currentFrameAbs) / framerate; 5686 5718 DoPlayerSeek(ctx, time); 5687 5719 UpdateOSDSeekMessage(ctx, mesg, kOSDTimeout_Med); 5688 5720 } 5689 5721 } 5690 5722 5691 void TV::DoArbSeek(PlayerContext *ctx, ArbSeekWhence whence )5723 void TV::DoArbSeek(PlayerContext *ctx, ArbSeekWhence whence, bool honorCutlist) 5692 5724 { 5693 5725 bool ok = false; 5694 5726 int seek = GetQueuedInputAsInt(&ok); … … void TV::DoArbSeek(PlayerContext *ctx, ArbSeekWhence whence) 5699 5731 float time = ((seek / 100) * 3600) + ((seek % 100) * 60); 5700 5732 5701 5733 if (whence == ARBSEEK_FORWARD) 5702 DoSeek(ctx, time, tr("Jump Ahead") );5734 DoSeek(ctx, time, tr("Jump Ahead"), true, honorCutlist); 5703 5735 else if (whence == ARBSEEK_REWIND) 5704 DoSeek(ctx, -time, tr("Jump Back") );5736 DoSeek(ctx, -time, tr("Jump Back"), true, honorCutlist); 5705 5737 else 5706 5738 { 5707 5739 ctx->LockDeletePlayer(__FILE__, __LINE__); … … void TV::DoArbSeek(PlayerContext *ctx, ArbSeekWhence whence) 5713 5745 if (whence == ARBSEEK_END) 5714 5746 time = (ctx->player->CalcMaxFFTime(LONG_MAX, false) / 5715 5747 ctx->player->GetFrameRate()) - time; 5716 else5717 time = time - (ctx->player->GetFramesPlayed() - 1) /5718 ctx->player->GetFrameRate();5719 5748 ctx->UnlockDeletePlayer(__FILE__, __LINE__); 5720 DoSeek(ctx, time, tr("Jump To") );5749 DoSeek(ctx, time, tr("Jump To"), (whence != ARBSEEK_SET), honorCutlist); 5721 5750 } 5722 5751 } 5723 5752 … … bool TV::CommitQueuedInput(PlayerContext *ctx) 6652 6681 { 6653 6682 commited = true; 6654 6683 if (HasQueuedInput()) 6684 // XXX Should the cutlist be honored? 6655 6685 DoArbSeek(ctx, ARBSEEK_FORWARD); 6656 6686 } 6657 6687 else if (StateIsLiveTV(GetState(ctx))) … … void TV::DVDJumpBack(PlayerContext *ctx) 11277 11307 uint chapterLength = dvdrb->GetChapterLength(); 11278 11308 if ((titleLength == chapterLength) && chapterLength > 300) 11279 11309 { 11280 DoSeek(ctx, -ctx->jumptime * 60, tr("Jump Back") );11310 DoSeek(ctx, -ctx->jumptime * 60, tr("Jump Back"), true); 11281 11311 } 11282 11312 else 11283 11313 { … … void TV::DVDJumpForward(PlayerContext *ctx) 11325 11355 (currentTime < (chapterLength - (ctx->jumptime * 60))) && 11326 11356 chapterLength > 300) 11327 11357 { 11328 DoSeek(ctx, ctx->jumptime * 60, tr("Jump Ahead") );11358 DoSeek(ctx, ctx->jumptime * 60, tr("Jump Ahead"), true); 11329 11359 } 11330 11360 else 11331 11361 { -
mythtv/libs/libmythtv/tv_play.h
diff --git a/mythtv/libs/libmythtv/tv_play.h b/mythtv/libs/libmythtv/tv_play.h index 53957c2..f839d5c 100644
a b class MPUBLIC TV : public QObject 401 401 402 402 bool SeekHandleAction(PlayerContext *actx, const QStringList &actions, 403 403 const bool isDVD); 404 void DoSeek(PlayerContext*, float time, const QString &mesg); 404 void DoSeek(PlayerContext*, float time, const QString &mesg, 405 bool timeIsOffset, bool honorCutlist=true); 405 406 bool DoPlayerSeek(PlayerContext*, float time); 406 407 enum ArbSeekWhence { 407 408 ARBSEEK_SET = 0, … … class MPUBLIC TV : public QObject 409 410 ARBSEEK_FORWARD, 410 411 ARBSEEK_END 411 412 }; 412 void DoArbSeek(PlayerContext*, ArbSeekWhence whence );413 void DoArbSeek(PlayerContext*, ArbSeekWhence whence, bool honorCutlist=true); 413 414 void NormalSpeed(PlayerContext*); 414 415 void ChangeSpeed(PlayerContext*, int direction); 415 416 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 6f8f4f5..ce378bc 100644
a b 352 352 <area>770,10,300,30</area> 353 353 <align>right,top</align> 354 354 </textarea> 355 <textarea name=" timedisplay" from="title">355 <textarea name="fulltimedisplay" from="title"> 356 356 <area>10,50,1060,30</area> 357 357 <align>hcenter,bottom</align> 358 358 </textarea>