|
|
|
@ -42,7 +42,6 @@ namespace { |
|
|
|
|
|
|
|
|
|
constexpr int MAIN_FPS = 20; |
|
|
|
|
const int MAIN_BITRATE = Hardware::TICI() ? 10000000 : 5000000; |
|
|
|
|
const int MAX_CAM_IDX = Hardware::TICI() ? LOG_CAMERA_ID_ECAMERA : LOG_CAMERA_ID_DCAMERA; |
|
|
|
|
const int DCAM_BITRATE = Hardware::TICI() ? MAIN_BITRATE : 2500000; |
|
|
|
|
|
|
|
|
|
#define NO_CAMERA_PATIENCE 500 // fall back to time-based rotation if all cameras are dead
|
|
|
|
@ -51,8 +50,9 @@ const int SEGMENT_LENGTH = getenv("LOGGERD_TEST") ? atoi(getenv("LOGGERD_SEGMENT |
|
|
|
|
|
|
|
|
|
ExitHandler do_exit; |
|
|
|
|
|
|
|
|
|
LogCameraInfo cameras_logged[LOG_CAMERA_ID_MAX] = { |
|
|
|
|
[LOG_CAMERA_ID_FCAMERA] = { |
|
|
|
|
const LogCameraInfo cameras_logged[] = { |
|
|
|
|
{ |
|
|
|
|
.type = RoadCam, |
|
|
|
|
.stream_type = VISION_STREAM_YUV_BACK, |
|
|
|
|
.filename = "fcamera.hevc", |
|
|
|
|
.frame_packet_name = "roadCameraState", |
|
|
|
@ -61,9 +61,11 @@ LogCameraInfo cameras_logged[LOG_CAMERA_ID_MAX] = { |
|
|
|
|
.is_h265 = true, |
|
|
|
|
.downscale = false, |
|
|
|
|
.has_qcamera = true, |
|
|
|
|
.trigger_rotate = true |
|
|
|
|
.trigger_rotate = true, |
|
|
|
|
.enable = true, |
|
|
|
|
}, |
|
|
|
|
[LOG_CAMERA_ID_DCAMERA] = { |
|
|
|
|
{ |
|
|
|
|
.type = DriverCam, |
|
|
|
|
.stream_type = VISION_STREAM_YUV_FRONT, |
|
|
|
|
.filename = "dcamera.hevc", |
|
|
|
|
.frame_packet_name = "driverCameraState", |
|
|
|
@ -73,8 +75,10 @@ LogCameraInfo cameras_logged[LOG_CAMERA_ID_MAX] = { |
|
|
|
|
.downscale = false, |
|
|
|
|
.has_qcamera = false, |
|
|
|
|
.trigger_rotate = Hardware::TICI(), |
|
|
|
|
.enable = !Hardware::PC() && Params().getBool("RecordFront"), |
|
|
|
|
}, |
|
|
|
|
[LOG_CAMERA_ID_ECAMERA] = { |
|
|
|
|
{ |
|
|
|
|
.type = WideRoadCam, |
|
|
|
|
.stream_type = VISION_STREAM_YUV_WIDE, |
|
|
|
|
.filename = "ecamera.hevc", |
|
|
|
|
.frame_packet_name = "wideRoadCameraState", |
|
|
|
@ -83,18 +87,19 @@ LogCameraInfo cameras_logged[LOG_CAMERA_ID_MAX] = { |
|
|
|
|
.is_h265 = true, |
|
|
|
|
.downscale = false, |
|
|
|
|
.has_qcamera = false, |
|
|
|
|
.trigger_rotate = true |
|
|
|
|
}, |
|
|
|
|
[LOG_CAMERA_ID_QCAMERA] = { |
|
|
|
|
.filename = "qcamera.ts", |
|
|
|
|
.fps = MAIN_FPS, |
|
|
|
|
.bitrate = 256000, |
|
|
|
|
.is_h265 = false, |
|
|
|
|
.downscale = true, |
|
|
|
|
.frame_width = Hardware::TICI() ? 526 : 480, |
|
|
|
|
.frame_height = Hardware::TICI() ? 330 : 360 // keep pixel count the same?
|
|
|
|
|
.trigger_rotate = true, |
|
|
|
|
.enable = Hardware::TICI(), |
|
|
|
|
}, |
|
|
|
|
}; |
|
|
|
|
const LogCameraInfo qcam_info = { |
|
|
|
|
.filename = "qcamera.ts", |
|
|
|
|
.fps = MAIN_FPS, |
|
|
|
|
.bitrate = 256000, |
|
|
|
|
.is_h265 = false, |
|
|
|
|
.downscale = true, |
|
|
|
|
.frame_width = Hardware::TICI() ? 526 : 480, |
|
|
|
|
.frame_height = Hardware::TICI() ? 330 : 360 // keep pixel count the same?
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
struct LoggerdState { |
|
|
|
|
Context *ctx; |
|
|
|
@ -110,9 +115,7 @@ struct LoggerdState { |
|
|
|
|
}; |
|
|
|
|
LoggerdState s; |
|
|
|
|
|
|
|
|
|
void encoder_thread(int cam_idx) { |
|
|
|
|
assert(cam_idx < LOG_CAMERA_ID_MAX-1); |
|
|
|
|
const LogCameraInfo &cam_info = cameras_logged[cam_idx]; |
|
|
|
|
void encoder_thread(const LogCameraInfo &cam_info) { |
|
|
|
|
set_thread_name(cam_info.filename); |
|
|
|
|
|
|
|
|
|
int cnt = 0, cur_seg = -1; |
|
|
|
@ -135,12 +138,9 @@ void encoder_thread(int cam_idx) { |
|
|
|
|
// main encoder
|
|
|
|
|
encoders.push_back(new Encoder(cam_info.filename, buf_info.width, buf_info.height, |
|
|
|
|
cam_info.fps, cam_info.bitrate, cam_info.is_h265, cam_info.downscale)); |
|
|
|
|
|
|
|
|
|
// qcamera encoder
|
|
|
|
|
if (cam_info.has_qcamera) { |
|
|
|
|
LogCameraInfo &qcam_info = cameras_logged[LOG_CAMERA_ID_QCAMERA]; |
|
|
|
|
encoders.push_back(new Encoder(qcam_info.filename, |
|
|
|
|
qcam_info.frame_width, qcam_info.frame_height, |
|
|
|
|
encoders.push_back(new Encoder(qcam_info.filename, qcam_info.frame_width, qcam_info.frame_height, |
|
|
|
|
qcam_info.fps, qcam_info.bitrate, qcam_info.is_h265, qcam_info.downscale)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -167,7 +167,7 @@ void encoder_thread(int cam_idx) { |
|
|
|
|
cur_seg = s.rotate_segment; |
|
|
|
|
cnt = 0; |
|
|
|
|
|
|
|
|
|
LOGW("camera %d rotate encoder to %s", cam_idx, s.segment_path); |
|
|
|
|
LOGW("camera %d rotate encoder to %s", cam_info.type, s.segment_path); |
|
|
|
|
for (auto &e : encoders) { |
|
|
|
|
e->encoder_close(); |
|
|
|
|
e->encoder_open(s.segment_path); |
|
|
|
@ -191,15 +191,15 @@ void encoder_thread(int cam_idx) { |
|
|
|
|
if (i == 0 && out_id != -1) { |
|
|
|
|
MessageBuilder msg; |
|
|
|
|
// this is really ugly
|
|
|
|
|
auto eidx = cam_idx == LOG_CAMERA_ID_DCAMERA ? msg.initEvent().initDriverEncodeIdx() : |
|
|
|
|
(cam_idx == LOG_CAMERA_ID_ECAMERA ? msg.initEvent().initWideRoadEncodeIdx() : msg.initEvent().initRoadEncodeIdx()); |
|
|
|
|
auto eidx = cam_info.type == DriverCam ? msg.initEvent().initDriverEncodeIdx() : |
|
|
|
|
(cam_info.type == WideRoadCam ? msg.initEvent().initWideRoadEncodeIdx() : msg.initEvent().initRoadEncodeIdx()); |
|
|
|
|
eidx.setFrameId(extra.frame_id); |
|
|
|
|
eidx.setTimestampSof(extra.timestamp_sof); |
|
|
|
|
eidx.setTimestampEof(extra.timestamp_eof); |
|
|
|
|
if (Hardware::TICI()) { |
|
|
|
|
eidx.setType(cereal::EncodeIndex::Type::FULL_H_E_V_C); |
|
|
|
|
} else { |
|
|
|
|
eidx.setType(cam_idx == LOG_CAMERA_ID_DCAMERA ? cereal::EncodeIndex::Type::FRONT : cereal::EncodeIndex::Type::FULL_H_E_V_C); |
|
|
|
|
eidx.setType(cam_info.type == DriverCam ? cereal::EncodeIndex::Type::FRONT : cereal::EncodeIndex::Type::FULL_H_E_V_C); |
|
|
|
|
} |
|
|
|
|
eidx.setEncodeId(encode_idx); |
|
|
|
|
eidx.setSegmentNum(cur_seg); |
|
|
|
@ -294,32 +294,18 @@ int main(int argc, char** argv) { |
|
|
|
|
qlog_states[sock] = {.counter = 0, .freq = it.decimation}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Params params; |
|
|
|
|
|
|
|
|
|
// init logger
|
|
|
|
|
logger_init(&s.logger, "rlog", true); |
|
|
|
|
logger_rotate(); |
|
|
|
|
params.put("CurrentRoute", s.logger.route_name); |
|
|
|
|
Params().put("CurrentRoute", s.logger.route_name); |
|
|
|
|
|
|
|
|
|
// init encoders
|
|
|
|
|
s.last_camera_seen_tms = millis_since_boot(); |
|
|
|
|
// TODO: create these threads dynamically on frame packet presence
|
|
|
|
|
std::vector<std::thread> encoder_threads; |
|
|
|
|
encoder_threads.push_back(std::thread(encoder_thread, LOG_CAMERA_ID_FCAMERA)); |
|
|
|
|
if (cameras_logged[LOG_CAMERA_ID_FCAMERA].trigger_rotate) { |
|
|
|
|
s.max_waiting += 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!Hardware::PC() && params.getBool("RecordFront")) { |
|
|
|
|
encoder_threads.push_back(std::thread(encoder_thread, LOG_CAMERA_ID_DCAMERA)); |
|
|
|
|
if (cameras_logged[LOG_CAMERA_ID_DCAMERA].trigger_rotate) { |
|
|
|
|
s.max_waiting += 1; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (Hardware::TICI()) { |
|
|
|
|
encoder_threads.push_back(std::thread(encoder_thread, LOG_CAMERA_ID_ECAMERA)); |
|
|
|
|
if (cameras_logged[LOG_CAMERA_ID_ECAMERA].trigger_rotate) { |
|
|
|
|
s.max_waiting += 1; |
|
|
|
|
for (const auto &ci : cameras_logged) { |
|
|
|
|
if (ci.enable) { |
|
|
|
|
encoder_threads.push_back(std::thread(encoder_thread, ci)); |
|
|
|
|
if (ci.trigger_rotate) s.max_waiting++; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|