refactoring

This commit is contained in:
Devaev Maxim
2021-01-03 12:24:01 +03:00
parent 0ccf540417
commit 3fdd69b444
3 changed files with 43 additions and 35 deletions

View File

@@ -25,6 +25,7 @@
static int _h264_encoder_configure(h264_encoder_s *encoder, const frame_s *frame);
static void _h264_encoder_cleanup(h264_encoder_s *encoder);
static int _h264_encoder_compress_raw(h264_encoder_s *encoder, const frame_s *src, frame_s *dest, bool force_key);
static void _mmal_callback(MMAL_WRAPPER_T *wrapper);
@@ -41,7 +42,8 @@ static const char *_mmal_error_to_string(MMAL_STATUS_T error);
h264_encoder_s *h264_encoder_init(void) {
h264_encoder_runtime_s *run;
A_CALLOC(run, 1);
run->tmp = frame_init("h264_tmp");
run->unjpegged = frame_init("h264_unjpegged_src");
run->last_online = -1;
h264_encoder_s *encoder;
A_CALLOC(encoder, 1);
@@ -49,7 +51,18 @@ h264_encoder_s *h264_encoder_init(void) {
encoder->bps = 5000 * 1000; // Kbps * 1000
encoder->fps = 30;
encoder->run = run;
if (vcos_semaphore_create(&run->handler_sem, "h264_handler_sem", 0) != VCOS_SUCCESS) {
LOG_PERROR("Can't create VCOS semaphore");
goto error;
}
run->i_handler_sem = true;
return encoder;
error:
h264_encoder_destroy(encoder);
return NULL;
}
void h264_encoder_destroy(h264_encoder_s *encoder) {
@@ -57,43 +70,37 @@ void h264_encoder_destroy(h264_encoder_s *encoder) {
if (RUN(i_handler_sem)) {
vcos_semaphore_delete(&RUN(handler_sem));
}
frame_destroy(RUN(tmp));
frame_destroy(RUN(unjpegged));
free(encoder);
}
int h264_encoder_compress(h264_encoder_s *encoder, const frame_s *src, frame_s *dest, bool force_key) {
int h264_encoder_compress(h264_encoder_s *encoder, const frame_s *src, frame_s *dest) {
assert(src->used > 0);
assert(src->width > 0);
assert(src->height > 0);
assert(src->format > 0);
if (!RUN(i_handler_sem)) {
if (vcos_semaphore_create(&RUN(handler_sem), "h264_handler_sem", 0) != VCOS_SUCCESS) {
LOG_PERROR("Can't create VCOS semaphore");
return -1;
}
RUN(i_handler_sem) = true;
}
if (src->format == V4L2_PIX_FMT_MJPEG || src->format == V4L2_PIX_FMT_JPEG) {
LOG_DEBUG("Input frame format is JPEG; decoding ...");
if (unjpeg(src, RUN(tmp), true) < 0) {
if (unjpeg(src, RUN(unjpegged), true) < 0) {
return -1;
}
src = RUN(tmp);
src = RUN(unjpegged);
}
if (RUN(width) != src->width || RUN(height) != src->height || RUN(format) != src->format) {
if (RUN(i_width) != src->width || RUN(i_height) != src->height || RUN(i_format) != src->format) {
if (_h264_encoder_configure(encoder, src) < 0) {
return -1;
}
force_key = true;
RUN(last_online) = -1;
}
if (_h264_encoder_compress_raw(encoder, src, dest, force_key) < 0) {
if (_h264_encoder_compress_raw(encoder, src, dest, (RUN(last_online) != src->online)) < 0) {
_h264_encoder_cleanup(encoder);
return -1;
}
RUN(last_online) = src->online;
return 0;
}
@@ -133,8 +140,6 @@ static int _h264_encoder_configure(h264_encoder_s *encoder, const frame_s *frame
_h264_encoder_cleanup(encoder);
LOG_INFO("Applying H264 configuration ...");
if ((error = mmal_wrapper_create(&RUN(wrapper), MMAL_COMPONENT_DEFAULT_VIDEO_ENCODER)) != MMAL_SUCCESS) {
LOG_ERROR_MMAL(error, "Can't create MMAL wrapper");
goto error;
@@ -221,9 +226,9 @@ static int _h264_encoder_configure(h264_encoder_s *encoder, const frame_s *frame
ENABLE_PORT(input);
ENABLE_PORT(output);
RUN(width) = frame->width;
RUN(height) = frame->height;
RUN(format) = frame->format;
RUN(i_width) = frame->width;
RUN(i_height) = frame->height;
RUN(i_format) = frame->format;
return 0;
@@ -261,16 +266,16 @@ static void _h264_encoder_cleanup(h264_encoder_s *encoder) {
RUN(wrapper) = NULL;
}
RUN(width) = 0;
RUN(height) = 0;
RUN(format) = 0;
RUN(i_width) = 0;
RUN(i_height) = 0;
RUN(i_format) = 0;
}
static int _h264_encoder_compress_raw(h264_encoder_s *encoder, const frame_s *src, frame_s *dest, bool force_key) {
assert(src->used > 0);
assert(src->width == encoder->width);
assert(src->height == encoder->height);
assert(src->format == encoder->format);
assert(src->width == encoder->i_width);
assert(src->height == encoder->i_height);
assert(src->format == encoder->i_format);
MMAL_STATUS_T error;
@@ -339,8 +344,8 @@ static int _h264_encoder_compress_raw(h264_encoder_s *encoder, const frame_s *sr
}
dest->encode_end_ts = get_now_monotonic();
LOG_VERBOSE("Compressed new H264 frame: force_key=%d, size=%zu, time=%0.3Lf",
force_key, dest->used, dest->encode_end_ts - dest->encode_begin_ts);
LOG_VERBOSE("Compressed new H264 frame: size=%zu, time=%0.3Lf, force_key=%d",
dest->used, dest->encode_end_ts - dest->encode_begin_ts, force_key);
return 0;
}

View File

@@ -47,16 +47,19 @@ typedef struct {
VCOS_SEMAPHORE_T handler_sem;
bool i_handler_sem;
unsigned width;
unsigned height;
unsigned format;
frame_s *tmp;
frame_s *unjpegged;
int last_online;
unsigned i_width;
unsigned i_height;
unsigned i_format;
} h264_encoder_runtime_s;
typedef struct {
unsigned gop; // Interval between keyframes
unsigned bps; // Bit-per-sec
unsigned fps;
h264_encoder_runtime_s *run;
} h264_encoder_s;
@@ -64,4 +67,4 @@ typedef struct {
h264_encoder_s *h264_encoder_init(void);
void h264_encoder_destroy(h264_encoder_s *encoder);
int h264_encoder_compress(h264_encoder_s *encoder, const frame_s *src, frame_s *dest, bool force_key);
int h264_encoder_compress(h264_encoder_s *encoder, const frame_s *src, frame_s *dest);

View File

@@ -25,7 +25,7 @@ int main(void) {
int error = 0;
while ((error = memsink_client_get(memsink, src)) != -1) {
if (error == 0 /*|| (error == -2 && src->used > 0)*/) {
if (!h264_encoder_compress(encoder, src, dest, false)) {
if (!h264_encoder_compress(encoder, src, dest)) {
LOG_INFO("frame %Lf", get_now_monotonic() - dest->grab_ts);
fwrite(dest->data, 1, dest->used, fp);
fflush(fp);