diff --git a/tools/replay/consoleui.cc b/tools/replay/consoleui.cc index 719bbd69ca..3332aa9c90 100644 --- a/tools/replay/consoleui.cc +++ b/tools/replay/consoleui.cc @@ -29,7 +29,7 @@ const std::initializer_list> keyboard_shortc }, { {"enter", "Enter seek request"}, - {"x", "+/-Replay speed"}, + {"+/-", "Playback speed"}, {"q", "Exit"}, }, }; @@ -331,13 +331,18 @@ void ConsoleUI::handleKey(char c) { refresh(); getch_timer.start(1000, this); - } else if (c == 'x') { - if (replay->hasFlag(REPLAY_FLAG_FULL_SPEED)) { - replay->removeFlag(REPLAY_FLAG_FULL_SPEED); - rWarning("replay at normal speed"); - } else { - replay->addFlag(REPLAY_FLAG_FULL_SPEED); - rWarning("replay at full speed"); + } else if (c == '+' || c == '=') { + auto it = std::upper_bound(speed_array.begin(), speed_array.end(), replay->getSpeed()); + if (it != speed_array.end()) { + rWarning("playback speed: %.1fx", *it); + replay->setSpeed(*it); + } + } else if (c == '_' || c == '-') { + auto it = std::lower_bound(speed_array.begin(), speed_array.end(), replay->getSpeed()); + if (it != speed_array.begin()) { + auto prev = std::prev(it); + rWarning("playback speed: %.1fx", *prev); + replay->setSpeed(*prev); } } else if (c == 'e') { replay->seekToFlag(FindFlag::nextEngagement); diff --git a/tools/replay/consoleui.h b/tools/replay/consoleui.h index 20e07524dd..6ed44bc623 100644 --- a/tools/replay/consoleui.h +++ b/tools/replay/consoleui.h @@ -16,6 +16,7 @@ class ConsoleUI : public QObject { public: ConsoleUI(Replay *replay, QObject *parent = 0); ~ConsoleUI(); + inline static const std::array speed_array = {0.2f, 0.5f, 1.0f, 2.0f, 3.0f}; private: void initWindows(); diff --git a/tools/replay/main.cc b/tools/replay/main.cc index 945cb4cd09..a0c072438d 100644 --- a/tools/replay/main.cc +++ b/tools/replay/main.cc @@ -33,6 +33,8 @@ int main(int argc, char *argv[]) { parser.addOption({{"b", "block"}, "blacklist of services to send", "block"}); parser.addOption({{"c", "cache"}, "cache segments in memory. default is 5", "n"}); parser.addOption({{"s", "start"}, "start from ", "seconds"}); + parser.addOption({"x", QString("playback . between %1 - %2") + .arg(ConsoleUI::speed_array.front()).arg(ConsoleUI::speed_array.back()), "speed"}); parser.addOption({"demo", "use a demo route instead of providing your own"}); parser.addOption({"data_dir", "local directory with routes", "data_dir"}); parser.addOption({"prefix", "set OPENPILOT_PREFIX", "prefix"}); @@ -67,6 +69,10 @@ int main(int argc, char *argv[]) { if (!parser.value("c").isEmpty()) { replay->setSegmentCacheLimit(parser.value("c").toInt()); } + if (!parser.value("x").isEmpty()) { + replay->setSpeed(std::clamp(parser.value("x").toFloat(), + ConsoleUI::speed_array.front(), ConsoleUI::speed_array.back())); + } if (!replay->load()) { return 0; } diff --git a/tools/replay/replay.cc b/tools/replay/replay.cc index 1ec484d677..9657375be7 100644 --- a/tools/replay/replay.cc +++ b/tools/replay/replay.cc @@ -363,7 +363,7 @@ void Replay::publishFrame(const Event *e) { void Replay::stream() { cereal::Event::Which cur_which = cereal::Event::Which::INIT_DATA; - double prev_replay_speed = 1.0; + double prev_replay_speed = speed_; std::unique_lock lk(stream_lock_); while (true) { @@ -398,14 +398,14 @@ void Replay::stream() { evt_start_ts = cur_mono_time_; loop_start_ts = nanos_since_boot(); prev_replay_speed = speed_; - } else if (behind_ns > 0 && !hasFlag(REPLAY_FLAG_FULL_SPEED)) { + } else if (behind_ns > 0) { precise_nano_sleep(behind_ns); } if (!evt->frame) { publishMessage(evt); } else if (camera_server_) { - if (hasFlag(REPLAY_FLAG_FULL_SPEED)) { + if (speed_ > 1.0) { camera_server_->waitForSent(); } publishFrame(evt); diff --git a/tools/replay/replay.h b/tools/replay/replay.h index 1144da2601..1a74b69c3d 100644 --- a/tools/replay/replay.h +++ b/tools/replay/replay.h @@ -27,7 +27,6 @@ enum REPLAY_FLAGS { REPLAY_FLAG_NO_FILE_CACHE = 0x0020, REPLAY_FLAG_QCAMERA = 0x0040, REPLAY_FLAG_NO_HW_DECODER = 0x0100, - REPLAY_FLAG_FULL_SPEED = 0x0200, REPLAY_FLAG_NO_VIPC = 0x0400, REPLAY_FLAG_ALL_SERVICES = 0x0800, };