mirror of
https://github.com/pikvm/ustreamer.git
synced 2026-02-27 04:06:30 +00:00
refactoring
This commit is contained in:
@@ -103,7 +103,7 @@ static const char *_standard_to_string(v4l2_std_id standard);
|
||||
static const char *_io_method_to_string_supported(enum v4l2_memory io_method);
|
||||
|
||||
|
||||
# define RUN(_next) dev->run->_next
|
||||
#define RUN(_next) dev->run->_next
|
||||
|
||||
|
||||
struct device_t *device_init(void) {
|
||||
@@ -354,6 +354,9 @@ int device_grab_buffer(struct device_t *dev) {
|
||||
A_MUTEX_UNLOCK(&HW(grabbed_mutex));
|
||||
|
||||
HW(used) = buf_info.bytesused;
|
||||
HW(width) = RUN(width);
|
||||
HW(height) = RUN(height);
|
||||
HW(format) = RUN(format);
|
||||
memcpy(&HW(buf_info), &buf_info, sizeof(struct v4l2_buffer));
|
||||
HW(grab_ts) = get_now_monotonic();
|
||||
|
||||
@@ -374,7 +377,6 @@ int device_release_buffer(struct device_t *dev, unsigned index) {
|
||||
}
|
||||
HW(grabbed) = false;
|
||||
A_MUTEX_UNLOCK(&HW(grabbed_mutex));
|
||||
HW(used) = 0;
|
||||
|
||||
# undef HW
|
||||
return 0;
|
||||
|
||||
@@ -55,6 +55,9 @@ struct hw_buffer_t {
|
||||
unsigned char *data;
|
||||
size_t used;
|
||||
size_t allocated;
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
unsigned format;
|
||||
long double grab_ts;
|
||||
|
||||
struct v4l2_buffer buf_info;
|
||||
|
||||
@@ -214,42 +214,41 @@ void encoder_prepare(struct encoder_t *encoder, struct device_t *dev) {
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
#pragma GCC diagnostic push
|
||||
int encoder_compress_buffer(
|
||||
struct encoder_t *encoder, struct device_t *dev,
|
||||
unsigned worker_number, unsigned buf_index,
|
||||
struct picture_t *picture) {
|
||||
struct encoder_t *encoder, unsigned worker_number,
|
||||
struct hw_buffer_t *hw, struct picture_t *picture) {
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
assert(ER(type) != ENCODER_TYPE_UNKNOWN);
|
||||
assert(DR(hw_buffers[buf_index].used) > 0);
|
||||
assert(hw->used > 0);
|
||||
|
||||
picture->grab_ts = DR(hw_buffers[buf_index].grab_ts);
|
||||
picture->grab_ts = hw->grab_ts;
|
||||
picture->encode_begin_ts = get_now_monotonic();
|
||||
|
||||
if (ER(type) == ENCODER_TYPE_CPU) {
|
||||
LOG_VERBOSE("Compressing buffer %u using CPU", buf_index);
|
||||
cpu_encoder_compress_buffer(dev, buf_index, ER(quality), picture);
|
||||
LOG_VERBOSE("Compressing buffer using CPU");
|
||||
cpu_encoder_compress_buffer(hw, picture, ER(quality));
|
||||
} else if (ER(type) == ENCODER_TYPE_HW) {
|
||||
LOG_VERBOSE("Compressing buffer %u using HW (just copying)", buf_index);
|
||||
hw_encoder_compress_buffer(dev, buf_index, picture);
|
||||
LOG_VERBOSE("Compressing buffer using HW (just copying)");
|
||||
hw_encoder_compress_buffer(hw, picture);
|
||||
}
|
||||
# ifdef WITH_OMX
|
||||
else if (ER(type) == ENCODER_TYPE_OMX) {
|
||||
LOG_VERBOSE("Compressing buffer %u using OMX", buf_index);
|
||||
if (omx_encoder_compress_buffer(ER(omxs[worker_number]), dev, buf_index, picture) < 0) {
|
||||
LOG_VERBOSE("Compressing buffer using OMX");
|
||||
if (omx_encoder_compress_buffer(ER(omxs[worker_number]), hw, picture) < 0) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
# ifdef WITH_RAWSINK
|
||||
else if (ER(type) == ENCODER_TYPE_NOOP) {
|
||||
LOG_VERBOSE("Compressing buffer %u using NOOP (do nothing)", buf_index);
|
||||
LOG_VERBOSE("Compressing buffer using NOOP (do nothing)");
|
||||
}
|
||||
# endif
|
||||
|
||||
picture->encode_end_ts = get_now_monotonic();
|
||||
|
||||
picture->width = DR(width);
|
||||
picture->height = DR(height);
|
||||
picture->width = hw->width;
|
||||
picture->height = hw->height;
|
||||
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -102,6 +102,5 @@ const char *encoder_type_to_string(enum encoder_type_t type);
|
||||
void encoder_prepare(struct encoder_t *encoder, struct device_t *dev);
|
||||
|
||||
int encoder_compress_buffer(
|
||||
struct encoder_t *encoder, struct device_t *dev,
|
||||
unsigned worker_number, unsigned buf_index,
|
||||
struct picture_t *picture);
|
||||
struct encoder_t *encoder, unsigned worker_number,
|
||||
struct hw_buffer_t *hw, struct picture_t *picture);
|
||||
|
||||
@@ -70,10 +70,7 @@ static boolean _jpeg_empty_output_buffer(j_compress_ptr jpeg);
|
||||
static void _jpeg_term_destination(j_compress_ptr jpeg);
|
||||
|
||||
|
||||
void cpu_encoder_compress_buffer(
|
||||
struct device_t *dev, unsigned index, unsigned quality,
|
||||
struct picture_t *picture) {
|
||||
|
||||
void cpu_encoder_compress_buffer(struct hw_buffer_t *hw, struct picture_t *picture, unsigned quality) {
|
||||
// This function based on compress_image_to_jpeg() from mjpg-streamer
|
||||
|
||||
struct jpeg_compress_struct jpeg;
|
||||
@@ -84,8 +81,8 @@ void cpu_encoder_compress_buffer(
|
||||
|
||||
_jpeg_set_picture(&jpeg, picture);
|
||||
|
||||
jpeg.image_width = dev->run->width;
|
||||
jpeg.image_height = dev->run->height;
|
||||
jpeg.image_width = hw->width;
|
||||
jpeg.image_height = hw->height;
|
||||
jpeg.input_components = 3;
|
||||
jpeg.in_color_space = JCS_RGB;
|
||||
|
||||
@@ -95,9 +92,9 @@ void cpu_encoder_compress_buffer(
|
||||
jpeg_start_compress(&jpeg, TRUE);
|
||||
|
||||
# define WRITE_SCANLINES(_format, _func) \
|
||||
case _format: { _func(&jpeg, dev->run->hw_buffers[index].data, dev->run->width, dev->run->height); break; }
|
||||
case _format: { _func(&jpeg, hw->data, hw->width, hw->height); break; }
|
||||
|
||||
switch (dev->run->format) {
|
||||
switch (hw->format) {
|
||||
// https://www.fourcc.org/yuv.php
|
||||
WRITE_SCANLINES(V4L2_PIX_FMT_YUYV, _jpeg_write_scanlines_yuyv);
|
||||
WRITE_SCANLINES(V4L2_PIX_FMT_UYVY, _jpeg_write_scanlines_uyvy);
|
||||
|
||||
@@ -26,6 +26,4 @@
|
||||
#include "../../picture.h"
|
||||
|
||||
|
||||
void cpu_encoder_compress_buffer(
|
||||
struct device_t *dev, unsigned index, unsigned quality,
|
||||
struct picture_t *picture);
|
||||
void cpu_encoder_compress_buffer(struct hw_buffer_t *hw, struct picture_t *picture, unsigned quality);
|
||||
|
||||
@@ -63,11 +63,11 @@ int hw_encoder_prepare(struct device_t *dev, unsigned quality) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hw_encoder_compress_buffer(struct device_t *dev, unsigned index, struct picture_t *picture) {
|
||||
if (dev->run->format != V4L2_PIX_FMT_MJPEG && dev->run->format != V4L2_PIX_FMT_JPEG) {
|
||||
void hw_encoder_compress_buffer(struct hw_buffer_t *hw, struct picture_t *picture) {
|
||||
if (hw->format != V4L2_PIX_FMT_MJPEG && hw->format != V4L2_PIX_FMT_JPEG) {
|
||||
assert(0 && "Unsupported input format for HW encoder");
|
||||
}
|
||||
_copy_plus_huffman(&dev->run->hw_buffers[index], picture);
|
||||
_copy_plus_huffman(hw, picture);
|
||||
}
|
||||
|
||||
void _copy_plus_huffman(const struct hw_buffer_t *src, struct picture_t *dest) {
|
||||
|
||||
@@ -27,4 +27,4 @@
|
||||
|
||||
|
||||
int hw_encoder_prepare(struct device_t *dev, unsigned quality);
|
||||
void hw_encoder_compress_buffer(struct device_t *dev, unsigned index, struct picture_t *picture);
|
||||
void hw_encoder_compress_buffer(struct hw_buffer_t *hw, struct picture_t *picture);
|
||||
|
||||
@@ -176,16 +176,12 @@ int omx_encoder_prepare(struct omx_encoder_t *omx, struct device_t *dev, unsigne
|
||||
return 0;
|
||||
}
|
||||
|
||||
int omx_encoder_compress_buffer(
|
||||
struct omx_encoder_t *omx, struct device_t *dev, unsigned index,
|
||||
struct picture_t *picture) {
|
||||
|
||||
# define HW(_next) dev->run->hw_buffers[index]._next
|
||||
int omx_encoder_compress_buffer(struct hw_buffer_t *hw, struct picture_t *picture) {
|
||||
# define IN(_next) omx->input_buffer->_next
|
||||
# define OUT(_next) omx->output_buffer->_next
|
||||
|
||||
OMX_ERRORTYPE error;
|
||||
size_t slice_size = (IN(nAllocLen) < HW(used) ? IN(nAllocLen) : HW(used));
|
||||
size_t slice_size = (IN(nAllocLen) < hw->used ? IN(nAllocLen) : hw->used);
|
||||
size_t pos = 0;
|
||||
|
||||
if ((error = OMX_FillThisBuffer(omx->encoder, omx->output_buffer)) != OMX_ErrorNone) {
|
||||
@@ -221,18 +217,18 @@ int omx_encoder_compress_buffer(
|
||||
if (omx->input_required) {
|
||||
omx->input_required = false;
|
||||
|
||||
if (pos == HW(used)) {
|
||||
if (pos == hw->used) {
|
||||
continue;
|
||||
}
|
||||
|
||||
memcpy(IN(pBuffer), HW(data) + pos, slice_size);
|
||||
memcpy(IN(pBuffer), hw->data + pos, slice_size);
|
||||
IN(nOffset) = 0;
|
||||
IN(nFilledLen) = slice_size;
|
||||
|
||||
pos += slice_size;
|
||||
|
||||
if (pos + slice_size > HW(used)) {
|
||||
slice_size = HW(used) - pos;
|
||||
if (pos + slice_size > hw->used) {
|
||||
slice_size = hw->used - pos;
|
||||
}
|
||||
|
||||
if ((error = OMX_EmptyThisBuffer(omx->encoder, omx->input_buffer)) != OMX_ErrorNone) {
|
||||
@@ -248,7 +244,6 @@ int omx_encoder_compress_buffer(
|
||||
|
||||
# undef OUT
|
||||
# undef IN
|
||||
# undef HW
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,4 @@ struct omx_encoder_t *omx_encoder_init(void);
|
||||
void omx_encoder_destroy(struct omx_encoder_t *omx);
|
||||
|
||||
int omx_encoder_prepare(struct omx_encoder_t *omx, struct device_t *dev, unsigned quality);
|
||||
|
||||
int omx_encoder_compress_buffer(
|
||||
struct omx_encoder_t *omx, struct device_t *dev, unsigned index,
|
||||
struct picture_t *picture);
|
||||
int omx_encoder_compress_buffer(struct hw_buffer_t *hw, struct picture_t *picture);
|
||||
|
||||
@@ -239,9 +239,9 @@ void stream_loop(struct stream_t *stream) {
|
||||
rawsink,
|
||||
DEV(run->hw_buffers[buf_index].data),
|
||||
DEV(run->hw_buffers[buf_index].used),
|
||||
DEV(run->format),
|
||||
DEV(run->width),
|
||||
DEV(run->height),
|
||||
DEV(run->hw_buffers[buf_index].format),
|
||||
DEV(run->hw_buffers[buf_index].width),
|
||||
DEV(run->hw_buffers[buf_index].height),
|
||||
DEV(run->hw_buffers[buf_index].grab_ts)
|
||||
);
|
||||
}
|
||||
@@ -461,9 +461,8 @@ static void *_worker_thread(void *v_worker) {
|
||||
|
||||
wr->job_failed = (bool)encoder_compress_buffer(
|
||||
wr->stream->encoder,
|
||||
wr->stream->dev,
|
||||
wr->number,
|
||||
wr->buf_index,
|
||||
&wr->stream->dev->run->hw_buffers[wr->buf_index],
|
||||
wr->picture
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user