refactoring

This commit is contained in:
Devaev Maxim 2021-01-04 20:38:14 +03:00
parent dd90d378a4
commit 85e63f49a0
7 changed files with 81 additions and 82 deletions

View File

@ -113,6 +113,7 @@ regen:
$(USTR): $(_USTR_SRCS:%.c=$(BUILD)/%.o)
$(info ========================================)
$(info == LD $@)
@ $(CC) $^ -o $@ $(LDFLAGS) $(_USTR_LIBS)
$(info :: CC = $(CC))
@ -123,6 +124,7 @@ $(USTR): $(_USTR_SRCS:%.c=$(BUILD)/%.o)
ifneq ($(call optbool,$(WITH_OMX)),)
$(REC): $(_REC_SRCS:%.c=$(BUILD)/%.o)
$(info ========================================)
$(info == LD $@)
@ $(CC) $^ -o $@ $(LDFLAGS) $(_REC_LIBS)
$(info :: CC = $(CC))

View File

@ -142,7 +142,7 @@ void encoder_prepare(encoder_s *enc, device_s *dev) {
}
for (unsigned index = 0; index < ER(n_omxs); ++index) {
if (omx_encoder_prepare(ER(omxs[index]), dev, quality) < 0) {
if (omx_encoder_prepare(ER(omxs[index]), DR(width), DR(height), DR(format), quality) < 0) {
LOG_ERROR("Can't prepare OMX encoder, falling back to CPU");
goto force_cpu;
}

View File

@ -30,7 +30,7 @@ static const OMX_U32 _OUTPUT_PORT = 341;
static int _vcos_semwait(VCOS_SEMAPHORE_T *sem);
static int _omx_init_component(omx_encoder_s *omx);
static int _omx_init_disable_ports(omx_encoder_s *omx);
static int _omx_setup_input(omx_encoder_s *omx, device_s *dev);
static int _omx_setup_input(omx_encoder_s *omx, unsigned width, unsigned height, unsigned format);
static int _omx_setup_output(omx_encoder_s *omx, unsigned quality);
static int _omx_encoder_clear_ports(omx_encoder_s *omx);
@ -106,14 +106,14 @@ void omx_encoder_destroy(omx_encoder_s *omx) {
free(omx);
}
int omx_encoder_prepare(omx_encoder_s *omx, device_s *dev, unsigned quality) {
int omx_encoder_prepare(omx_encoder_s *omx, unsigned width, unsigned height, unsigned format, unsigned quality) {
if (omx_component_set_state(&omx->comp, OMX_StateIdle) < 0) {
return -1;
}
if (_omx_encoder_clear_ports(omx) < 0) {
return -1;
}
if (_omx_setup_input(omx, dev) < 0) {
if (_omx_setup_input(omx, width, height, format) < 0) {
return -1;
}
if (_omx_setup_output(omx, quality) < 0) {
@ -277,7 +277,7 @@ static int _omx_init_disable_ports(omx_encoder_s *omx) {
return 0;
}
static int _omx_setup_input(omx_encoder_s *omx, device_s *dev) {
static int _omx_setup_input(omx_encoder_s *omx, unsigned width, unsigned height, unsigned format) {
LOG_DEBUG("Setting up OMX JPEG input port ...");
OMX_ERRORTYPE error;
@ -289,14 +289,14 @@ static int _omx_setup_input(omx_encoder_s *omx, device_s *dev) {
}
# define IFMT(_next) portdef.format.image._next
IFMT(nFrameWidth) = dev->run->width;
IFMT(nFrameHeight) = dev->run->height;
IFMT(nFrameWidth) = width;
IFMT(nFrameHeight) = height;
IFMT(nStride) = 0;
IFMT(nSliceHeight) = align_size(dev->run->height, 16);
IFMT(nSliceHeight) = align_size(height, 16);
IFMT(bFlagErrorConcealment) = OMX_FALSE;
IFMT(eCompressionFormat) = OMX_IMAGE_CodingUnused;
portdef.nBufferSize = ((dev->run->width * dev->run->height) << 1) * 2;
switch (dev->run->format) {
portdef.nBufferSize = ((width * height) << 1) * 2;
switch (format) {
// https://www.fourcc.org/yuv.php
// Also see comments inside OMX_IVCommon.h
case V4L2_PIX_FMT_YUYV: IFMT(eColorFormat) = OMX_COLOR_FormatYCbYCr; break;

View File

@ -38,7 +38,6 @@
#include "../../../libs/common/tools.h"
#include "../../../libs/common/logging.h"
#include "../../../libs/common/frame.h"
#include "../../device.h"
#include "formatters.h"
#include "component.h"
@ -69,5 +68,5 @@ typedef struct {
omx_encoder_s *omx_encoder_init(void);
void omx_encoder_destroy(omx_encoder_s *omx);
int omx_encoder_prepare(omx_encoder_s *omx, device_s *dev, unsigned quality);
int omx_encoder_prepare(omx_encoder_s *omx, unsigned width, unsigned height, unsigned format, unsigned quality);
int omx_encoder_compress(omx_encoder_s *omx, const frame_s *src, frame_s *dest);

View File

@ -23,9 +23,7 @@
#include "encoder.h"
static int _h264_encoder_configure(h264_encoder_s *enc, const frame_s *frame);
static void _h264_encoder_cleanup(h264_encoder_s *enc);
static int _h264_encoder_compress_raw(h264_encoder_s *enc, const frame_s *src, frame_s *dest, bool force_key);
static void _mmal_callback(MMAL_WRAPPER_T *wrapper);
@ -97,53 +95,8 @@ void h264_encoder_destroy(h264_encoder_s *enc) {
free(enc);
}
int h264_encoder_compress(h264_encoder_s *enc, const frame_s *src, frame_s *dest) {
assert(src->used > 0);
assert(src->width > 0);
assert(src->height > 0);
assert(src->format > 0);
frame_copy_meta(src, dest);
dest->encode_begin_ts = get_now_monotonic();
dest->format = V4L2_PIX_FMT_H264;
if (src->format == V4L2_PIX_FMT_MJPEG || src->format == V4L2_PIX_FMT_JPEG) {
LOG_DEBUG("H264: Input frame format is JPEG; decoding ...");
if (unjpeg(src, RUN(tmp), true) < 0) {
return -1;
}
LOG_VERBOSE("H264: JPEG decoded; time=%Lf", get_now_monotonic() - dest->encode_begin_ts);
} else {
LOG_DEBUG("H264: Copying source to tmp buffer ...");
frame_copy(src, RUN(tmp));
LOG_VERBOSE("H264: Source copied; time=%Lf", get_now_monotonic() - dest->encode_begin_ts);
}
src = RUN(tmp);
if (RUN(i_width) != src->width || RUN(i_height) != src->height || RUN(i_format) != src->format) {
if (_h264_encoder_configure(enc, src) < 0) {
return -1;
}
RUN(last_online) = -1;
}
bool force_key = (RUN(last_online) != src->online);
if (_h264_encoder_compress_raw(enc, src, dest, force_key) < 0) {
_h264_encoder_cleanup(enc);
return -1;
}
dest->encode_end_ts = get_now_monotonic();
LOG_VERBOSE("H264: Compressed new frame: size=%zu, time=%0.3Lf, force_key=%d",
dest->used, dest->encode_end_ts - dest->encode_begin_ts, force_key);
RUN(last_online) = src->online;
return 0;
}
static int _h264_encoder_configure(h264_encoder_s *enc, const frame_s *frame) {
LOG_INFO("H264: Reconfiguring MMAL encoder ...");
int h264_encoder_prepare(h264_encoder_s *enc, unsigned width, unsigned height, unsigned format) {
LOG_INFO("H264: Configuring MMAL encoder ...");
MMAL_STATUS_T error;
@ -186,19 +139,21 @@ static int _h264_encoder_configure(h264_encoder_s *enc, const frame_s *frame) {
# define IFMT(_next) RUN(input_port->format->_next)
IFMT(type) = MMAL_ES_TYPE_VIDEO;
switch (frame->format) {
switch (format) {
case V4L2_PIX_FMT_YUYV: IFMT(encoding) = MMAL_ENCODING_YUYV; break;
case V4L2_PIX_FMT_UYVY: IFMT(encoding) = MMAL_ENCODING_UYVY; break;
case V4L2_PIX_FMT_RGB565: IFMT(encoding) = MMAL_ENCODING_RGB16; break;
case V4L2_PIX_FMT_MJPEG:
case V4L2_PIX_FMT_JPEG: // See unjpeg.c
case V4L2_PIX_FMT_RGB24: IFMT(encoding) = MMAL_ENCODING_RGB24; break;
default: assert(0 && "Unsupported input format for MMAL H264 encoder");
}
IFMT(es->video.width) = align_size(frame->width, 32);
IFMT(es->video.height) = align_size(frame->height, 16);
IFMT(es->video.width) = align_size(width, 32);
IFMT(es->video.height) = align_size(height, 16);
IFMT(es->video.crop.x) = 0;
IFMT(es->video.crop.y) = 0;
IFMT(es->video.crop.width) = frame->width;
IFMT(es->video.crop.height) = frame->height;
IFMT(es->video.crop.width) = width;
IFMT(es->video.crop.height) = height;
IFMT(flags) = MMAL_ES_FORMAT_FLAG_FRAMED;
RUN(input_port->buffer_size) = 1000 * 1000;
RUN(input_port->buffer_num) = RUN(input_port->buffer_num_recommended) * 4;
@ -256,9 +211,9 @@ static int _h264_encoder_configure(h264_encoder_s *enc, const frame_s *frame) {
ENABLE_PORT(input);
ENABLE_PORT(output);
RUN(i_width) = frame->width;
RUN(i_height) = frame->height;
RUN(i_format) = frame->format;
RUN(width) = width;
RUN(height) = height;
RUN(format) = format;
return 0;
@ -289,17 +244,52 @@ static void _h264_encoder_cleanup(h264_encoder_s *enc) {
# undef DISABLE_PORT
RUN(i_width) = 0;
RUN(i_height) = 0;
RUN(i_format) = 0;
RUN(width) = 0;
RUN(height) = 0;
RUN(format) = 0;
RUN(last_online) = -1;
}
int h264_encoder_compress(h264_encoder_s *enc, const frame_s *src, frame_s *dest) {
frame_copy_meta(src, dest);
dest->encode_begin_ts = get_now_monotonic();
dest->format = V4L2_PIX_FMT_H264;
if (src->format == V4L2_PIX_FMT_MJPEG || src->format == V4L2_PIX_FMT_JPEG) {
LOG_DEBUG("H264: Input frame format is JPEG; decoding ...");
if (unjpeg(src, RUN(tmp), true) < 0) {
return -1;
}
assert(RUN(tmp->format) == V4L2_PIX_FMT_RGB24);
LOG_VERBOSE("H264: JPEG decoded; time=%Lf", get_now_monotonic() - dest->encode_begin_ts);
} else {
LOG_DEBUG("H264: Copying source to tmp buffer ...");
frame_copy(src, RUN(tmp));
assert(src->format == RUN(format));
LOG_VERBOSE("H264: Source copied; time=%Lf", get_now_monotonic() - dest->encode_begin_ts);
}
src = RUN(tmp);
assert(src->used > 0);
assert(src->width == RUN(width));
assert(src->height == RUN(height));
bool force_key = (RUN(last_online) != src->online);
if (_h264_encoder_compress_raw(enc, src, dest, force_key) < 0) {
_h264_encoder_cleanup(enc);
return -1;
}
dest->encode_end_ts = get_now_monotonic();
LOG_VERBOSE("H264: Compressed new frame: size=%zu, time=%0.3Lf, force_key=%d",
dest->used, dest->encode_end_ts - dest->encode_begin_ts, force_key);
RUN(last_online) = src->online;
return 0;
}
static int _h264_encoder_compress_raw(h264_encoder_s *enc, const frame_s *src, frame_s *dest, bool force_key) {
assert(src->used > 0);
assert(src->width == RUN(i_width));
assert(src->height == RUN(i_height));
assert(src->format == RUN(i_format));
LOG_DEBUG("H264: Compressing new frame; force_key=%d ...", force_key);
MMAL_STATUS_T error;

View File

@ -50,9 +50,9 @@ typedef struct {
frame_s *tmp;
int last_online;
unsigned i_width;
unsigned i_height;
unsigned i_format;
unsigned width;
unsigned height;
unsigned format;
} h264_encoder_runtime_s;
typedef struct {
@ -67,4 +67,5 @@ typedef struct {
h264_encoder_s *h264_encoder_init(void);
void h264_encoder_destroy(h264_encoder_s *enc);
int h264_encoder_prepare(h264_encoder_s *enc, unsigned width, unsigned height, unsigned format);
int h264_encoder_compress(h264_encoder_s *enc, const frame_s *src, frame_s *dest);

View File

@ -428,8 +428,15 @@ static void _h264_stream_destroy(h264_stream_s *h264) {
}
static void _h264_stream_process(h264_stream_s *h264, const frame_s *frame) {
if (h264_encoder_compress(h264->enc, frame, h264->dest) == 0) {
memsink_server_put(h264->sink, h264->dest);
# define NEQ(_field) (frame->_field != h264->enc->run->_field)
if (NEQ(width) || NEQ(height) || NEQ(format)) {
# undef NEQ
h264_encoder_prepare(h264->enc, frame->width, frame->height, frame->format);
}
if (h264->enc->run->format) {
if (h264_encoder_compress(h264->enc, frame, h264->dest) == 0) {
memsink_server_put(h264->sink, h264->dest);
}
}
}
#endif