mirror of
https://github.com/pikvm/ustreamer.git
synced 2026-02-19 08:16:31 +00:00
145 lines
4.3 KiB
C
145 lines
4.3 KiB
C
/*****************************************************************************
|
|
# uStreamer - Lightweight and fast MJPG-HTTP streamer. #
|
|
# #
|
|
# Copyright (C) 2018 Maxim Devaev <mdevaev@gmail.com> #
|
|
# #
|
|
# This program is free software: you can redistribute it and/or modify #
|
|
# it under the terms of the GNU General Public License as published by #
|
|
# the Free Software Foundation, either version 3 of the License, or #
|
|
# (at your option) any later version. #
|
|
# #
|
|
# This program is distributed in the hope that it will be useful, #
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
|
# GNU General Public License for more details. #
|
|
# #
|
|
# You should have received a copy of the GNU General Public License #
|
|
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
|
|
# #
|
|
*****************************************************************************/
|
|
|
|
|
|
#include <strings.h>
|
|
#include <assert.h>
|
|
|
|
#include "tools.h"
|
|
#include "logging.h"
|
|
#include "device.h"
|
|
#include "encoder.h"
|
|
|
|
#include "jpeg/encoder.h"
|
|
|
|
#ifdef OMX_ENCODER
|
|
# include "omx/encoder.h"
|
|
#endif
|
|
|
|
|
|
static const struct {
|
|
const char *name;
|
|
const enum encoder_type_t type;
|
|
} ENCODER_TYPES[] = {
|
|
{"CPU", ENCODER_TYPE_CPU},
|
|
# ifdef OMX_ENCODER
|
|
{"OMX", ENCODER_TYPE_OMX},
|
|
# endif
|
|
};
|
|
|
|
|
|
struct encoder_t *encoder_init(enum encoder_type_t type) {
|
|
struct encoder_t *encoder;
|
|
|
|
assert(type != ENCODER_TYPE_UNKNOWN);
|
|
A_CALLOC(encoder, 1);
|
|
encoder->type = type;
|
|
|
|
if (encoder->type != ENCODER_TYPE_CPU) {
|
|
LOG_DEBUG("Initializing encoder ...");
|
|
}
|
|
|
|
# ifdef OMX_ENCODER
|
|
if (type == ENCODER_TYPE_OMX) {
|
|
if ((encoder->omx = omx_encoder_init()) == NULL) {
|
|
goto use_fallback;
|
|
}
|
|
}
|
|
# endif
|
|
|
|
return encoder;
|
|
|
|
# pragma GCC diagnostic ignored "-Wunused-label"
|
|
# pragma GCC diagnostic push
|
|
use_fallback:
|
|
LOG_ERROR("Can't initialize selected encoder, using CPU instead it");
|
|
encoder->type = ENCODER_TYPE_CPU;
|
|
return encoder;
|
|
# pragma GCC diagnostic pop
|
|
}
|
|
|
|
void encoder_destroy(struct encoder_t *encoder) {
|
|
# ifdef OMX_ENCODER
|
|
if (encoder->omx) {
|
|
omx_encoder_destroy(encoder->omx);
|
|
}
|
|
# endif
|
|
free(encoder);
|
|
}
|
|
|
|
enum encoder_type_t encoder_parse_type(const char *const str) {
|
|
for (unsigned index = 0; index < sizeof(ENCODER_TYPES) / sizeof(ENCODER_TYPES[0]); ++index) {
|
|
if (!strcasecmp(str, ENCODER_TYPES[index].name)) {
|
|
return ENCODER_TYPES[index].type;
|
|
}
|
|
}
|
|
return ENCODER_TYPE_UNKNOWN;
|
|
}
|
|
|
|
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
|
#pragma GCC diagnostic push
|
|
void encoder_prepare(struct encoder_t *encoder, struct device_t *dev) {
|
|
#pragma GCC diagnostic pop
|
|
# ifdef OMX_ENCODER
|
|
if (encoder->type == ENCODER_TYPE_OMX) {
|
|
if (omx_encoder_prepare(encoder->omx, dev) < 0) {
|
|
goto use_fallback;
|
|
}
|
|
if (dev->run->n_workers > 1) {
|
|
LOG_INFO("OMX encoder can only work with one worker thread; forcing n_workers to 1");
|
|
dev->run->n_workers = 1;
|
|
}
|
|
}
|
|
# endif
|
|
|
|
return;
|
|
|
|
# pragma GCC diagnostic ignored "-Wunused-label"
|
|
# pragma GCC diagnostic push
|
|
use_fallback:
|
|
LOG_ERROR("Can't prepare selected encoder, falling back to CPU");
|
|
encoder->type = ENCODER_TYPE_CPU;
|
|
dev->run->n_workers = dev->n_workers;
|
|
# pragma GCC diagnostic pop
|
|
}
|
|
|
|
int encoder_compress_buffer(struct encoder_t *encoder, struct device_t *dev, int index) {
|
|
if (encoder->type == ENCODER_TYPE_CPU) {
|
|
jpeg_encoder_compress_buffer(dev, index);
|
|
}
|
|
# ifdef OMX_ENCODER
|
|
else if (encoder->type == ENCODER_TYPE_OMX) {
|
|
if (omx_encoder_compress_buffer(encoder->omx, dev, index) < 0) {
|
|
goto error;
|
|
}
|
|
}
|
|
# endif
|
|
return 0;
|
|
|
|
# pragma GCC diagnostic ignored "-Wunused-label"
|
|
# pragma GCC diagnostic push
|
|
error:
|
|
LOG_INFO("HW compressing error, falling back to CPU");
|
|
encoder->type = ENCODER_TYPE_CPU;
|
|
dev->run->n_workers = dev->n_workers;
|
|
return -1;
|
|
# pragma GCC diagnostic pop
|
|
}
|