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