loggerd/encoder: refactor constructors to take EncoderInfo as parameter (#28921)

* refactor constructors to take EncoderInfo as parameter

* remove last arg codec

* use macro to init function pointers
old-commit-hash: 713d2ec586
beeps
Dean Lee 2 years ago committed by GitHub
parent 8f7729809d
commit b59b27e01e
  1. 11
      system/loggerd/encoder/encoder.cc
  2. 17
      system/loggerd/encoder/encoder.h
  3. 18
      system/loggerd/encoder/ffmpeg_encoder.cc
  4. 9
      system/loggerd/encoder/ffmpeg_encoder.h
  5. 16
      system/loggerd/encoder/v4l_encoder.cc
  6. 5
      system/loggerd/encoder/v4l_encoder.h
  7. 14
      system/loggerd/encoderd.cc
  8. 3
      system/loggerd/loggerd.cc
  9. 50
      system/loggerd/loggerd.h

@ -5,8 +5,7 @@ VideoEncoder::~VideoEncoder() {}
void VideoEncoder::publisher_init() {
// publish
service_name = this->publish_name;
pm.reset(new PubMaster({service_name}));
pm.reset(new PubMaster({encoder_info.publish_name}));
}
void VideoEncoder::publisher_publish(VideoEncoder *e, int segment_num, uint32_t idx, VisionIpcBufExtra &extra,
@ -14,9 +13,7 @@ void VideoEncoder::publisher_publish(VideoEncoder *e, int segment_num, uint32_t
// broadcast packet
MessageBuilder msg;
auto event = msg.initEvent(true);
auto edat = (e->type == DriverCam) ? event.initDriverEncodeData() :
((e->type == WideRoadCam) ? event.initWideRoadEncodeData() :
(e->in_width == e->out_width ? event.initRoadEncodeData() : event.initQRoadEncodeData()));
auto edat = (event.*(e->encoder_info.init_encode_data_func))();
auto edata = edat.initIdx();
struct timespec ts;
timespec_get(&ts, TIME_UTC);
@ -24,7 +21,7 @@ void VideoEncoder::publisher_publish(VideoEncoder *e, int segment_num, uint32_t
edata.setFrameId(extra.frame_id);
edata.setTimestampSof(extra.timestamp_sof);
edata.setTimestampEof(extra.timestamp_eof);
edata.setType(e->codec);
edata.setType(e->encoder_info.encode_type);
edata.setEncodeId(e->cnt++);
edata.setSegmentNum(segment_num);
edata.setSegmentId(idx);
@ -35,6 +32,6 @@ void VideoEncoder::publisher_publish(VideoEncoder *e, int segment_num, uint32_t
auto words = new kj::Array<capnp::word>(capnp::messageToFlatArray(msg));
auto bytes = words->asBytes();
e->pm->send(e->service_name, bytes.begin(), bytes.size());
e->pm->send(e->encoder_info.publish_name, bytes.begin(), bytes.size());
delete words;
}

@ -8,17 +8,14 @@
#include "cereal/visionipc/visionipc.h"
#include "common/queue.h"
#include "system/camerad/cameras/camera_common.h"
#include "system/loggerd/loggerd.h"
#define V4L2_BUF_FLAG_KEYFRAME 8
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,
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),
publish_name(publish_name) { }
VideoEncoder(const EncoderInfo &encoder_info, int in_width, int in_height)
: encoder_info(encoder_info), in_width(in_width), in_height(in_height) {}
virtual ~VideoEncoder();
virtual int encode_frame(VisionBuf* buf, VisionIpcBufExtra *extra) = 0;
virtual void encoder_open(const char* path) = 0;
@ -29,13 +26,8 @@ public:
protected:
const char* filename;
const char* publish_name;
int in_width, in_height;
int out_width, out_height, fps;
int bitrate;
cereal::EncodeIndex::Type codec;
CameraType type;
const EncoderInfo encoder_info;
private:
// total frames encoded
@ -43,5 +35,4 @@ private:
// publishing
std::unique_ptr<PubMaster> pm;
const char *service_name;
};

@ -28,16 +28,16 @@ void FfmpegEncoder::encoder_init() {
frame = av_frame_alloc();
assert(frame);
frame->format = AV_PIX_FMT_YUV420P;
frame->width = out_width;
frame->height = out_height;
frame->linesize[0] = out_width;
frame->linesize[1] = out_width/2;
frame->linesize[2] = out_width/2;
frame->width = encoder_info.frame_width;
frame->height = encoder_info.frame_height;
frame->linesize[0] = encoder_info.frame_width;
frame->linesize[1] = encoder_info.frame_width/2;
frame->linesize[2] = encoder_info.frame_width/2;
convert_buf.resize(in_width * in_height * 3 / 2);
if (in_width != out_width || in_height != out_height) {
downscale_buf.resize(out_width * out_height * 3 / 2);
if (in_width != encoder_info.frame_width || in_height != encoder_info.frame_height) {
downscale_buf.resize(encoder_info.frame_width * encoder_info.frame_height * 3 / 2);
}
publisher_init();
@ -56,7 +56,7 @@ void FfmpegEncoder::encoder_open(const char* path) {
this->codec_ctx->width = frame->width;
this->codec_ctx->height = frame->height;
this->codec_ctx->pix_fmt = AV_PIX_FMT_YUV420P;
this->codec_ctx->time_base = (AVRational){ 1, fps };
this->codec_ctx->time_base = (AVRational){ 1, encoder_info.fps };
int err = avcodec_open2(this->codec_ctx, codec, NULL);
assert(err >= 0);
@ -136,7 +136,7 @@ int FfmpegEncoder::encode_frame(VisionBuf* buf, VisionIpcBufExtra *extra) {
}
if (env_debug_encoder) {
printf("%20s got %8d bytes flags %8x idx %4d id %8d\n", this->filename, pkt.size, pkt.flags, counter, extra->frame_id);
printf("%20s got %8d bytes flags %8x idx %4d id %8d\n", encoder_info.filename, pkt.size, pkt.flags, counter, extra->frame_id);
}
publisher_publish(this, segment_num, counter, *extra,

@ -15,12 +15,9 @@ extern "C" {
#include "system/loggerd/loggerd.h"
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,
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(); }
public:
FfmpegEncoder(const EncoderInfo &encoder_info, int in_width, int in_height)
: VideoEncoder(encoder_info, in_width, in_height) { encoder_init(); }
~FfmpegEncoder();
void encoder_init();
int encode_frame(VisionBuf* buf, VisionIpcBufExtra *extra);

@ -68,7 +68,7 @@ static void request_buffers(int fd, v4l2_buf_type buf_type, unsigned int count)
}
void V4LEncoder::dequeue_handler(V4LEncoder *e) {
std::string dequeue_thread_name = "dq-"+std::string(e->filename);
std::string dequeue_thread_name = "dq-"+std::string(e->encoder_info.filename);
util::set_thread_name(dequeue_thread_name.c_str());
e->segment_num++;
@ -88,7 +88,7 @@ void V4LEncoder::dequeue_handler(V4LEncoder *e) {
if (!rc) { LOGE("encoder dequeue poll timeout"); continue; }
if (env_debug_encoder >= 2) {
printf("%20s poll %x at %.2f ms\n", e->filename, pfd.revents, millis_since_boot());
printf("%20s poll %x at %.2f ms\n", e->encoder_info.filename, pfd.revents, millis_since_boot());
}
int frame_id = -1;
@ -116,7 +116,7 @@ void V4LEncoder::dequeue_handler(V4LEncoder *e) {
if (env_debug_encoder) {
printf("%20s got(%d) %6d bytes flags %8x idx %3d/%4d id %8d ts %ld lat %.2f ms (%lu frames free)\n",
e->filename, index, bytesused, flags, e->segment_num, idx, frame_id, ts, millis_since_boot()-(ts/1000.), e->free_buf_in.size());
e->encoder_info.filename, index, bytesused, flags, e->segment_num, idx, frame_id, ts, millis_since_boot()-(ts/1000.), e->free_buf_in.size());
}
// requeue the buffer
@ -146,9 +146,9 @@ void V4LEncoder::encoder_init() {
.fmt = {
.pix_mp = {
// downscales are free with v4l
.width = (unsigned int)out_width,
.height = (unsigned int)out_height,
.pixelformat = (codec == cereal::EncodeIndex::Type::FULL_H_E_V_C) ? V4L2_PIX_FMT_HEVC : V4L2_PIX_FMT_H264,
.width = (unsigned int)encoder_info.frame_width,
.height = (unsigned int)encoder_info.frame_height,
.pixelformat = (encoder_info.encode_type == cereal::EncodeIndex::Type::FULL_H_E_V_C) ? V4L2_PIX_FMT_HEVC : V4L2_PIX_FMT_H264,
.field = V4L2_FIELD_ANY,
.colorspace = V4L2_COLORSPACE_DEFAULT,
}
@ -192,7 +192,7 @@ void V4LEncoder::encoder_init() {
{
struct v4l2_control ctrls[] = {
{ .id = V4L2_CID_MPEG_VIDEO_HEADER_MODE, .value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE},
{ .id = V4L2_CID_MPEG_VIDEO_BITRATE, .value = bitrate},
{ .id = V4L2_CID_MPEG_VIDEO_BITRATE, .value = encoder_info.bitrate},
{ .id = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL, .value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_CFR},
{ .id = V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY, .value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_DISABLE},
{ .id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD, .value = 1},
@ -202,7 +202,7 @@ void V4LEncoder::encoder_init() {
}
}
if (codec == cereal::EncodeIndex::Type::FULL_H_E_V_C) {
if (encoder_info.encode_type == cereal::EncodeIndex::Type::FULL_H_E_V_C) {
struct v4l2_control ctrls[] = {
{ .id = V4L2_CID_MPEG_VIDC_VIDEO_HEVC_PROFILE, .value = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN},
{ .id = V4L2_CID_MPEG_VIDC_VIDEO_HEVC_TIER_LEVEL, .value = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5},

@ -8,9 +8,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, const char* publish_name) :
VideoEncoder(filename, type, in_width, in_height, fps, bitrate, codec, out_width, out_height, publish_name) { encoder_init(); }
V4LEncoder(const EncoderInfo &encoder_info, int in_width, int in_height)
: VideoEncoder(encoder_info, in_width, in_height) { encoder_init(); }
~V4LEncoder();
void encoder_init();
int encode_frame(VisionBuf* buf, VisionIpcBufExtra *extra);

@ -1,5 +1,13 @@
#include "system/loggerd/loggerd.h"
#ifdef QCOM2
#include "system/loggerd/encoder/v4l_encoder.h"
#define Encoder V4LEncoder
#else
#include "system/loggerd/encoder/ffmpeg_encoder.h"
#define Encoder FfmpegEncoder
#endif
ExitHandler do_exit;
struct EncoderdState {
@ -54,11 +62,7 @@ void encoder_thread(EncoderdState *s, const LogCameraInfo &cam_info) {
if (buf_info.width > 0 && buf_info.height > 0) {
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));
encoders.push_back(new Encoder(encoder_info, buf_info.width, buf_info.height));
}
} else {
LOGE("not initting empty encoder");

@ -1,3 +1,6 @@
#include <unordered_map>
#include "system/loggerd/encoder/encoder.h"
#include "system/loggerd/loggerd.h"
#include "system/loggerd/video_writer.h"

@ -1,42 +1,25 @@
#pragma once
#include <unistd.h>
#include <atomic>
#include <cassert>
#include <cerrno>
#include <condition_variable>
#include <mutex>
#include <string>
#include <thread>
#include <unordered_map>
#include <utility>
#include "cereal/messaging/messaging.h"
#include "cereal/services.h"
#include "cereal/visionipc/visionipc.h"
#include "cereal/visionipc/visionipc_client.h"
#include "system/camerad/cameras/camera_common.h"
#include "system/hardware/hw.h"
#include "common/params.h"
#include "common/swaglog.h"
#include "common/timing.h"
#include "common/util.h"
#include "system/hardware/hw.h"
#include "system/loggerd/encoder/encoder.h"
#include "system/loggerd/logger.h"
#ifdef QCOM2
#include "system/loggerd/encoder/v4l_encoder.h"
#define Encoder V4LEncoder
#else
#include "system/loggerd/encoder/ffmpeg_encoder.h"
#define Encoder FfmpegEncoder
#endif
constexpr int MAIN_FPS = 20;
const int MAIN_BITRATE = 10000000;
#define NO_CAMERA_PATIENCE 500 // fall back to time-based rotation if all cameras are dead
#define NO_CAMERA_PATIENCE 500 // fall back to time-based rotation if all cameras are dead
#define INIT_ENCODE_FUNCTIONS(encode_type) \
.get_encode_data_func = &cereal::Event::Reader::get##encode_type##Data, \
.set_encode_idx_func = &cereal::Event::Builder::set##encode_type##Idx, \
.init_encode_data_func = &cereal::Event::Builder::init##encode_type##Data
const bool LOGGERD_TEST = getenv("LOGGERD_TEST");
const int SEGMENT_LENGTH = LOGGERD_TEST ? atoi(getenv("LOGGERD_SEGMENT_LENGTH")) : 60;
@ -50,9 +33,11 @@ public:
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;
cereal::EncodeIndex::Type encode_type = Hardware::PC() ? cereal::EncodeIndex::Type::BIG_BOX_LOSSLESS
: cereal::EncodeIndex::Type::FULL_H_E_V_C;
::cereal::EncodeData::Reader (cereal::Event::Reader::*get_encode_data_func)() const;
void (cereal::Event::Builder::*set_encode_idx_func)(::cereal::EncodeIndex::Reader);
cereal::EncodeData::Builder (cereal::Event::Builder::*init_encode_data_func)();
};
class LogCameraInfo {
@ -67,21 +52,18 @@ public:
const EncoderInfo main_road_encoder_info = {
.publish_name = "roadEncodeData",
.filename = "fcamera.hevc",
.get_encode_data_func = &cereal::Event::Reader::getRoadEncodeData,
.set_encode_idx_func = &cereal::Event::Builder::setRoadEncodeIdx,
INIT_ENCODE_FUNCTIONS(RoadEncode),
};
const EncoderInfo main_wide_road_encoder_info = {
.publish_name = "wideRoadEncodeData",
.filename = "ecamera.hevc",
.get_encode_data_func = &cereal::Event::Reader::getWideRoadEncodeData,
.set_encode_idx_func = &cereal::Event::Builder::setWideRoadEncodeIdx,
INIT_ENCODE_FUNCTIONS(WideRoadEncode),
};
const EncoderInfo main_driver_encoder_info = {
.publish_name = "driverEncodeData",
.filename = "dcamera.hevc",
.record = Params().getBool("RecordFront"),
.get_encode_data_func = &cereal::Event::Reader::getDriverEncodeData,
.set_encode_idx_func = &cereal::Event::Builder::setDriverEncodeIdx,
INIT_ENCODE_FUNCTIONS(DriverEncode),
};
const EncoderInfo qcam_encoder_info = {
@ -91,8 +73,7 @@ const EncoderInfo qcam_encoder_info = {
.encode_type = cereal::EncodeIndex::Type::QCAMERA_H264,
.frame_width = 526,
.frame_height = 330,
.get_encode_data_func = &cereal::Event::Reader::getQRoadEncodeData,
.set_encode_idx_func = &cereal::Event::Builder::setQRoadEncodeIdx,
INIT_ENCODE_FUNCTIONS(QRoadEncode),
};
@ -109,7 +90,7 @@ const LogCameraInfo wide_road_camera_info{
.stream_type = VISION_STREAM_WIDE_ROAD,
.encoder_infos = {main_wide_road_encoder_info}
};
const LogCameraInfo driver_camera_info{
.thread_name = "driver_cam_encoder",
.type = DriverCam,
@ -118,4 +99,3 @@ const LogCameraInfo driver_camera_info{
};
const LogCameraInfo cameras_logged[] = {road_camera_info, wide_road_camera_info, driver_camera_info};

Loading…
Cancel
Save