Encoderd: give every camera stream list of encoder streams (#28480)

* Compiles

* fixed something

* CLEANUP

* todo

* More cleanup

* Add TODO

* Update loggerd.cc

* remove write here too
pull/28508/head
Harald Schäfer 2 years ago committed by GitHub
parent d8f677c5eb
commit ac45b77d3b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      system/loggerd/encoder/encoder.cc
  2. 7
      system/loggerd/encoder/encoder.h
  3. 6
      system/loggerd/encoder/ffmpeg_encoder.h
  4. 4
      system/loggerd/encoder/v4l_encoder.h
  5. 23
      system/loggerd/encoderd.cc
  6. 26
      system/loggerd/loggerd.cc
  7. 103
      system/loggerd/loggerd.h

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

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

@ -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);

@ -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);

@ -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<Encoder *> 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;

@ -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>((capnp::word *)msg->getData(), msg->getSize() / sizeof(capnp::word)));
auto event = cmsg.getRoot<cereal::Event>();
// 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<std::string, EncoderInfo> 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();

@ -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<EncoderInfo> 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 LogCameraInfo qcam_info = {
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 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};

Loading…
Cancel
Save