set hw quality in device_open()

This commit is contained in:
Devaev Maxim
2021-01-02 10:35:36 +03:00
parent daaefdd391
commit f1fe57109e
7 changed files with 32 additions and 32 deletions

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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

View File

@@ -91,7 +91,6 @@ typedef struct {
typedef struct {
encoder_type_e type;
unsigned quality;
unsigned n_workers;
# ifdef WITH_OMX
unsigned n_glitched_resolutions;

View File

@@ -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");

View File

@@ -29,14 +29,9 @@
#include <linux/videodev2.h>
#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);

View File

@@ -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 <N> ──────────────────── 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 <N> ──────────────────── Set quality of JPEG encoding from 1 to 100 (best). Default: %u.\n", encoder->quality);
printf(" -q|--quality <N> ──────────────────── 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");