From ad522f8444b39b47acfe4c6e4c376c8dc7fbbe5a Mon Sep 17 00:00:00 2001 From: stef <19478336+stefpi@users.noreply.github.com> Date: Fri, 29 May 2026 18:00:47 -0700 Subject: [PATCH] hw encoder: set_bitrate and apply_bitrate based on Param (#38095) * initial codex * remove ISP delay from encode ms * try something simpler * not allowing increase bug * decrease bitrate increase rate * upsample only on consecutive good checks * rearrange * clean * Revert frame timing processing time change * clean * remove bitrate option and just do it on --stream * make set_bitrate a lot more simple * clean default impl * further cleaning * struct for bitrate to pass ci * refactor a bit * add comment * small clean * add init() * increase bitrate * update ffmpeg message * remove unnecessary include * modify set_bitrate * change to Param * remove getInt helper; add back in diff pr * reword unclear error message * move webrtcd change to new branch --- common/params_keys.h | 1 + system/loggerd/encoder/encoder.h | 1 + system/loggerd/encoder/ffmpeg_encoder.cc | 4 ++++ system/loggerd/encoder/ffmpeg_encoder.h | 1 + system/loggerd/encoder/v4l_encoder.cc | 21 +++++++++++++++++++++ system/loggerd/encoder/v4l_encoder.h | 3 +++ system/loggerd/encoderd.cc | 15 +++++++++++++++ system/loggerd/loggerd.h | 12 ++++++++---- 8 files changed, 54 insertions(+), 4 deletions(-) diff --git a/common/params_keys.h b/common/params_keys.h index d0ee114bc..7a96da0be 100644 --- a/common/params_keys.h +++ b/common/params_keys.h @@ -80,6 +80,7 @@ inline static std::unordered_map keys = { {"LiveDelay", {PERSISTENT, BYTES}}, {"LiveParameters", {PERSISTENT, JSON}}, {"LiveParametersV2", {PERSISTENT, BYTES}}, + {"LivestreamEncoderBitrate", {CLEAR_ON_MANAGER_START | DONT_LOG, INT}}, {"LiveTorqueParameters", {PERSISTENT | DONT_LOG, BYTES}}, {"LocationFilterInitialState", {PERSISTENT, BYTES}}, {"LateralManeuverMode", {CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION, BOOL}}, diff --git a/system/loggerd/encoder/encoder.h b/system/loggerd/encoder/encoder.h index 97cd10acc..0a136f769 100644 --- a/system/loggerd/encoder/encoder.h +++ b/system/loggerd/encoder/encoder.h @@ -26,6 +26,7 @@ public: virtual int encode_frame(VisionBuf* buf, VisionIpcBufExtra *extra) = 0; virtual void encoder_open() = 0; virtual void encoder_close() = 0; + virtual void set_bitrate(int bitrate) = 0; void publisher_publish(int segment_num, uint32_t idx, VisionIpcBufExtra &extra, unsigned int flags, kj::ArrayPtr header, kj::ArrayPtr dat); diff --git a/system/loggerd/encoder/ffmpeg_encoder.cc b/system/loggerd/encoder/ffmpeg_encoder.cc index 275a2e481..f6399659b 100644 --- a/system/loggerd/encoder/ffmpeg_encoder.cc +++ b/system/loggerd/encoder/ffmpeg_encoder.cc @@ -72,6 +72,10 @@ void FfmpegEncoder::encoder_close() { is_open = false; } +void FfmpegEncoder::set_bitrate(int bitrate) { + LOGE("adaptive bitrate is not supported for ffmpeg encoder %s", encoder_info.publish_name); +} + int FfmpegEncoder::encode_frame(VisionBuf* buf, VisionIpcBufExtra *extra) { assert(buf->width == this->in_width); assert(buf->height == this->in_height); diff --git a/system/loggerd/encoder/ffmpeg_encoder.h b/system/loggerd/encoder/ffmpeg_encoder.h index cd5ac1e13..a85e1d381 100644 --- a/system/loggerd/encoder/ffmpeg_encoder.h +++ b/system/loggerd/encoder/ffmpeg_encoder.h @@ -21,6 +21,7 @@ public: int encode_frame(VisionBuf* buf, VisionIpcBufExtra *extra); void encoder_open(); void encoder_close(); + void set_bitrate(int bitrate); private: int segment_num = -1; diff --git a/system/loggerd/encoder/v4l_encoder.cc b/system/loggerd/encoder/v4l_encoder.cc index c54469f69..96a565f4a 100644 --- a/system/loggerd/encoder/v4l_encoder.cc +++ b/system/loggerd/encoder/v4l_encoder.cc @@ -155,6 +155,8 @@ V4LEncoder::V4LEncoder(const EncoderInfo &encoder_info, int in_width, int in_hei assert(strcmp((const char *)cap.card, "msm_vidc_venc") == 0); EncoderSettings encoder_settings = encoder_info.get_settings(in_width); + current_bitrate = encoder_settings.bitrate; + adaptive_bitrate = encoder_info.adaptive_bitrate; bool is_h265 = encoder_settings.encode_type == cereal::EncodeIndex::Type::FULL_H_E_V_C; struct v4l2_format fmt_out = { @@ -304,6 +306,25 @@ void V4LEncoder::encoder_close() { this->is_open = false; } +void V4LEncoder::set_bitrate(int bitrate) { + if (!adaptive_bitrate || bitrate == current_bitrate) return; + if (bitrate <= 0) { + LOGE("invalid livestream encoder bitrate %d", bitrate); + return; + } + + struct v4l2_control ctrl = { + .id = V4L2_CID_MPEG_VIDEO_BITRATE, + .value = bitrate, + }; + + if (util::safe_ioctl(fd, VIDIOC_S_CTRL, &ctrl) == -1) { + LOGE("failed to update %s bitrate to %d", encoder_info.publish_name, bitrate); + return; + } + current_bitrate = bitrate; +} + V4LEncoder::~V4LEncoder() { encoder_close(); v4l2_buf_type buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; diff --git a/system/loggerd/encoder/v4l_encoder.h b/system/loggerd/encoder/v4l_encoder.h index 58011d60e..298540960 100644 --- a/system/loggerd/encoder/v4l_encoder.h +++ b/system/loggerd/encoder/v4l_encoder.h @@ -13,6 +13,7 @@ public: int encode_frame(VisionBuf* buf, VisionIpcBufExtra *extra); void encoder_open(); void encoder_close(); + void set_bitrate(int bitrate); private: int fd; @@ -20,6 +21,8 @@ private: bool is_open = false; int segment_num = -1; int counter = 0; + int current_bitrate = -1; + bool adaptive_bitrate; SafeQueue extras; diff --git a/system/loggerd/encoderd.cc b/system/loggerd/encoderd.cc index 9d4b81a3f..546990041 100644 --- a/system/loggerd/encoderd.cc +++ b/system/loggerd/encoderd.cc @@ -44,11 +44,24 @@ bool sync_encoders(EncoderdState *s, VisionStreamType cam_type, uint32_t frame_i } } +void apply_bitrate(std::vector> &encoders) { + static Params params; + std::string val = params.get("LivestreamEncoderBitrate"); + if (val.empty()) return; + int bitrate = std::stoi(val); + for (auto &e : encoders) { + e->set_bitrate(bitrate); + } +} void encoder_thread(EncoderdState *s, const LogCameraInfo &cam_info) { util::set_thread_name(cam_info.thread_name); std::vector> encoders; + + bool has_adaptive = std::any_of(cam_info.encoder_infos.begin(), cam_info.encoder_infos.end(), + [](const auto &ei) { return ei.adaptive_bitrate; }); + VisionIpcClient vipc_client = VisionIpcClient("camerad", cam_info.stream_type, false); std::unique_ptr jpeg_encoder; @@ -108,6 +121,8 @@ void encoder_thread(EncoderdState *s, const LogCameraInfo &cam_info) { ++cur_seg; } + if (has_adaptive) apply_bitrate(encoders); + // encode a frame for (int i = 0; i < encoders.size(); ++i) { int out_id = encoders[i]->encode_frame(buf, &extra); diff --git a/system/loggerd/loggerd.h b/system/loggerd/loggerd.h index 01bce2c9e..340e72e6f 100644 --- a/system/loggerd/loggerd.h +++ b/system/loggerd/loggerd.h @@ -47,7 +47,7 @@ struct EncoderSettings { } static EncoderSettings StreamEncoderSettings() { - int _stream_bitrate = getenv("STREAM_BITRATE") ? atoi(getenv("STREAM_BITRATE")) : 4'000'000; + int _stream_bitrate = getenv("STREAM_BITRATE") ? atoi(getenv("STREAM_BITRATE")) : 5'000'000; return EncoderSettings{.encode_type = cereal::EncodeIndex::Type::QCAMERA_H264, .bitrate = _stream_bitrate , .gop_size = 5}; } }; @@ -59,6 +59,7 @@ public: const char *filename = NULL; bool record = true; bool include_audio = false; + bool adaptive_bitrate = false; int frame_width = -1; int frame_height = -1; int fps = MAIN_FPS; @@ -104,6 +105,7 @@ const EncoderInfo stream_road_encoder_info = { .publish_name = "livestreamRoadEncodeData", //.thumbnail_name = "thumbnail", .record = false, + .adaptive_bitrate = true, .get_settings = [](int){return EncoderSettings::StreamEncoderSettings();}, INIT_ENCODE_FUNCTIONS(LivestreamRoadEncode), }; @@ -111,6 +113,7 @@ const EncoderInfo stream_road_encoder_info = { const EncoderInfo stream_wide_road_encoder_info = { .publish_name = "livestreamWideRoadEncodeData", .record = false, + .adaptive_bitrate = true, .get_settings = [](int){return EncoderSettings::StreamEncoderSettings();}, INIT_ENCODE_FUNCTIONS(LivestreamWideRoadEncode), }; @@ -118,6 +121,7 @@ const EncoderInfo stream_wide_road_encoder_info = { const EncoderInfo stream_driver_encoder_info = { .publish_name = "livestreamDriverEncodeData", .record = false, + .adaptive_bitrate = true, .get_settings = [](int){return EncoderSettings::StreamEncoderSettings();}, INIT_ENCODE_FUNCTIONS(LivestreamDriverEncode), }; @@ -153,19 +157,19 @@ const LogCameraInfo driver_camera_info{ const LogCameraInfo stream_road_camera_info{ .thread_name = "road_cam_encoder", .stream_type = VISION_STREAM_ROAD, - .encoder_infos = {stream_road_encoder_info} + .encoder_infos = {stream_road_encoder_info}, }; const LogCameraInfo stream_wide_road_camera_info{ .thread_name = "wide_road_cam_encoder", .stream_type = VISION_STREAM_WIDE_ROAD, - .encoder_infos = {stream_wide_road_encoder_info} + .encoder_infos = {stream_wide_road_encoder_info}, }; const LogCameraInfo stream_driver_camera_info{ .thread_name = "driver_cam_encoder", .stream_type = VISION_STREAM_DRIVER, - .encoder_infos = {stream_driver_encoder_info} + .encoder_infos = {stream_driver_encoder_info}, }; const LogCameraInfo cameras_logged[] = {road_camera_info, wide_road_camera_info, driver_camera_info};