diff --git a/internal/core/path_manager.go b/internal/core/path_manager.go index f5317572aad..f37d3bc92ec 100644 --- a/internal/core/path_manager.go +++ b/internal/core/path_manager.go @@ -29,6 +29,8 @@ func pathConfCanBeUpdated(oldPathConf *conf.Path, newPathConf *conf.Path) bool { clone.RPICameraGain = newPathConf.RPICameraGain clone.RPICameraEV = newPathConf.RPICameraEV clone.RPICameraFPS = newPathConf.RPICameraFPS + clone.RPICameraIDRPeriod = newPathConf.RPICameraIDRPeriod + clone.RPICameraBitrate = newPathConf.RPICameraBitrate return newPathConf.Equal(clone) } diff --git a/internal/protocols/rpicamera/exe/encoder.c b/internal/protocols/rpicamera/exe/encoder.c index 2f3d638bfe5..0bfeb7b5b6f 100644 --- a/internal/protocols/rpicamera/exe/encoder.c +++ b/internal/protocols/rpicamera/exe/encoder.c @@ -111,6 +111,27 @@ static void *output_thread(void *userdata) { return NULL; } +static bool fill_dynamic_params(int fd, const parameters_t *params) { + struct v4l2_control ctrl = {0}; + ctrl.id = V4L2_CID_MPEG_VIDEO_H264_I_PERIOD; + ctrl.value = params->idr_period; + int res = ioctl(fd, VIDIOC_S_CTRL, &ctrl); + if (res != 0) { + set_error("unable to set IDR period"); + return false; + } + + ctrl.id = V4L2_CID_MPEG_VIDEO_BITRATE; + ctrl.value = params->bitrate; + res = ioctl(fd, VIDIOC_S_CTRL, &ctrl); + if (res != 0) { + set_error("unable to set bitrate"); + return false; + } + + return true; +} + bool encoder_create(const parameters_t *params, int stride, int colorspace, encoder_output_cb output_cb, encoder_t **enc) { *enc = malloc(sizeof(encoder_priv_t)); encoder_priv_t *encp = (encoder_priv_t *)(*enc); @@ -122,18 +143,15 @@ bool encoder_create(const parameters_t *params, int stride, int colorspace, enco goto failed; } - struct v4l2_control ctrl = {0}; - ctrl.id = V4L2_CID_MPEG_VIDEO_BITRATE; - ctrl.value = params->bitrate; - int res = ioctl(encp->fd, VIDIOC_S_CTRL, &ctrl); - if (res != 0) { - set_error("unable to set bitrate"); + bool res2 = fill_dynamic_params(encp->fd, params); + if (!res2) { goto failed; } + struct v4l2_control ctrl = {0}; ctrl.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE; ctrl.value = params->profile; - res = ioctl(encp->fd, VIDIOC_S_CTRL, &ctrl); + int res = ioctl(encp->fd, VIDIOC_S_CTRL, &ctrl); if (res != 0) { set_error("unable to set profile"); goto failed; @@ -147,14 +165,6 @@ bool encoder_create(const parameters_t *params, int stride, int colorspace, enco goto failed; } - ctrl.id = V4L2_CID_MPEG_VIDEO_H264_I_PERIOD; - ctrl.value = params->idr_period; - res = ioctl(encp->fd, VIDIOC_S_CTRL, &ctrl); - if (res != 0) { - set_error("unable to set IDR period"); - goto failed; - } - ctrl.id = V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER; ctrl.value = 0; res = ioctl(encp->fd, VIDIOC_S_CTRL, &ctrl); @@ -319,3 +329,9 @@ void encoder_encode(encoder_t *enc, int buffer_fd, size_t size, int64_t timestam // it happens when the raspberry is under pressure. do not exit. } } + +void encoder_reload_params(encoder_t *enc, const parameters_t *params) { + encoder_priv_t *encp = (encoder_priv_t *)enc; + + fill_dynamic_params(encp->fd, params); +} diff --git a/internal/protocols/rpicamera/exe/encoder.h b/internal/protocols/rpicamera/exe/encoder.h index d5a416aeb99..eb1e7928e9e 100644 --- a/internal/protocols/rpicamera/exe/encoder.h +++ b/internal/protocols/rpicamera/exe/encoder.h @@ -10,5 +10,6 @@ typedef void (*encoder_output_cb)(uint64_t ts, const uint8_t *buf, uint64_t size const char *encoder_get_error(); bool encoder_create(const parameters_t *params, int stride, int colorspace, encoder_output_cb output_cb, encoder_t **enc); void encoder_encode(encoder_t *enc, int buffer_fd, size_t size, int64_t timestamp_us); +void encoder_reload_params(encoder_t *enc, const parameters_t *params); #endif diff --git a/internal/protocols/rpicamera/exe/main.c b/internal/protocols/rpicamera/exe/main.c index 48dab5c3ca7..bb379215f2a 100644 --- a/internal/protocols/rpicamera/exe/main.c +++ b/internal/protocols/rpicamera/exe/main.c @@ -106,6 +106,7 @@ int main() { continue; } camera_reload_params(cam, ¶ms); + encoder_reload_params(enc, ¶ms); parameters_destroy(¶ms); } }