mirror of
https://github.com/pikvm/ustreamer.git
synced 2026-05-27 15:56:22 +00:00
refactoring
This commit is contained in:
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
static int _h264_encoder_configure(h264_encoder_s *encoder, const frame_s *frame);
|
static int _h264_encoder_configure(h264_encoder_s *encoder, const frame_s *frame);
|
||||||
static void _h264_encoder_cleanup(h264_encoder_s *encoder);
|
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 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);
|
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_s *h264_encoder_init(void) {
|
||||||
h264_encoder_runtime_s *run;
|
h264_encoder_runtime_s *run;
|
||||||
A_CALLOC(run, 1);
|
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;
|
h264_encoder_s *encoder;
|
||||||
A_CALLOC(encoder, 1);
|
A_CALLOC(encoder, 1);
|
||||||
@@ -49,7 +51,18 @@ h264_encoder_s *h264_encoder_init(void) {
|
|||||||
encoder->bps = 5000 * 1000; // Kbps * 1000
|
encoder->bps = 5000 * 1000; // Kbps * 1000
|
||||||
encoder->fps = 30;
|
encoder->fps = 30;
|
||||||
encoder->run = run;
|
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;
|
return encoder;
|
||||||
|
|
||||||
|
error:
|
||||||
|
h264_encoder_destroy(encoder);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void h264_encoder_destroy(h264_encoder_s *encoder) {
|
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)) {
|
if (RUN(i_handler_sem)) {
|
||||||
vcos_semaphore_delete(&RUN(handler_sem));
|
vcos_semaphore_delete(&RUN(handler_sem));
|
||||||
}
|
}
|
||||||
frame_destroy(RUN(tmp));
|
frame_destroy(RUN(unjpegged));
|
||||||
free(encoder);
|
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->used > 0);
|
||||||
assert(src->width > 0);
|
assert(src->width > 0);
|
||||||
assert(src->height > 0);
|
assert(src->height > 0);
|
||||||
assert(src->format > 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) {
|
if (src->format == V4L2_PIX_FMT_MJPEG || src->format == V4L2_PIX_FMT_JPEG) {
|
||||||
LOG_DEBUG("Input frame format is JPEG; decoding ...");
|
LOG_DEBUG("Input frame format is JPEG; decoding ...");
|
||||||
if (unjpeg(src, RUN(tmp), true) < 0) {
|
if (unjpeg(src, RUN(unjpegged), true) < 0) {
|
||||||
return -1;
|
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) {
|
if (_h264_encoder_configure(encoder, src) < 0) {
|
||||||
return -1;
|
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);
|
_h264_encoder_cleanup(encoder);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RUN(last_online) = src->online;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,8 +140,6 @@ static int _h264_encoder_configure(h264_encoder_s *encoder, const frame_s *frame
|
|||||||
|
|
||||||
_h264_encoder_cleanup(encoder);
|
_h264_encoder_cleanup(encoder);
|
||||||
|
|
||||||
LOG_INFO("Applying H264 configuration ...");
|
|
||||||
|
|
||||||
if ((error = mmal_wrapper_create(&RUN(wrapper), MMAL_COMPONENT_DEFAULT_VIDEO_ENCODER)) != MMAL_SUCCESS) {
|
if ((error = mmal_wrapper_create(&RUN(wrapper), MMAL_COMPONENT_DEFAULT_VIDEO_ENCODER)) != MMAL_SUCCESS) {
|
||||||
LOG_ERROR_MMAL(error, "Can't create MMAL wrapper");
|
LOG_ERROR_MMAL(error, "Can't create MMAL wrapper");
|
||||||
goto error;
|
goto error;
|
||||||
@@ -221,9 +226,9 @@ static int _h264_encoder_configure(h264_encoder_s *encoder, const frame_s *frame
|
|||||||
ENABLE_PORT(input);
|
ENABLE_PORT(input);
|
||||||
ENABLE_PORT(output);
|
ENABLE_PORT(output);
|
||||||
|
|
||||||
RUN(width) = frame->width;
|
RUN(i_width) = frame->width;
|
||||||
RUN(height) = frame->height;
|
RUN(i_height) = frame->height;
|
||||||
RUN(format) = frame->format;
|
RUN(i_format) = frame->format;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -261,16 +266,16 @@ static void _h264_encoder_cleanup(h264_encoder_s *encoder) {
|
|||||||
RUN(wrapper) = NULL;
|
RUN(wrapper) = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
RUN(width) = 0;
|
RUN(i_width) = 0;
|
||||||
RUN(height) = 0;
|
RUN(i_height) = 0;
|
||||||
RUN(format) = 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) {
|
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->used > 0);
|
||||||
assert(src->width == encoder->width);
|
assert(src->width == encoder->i_width);
|
||||||
assert(src->height == encoder->height);
|
assert(src->height == encoder->i_height);
|
||||||
assert(src->format == encoder->format);
|
assert(src->format == encoder->i_format);
|
||||||
|
|
||||||
MMAL_STATUS_T error;
|
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();
|
dest->encode_end_ts = get_now_monotonic();
|
||||||
LOG_VERBOSE("Compressed new H264 frame: force_key=%d, size=%zu, time=%0.3Lf",
|
LOG_VERBOSE("Compressed new H264 frame: size=%zu, time=%0.3Lf, force_key=%d",
|
||||||
force_key, dest->used, dest->encode_end_ts - dest->encode_begin_ts);
|
dest->used, dest->encode_end_ts - dest->encode_begin_ts, force_key);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,16 +47,19 @@ typedef struct {
|
|||||||
VCOS_SEMAPHORE_T handler_sem;
|
VCOS_SEMAPHORE_T handler_sem;
|
||||||
bool i_handler_sem;
|
bool i_handler_sem;
|
||||||
|
|
||||||
unsigned width;
|
frame_s *unjpegged;
|
||||||
unsigned height;
|
int last_online;
|
||||||
unsigned format;
|
|
||||||
frame_s *tmp;
|
unsigned i_width;
|
||||||
|
unsigned i_height;
|
||||||
|
unsigned i_format;
|
||||||
} h264_encoder_runtime_s;
|
} h264_encoder_runtime_s;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned gop; // Interval between keyframes
|
unsigned gop; // Interval between keyframes
|
||||||
unsigned bps; // Bit-per-sec
|
unsigned bps; // Bit-per-sec
|
||||||
unsigned fps;
|
unsigned fps;
|
||||||
|
|
||||||
h264_encoder_runtime_s *run;
|
h264_encoder_runtime_s *run;
|
||||||
} h264_encoder_s;
|
} h264_encoder_s;
|
||||||
|
|
||||||
@@ -64,4 +67,4 @@ typedef struct {
|
|||||||
h264_encoder_s *h264_encoder_init(void);
|
h264_encoder_s *h264_encoder_init(void);
|
||||||
void h264_encoder_destroy(h264_encoder_s *encoder);
|
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);
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ int main(void) {
|
|||||||
int error = 0;
|
int error = 0;
|
||||||
while ((error = memsink_client_get(memsink, src)) != -1) {
|
while ((error = memsink_client_get(memsink, src)) != -1) {
|
||||||
if (error == 0 /*|| (error == -2 && src->used > 0)*/) {
|
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);
|
LOG_INFO("frame %Lf", get_now_monotonic() - dest->grab_ts);
|
||||||
fwrite(dest->data, 1, dest->used, fp);
|
fwrite(dest->data, 1, dest->used, fp);
|
||||||
fflush(fp);
|
fflush(fp);
|
||||||
|
|||||||
Reference in New Issue
Block a user