|
|
@ -106,31 +106,27 @@ void Replay::seekTo(double seconds, bool relative) { |
|
|
|
rInfo("Seeking to %d s, segment %d", (int)target_time, target_segment); |
|
|
|
rInfo("Seeking to %d s, segment %d", (int)target_time, target_segment); |
|
|
|
notifyEvent(onSeeking, target_time); |
|
|
|
notifyEvent(onSeeking, target_time); |
|
|
|
|
|
|
|
|
|
|
|
double seeked_to_sec = -1; |
|
|
|
|
|
|
|
interruptStream([&]() { |
|
|
|
interruptStream([&]() { |
|
|
|
current_segment_ = target_segment; |
|
|
|
current_segment_.store(target_segment); |
|
|
|
cur_mono_time_ = route_start_ts_ + target_time * 1e9; |
|
|
|
cur_mono_time_ = route_start_ts_ + target_time * 1e9; |
|
|
|
seeking_to_ = target_time; |
|
|
|
seeking_to_.store(target_time, std::memory_order_relaxed); |
|
|
|
|
|
|
|
|
|
|
|
if (event_data_->isSegmentLoaded(target_segment)) { |
|
|
|
|
|
|
|
seeked_to_sec = *seeking_to_; |
|
|
|
|
|
|
|
seeking_to_.reset(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return false; |
|
|
|
return false; |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
checkSeekProgress(seeked_to_sec); |
|
|
|
|
|
|
|
seg_mgr_->setCurrentSegment(target_segment); |
|
|
|
seg_mgr_->setCurrentSegment(target_segment); |
|
|
|
|
|
|
|
checkSeekProgress(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void Replay::checkSeekProgress(double seeked_to_sec) { |
|
|
|
void Replay::checkSeekProgress() { |
|
|
|
if (seeked_to_sec >= 0) { |
|
|
|
if (!seg_mgr_->getEventData()->isSegmentLoaded(current_segment_.load())) return; |
|
|
|
if (onSeekedTo) { |
|
|
|
|
|
|
|
onSeekedTo(seeked_to_sec); |
|
|
|
double seek_to = seeking_to_.exchange(-1.0, std::memory_order_acquire); |
|
|
|
} else { |
|
|
|
if (seek_to >= 0 && onSeekedTo) { |
|
|
|
interruptStream([]() { return true; }); |
|
|
|
onSeekedTo(seek_to); |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Resume the interrupted stream
|
|
|
|
|
|
|
|
interruptStream([]() { return true; }); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void Replay::seekToFlag(FindFlag flag) { |
|
|
|
void Replay::seekToFlag(FindFlag flag) { |
|
|
@ -152,29 +148,19 @@ void Replay::pause(bool pause) { |
|
|
|
void Replay::handleSegmentMerge() { |
|
|
|
void Replay::handleSegmentMerge() { |
|
|
|
if (exit_) return; |
|
|
|
if (exit_) return; |
|
|
|
|
|
|
|
|
|
|
|
double seeked_to_sec = -1; |
|
|
|
auto event_data = seg_mgr_->getEventData(); |
|
|
|
interruptStream([&]() { |
|
|
|
if (!stream_thread_.joinable() && !event_data->segments.empty()) { |
|
|
|
event_data_ = seg_mgr_->getEventData(); |
|
|
|
startStream(event_data->segments.begin()->second); |
|
|
|
notifyEvent(onSegmentsMerged); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool segment_loaded = event_data_->isSegmentLoaded(current_segment_); |
|
|
|
|
|
|
|
if (seeking_to_ && segment_loaded) { |
|
|
|
|
|
|
|
seeked_to_sec = *seeking_to_; |
|
|
|
|
|
|
|
seeking_to_.reset(); |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
return segment_loaded; |
|
|
|
notifyEvent(onSegmentsMerged); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
checkSeekProgress(seeked_to_sec); |
|
|
|
// Interrupt the stream to handle segment merge
|
|
|
|
if (!stream_thread_.joinable() && !event_data_->events.empty()) { |
|
|
|
interruptStream([]() { return false; }); |
|
|
|
startStream(); |
|
|
|
checkSeekProgress(); |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void Replay::startStream() { |
|
|
|
void Replay::startStream(const std::shared_ptr<Segment> segment) { |
|
|
|
const auto &cur_segment = event_data_->segments.begin()->second; |
|
|
|
const auto &events = segment->log->events; |
|
|
|
const auto &events = cur_segment->log->events; |
|
|
|
|
|
|
|
route_start_ts_ = events.front().mono_time; |
|
|
|
route_start_ts_ = events.front().mono_time; |
|
|
|
cur_mono_time_ += route_start_ts_ - 1; |
|
|
|
cur_mono_time_ += route_start_ts_ - 1; |
|
|
|
|
|
|
|
|
|
|
@ -212,7 +198,7 @@ void Replay::startStream() { |
|
|
|
if (!hasFlag(REPLAY_FLAG_NO_VIPC)) { |
|
|
|
if (!hasFlag(REPLAY_FLAG_NO_VIPC)) { |
|
|
|
std::pair<int, int> camera_size[MAX_CAMERAS] = {}; |
|
|
|
std::pair<int, int> camera_size[MAX_CAMERAS] = {}; |
|
|
|
for (auto type : ALL_CAMERAS) { |
|
|
|
for (auto type : ALL_CAMERAS) { |
|
|
|
if (auto &fr = cur_segment->frames[type]) { |
|
|
|
if (auto &fr = segment->frames[type]) { |
|
|
|
camera_size[type] = {fr->width, fr->height}; |
|
|
|
camera_size[type] = {fr->width, fr->height}; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -271,6 +257,7 @@ void Replay::streamThread() { |
|
|
|
stream_cv_.wait(lk, [this]() { return exit_ || (events_ready_ && !interrupt_requested_); }); |
|
|
|
stream_cv_.wait(lk, [this]() { return exit_ || (events_ready_ && !interrupt_requested_); }); |
|
|
|
if (exit_) break; |
|
|
|
if (exit_) break; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
event_data_ = seg_mgr_->getEventData(); |
|
|
|
const auto &events = event_data_->events; |
|
|
|
const auto &events = event_data_->events; |
|
|
|
auto first = std::upper_bound(events.cbegin(), events.cend(), Event(cur_which, cur_mono_time_, {})); |
|
|
|
auto first = std::upper_bound(events.cbegin(), events.cend(), Event(cur_which, cur_mono_time_, {})); |
|
|
|
if (first == events.cend()) { |
|
|
|
if (first == events.cend()) { |
|
|
@ -308,11 +295,11 @@ std::vector<Event>::const_iterator Replay::publishEvents(std::vector<Event>::con |
|
|
|
|
|
|
|
|
|
|
|
for (; !interrupt_requested_ && first != last; ++first) { |
|
|
|
for (; !interrupt_requested_ && first != last; ++first) { |
|
|
|
const Event &evt = *first; |
|
|
|
const Event &evt = *first; |
|
|
|
int segment = toSeconds(evt.mono_time) / 60; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (current_segment_ != segment) { |
|
|
|
int segment = toSeconds(evt.mono_time) / 60; |
|
|
|
current_segment_ = segment; |
|
|
|
if (current_segment_.load(std::memory_order_relaxed) != segment) { |
|
|
|
seg_mgr_->setCurrentSegment(current_segment_); |
|
|
|
current_segment_.store(segment, std::memory_order_relaxed); |
|
|
|
|
|
|
|
seg_mgr_->setCurrentSegment(segment); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Skip events if socket is not present
|
|
|
|
// Skip events if socket is not present
|
|
|
|