mirror of
https://github.com/pikvm/ustreamer.git
synced 2026-03-13 11:03:43 +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_apply_dv_timings(device_s *dev);
|
||||||
static int _device_open_format(device_s *dev);
|
static int _device_open_format(device_s *dev);
|
||||||
static void _device_open_hw_fps(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(device_s *dev);
|
||||||
static int _device_open_io_method_mmap(device_s *dev);
|
static int _device_open_io_method_mmap(device_s *dev);
|
||||||
static int _device_open_io_method_userptr(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->width = 640;
|
||||||
dev->height = 480;
|
dev->height = 480;
|
||||||
dev->format = V4L2_PIX_FMT_YUYV;
|
dev->format = V4L2_PIX_FMT_YUYV;
|
||||||
|
dev->jpeg_quality = 80;
|
||||||
dev->standard = V4L2_STD_UNKNOWN;
|
dev->standard = V4L2_STD_UNKNOWN;
|
||||||
dev->io_method = V4L2_MEMORY_MMAP;
|
dev->io_method = V4L2_MEMORY_MMAP;
|
||||||
dev->n_buffers = get_cores_available() + 1;
|
dev->n_buffers = get_cores_available() + 1;
|
||||||
@@ -151,6 +153,7 @@ int device_open(device_s *dev) {
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
_device_open_hw_fps(dev);
|
_device_open_hw_fps(dev);
|
||||||
|
_device_open_jpeg_quality(dev);
|
||||||
if (_device_open_io_method(dev) < 0) {
|
if (_device_open_io_method(dev) < 0) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
@@ -566,6 +569,28 @@ static void _device_open_hw_fps(device_s *dev) {
|
|||||||
# undef SETFPS_TPF
|
# 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) {
|
static int _device_open_io_method(device_s *dev) {
|
||||||
LOG_INFO("Using IO method: %s", _io_method_to_string_supported(dev->io_method));
|
LOG_INFO("Using IO method: %s", _io_method_to_string_supported(dev->io_method));
|
||||||
switch (dev->io_method) {
|
switch (dev->io_method) {
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ typedef struct {
|
|||||||
unsigned height;
|
unsigned height;
|
||||||
unsigned format;
|
unsigned format;
|
||||||
unsigned hw_fps;
|
unsigned hw_fps;
|
||||||
|
unsigned jpeg_quality;
|
||||||
size_t raw_size;
|
size_t raw_size;
|
||||||
unsigned n_buffers;
|
unsigned n_buffers;
|
||||||
hw_buffer_s *hw_buffers;
|
hw_buffer_s *hw_buffers;
|
||||||
@@ -126,6 +127,7 @@ typedef struct {
|
|||||||
unsigned width;
|
unsigned width;
|
||||||
unsigned height;
|
unsigned height;
|
||||||
unsigned format;
|
unsigned format;
|
||||||
|
unsigned jpeg_quality;
|
||||||
v4l2_std_id standard;
|
v4l2_std_id standard;
|
||||||
enum v4l2_memory io_method;
|
enum v4l2_memory io_method;
|
||||||
bool dv_timings;
|
bool dv_timings;
|
||||||
|
|||||||
@@ -52,7 +52,6 @@ encoder_s *encoder_init(void) {
|
|||||||
encoder_s *encoder;
|
encoder_s *encoder;
|
||||||
A_CALLOC(encoder, 1);
|
A_CALLOC(encoder, 1);
|
||||||
encoder->type = run->type;
|
encoder->type = run->type;
|
||||||
encoder->quality = run->quality;
|
|
||||||
encoder->n_workers = get_cores_available();
|
encoder->n_workers = get_cores_available();
|
||||||
encoder->run = run;
|
encoder->run = run;
|
||||||
return encoder;
|
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) {
|
void encoder_prepare(encoder_s *encoder, device_s *dev) {
|
||||||
encoder_type_e type = (ER(cpu_forced) ? ENCODER_TYPE_CPU : encoder->type);
|
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;
|
bool cpu_forced = false;
|
||||||
|
|
||||||
ER(n_workers) = min_u(encoder->n_workers, DR(n_buffers));
|
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");
|
LOG_INFO("Switching to CPU encoder because the input format is not (M)JPEG");
|
||||||
goto use_cpu;
|
goto use_cpu;
|
||||||
}
|
}
|
||||||
|
quality = DR(jpeg_quality);
|
||||||
if (hw_encoder_prepare(dev, quality) < 0) {
|
|
||||||
quality = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ER(n_workers) = 1;
|
ER(n_workers) = 1;
|
||||||
}
|
}
|
||||||
# ifdef WITH_OMX
|
# ifdef WITH_OMX
|
||||||
@@ -174,7 +169,7 @@ void encoder_prepare(encoder_s *encoder, device_s *dev) {
|
|||||||
|
|
||||||
use_cpu:
|
use_cpu:
|
||||||
type = ENCODER_TYPE_CPU;
|
type = ENCODER_TYPE_CPU;
|
||||||
quality = encoder->quality;
|
quality = dev->jpeg_quality;
|
||||||
|
|
||||||
ok:
|
ok:
|
||||||
# ifdef WITH_RAWSINK
|
# ifdef WITH_RAWSINK
|
||||||
|
|||||||
@@ -91,7 +91,6 @@ typedef struct {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
encoder_type_e type;
|
encoder_type_e type;
|
||||||
unsigned quality;
|
|
||||||
unsigned n_workers;
|
unsigned n_workers;
|
||||||
# ifdef WITH_OMX
|
# ifdef WITH_OMX
|
||||||
unsigned n_glitched_resolutions;
|
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);
|
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) {
|
void hw_encoder_compress(frame_s *src, frame_s *dest) {
|
||||||
if (src->format != V4L2_PIX_FMT_MJPEG && src->format != V4L2_PIX_FMT_JPEG) {
|
if (src->format != V4L2_PIX_FMT_MJPEG && src->format != V4L2_PIX_FMT_JPEG) {
|
||||||
assert(0 && "Unsupported input format for HW encoder");
|
assert(0 && "Unsupported input format for HW encoder");
|
||||||
|
|||||||
@@ -29,14 +29,9 @@
|
|||||||
|
|
||||||
#include <linux/videodev2.h>
|
#include <linux/videodev2.h>
|
||||||
|
|
||||||
#include "../../../libs/common/tools.h"
|
|
||||||
#include "../../../libs/common/logging.h"
|
|
||||||
#include "../../../libs/common/frame.h"
|
#include "../../../libs/common/frame.h"
|
||||||
#include "../../xioctl.h"
|
|
||||||
#include "../../device.h"
|
|
||||||
|
|
||||||
#include "huffman.h"
|
#include "huffman.h"
|
||||||
|
|
||||||
|
|
||||||
int hw_encoder_prepare(device_s *dev, unsigned quality);
|
|
||||||
void hw_encoder_compress(frame_s *src, frame_s *dest);
|
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_DV_TIMINGS: OPT_SET(dev->dv_timings, true);
|
||||||
case _O_BUFFERS: OPT_NUMBER("--buffers", dev->n_buffers, 1, 32, 0);
|
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_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);
|
case _O_ENCODER: OPT_PARSE("encoder type", encoder->type, encoder_parse_type, ENCODER_TYPE_UNKNOWN, ENCODER_TYPES_STR);
|
||||||
# ifdef WITH_OMX
|
# ifdef WITH_OMX
|
||||||
case _O_GLITCHED_RESOLUTIONS:
|
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(" 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(" -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(" 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(" Note: If HW encoding is used (JPEG source format selected),\n");
|
||||||
printf(" this parameter attempts to configure the camera\n");
|
printf(" this parameter attempts to configure the camera\n");
|
||||||
printf(" or capture device hardware's internal encoder.\n");
|
printf(" or capture device hardware's internal encoder.\n");
|
||||||
|
|||||||
Reference in New Issue
Block a user