diff --git a/src/ustreamer/encoder.c b/src/ustreamer/encoder.c index a59c5b4..4c2367f 100644 --- a/src/ustreamer/encoder.c +++ b/src/ustreamer/encoder.c @@ -22,6 +22,26 @@ #include "encoder.h" +#include +#include +#include + +#include + +#include "../libs/types.h" +#include "../libs/tools.h" +#include "../libs/array.h" +#include "../libs/threading.h" +#include "../libs/logging.h" +#include "../libs/frame.h" +#include "../libs/capture.h" + +#include "workers.h" +#include "m2m.h" + +#include "encoders/cpu/encoder.h" +#include "encoders/hw/encoder.h" + static const struct { const char *name; @@ -43,9 +63,6 @@ static void _worker_job_destroy(void *v_job); static bool _worker_run_job(us_worker_s *wr); -#define _ER(x_next) enc->run->x_next - - us_encoder_s *us_encoder_init(void) { us_encoder_runtime_s *run; US_CALLOC(run, 1); @@ -62,14 +79,15 @@ us_encoder_s *us_encoder_init(void) { } void us_encoder_destroy(us_encoder_s *enc) { - if (_ER(m2ms) != NULL) { - for (unsigned index = 0; index < _ER(n_m2ms); ++index) { - US_DELETE(_ER(m2ms[index]), us_m2m_encoder_destroy) + us_encoder_runtime_s *const run = enc->run; + if (run->m2ms != NULL) { + for (uint index = 0; index < run->n_m2ms; ++index) { + US_DELETE(run->m2ms[index], us_m2m_encoder_destroy); } - free(_ER(m2ms)); + free(run->m2ms); } - US_MUTEX_DESTROY(_ER(mutex)); - free(enc->run); + US_MUTEX_DESTROY(run->mutex); + free(run); free(enc); } @@ -92,79 +110,78 @@ const char *us_encoder_type_to_string(us_encoder_type_e type) { } void us_encoder_open(us_encoder_s *enc, us_capture_s *cap) { - assert(enc->run->pool == NULL); + us_encoder_runtime_s *const run = enc->run; + us_capture_runtime_s *const cr = cap->run; -# define DR(x_next) cap->run->x_next + assert(run->pool == NULL); - us_encoder_type_e type = (_ER(cpu_forced) ? US_ENCODER_TYPE_CPU : enc->type); - unsigned quality = cap->jpeg_quality; - unsigned n_workers = US_MIN(enc->n_workers, DR(n_bufs)); + us_encoder_type_e type = (run->cpu_forced ? US_ENCODER_TYPE_CPU : enc->type); + uint quality = cap->jpeg_quality; + uint n_workers = US_MIN(enc->n_workers, cr->n_bufs); bool cpu_forced = false; - if (us_is_jpeg(DR(format)) && type != US_ENCODER_TYPE_HW) { + if (us_is_jpeg(cr->format) && type != US_ENCODER_TYPE_HW) { US_LOG_INFO("Switching to HW encoder: the input is (M)JPEG ..."); type = US_ENCODER_TYPE_HW; } if (type == US_ENCODER_TYPE_HW) { - if (!us_is_jpeg(DR(format))) { + if (!us_is_jpeg(cr->format)) { US_LOG_INFO("Switching to CPU encoder: the input format is not (M)JPEG ..."); goto use_cpu; } - quality = DR(jpeg_quality); + quality = cr->jpeg_quality; n_workers = 1; } else if (type == US_ENCODER_TYPE_M2M_VIDEO || type == US_ENCODER_TYPE_M2M_IMAGE) { US_LOG_DEBUG("Preparing M2M-%s encoder ...", (type == US_ENCODER_TYPE_M2M_VIDEO ? "VIDEO" : "IMAGE")); - if (_ER(m2ms) == NULL) { - US_CALLOC(_ER(m2ms), n_workers); + if (run->m2ms == NULL) { + US_CALLOC(run->m2ms, n_workers); } - for (; _ER(n_m2ms) < n_workers; ++_ER(n_m2ms)) { + for (; run->n_m2ms < n_workers; ++run->n_m2ms) { // Начинаем с нуля и доинициализируем на следующих заходах при необходимости char name[32]; - US_SNPRINTF(name, 31, "JPEG-%u", _ER(n_m2ms)); + US_SNPRINTF(name, 31, "JPEG-%u", run->n_m2ms); if (type == US_ENCODER_TYPE_M2M_VIDEO) { - _ER(m2ms[_ER(n_m2ms)]) = us_m2m_mjpeg_encoder_init(name, enc->m2m_path, quality); + run->m2ms[run->n_m2ms] = us_m2m_mjpeg_encoder_init(name, enc->m2m_path, quality); } else { - _ER(m2ms[_ER(n_m2ms)]) = us_m2m_jpeg_encoder_init(name, enc->m2m_path, quality); + run->m2ms[run->n_m2ms] = us_m2m_jpeg_encoder_init(name, enc->m2m_path, quality); } } } goto ok; - use_cpu: - type = US_ENCODER_TYPE_CPU; - quality = cap->jpeg_quality; +use_cpu: + type = US_ENCODER_TYPE_CPU; + quality = cap->jpeg_quality; - ok: - if (quality == 0) { - US_LOG_INFO("Using JPEG quality: encoder default"); - } else { - US_LOG_INFO("Using JPEG quality: %u%%", quality); - } +ok: + if (quality == 0) { + US_LOG_INFO("Using JPEG quality: encoder default"); + } else { + US_LOG_INFO("Using JPEG quality: %u%%", quality); + } - US_MUTEX_LOCK(_ER(mutex)); - _ER(type) = type; - _ER(quality) = quality; - if (cpu_forced) { - _ER(cpu_forced) = true; - } - US_MUTEX_UNLOCK(_ER(mutex)); + US_MUTEX_LOCK(run->mutex); + run->type = type; + run->quality = quality; + if (cpu_forced) { + run->cpu_forced = true; + } + US_MUTEX_UNLOCK(run->mutex); - const long double desired_interval = ( - cap->desired_fps > 0 && (cap->desired_fps < cap->run->hw_fps || cap->run->hw_fps == 0) - ? (long double)1 / cap->desired_fps - : 0 - ); + const ldf desired_interval = ( + cap->desired_fps > 0 && (cap->desired_fps < cap->run->hw_fps || cap->run->hw_fps == 0) + ? (ldf)1 / cap->desired_fps + : 0 + ); - enc->run->pool = us_workers_pool_init( - "JPEG", "jw", n_workers, desired_interval, - _worker_job_init, (void*)enc, - _worker_job_destroy, - _worker_run_job); - -# undef DR + enc->run->pool = us_workers_pool_init( + "JPEG", "jw", n_workers, desired_interval, + _worker_job_init, (void*)enc, + _worker_job_destroy, + _worker_run_job); } void us_encoder_close(us_encoder_s *enc) { @@ -172,11 +189,12 @@ void us_encoder_close(us_encoder_s *enc) { US_DELETE(enc->run->pool, us_workers_pool_destroy); } -void us_encoder_get_runtime_params(us_encoder_s *enc, us_encoder_type_e *type, unsigned *quality) { - US_MUTEX_LOCK(_ER(mutex)); - *type = _ER(type); - *quality = _ER(quality); - US_MUTEX_UNLOCK(_ER(mutex)); +void us_encoder_get_runtime_params(us_encoder_s *enc, us_encoder_type_e *type, uint *quality) { + us_encoder_runtime_s *const run = enc->run; + US_MUTEX_LOCK(run->mutex); + *type = run->type; + *quality = run->quality; + US_MUTEX_UNLOCK(run->mutex); } static void *_worker_job_init(void *v_enc) { @@ -194,25 +212,25 @@ static void _worker_job_destroy(void *v_job) { } static bool _worker_run_job(us_worker_s *wr) { - us_encoder_job_s *job = wr->job; - us_encoder_s *enc = job->enc; // Just for _ER() - const us_frame_s *src = &job->hw->raw; - us_frame_s *dest = job->dest; + us_encoder_job_s *const job = wr->job; + us_encoder_runtime_s *const run = job->enc->run; + const us_frame_s *const src = &job->hw->raw; + us_frame_s *const dest = job->dest; - if (_ER(type) == US_ENCODER_TYPE_CPU) { + if (run->type == US_ENCODER_TYPE_CPU) { US_LOG_VERBOSE("Compressing JPEG using CPU: worker=%s, buffer=%u", wr->name, job->hw->buf.index); - us_cpu_encoder_compress(src, dest, _ER(quality)); + us_cpu_encoder_compress(src, dest, run->quality); - } else if (_ER(type) == US_ENCODER_TYPE_HW) { + } else if (run->type == US_ENCODER_TYPE_HW) { US_LOG_VERBOSE("Compressing JPEG using HW (just copying): worker=%s, buffer=%u", wr->name, job->hw->buf.index); us_hw_encoder_compress(src, dest); - } else if (_ER(type) == US_ENCODER_TYPE_M2M_VIDEO || _ER(type) == US_ENCODER_TYPE_M2M_IMAGE) { + } else if (run->type == US_ENCODER_TYPE_M2M_VIDEO || run->type == US_ENCODER_TYPE_M2M_IMAGE) { US_LOG_VERBOSE("Compressing JPEG using M2M-%s: worker=%s, buffer=%u", - (_ER(type) == US_ENCODER_TYPE_M2M_VIDEO ? "VIDEO" : "IMAGE"), wr->name, job->hw->buf.index); - if (us_m2m_encoder_compress(_ER(m2ms[wr->number]), src, dest, false) < 0) { + (run->type == US_ENCODER_TYPE_M2M_VIDEO ? "VIDEO" : "IMAGE"), wr->name, job->hw->buf.index); + if (us_m2m_encoder_compress(run->m2ms[wr->number], src, dest, false) < 0) { goto error; } @@ -228,11 +246,11 @@ static bool _worker_run_job(us_worker_s *wr) { return true; - error: - US_LOG_ERROR("Compression failed: worker=%s, buffer=%u", wr->name, job->hw->buf.index); - US_LOG_ERROR("Error while compressing buffer, falling back to CPU"); - US_MUTEX_LOCK(_ER(mutex)); - _ER(cpu_forced) = true; - US_MUTEX_UNLOCK(_ER(mutex)); - return false; +error: + US_LOG_ERROR("Compression failed: worker=%s, buffer=%u", wr->name, job->hw->buf.index); + US_LOG_ERROR("Error while compressing buffer, falling back to CPU"); + US_MUTEX_LOCK(run->mutex); + run->cpu_forced = true; + US_MUTEX_UNLOCK(run->mutex); + return false; } diff --git a/src/ustreamer/encoder.h b/src/ustreamer/encoder.h index 21a810a..42a1973 100644 --- a/src/ustreamer/encoder.h +++ b/src/ustreamer/encoder.h @@ -22,30 +22,19 @@ #pragma once -#include -#include -#include -#include - #include -#include -#include "../libs/tools.h" -#include "../libs/array.h" -#include "../libs/threading.h" -#include "../libs/logging.h" +#include "../libs/types.h" #include "../libs/frame.h" #include "../libs/capture.h" #include "workers.h" #include "m2m.h" -#include "encoders/cpu/encoder.h" -#include "encoders/hw/encoder.h" - #define ENCODER_TYPES_STR "CPU, HW, M2M-VIDEO, M2M-IMAGE" + typedef enum { US_ENCODER_TYPE_CPU, US_ENCODER_TYPE_HW, @@ -55,11 +44,11 @@ typedef enum { typedef struct { us_encoder_type_e type; - unsigned quality; + uint quality; bool cpu_forced; pthread_mutex_t mutex; - unsigned n_m2ms; + uint n_m2ms; us_m2m_encoder_s **m2ms; us_workers_pool_s *pool; @@ -67,7 +56,7 @@ typedef struct { typedef struct { us_encoder_type_e type; - unsigned n_workers; + uint n_workers; char *m2m_path; us_encoder_runtime_s *run; @@ -89,4 +78,4 @@ const char *us_encoder_type_to_string(us_encoder_type_e type); void us_encoder_open(us_encoder_s *enc, us_capture_s *cap); void us_encoder_close(us_encoder_s *enc); -void us_encoder_get_runtime_params(us_encoder_s *enc, us_encoder_type_e *type, unsigned *quality); +void us_encoder_get_runtime_params(us_encoder_s *enc, us_encoder_type_e *type, uint *quality);