diff --git a/src/ustreamer/encoder.c b/src/ustreamer/encoder.c index 94558a6..581c301 100644 --- a/src/ustreamer/encoder.c +++ b/src/ustreamer/encoder.c @@ -118,15 +118,26 @@ workers_pool_s *encoder_workers_pool_init(encoder_s *enc, device_s *dev) { if (ER(m2ms) == NULL) { A_CALLOC(ER(m2ms), n_workers); } - // Начинаем с нуля и доинициализируем на следующих заходах при необходимости - for (; ER(n_m2ms) < n_workers; ++ER(n_m2ms)) { - char name[32]; - snprintf(name, 32, "JPEG-%u", ER(n_m2ms)); - m2m_option_s options[] = { - {"COMPRESSION_QUALITY", false, V4L2_CID_JPEG_COMPRESSION_QUALITY, quality}, - {NULL, false, 0, 0}, - }; - ER(m2ms[ER(n_m2ms)]) = m2m_encoder_init(name, "/dev/video11", V4L2_PIX_FMT_MJPEG, 0, options); + + if (ER(n_m2ms) < n_workers) { + double b_min = ENCODER_M2M_BITRATE_MIN; + double b_max = ENCODER_M2M_BITRATE_MAX; + double step = ENCODER_M2M_BITRATE_STEP; + double bitrate = log10(quality) * (b_max - b_min) / 2 + b_min; + bitrate = step * round(bitrate / step); + LOG_VERBOSE("Using JPEG M2M bitrate: %u%% -> %u Kbps", quality, (unsigned)bitrate); + + // Начинаем с нуля и доинициализируем на следующих заходах при необходимости + for (; ER(n_m2ms) < n_workers; ++ER(n_m2ms)) { + assert(bitrate > 0); + char name[32]; + snprintf(name, 32, "JPEG-%u", ER(n_m2ms)); + m2m_option_s options[] = { + {"BITRATE", true, V4L2_CID_MPEG_VIDEO_BITRATE, bitrate * 1000}, + {NULL, false, 0, 0}, + }; + ER(m2ms[ER(n_m2ms)]) = m2m_encoder_init(name, "/dev/video11", V4L2_PIX_FMT_MJPEG, 0, options); + } } } else if (type == ENCODER_TYPE_NOOP) { diff --git a/src/ustreamer/encoder.h b/src/ustreamer/encoder.h index e4cc5a9..5c1d517 100644 --- a/src/ustreamer/encoder.h +++ b/src/ustreamer/encoder.h @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -43,6 +44,22 @@ #include "encoders/hw/encoder.h" +#ifndef CFG_ENCODER_M2M_BITRATE_MIN +# define CFG_ENCODER_M2M_BITRATE_MIN 25 +#endif +#define ENCODER_M2M_BITRATE_MIN ((unsigned)CFG_ENCODER_M2M_BITRATE_MIN) + +#ifndef CFG_ENCODER_M2M_BITRATE_MAX +# define CFG_ENCODER_M2M_BITRATE_MAX 25000 +#endif +#define ENCODER_M2M_BITRATE_MAX ((unsigned)CFG_ENCODER_M2M_BITRATE_MAX) + +#ifndef CFG_ENCODER_M2M_BITRATE_STEP +# define CFG_ENCODER_M2M_BITRATE_STEP 25 +#endif +#define ENCODER_M2M_BITRATE_STEP ((unsigned)CFG_ENCODER_M2M_BITRATE_STEP) + + #define ENCODER_TYPES_STR "CPU, HW, M2M, NOOP" typedef enum {