diff --git a/system/loggerd/encoder/encoder.cc b/system/loggerd/encoder/encoder.cc index 377e48d001..7ac2948861 100644 --- a/system/loggerd/encoder/encoder.cc +++ b/system/loggerd/encoder/encoder.cc @@ -5,9 +5,7 @@ VideoEncoder::~VideoEncoder() {} void VideoEncoder::publisher_init() { // publish - service_name = this->type == DriverCam ? "driverEncodeData" : - (this->type == WideRoadCam ? "wideRoadEncodeData" : - (this->in_width == this->out_width ? "roadEncodeData" : "qRoadEncodeData")); + service_name = this->publish_name; pm.reset(new PubMaster({service_name})); } diff --git a/system/loggerd/encoder/encoder.h b/system/loggerd/encoder/encoder.h index 564af625a1..9ea6b884cf 100644 --- a/system/loggerd/encoder/encoder.h +++ b/system/loggerd/encoder/encoder.h @@ -14,9 +14,11 @@ class VideoEncoder { public: VideoEncoder(const char* filename, CameraType type, int in_width, int in_height, int fps, - int bitrate, cereal::EncodeIndex::Type codec, int out_width, int out_height) + int bitrate, cereal::EncodeIndex::Type codec, int out_width, int out_height, + const char* publish_name) : filename(filename), type(type), in_width(in_width), in_height(in_height), fps(fps), - bitrate(bitrate), codec(codec), out_width(out_width), out_height(out_height) { } + bitrate(bitrate), codec(codec), out_width(out_width), out_height(out_height), + publish_name(publish_name) { } virtual ~VideoEncoder(); virtual int encode_frame(VisionBuf* buf, VisionIpcBufExtra *extra) = 0; virtual void encoder_open(const char* path) = 0; @@ -28,6 +30,7 @@ public: protected: const char* filename; + const char* publish_name; int in_width, in_height; int out_width, out_height, fps; int bitrate; diff --git a/system/loggerd/encoder/ffmpeg_encoder.h b/system/loggerd/encoder/ffmpeg_encoder.h index 1ba991f09b..6b4b6e104c 100644 --- a/system/loggerd/encoder/ffmpeg_encoder.h +++ b/system/loggerd/encoder/ffmpeg_encoder.h @@ -17,8 +17,10 @@ extern "C" { class FfmpegEncoder : public VideoEncoder { public: FfmpegEncoder(const char* filename, CameraType type, int in_width, int in_height, int fps, - int bitrate, cereal::EncodeIndex::Type codec, int out_width, int out_height) : - VideoEncoder(filename, type, in_width, in_height, fps, bitrate, cereal::EncodeIndex::Type::BIG_BOX_LOSSLESS, out_width, out_height) { encoder_init(); } + + int bitrate, cereal::EncodeIndex::Type codec, int out_width, int out_height, + const char* publish_name) : + VideoEncoder(filename, type, in_width, in_height, fps, bitrate, cereal::EncodeIndex::Type::BIG_BOX_LOSSLESS, out_width, out_height, publish_name) { encoder_init(); } ~FfmpegEncoder(); void encoder_init(); int encode_frame(VisionBuf* buf, VisionIpcBufExtra *extra); diff --git a/system/loggerd/encoder/v4l_encoder.h b/system/loggerd/encoder/v4l_encoder.h index 1016c0f5c6..b0af4039fe 100644 --- a/system/loggerd/encoder/v4l_encoder.h +++ b/system/loggerd/encoder/v4l_encoder.h @@ -9,8 +9,8 @@ class V4LEncoder : public VideoEncoder { public: V4LEncoder(const char* filename, CameraType type, int in_width, int in_height, int fps, - int bitrate, cereal::EncodeIndex::Type codec, int out_width, int out_height) : - VideoEncoder(filename, type, in_width, in_height, fps, bitrate, codec, out_width, out_height) { encoder_init(); } + int bitrate, cereal::EncodeIndex::Type codec, int out_width, int out_height, const char* publish_name) : + VideoEncoder(filename, type, in_width, in_height, fps, bitrate, codec, out_width, out_height, publish_name) { encoder_init(); } ~V4LEncoder(); void encoder_init(); int encode_frame(VisionBuf* buf, VisionIpcBufExtra *extra); diff --git a/system/loggerd/encoderd.cc b/system/loggerd/encoderd.cc index 45120ec334..24d4dad2d9 100644 --- a/system/loggerd/encoderd.cc +++ b/system/loggerd/encoderd.cc @@ -35,7 +35,7 @@ bool sync_encoders(EncoderdState *s, CameraType cam_type, uint32_t frame_id) { void encoder_thread(EncoderdState *s, const LogCameraInfo &cam_info) { - util::set_thread_name(cam_info.filename); + util::set_thread_name(cam_info.encoder_infos[0].filename); std::vector encoders; VisionIpcClient vipc_client = VisionIpcClient("camerad", cam_info.stream_type, false); @@ -50,20 +50,15 @@ void encoder_thread(EncoderdState *s, const LogCameraInfo &cam_info) { // init encoders if (encoders.empty()) { VisionBuf buf_info = vipc_client.buffers[0]; - LOGW("encoder %s init %dx%d", cam_info.filename, buf_info.width, buf_info.height); + LOGW("encoder %s init %dx%d", cam_info.encoder_infos[0].filename, buf_info.width, buf_info.height); if (buf_info.width > 0 && buf_info.height > 0) { - // main encoder - encoders.push_back(new Encoder(cam_info.filename, cam_info.type, buf_info.width, buf_info.height, - cam_info.fps, cam_info.bitrate, - cam_info.is_h265 ? cereal::EncodeIndex::Type::FULL_H_E_V_C : cereal::EncodeIndex::Type::QCAMERA_H264, - buf_info.width, buf_info.height)); - // qcamera encoder - if (cam_info.has_qcamera) { - encoders.push_back(new Encoder(qcam_info.filename, cam_info.type, buf_info.width, buf_info.height, - qcam_info.fps, qcam_info.bitrate, - qcam_info.is_h265 ? cereal::EncodeIndex::Type::FULL_H_E_V_C : cereal::EncodeIndex::Type::QCAMERA_H264, - qcam_info.frame_width, qcam_info.frame_height)); + for (const auto &encoder_info: cam_info.encoder_infos){ + encoders.push_back(new Encoder(encoder_info.filename, cam_info.type, buf_info.width, buf_info.height, + encoder_info.fps, encoder_info.bitrate, + encoder_info.encode_type, + encoder_info.frame_width, encoder_info.frame_height, + encoder_info.publish_name)); } } else { LOGE("not initting empty encoder"); @@ -85,7 +80,7 @@ void encoder_thread(EncoderdState *s, const LogCameraInfo &cam_info) { // detect loop around and drop the frames if (buf->get_frame_id() != extra.frame_id) { if (!lagging) { - LOGE("encoder %s lag buffer id: %d extra id: %d", cam_info.filename, buf->get_frame_id(), extra.frame_id); + LOGE("encoder %s lag buffer id: %d extra id: %d", cam_info.encoder_infos[0].filename, buf->get_frame_id(), extra.frame_id); lagging = true; } continue; diff --git a/system/loggerd/loggerd.cc b/system/loggerd/loggerd.cc index a7f7db4801..dbda432192 100644 --- a/system/loggerd/loggerd.cc +++ b/system/loggerd/loggerd.cc @@ -58,15 +58,13 @@ struct RemoteEncoder { bool seen_first_packet = false; }; -int handle_encoder_msg(LoggerdState *s, Message *msg, std::string &name, struct RemoteEncoder &re) { - const LogCameraInfo &cam_info = (name == "driverEncodeData") ? cameras_logged[1] : - ((name == "wideRoadEncodeData") ? cameras_logged[2] : - ((name == "qRoadEncodeData") ? qcam_info : cameras_logged[0])); +int handle_encoder_msg(LoggerdState *s, Message *msg, std::string &name, struct RemoteEncoder &re, EncoderInfo encoder_info) { int bytes_count = 0; // extract the message capnp::FlatArrayMessageReader cmsg(kj::ArrayPtr((capnp::word *)msg->getData(), msg->getSize() / sizeof(capnp::word))); auto event = cmsg.getRoot(); + // TODO this should be dealt with generically auto edata = (name == "driverEncodeData") ? event.getDriverEncodeData() : ((name == "wideRoadEncodeData") ? event.getWideRoadEncodeData() : ((name == "qRoadEncodeData") ? event.getQRoadEncodeData() : event.getRoadEncodeData())); @@ -95,7 +93,7 @@ int handle_encoder_msg(LoggerdState *s, Message *msg, std::string &name, struct // we are in this segment now, process any queued messages before this one if (!re.q.empty()) { for (auto &qmsg: re.q) { - bytes_count += handle_encoder_msg(s, qmsg, name, re); + bytes_count += handle_encoder_msg(s, qmsg, name, re, encoder_info); } re.q.clear(); } @@ -111,10 +109,10 @@ int handle_encoder_msg(LoggerdState *s, Message *msg, std::string &name, struct re.dropped_frames = 0; } // if we aren't actually recording, don't create the writer - if (cam_info.record) { + if (encoder_info.record) { re.writer.reset(new VideoWriter(s->segment_path, - cam_info.filename, idx.getType() != cereal::EncodeIndex::Type::FULL_H_E_V_C, - cam_info.frame_width, cam_info.frame_height, cam_info.fps, idx.getType())); + encoder_info.filename, idx.getType() != cereal::EncodeIndex::Type::FULL_H_E_V_C, + encoder_info.frame_width, encoder_info.frame_height, encoder_info.fps, idx.getType())); // write the header auto header = edata.getHeader(); re.writer->write((uint8_t *)header.begin(), header.size(), idx.getTimestampEof()/1000, true, false); @@ -142,6 +140,7 @@ int handle_encoder_msg(LoggerdState *s, Message *msg, std::string &name, struct MessageBuilder bmsg; auto evt = bmsg.initEvent(event.getValid()); evt.setLogMonoTime(event.getLogMonoTime()); + // TODO this should be dealt with generically if (name == "driverEncodeData") { evt.setDriverEncodeIdx(idx); } if (name == "wideRoadEncodeData") { evt.setWideRoadEncodeIdx(idx); } if (name == "qRoadEncodeData") { evt.setQRoadEncodeIdx(idx); } @@ -211,11 +210,12 @@ void loggerd_thread() { logger_rotate(&s); Params().put("CurrentRoute", s.logger.route_name); - // init encoders - s.last_camera_seen_tms = millis_since_boot(); + std::map encoder_infos_dict; for (const auto &cam : cameras_logged) { - s.max_waiting++; - if (cam.has_qcamera) { s.max_waiting++; } + for (const auto &encoder_info: cam.encoder_infos) { + encoder_infos_dict[encoder_info.publish_name] = encoder_info; + s.max_waiting++; + } } uint64_t msg_count = 0, bytes_count = 0; @@ -234,7 +234,7 @@ void loggerd_thread() { if (qs.encoder) { s.last_camera_seen_tms = millis_since_boot(); - bytes_count += handle_encoder_msg(&s, msg, qs.name, remote_encoders[sock]); + bytes_count += handle_encoder_msg(&s, msg, qs.name, remote_encoders[sock], encoder_infos_dict[qs.name]); } else { logger_log(&s.logger, (uint8_t *)msg->getData(), msg->getSize(), in_qlog); bytes_count += msg->getSize(); diff --git a/system/loggerd/loggerd.h b/system/loggerd/loggerd.h index 1b8f9e0d2a..01aa5b434c 100644 --- a/system/loggerd/loggerd.h +++ b/system/loggerd/loggerd.h @@ -42,62 +42,67 @@ const int DCAM_BITRATE = MAIN_BITRATE; const bool LOGGERD_TEST = getenv("LOGGERD_TEST"); const int SEGMENT_LENGTH = LOGGERD_TEST ? atoi(getenv("LOGGERD_SEGMENT_LENGTH")) : 60; -struct LogCameraInfo { - CameraType type; +class EncoderInfo { +public: + const char *publish_name; const char *filename; + bool record = true; + int frame_width = 1928; + int frame_height = 1208; + int fps = MAIN_FPS; + int bitrate = MAIN_BITRATE; + cereal::EncodeIndex::Type encode_type = cereal::EncodeIndex::Type::FULL_H_E_V_C; +}; + +class LogCameraInfo { +public: + int fps = MAIN_FPS; + CameraType type; VisionStreamType stream_type; - int frame_width, frame_height; - int fps; - int bitrate; - bool is_h265; - bool has_qcamera; - bool record; + std::vector encoder_infos; }; -const LogCameraInfo cameras_logged[] = { - { - .type = RoadCam, - .stream_type = VISION_STREAM_ROAD, - .filename = "fcamera.hevc", - .fps = MAIN_FPS, - .bitrate = MAIN_BITRATE, - .is_h265 = true, - .has_qcamera = true, - .record = true, - .frame_width = 1928, - .frame_height = 1208, - }, - { - .type = DriverCam, - .stream_type = VISION_STREAM_DRIVER, - .filename = "dcamera.hevc", - .fps = MAIN_FPS, - .bitrate = DCAM_BITRATE, - .is_h265 = true, - .has_qcamera = false, - .record = Params().getBool("RecordFront"), - .frame_width = 1928, - .frame_height = 1208, - }, - { - .type = WideRoadCam, - .stream_type = VISION_STREAM_WIDE_ROAD, - .filename = "ecamera.hevc", - .fps = MAIN_FPS, - .bitrate = MAIN_BITRATE, - .is_h265 = true, - .has_qcamera = false, - .record = true, - .frame_width = 1928, - .frame_height = 1208, - }, +const EncoderInfo main_road_encoder_info = { + .publish_name = "roadEncodeData", + .filename = "fcamera.hevc", +}; +const EncoderInfo main_wide_road_encoder_info = { + .publish_name = "wideRoadEncodeData", + .filename = "ecamera.hevc", +}; +const EncoderInfo main_driver_encoder_info = { + .publish_name = "driverEncodeData", + .filename = "dcamera.hevc", + .record = Params().getBool("RecordFront"), }; -const LogCameraInfo qcam_info = { + +const EncoderInfo qcam_encoder_info = { + .publish_name = "qRoadEncodeData", .filename = "qcamera.ts", - .fps = MAIN_FPS, .bitrate = 256000, - .is_h265 = false, - .record = true, + .encode_type = cereal::EncodeIndex::Type::QCAMERA_H264, .frame_width = 526, .frame_height = 330, }; + + +const LogCameraInfo road_camera_info{ + .type = RoadCam, + .stream_type = VISION_STREAM_ROAD, + .encoder_infos = {main_road_encoder_info, qcam_encoder_info} + }; + +const LogCameraInfo wide_road_camera_info{ + .type = WideRoadCam, + .stream_type = VISION_STREAM_WIDE_ROAD, + .encoder_infos = {main_wide_road_encoder_info} + }; + +const LogCameraInfo driver_camera_info{ + .type = DriverCam, + .stream_type = VISION_STREAM_DRIVER, + .encoder_infos = {main_driver_encoder_info} + }; + +const LogCameraInfo cameras_logged[] = {road_camera_info, wide_road_camera_info, driver_camera_info}; +