From f1fe57109e467d7e2618e9baf6ebe9d3e2dddde0 Mon Sep 17 00:00:00 2001 From: Devaev Maxim Date: Sat, 2 Jan 2021 10:35:36 +0300 Subject: [PATCH] set hw quality in device_open() --- src/ustreamer/device.c | 25 +++++++++++++++++++++++++ src/ustreamer/device.h | 2 ++ src/ustreamer/encoder.c | 11 +++-------- src/ustreamer/encoder.h | 1 - src/ustreamer/encoders/hw/encoder.c | 16 ---------------- src/ustreamer/encoders/hw/encoder.h | 5 ----- src/ustreamer/options.c | 4 ++-- 7 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/ustreamer/device.c b/src/ustreamer/device.c index 54beed2..3235f5a 100644 --- a/src/ustreamer/device.c +++ b/src/ustreamer/device.c @@ -59,6 +59,7 @@ static int _device_open_dv_timings(device_s *dev); static int _device_apply_dv_timings(device_s *dev); static int _device_open_format(device_s *dev); static void _device_open_hw_fps(device_s *dev); +static void _device_open_jpeg_quality(device_s *dev); static int _device_open_io_method(device_s *dev); static int _device_open_io_method_mmap(device_s *dev); static int _device_open_io_method_userptr(device_s *dev); @@ -93,6 +94,7 @@ device_s *device_init(void) { dev->width = 640; dev->height = 480; dev->format = V4L2_PIX_FMT_YUYV; + dev->jpeg_quality = 80; dev->standard = V4L2_STD_UNKNOWN; dev->io_method = V4L2_MEMORY_MMAP; dev->n_buffers = get_cores_available() + 1; @@ -151,6 +153,7 @@ int device_open(device_s *dev) { goto error; } _device_open_hw_fps(dev); + _device_open_jpeg_quality(dev); if (_device_open_io_method(dev) < 0) { goto error; } @@ -566,6 +569,28 @@ static void _device_open_hw_fps(device_s *dev) { # undef SETFPS_TPF } +static void _device_open_jpeg_quality(device_s *dev) { + unsigned quality = 0; + + if (RUN(format) == V4L2_PIX_FMT_MJPEG || RUN(format) == V4L2_PIX_FMT_JPEG) { + struct v4l2_jpegcompression comp; + MEMSET_ZERO(comp); + + if (xioctl(RUN(fd), VIDIOC_G_JPEGCOMP, &comp) < 0) { + LOG_ERROR("Device does not support setting of HW encoding quality parameters"); + } else { + comp.quality = dev->jpeg_quality; + if (xioctl(RUN(fd), VIDIOC_S_JPEGCOMP, &comp) < 0) { + LOG_ERROR("Unable to change MJPG quality for JPEG source with HW pass-through encoder"); + } else { + quality = dev->jpeg_quality; + } + } + } + + RUN(jpeg_quality) = quality; +} + static int _device_open_io_method(device_s *dev) { LOG_INFO("Using IO method: %s", _io_method_to_string_supported(dev->io_method)); switch (dev->io_method) { diff --git a/src/ustreamer/device.h b/src/ustreamer/device.h index d7c4013..6ec62f0 100644 --- a/src/ustreamer/device.h +++ b/src/ustreamer/device.h @@ -86,6 +86,7 @@ typedef struct { unsigned height; unsigned format; unsigned hw_fps; + unsigned jpeg_quality; size_t raw_size; unsigned n_buffers; hw_buffer_s *hw_buffers; @@ -126,6 +127,7 @@ typedef struct { unsigned width; unsigned height; unsigned format; + unsigned jpeg_quality; v4l2_std_id standard; enum v4l2_memory io_method; bool dv_timings; diff --git a/src/ustreamer/encoder.c b/src/ustreamer/encoder.c index 6913e6a..51cabf2 100644 --- a/src/ustreamer/encoder.c +++ b/src/ustreamer/encoder.c @@ -52,7 +52,6 @@ encoder_s *encoder_init(void) { encoder_s *encoder; A_CALLOC(encoder, 1); encoder->type = run->type; - encoder->quality = run->quality; encoder->n_workers = get_cores_available(); encoder->run = run; return encoder; @@ -94,7 +93,7 @@ const char *encoder_type_to_string(encoder_type_e type) { void encoder_prepare(encoder_s *encoder, device_s *dev) { encoder_type_e type = (ER(cpu_forced) ? ENCODER_TYPE_CPU : encoder->type); - unsigned quality = encoder->quality; + unsigned quality = dev->jpeg_quality; bool cpu_forced = false; ER(n_workers) = min_u(encoder->n_workers, DR(n_buffers)); @@ -109,11 +108,7 @@ void encoder_prepare(encoder_s *encoder, device_s *dev) { LOG_INFO("Switching to CPU encoder because the input format is not (M)JPEG"); goto use_cpu; } - - if (hw_encoder_prepare(dev, quality) < 0) { - quality = 0; - } - + quality = DR(jpeg_quality); ER(n_workers) = 1; } # ifdef WITH_OMX @@ -174,7 +169,7 @@ void encoder_prepare(encoder_s *encoder, device_s *dev) { use_cpu: type = ENCODER_TYPE_CPU; - quality = encoder->quality; + quality = dev->jpeg_quality; ok: # ifdef WITH_RAWSINK diff --git a/src/ustreamer/encoder.h b/src/ustreamer/encoder.h index b5009a7..b0f6638 100644 --- a/src/ustreamer/encoder.h +++ b/src/ustreamer/encoder.h @@ -91,7 +91,6 @@ typedef struct { typedef struct { encoder_type_e type; - unsigned quality; unsigned n_workers; # ifdef WITH_OMX unsigned n_glitched_resolutions; diff --git a/src/ustreamer/encoders/hw/encoder.c b/src/ustreamer/encoders/hw/encoder.c index 014198a..adc5b11 100644 --- a/src/ustreamer/encoders/hw/encoder.c +++ b/src/ustreamer/encoders/hw/encoder.c @@ -32,22 +32,6 @@ void _copy_plus_huffman(const frame_s *src, frame_s *dest); static bool _is_huffman(const uint8_t *data); -int hw_encoder_prepare(device_s *dev, unsigned quality) { - struct v4l2_jpegcompression comp; - MEMSET_ZERO(comp); - - if (xioctl(dev->run->fd, VIDIOC_G_JPEGCOMP, &comp) < 0) { - LOG_ERROR("Device does not support setting of HW encoding quality parameters"); - return -1; - } - comp.quality = quality; - if (xioctl(dev->run->fd, VIDIOC_S_JPEGCOMP, &comp) < 0) { - LOG_ERROR("Unable to change MJPG quality for JPEG source with HW pass-through encoder"); - return -1; - } - return 0; -} - void hw_encoder_compress(frame_s *src, frame_s *dest) { if (src->format != V4L2_PIX_FMT_MJPEG && src->format != V4L2_PIX_FMT_JPEG) { assert(0 && "Unsupported input format for HW encoder"); diff --git a/src/ustreamer/encoders/hw/encoder.h b/src/ustreamer/encoders/hw/encoder.h index 2b78d9f..9f374a4 100644 --- a/src/ustreamer/encoders/hw/encoder.h +++ b/src/ustreamer/encoders/hw/encoder.h @@ -29,14 +29,9 @@ #include -#include "../../../libs/common/tools.h" -#include "../../../libs/common/logging.h" #include "../../../libs/common/frame.h" -#include "../../xioctl.h" -#include "../../device.h" #include "huffman.h" -int hw_encoder_prepare(device_s *dev, unsigned quality); void hw_encoder_compress(frame_s *src, frame_s *dest); diff --git a/src/ustreamer/options.c b/src/ustreamer/options.c index 780b442..560f4c5 100644 --- a/src/ustreamer/options.c +++ b/src/ustreamer/options.c @@ -354,7 +354,7 @@ int options_parse(options_s *options, device_s *dev, encoder_s *encoder, stream_ case _O_DV_TIMINGS: OPT_SET(dev->dv_timings, true); case _O_BUFFERS: OPT_NUMBER("--buffers", dev->n_buffers, 1, 32, 0); case _O_WORKERS: OPT_NUMBER("--workers", encoder->n_workers, 1, 32, 0); - case _O_QUALITY: OPT_NUMBER("--quality", encoder->quality, 1, 100, 0); + case _O_QUALITY: OPT_NUMBER("--quality", dev->jpeg_quality, 1, 100, 0); case _O_ENCODER: OPT_PARSE("encoder type", encoder->type, encoder_parse_type, ENCODER_TYPE_UNKNOWN, ENCODER_TYPES_STR); # ifdef WITH_OMX case _O_GLITCHED_RESOLUTIONS: @@ -620,7 +620,7 @@ static void _help(device_s *dev, encoder_s *encoder, stream_s *stream, server_s printf(" Default: %u (the number of CPU cores (but not more than 4) + 1).\n\n", dev->n_buffers); printf(" -w|--workers ──────────────────── The number of worker threads but not more than buffers.\n"); printf(" Default: %u (the number of CPU cores (but not more than 4)).\n\n", encoder->n_workers); - printf(" -q|--quality ──────────────────── Set quality of JPEG encoding from 1 to 100 (best). Default: %u.\n", encoder->quality); + printf(" -q|--quality ──────────────────── Set quality of JPEG encoding from 1 to 100 (best). Default: %u.\n", dev->jpeg_quality); printf(" Note: If HW encoding is used (JPEG source format selected),\n"); printf(" this parameter attempts to configure the camera\n"); printf(" or capture device hardware's internal encoder.\n");