mirror of
https://github.com/pikvm/ustreamer.git
synced 2026-02-27 12:16:31 +00:00
set hw quality in device_open()
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -91,7 +91,6 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
encoder_type_e type;
|
||||
unsigned quality;
|
||||
unsigned n_workers;
|
||||
# ifdef WITH_OMX
|
||||
unsigned n_glitched_resolutions;
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user