|  |  |  | @ -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++; | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | 
 |