mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-07-12 21:02:13 +08:00
logg
This commit is contained in:
@@ -31,7 +31,7 @@ void logger_rotate(LoggerdState *s) {
|
||||
|
||||
void rotate_if_needed(LoggerdState *s) {
|
||||
// all encoders ready, trigger rotation
|
||||
bool all_ready = s->ready_to_rotate == s->max_waiting;
|
||||
bool all_ready = s->max_waiting > 0 && s->ready_to_rotate == s->max_waiting;
|
||||
|
||||
// fallback logic to prevent extremely long segments in the case of camera, encoder, etc. malfunctions
|
||||
bool timed_out = false;
|
||||
@@ -53,6 +53,22 @@ void rotate_if_needed(LoggerdState *s) {
|
||||
}
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
int get_expected_encoder_count(const LogCameraInfo (&cameras)[N]) {
|
||||
const auto streams = VisionIpcClient::getAvailableStreams("camerad", false);
|
||||
if (streams.empty()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
for (const auto &cam : cameras) {
|
||||
if (streams.count(cam.stream_type) > 0) {
|
||||
count += cam.encoder_infos.size();
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
struct RemoteEncoder {
|
||||
std::unique_ptr<VideoWriter> writer;
|
||||
int encoderd_segment_offset;
|
||||
@@ -262,9 +278,9 @@ void loggerd_thread() {
|
||||
for (const auto &cam : cameras_logged) {
|
||||
for (const auto &encoder_info : cam.encoder_infos) {
|
||||
encoder_infos_dict[encoder_info.publish_name] = encoder_info;
|
||||
s.max_waiting++;
|
||||
}
|
||||
}
|
||||
s.max_waiting = get_expected_encoder_count(cameras_logged);
|
||||
|
||||
for (auto &[sock, service] : service_state) {
|
||||
auto it = encoder_infos_dict.find(service.name);
|
||||
@@ -305,6 +321,9 @@ void loggerd_thread() {
|
||||
}
|
||||
|
||||
if (service.encoder) {
|
||||
if (s.max_waiting == 0) {
|
||||
s.max_waiting = get_expected_encoder_count(cameras_logged);
|
||||
}
|
||||
s.last_camera_seen_tms = millis_since_boot();
|
||||
bytes_count += handle_encoder_msg(&s, msg, service.name, remote_encoders[sock], encoder_infos_dict[service.name]);
|
||||
} else {
|
||||
|
||||
@@ -97,12 +97,12 @@ class TestLoggerd:
|
||||
|
||||
return sent_msgs
|
||||
|
||||
def _publish_camera_and_audio_messages(self, num_segs=1, segment_length=5):
|
||||
def _publish_camera_and_audio_messages(self, num_segs=1, segment_length=5, streams=None):
|
||||
# Use small frame sizes for testing (width, height, size, stride, uv_offset)
|
||||
# NV12 format: size = stride * height * 1.5, uv_offset = stride * height
|
||||
w, h = 320, 240
|
||||
frame_spec = (w, h, w * h * 3 // 2, w, w * h)
|
||||
streams = [
|
||||
streams = streams or [
|
||||
(VisionStreamType.VISION_STREAM_ROAD, frame_spec, "roadCameraState"),
|
||||
(VisionStreamType.VISION_STREAM_DRIVER, frame_spec, "driverCameraState"),
|
||||
(VisionStreamType.VISION_STREAM_WIDE_ROAD, frame_spec, "wideRoadCameraState"),
|
||||
@@ -204,6 +204,30 @@ class TestLoggerd:
|
||||
diff = logged ^ expected_files
|
||||
assert len(diff) == 0, f"didn't get all expected files. seg={n} {route_path=}, {diff=}\n{logged=} {expected_files=}"
|
||||
|
||||
@pytest.mark.xdist_group("camera_encoder_tests")
|
||||
def test_rotation_without_wide_camera(self):
|
||||
Params().put("RecordFront", True)
|
||||
|
||||
w, h = 320, 240
|
||||
frame_spec = (w, h, w * h * 3 // 2, w, w * h)
|
||||
streams = [
|
||||
(VisionStreamType.VISION_STREAM_ROAD, frame_spec, "roadCameraState"),
|
||||
(VisionStreamType.VISION_STREAM_DRIVER, frame_spec, "driverCameraState"),
|
||||
]
|
||||
expected_files = {"rlog.zst", "qlog.zst", "qcamera.ts", "fcamera.hevc", "dcamera.hevc"}
|
||||
|
||||
num_segs = random.randint(2, 3)
|
||||
length = random.randint(4, 5)
|
||||
|
||||
self._publish_camera_and_audio_messages(num_segs=num_segs, segment_length=length, streams=streams)
|
||||
|
||||
route_path = str(self._get_latest_log_dir()).rsplit("--", 1)[0]
|
||||
for n in range(num_segs):
|
||||
p = Path(f"{route_path}--{n}")
|
||||
logged = {f.name for f in p.iterdir() if f.is_file()}
|
||||
diff = logged ^ expected_files
|
||||
assert len(diff) == 0, f"unexpected files without wide camera. seg={n} {route_path=}, {diff=}\n{logged=} {expected_files=}"
|
||||
|
||||
def test_bootlog(self):
|
||||
# generate bootlog with fake launch log
|
||||
launch_log = ''.join(str(random.choice(string.printable)) for _ in range(100))
|
||||
|
||||
Reference in New Issue
Block a user