diff --git a/selfdrive/ui/replay/main.cc b/selfdrive/ui/replay/main.cc index 82f9c4e4af..f52093bd94 100644 --- a/selfdrive/ui/replay/main.cc +++ b/selfdrive/ui/replay/main.cc @@ -107,6 +107,7 @@ int main(int argc, char *argv[]) { {"qcam", REPLAY_FLAG_QCAMERA, "load qcamera"}, {"yuv", REPLAY_FLAG_SEND_YUV, "send yuv frame"}, {"no-cuda", REPLAY_FLAG_NO_CUDA, "disable CUDA"}, + {"no-vipc", REPLAY_FLAG_NO_VIPC, "do not output video"}, }; QCommandLineParser parser; diff --git a/selfdrive/ui/replay/replay.cc b/selfdrive/ui/replay/replay.cc index 5aea11bb2c..bd5f4808f8 100644 --- a/selfdrive/ui/replay/replay.cc +++ b/selfdrive/ui/replay/replay.cc @@ -58,8 +58,10 @@ bool Replay::load() { } for (auto &[n, f] : route_->segments()) { - if ((!f.rlog.isEmpty() || !f.qlog.isEmpty()) && (!f.road_cam.isEmpty() || !f.qcamera.isEmpty())) { - segments_[n] = nullptr; + bool has_log = !f.rlog.isEmpty() || !f.qlog.isEmpty(); + bool has_video = !f.road_cam.isEmpty() || !f.qcamera.isEmpty(); + if (has_log && (has_video || hasFlag(REPLAY_FLAG_NO_VIPC))) { + segments_.insert({n, nullptr}); } } if (segments_.empty()) { @@ -218,13 +220,15 @@ void Replay::startStream(const Segment *cur_segment) { } // start camera server - std::pair camera_size[MAX_CAMERAS] = {}; - for (auto type : ALL_CAMERAS) { - if (auto &fr = cur_segment->frames[type]) { - camera_size[type] = {fr->width, fr->height}; + if (!hasFlag(REPLAY_FLAG_NO_VIPC)) { + std::pair camera_size[MAX_CAMERAS] = {}; + for (auto type : ALL_CAMERAS) { + if (auto &fr = cur_segment->frames[type]) { + camera_size[type] = {fr->width, fr->height}; + } } + camera_server_ = std::make_unique(camera_size, hasFlag(REPLAY_FLAG_SEND_YUV)); } - camera_server_ = std::make_unique(camera_size, hasFlag(REPLAY_FLAG_SEND_YUV)); // start stream thread stream_thread_ = new QThread(); @@ -318,18 +322,20 @@ void Replay::stream() { precise_nano_sleep(behind_ns); } - if (evt->frame) { + if (!evt->frame) { + publishMessage(evt); + } else if (camera_server_) { if (hasFlag(REPLAY_FLAG_FULL_SPEED)) { camera_server_->waitFinish(); } publishFrame(evt); - } else { - publishMessage(evt); } } } // wait for frame to be sent before unlock.(frameReader may be deleted after unlock) - camera_server_->waitFinish(); + if (camera_server_) { + camera_server_->waitFinish(); + } if (eit == events_->end() && !hasFlag(REPLAY_FLAG_NO_LOOP)) { int last_segment = segments_.rbegin()->first; diff --git a/selfdrive/ui/replay/replay.h b/selfdrive/ui/replay/replay.h index 4a3fab2981..e1ec091225 100644 --- a/selfdrive/ui/replay/replay.h +++ b/selfdrive/ui/replay/replay.h @@ -18,6 +18,7 @@ enum REPLAY_FLAGS { REPLAY_FLAG_SEND_YUV = 0x0080, REPLAY_FLAG_NO_CUDA = 0x0100, REPLAY_FLAG_FULL_SPEED = 0x0200, + REPLAY_FLAG_NO_VIPC = 0x0400, }; class Replay : public QObject { diff --git a/selfdrive/ui/replay/route.cc b/selfdrive/ui/replay/route.cc index 4ed832cd52..fe6e21a91a 100644 --- a/selfdrive/ui/replay/route.cc +++ b/selfdrive/ui/replay/route.cc @@ -98,7 +98,7 @@ Segment::Segment(int n, const SegmentFile &files, uint32_t flags) : seg_num(n), files.rlog.isEmpty() ? files.qlog : files.rlog, }; for (int i = 0; i < file_list.size(); ++i) { - if (!file_list[i].isEmpty()) { + if (!file_list[i].isEmpty() && (!(flags & REPLAY_FLAG_NO_VIPC) || i >= MAX_CAMERAS)) { ++loading_; synchronizer_.addFuture(QtConcurrent::run(this, &Segment::loadFile, i, file_list[i].toStdString())); }