From af7dba9250ba99ebb9afa32d393190dcce6954cc Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Sat, 23 Oct 2021 14:28:53 +0800 Subject: [PATCH] replay: use an enum for flags (#22635) * enum flags * continue * remove yuv flag for now --- selfdrive/ui/replay/framereader.cc | 4 ++-- selfdrive/ui/replay/main.cc | 20 ++++++++++++++++---- selfdrive/ui/replay/replay.cc | 11 ++++++----- selfdrive/ui/replay/replay.h | 18 +++++++++++++----- 4 files changed, 37 insertions(+), 16 deletions(-) diff --git a/selfdrive/ui/replay/framereader.cc b/selfdrive/ui/replay/framereader.cc index ec61444d7c..aeef1a8e69 100644 --- a/selfdrive/ui/replay/framereader.cc +++ b/selfdrive/ui/replay/framereader.cc @@ -159,8 +159,8 @@ bool FrameReader::decodeFrame(AVFrame *f, uint8_t *rgb, uint8_t *yuv) { memcpy(y + f->width * i + f->width / 2 * j + f->width / 2 * k, f->data[2] + f->linesize[2] * k, f->width / 2); } - uint8_t *u = yuv + f->width * f->height; + uint8_t *u = y + f->width * f->height; uint8_t *v = u + (f->width / 2) * (f->height / 2); - libyuv::I420ToRGB24(yuv, f->width, u, f->width / 2, v, f->width / 2, rgb, f->width * 3, f->width, f->height); + libyuv::I420ToRGB24(y, f->width, u, f->width / 2, v, f->width / 2, rgb, f->width * 3, f->width, f->height); return true; } diff --git a/selfdrive/ui/replay/main.cc b/selfdrive/ui/replay/main.cc index 9439f2db55..2d44975e46 100644 --- a/selfdrive/ui/replay/main.cc +++ b/selfdrive/ui/replay/main.cc @@ -10,7 +10,6 @@ #include const QString DEMO_ROUTE = "4cf7a6ad03080c90|2021-09-29--13-46-36"; - struct termios oldt = {}; void sigHandler(int s) { @@ -75,6 +74,12 @@ int main(int argc, char *argv[]){ std::signal(SIGINT, sigHandler); std::signal(SIGTERM, sigHandler); + const std::tuple flags[] = { + {"dcam", REPLAY_FLAG_DCAM, "load driver camera"}, + {"ecam", REPLAY_FLAG_ECAM, "load wide road camera"}, + {"no-loop", REPLAY_FLAG_NO_LOOP, "stop at the end of the route"}, + }; + QCommandLineParser parser; parser.setApplicationDescription("Mock openpilot components by publishing logged messages."); parser.addHelpOption(); @@ -84,8 +89,9 @@ int main(int argc, char *argv[]){ parser.addOption({{"s", "start"}, "start from ", "seconds"}); parser.addOption({"demo", "use a demo route instead of providing your own"}); parser.addOption({"data_dir", "local directory with routes", "data_dir"}); - parser.addOption({"dcam", "load driver camera"}); - parser.addOption({"ecam", "load wide road camera"}); + for (auto &[name, _, desc] : flags) { + parser.addOption({name, desc}); + } parser.process(app); const QStringList args = parser.positionalArguments(); @@ -97,7 +103,13 @@ int main(int argc, char *argv[]){ QStringList allow = parser.value("allow").isEmpty() ? QStringList{} : parser.value("allow").split(","); QStringList block = parser.value("block").isEmpty() ? QStringList{} : parser.value("block").split(","); - Replay *replay = new Replay(route, allow, block, nullptr, parser.isSet("dcam"), parser.isSet("ecam"), parser.value("data_dir"), &app); + uint32_t replay_flags = REPLAY_FLAG_NONE; + for (const auto &[name, flag, _] : flags) { + if (parser.isSet(name)) { + replay_flags |= flag; + } + } + Replay *replay = new Replay(route, allow, block, nullptr, replay_flags, parser.value("data_dir"), &app); if (!replay->load()) { return 0; } diff --git a/selfdrive/ui/replay/replay.cc b/selfdrive/ui/replay/replay.cc index e4c9db1d48..8983ef5b1a 100644 --- a/selfdrive/ui/replay/replay.cc +++ b/selfdrive/ui/replay/replay.cc @@ -10,8 +10,8 @@ #include "selfdrive/hardware/hw.h" #include "selfdrive/ui/replay/util.h" -Replay::Replay(QString route, QStringList allow, QStringList block, SubMaster *sm_, bool dcam, bool ecam, QString data_dir, QObject *parent) - : sm(sm_), load_dcam(dcam), load_ecam(ecam), QObject(parent) { +Replay::Replay(QString route, QStringList allow, QStringList block, SubMaster *sm_, uint32_t flags, QString data_dir, QObject *parent) + : sm(sm_), flags_(flags), QObject(parent) { std::vector s; auto event_struct = capnp::Schema::from().asStruct(); sockets_.resize(event_struct.getUnionFields().size()); @@ -141,7 +141,7 @@ void Replay::queueSegment() { for (int i = 0; end != segments_.end() && i <= fwd; ++end, ++i) { auto &[n, seg] = *end; if (!seg) { - seg = std::make_unique(n, route_->at(n), load_dcam, load_ecam); + seg = std::make_unique(n, route_->at(n), hasFlag(REPLAY_FLAG_DCAM), hasFlag(REPLAY_FLAG_ECAM)); QObject::connect(seg.get(), &Segment::loadFinished, this, &Replay::segmentLoadFinished); qInfo() << "loading segment" << n << "..."; } @@ -246,7 +246,8 @@ void Replay::publishFrame(const Event *e) { {cereal::Event::DRIVER_ENCODE_IDX, DriverCam}, {cereal::Event::WIDE_ROAD_ENCODE_IDX, WideRoadCam}, }; - if ((e->which == cereal::Event::DRIVER_ENCODE_IDX && !load_dcam) || (e->which == cereal::Event::WIDE_ROAD_ENCODE_IDX && !load_ecam)) { + if ((e->which == cereal::Event::DRIVER_ENCODE_IDX && !hasFlag(REPLAY_FLAG_DCAM)) || + (e->which == cereal::Event::WIDE_ROAD_ENCODE_IDX && !hasFlag(REPLAY_FLAG_ECAM))) { return; } auto eidx = capnp::AnyStruct::Reader(e->event).getPointerSection()[0].getAs(); @@ -321,7 +322,7 @@ void Replay::stream() { // wait for frame to be sent before unlock.(frameReader may be deleted after unlock) camera_server_->waitFinish(); - if (eit == events_->end()) { + if (eit == events_->end() && !hasFlag(REPLAY_FLAG_NO_LOOP)) { int last_segment = segments_.rbegin()->first; if (current_segment_ >= last_segment && isSegmentMerged(last_segment)) { qInfo() << "reaches the end of route, restart from beginning"; diff --git a/selfdrive/ui/replay/replay.h b/selfdrive/ui/replay/replay.h index e0380e06b0..5b5f7dfa8b 100644 --- a/selfdrive/ui/replay/replay.h +++ b/selfdrive/ui/replay/replay.h @@ -7,21 +7,29 @@ constexpr int FORWARD_SEGS = 2; +enum REPLAY_FLAGS { + REPLAY_FLAG_NONE = 0x0000, + REPLAY_FLAG_DCAM = 0x0002, + REPLAY_FLAG_ECAM = 0x0004, + REPLAY_FLAG_NO_LOOP = 0x0010, +}; + class Replay : public QObject { Q_OBJECT public: - Replay(QString route, QStringList allow, QStringList block, SubMaster *sm = nullptr, bool dcam = false, bool ecam = false, - QString data_dir="", QObject *parent = 0); + Replay(QString route, QStringList allow, QStringList block, SubMaster *sm = nullptr, + uint32_t flags = REPLAY_FLAG_NONE, QString data_dir = "", QObject *parent = 0); ~Replay(); bool load(); void start(int seconds = 0); void pause(bool pause); bool isPaused() const { return paused_; } + inline bool hasFlag(REPLAY_FLAGS flag) { return flags_ & flag; }; signals: - void segmentChanged(); - void seekTo(int seconds, bool relative); + void segmentChanged(); + void seekTo(int seconds, bool relative); protected slots: void queueSegment(); @@ -64,6 +72,6 @@ protected: PubMaster *pm = nullptr; std::vector sockets_; std::unique_ptr route_; - bool load_dcam = false, load_ecam = false; std::unique_ptr camera_server_; + uint32_t flags_ = REPLAY_FLAG_NONE; };