replay.h 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. #pragma once
  2. #include <algorithm>
  3. #include <map>
  4. #include <memory>
  5. #include <optional>
  6. #include <set>
  7. #include <string>
  8. #include <tuple>
  9. #include <vector>
  10. #include <utility>
  11. #include <QThread>
  12. #include "tools/replay/camera.h"
  13. #include "tools/replay/route.h"
  14. const QString DEMO_ROUTE = "a2a0ccea32023010|2023-07-27--13-01-19";
  15. // one segment uses about 100M of memory
  16. constexpr int MIN_SEGMENTS_CACHE = 5;
  17. enum REPLAY_FLAGS {
  18. REPLAY_FLAG_NONE = 0x0000,
  19. REPLAY_FLAG_DCAM = 0x0002,
  20. REPLAY_FLAG_ECAM = 0x0004,
  21. REPLAY_FLAG_NO_LOOP = 0x0010,
  22. REPLAY_FLAG_NO_FILE_CACHE = 0x0020,
  23. REPLAY_FLAG_QCAMERA = 0x0040,
  24. REPLAY_FLAG_NO_HW_DECODER = 0x0100,
  25. REPLAY_FLAG_NO_VIPC = 0x0400,
  26. REPLAY_FLAG_ALL_SERVICES = 0x0800,
  27. };
  28. enum class FindFlag {
  29. nextEngagement,
  30. nextDisEngagement,
  31. nextUserFlag,
  32. nextInfo,
  33. nextWarning,
  34. nextCritical
  35. };
  36. enum class TimelineType { None, Engaged, AlertInfo, AlertWarning, AlertCritical, UserFlag };
  37. typedef bool (*replayEventFilter)(const Event *, void *);
  38. Q_DECLARE_METATYPE(std::shared_ptr<LogReader>);
  39. class Replay : public QObject {
  40. Q_OBJECT
  41. public:
  42. Replay(QString route, QStringList allow, QStringList block, SubMaster *sm = nullptr,
  43. uint32_t flags = REPLAY_FLAG_NONE, QString data_dir = "", QObject *parent = 0);
  44. ~Replay();
  45. bool load();
  46. RouteLoadError lastRouteError() const { return route_->lastError(); }
  47. void start(int seconds = 0);
  48. void stop();
  49. void pause(bool pause);
  50. void seekToFlag(FindFlag flag);
  51. void seekTo(double seconds, bool relative);
  52. inline bool isPaused() const { return user_paused_; }
  53. // the filter is called in streaming thread.try to return quickly from it to avoid blocking streaming.
  54. // the filter function must return true if the event should be filtered.
  55. // otherwise it must return false.
  56. inline void installEventFilter(replayEventFilter filter, void *opaque) {
  57. filter_opaque = opaque;
  58. event_filter = filter;
  59. }
  60. inline int segmentCacheLimit() const { return segment_cache_limit; }
  61. inline void setSegmentCacheLimit(int n) { segment_cache_limit = std::max(MIN_SEGMENTS_CACHE, n); }
  62. inline bool hasFlag(REPLAY_FLAGS flag) const { return flags_ & flag; }
  63. inline void addFlag(REPLAY_FLAGS flag) { flags_ |= flag; }
  64. inline void removeFlag(REPLAY_FLAGS flag) { flags_ &= ~flag; }
  65. inline const Route* route() const { return route_.get(); }
  66. inline double currentSeconds() const { return double(cur_mono_time_ - route_start_ts_) / 1e9; }
  67. inline QDateTime routeDateTime() const { return route_date_time_; }
  68. inline QDateTime currentDateTime() const { return route_date_time_.addSecs(currentSeconds()); }
  69. inline uint64_t routeStartNanos() const { return route_start_ts_; }
  70. inline double toSeconds(uint64_t mono_time) const { return (mono_time - route_start_ts_) / 1e9; }
  71. inline double minSeconds() const { return !segments_.empty() ? segments_.begin()->first * 60 : 0; }
  72. inline double maxSeconds() const { return max_seconds_; }
  73. inline void setSpeed(float speed) { speed_ = speed; }
  74. inline float getSpeed() const { return speed_; }
  75. inline const std::vector<Event> *events() const { return &events_; }
  76. inline const std::map<int, std::unique_ptr<Segment>> &segments() const { return segments_; }
  77. inline const std::string &carFingerprint() const { return car_fingerprint_; }
  78. inline const std::vector<std::tuple<double, double, TimelineType>> getTimeline() {
  79. std::lock_guard lk(timeline_lock);
  80. return timeline_;
  81. }
  82. signals:
  83. void streamStarted();
  84. void segmentsMerged();
  85. void seeking(double sec);
  86. void seekedTo(double sec);
  87. void qLogLoaded(std::shared_ptr<LogReader> qlog);
  88. void minMaxTimeChanged(double min_sec, double max_sec);
  89. protected slots:
  90. void segmentLoadFinished(bool success);
  91. protected:
  92. typedef std::map<int, std::unique_ptr<Segment>> SegmentMap;
  93. std::optional<uint64_t> find(FindFlag flag);
  94. void pauseStreamThread();
  95. void startStream(const Segment *cur_segment);
  96. void streamThread();
  97. void updateSegmentsCache();
  98. void loadSegmentInRange(SegmentMap::iterator begin, SegmentMap::iterator cur, SegmentMap::iterator end);
  99. void mergeSegments(const SegmentMap::iterator &begin, const SegmentMap::iterator &end);
  100. void updateEvents(const std::function<bool()>& update_events_function);
  101. std::vector<Event>::const_iterator publishEvents(std::vector<Event>::const_iterator first,
  102. std::vector<Event>::const_iterator last);
  103. void publishMessage(const Event *e);
  104. void publishFrame(const Event *e);
  105. void buildTimeline();
  106. void checkSeekProgress();
  107. inline bool isSegmentMerged(int n) const { return merged_segments_.count(n) > 0; }
  108. pthread_t stream_thread_id = 0;
  109. QThread *stream_thread_ = nullptr;
  110. std::mutex stream_lock_;
  111. bool user_paused_ = false;
  112. std::condition_variable stream_cv_;
  113. std::atomic<int> current_segment_ = 0;
  114. std::optional<double> seeking_to_;
  115. SegmentMap segments_;
  116. // the following variables must be protected with stream_lock_
  117. std::atomic<bool> exit_ = false;
  118. std::atomic<bool> paused_ = false;
  119. bool events_ready_ = false;
  120. QDateTime route_date_time_;
  121. uint64_t route_start_ts_ = 0;
  122. std::atomic<uint64_t> cur_mono_time_ = 0;
  123. std::atomic<double> max_seconds_ = 0;
  124. std::vector<Event> events_;
  125. std::set<int> merged_segments_;
  126. // messaging
  127. SubMaster *sm = nullptr;
  128. std::unique_ptr<PubMaster> pm;
  129. std::vector<const char*> sockets_;
  130. std::vector<bool> filters_;
  131. std::unique_ptr<Route> route_;
  132. std::unique_ptr<CameraServer> camera_server_;
  133. std::atomic<uint32_t> flags_ = REPLAY_FLAG_NONE;
  134. std::mutex timeline_lock;
  135. QFuture<void> timeline_future;
  136. std::vector<std::tuple<double, double, TimelineType>> timeline_;
  137. std::string car_fingerprint_;
  138. std::atomic<float> speed_ = 1.0;
  139. replayEventFilter event_filter = nullptr;
  140. void *filter_opaque = nullptr;
  141. int segment_cache_limit = MIN_SEGMENTS_CACHE;
  142. };