From 245901a4d1f7f1f195926c4b72321eb52e2ebb1a Mon Sep 17 00:00:00 2001 From: erankor Date: Sat, 9 Nov 2024 17:11:35 +0200 Subject: [PATCH] audio filter: support additional codecs support additional input codecs in audio filters, output is currently hardcoded to AAC --- vod/filters/audio_decoder.c | 53 +++++++++++++++++++++++++------------ vod/filters/audio_encoder.c | 41 +++++++++------------------- vod/filters/audio_encoder.h | 5 ++-- vod/filters/audio_filter.c | 8 +++--- vod/filters/volume_map.c | 7 +++++ vod/filters/volume_map.h | 5 ++-- 6 files changed, 64 insertions(+), 55 deletions(-) diff --git a/vod/filters/audio_decoder.c b/vod/filters/audio_decoder.c index 87b13d2b..f00e1488 100644 --- a/vod/filters/audio_decoder.c +++ b/vod/filters/audio_decoder.c @@ -1,25 +1,49 @@ #include "audio_decoder.h" // globals -static const AVCodec *decoder_codec = NULL; -static bool_t initialized = FALSE; +static const AVCodec *decoder_codecs[VOD_CODEC_ID_COUNT]; + +typedef struct { + const char *name; + uint32_t vod_codec; + enum AVCodecID av_codec; +} audio_codec_mapping_t; + +static audio_codec_mapping_t audio_codec_mapping[] = { + { "aac", VOD_CODEC_ID_AAC, AV_CODEC_ID_AAC }, + { "ac3", VOD_CODEC_ID_AC3, AV_CODEC_ID_AC3 }, + { "eac3", VOD_CODEC_ID_EAC3, AV_CODEC_ID_EAC3 }, + { "mp3", VOD_CODEC_ID_MP3, AV_CODEC_ID_MP3 }, + { "dts", VOD_CODEC_ID_DTS, AV_CODEC_ID_DTS }, + { "vorbis", VOD_CODEC_ID_VORBIS, AV_CODEC_ID_VORBIS }, + { "opus", VOD_CODEC_ID_OPUS, AV_CODEC_ID_OPUS }, + + { NULL, VOD_CODEC_ID_INVALID, AV_CODEC_ID_NONE } +}; void audio_decoder_process_init(vod_log_t* log) { + audio_codec_mapping_t* mapping; + const AVCodec* decoder_codec; + #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 18, 100) avcodec_register_all(); #endif - decoder_codec = avcodec_find_decoder(AV_CODEC_ID_AAC); - if (decoder_codec == NULL) + vod_memzero(decoder_codecs, sizeof(decoder_codecs)); + + for (mapping = audio_codec_mapping; mapping->vod_codec != VOD_CODEC_ID_INVALID; mapping++) { - vod_log_error(VOD_LOG_WARN, log, 0, - "audio_decoder_process_init: failed to get AAC decoder, audio decoding is disabled"); - return; - } + decoder_codec = avcodec_find_decoder(mapping->av_codec); + if (decoder_codec == NULL) + { + vod_log_error(VOD_LOG_WARN, log, 0, + "audio_decoder_process_init: failed to get %s decoder, audio decoding for this codec is disabled", mapping->name); + } - initialized = TRUE; + decoder_codecs[mapping->vod_codec] = decoder_codec; + } } static vod_status_t @@ -27,10 +51,12 @@ audio_decoder_init_decoder( audio_decoder_state_t* state, media_info_t* media_info) { + const AVCodec *decoder_codec; AVCodecContext* decoder; int avrc; - if (media_info->codec_id != VOD_CODEC_ID_AAC) + decoder_codec = decoder_codecs[media_info->codec_id]; + if (decoder_codec == NULL) { vod_log_error(VOD_LOG_ERR, state->request_context->log, 0, "audio_decoder_init_decoder: codec id %uD not supported", media_info->codec_id); @@ -89,13 +115,6 @@ audio_decoder_init( input_frame_t* cur_frame; vod_status_t rc; - if (!initialized) - { - vod_log_error(VOD_LOG_ERR, request_context->log, 0, - "audio_decoder_init: module failed to initialize successfully"); - return VOD_UNEXPECTED; - } - state->request_context = request_context; // init the decoder diff --git a/vod/filters/audio_encoder.c b/vod/filters/audio_encoder.c index f27ccb93..1791b252 100644 --- a/vod/filters/audio_encoder.c +++ b/vod/filters/audio_encoder.c @@ -1,5 +1,6 @@ #include "audio_encoder.h" #include "audio_filter.h" +#include "../mp4/mp4_defs.h" // constants #define AUDIO_ENCODER_BITS_PER_SAMPLE (16) @@ -14,7 +15,7 @@ typedef struct // globals static const AVCodec *encoder_codec = NULL; -static bool_t initialized = FALSE; +static enum AVSampleFormat audio_encoder_format = AV_SAMPLE_FMT_NONE; static char* aac_encoder_names[] = { "libfdk_aac", @@ -22,23 +23,6 @@ static char* aac_encoder_names[] = { NULL }; - -static bool_t -audio_encoder_is_format_supported(const AVCodec *codec, enum AVSampleFormat sample_fmt) -{ - const enum AVSampleFormat *p; - - for (p = codec->sample_fmts; *p != AV_SAMPLE_FMT_NONE; p++) - { - if (*p == sample_fmt) - { - return TRUE; - } - } - - return FALSE; -} - void audio_encoder_process_init(vod_log_t* log) { @@ -66,14 +50,7 @@ audio_encoder_process_init(vod_log_t* log) } } - if (!audio_encoder_is_format_supported(encoder_codec, AUDIO_ENCODER_INPUT_SAMPLE_FORMAT)) - { - vod_log_error(VOD_LOG_WARN, log, 0, - "audio_encoder_process_init: encoder does not support the required input format, audio encoding is disabled"); - return; - } - - initialized = TRUE; + audio_encoder_format = *encoder_codec->sample_fmts; } vod_status_t @@ -87,7 +64,7 @@ audio_encoder_init( AVCodecContext* encoder; int avrc; - if (!initialized) + if (audio_encoder_format == AV_SAMPLE_FMT_NONE) { vod_log_error(VOD_LOG_ERR, request_context->log, 0, "audio_encoder_init: module failed to initialize successfully"); @@ -113,7 +90,7 @@ audio_encoder_init( state->encoder = encoder; - encoder->sample_fmt = AUDIO_ENCODER_INPUT_SAMPLE_FORMAT; + encoder->sample_fmt = audio_encoder_format; encoder->time_base.num = 1; encoder->time_base.den = params->timescale; encoder->sample_rate = params->sample_rate; @@ -326,6 +303,8 @@ audio_encoder_update_media_info( return VOD_UNEXPECTED; } + media_info->format = FORMAT_MP4A; + media_info->codec_id = VOD_CODEC_ID_AAC; media_info->timescale = encoder->time_base.den; media_info->bitrate = encoder->bit_rate; @@ -357,3 +336,9 @@ audio_encoder_update_media_info( return VOD_OK; } + +enum AVSampleFormat +audio_encoder_get_format() +{ + return audio_encoder_format; +} diff --git a/vod/filters/audio_encoder.h b/vod/filters/audio_encoder.h index 70185790..d27df60b 100644 --- a/vod/filters/audio_encoder.h +++ b/vod/filters/audio_encoder.h @@ -5,9 +5,6 @@ #include "../media_format.h" #include -// constants -#define AUDIO_ENCODER_INPUT_SAMPLE_FORMAT (AV_SAMPLE_FMT_S16) - //typedefs typedef struct { @@ -45,4 +42,6 @@ vod_status_t audio_encoder_update_media_info( void* context, media_info_t* media_info); +enum AVSampleFormat audio_encoder_get_format(); + #endif // __AUDIO_ENCODER_H__ diff --git a/vod/filters/audio_filter.c b/vod/filters/audio_filter.c index 0daeaf0e..50d147f3 100644 --- a/vod/filters/audio_filter.c +++ b/vod/filters/audio_filter.c @@ -33,12 +33,12 @@ // typedefs typedef struct { - enum AVSampleFormat format; void (*free)(void* context); size_t (*get_frame_size)(void* context); vod_status_t (*write)(void* context, AVFrame* frame); vod_status_t(*flush)(void* context); vod_status_t(*update_media_info)(void* context, media_info_t* media_info); + enum AVSampleFormat (*get_format)(); } audio_filter_encoder_t; typedef struct @@ -58,21 +58,21 @@ typedef struct // constants static audio_filter_encoder_t libav_encoder = { - AUDIO_ENCODER_INPUT_SAMPLE_FORMAT, audio_encoder_free, audio_encoder_get_frame_size, audio_encoder_write_frame, audio_encoder_flush, audio_encoder_update_media_info, + audio_encoder_get_format, }; static audio_filter_encoder_t volume_map_encoder = { - VOLUME_MAP_INPUT_SAMPLE_FORMAT, NULL, NULL, volume_map_encoder_write_frame, NULL, volume_map_encoder_update_media_info, + volume_map_encoder_get_format, }; #endif @@ -394,7 +394,7 @@ audio_filter_init_sink( } // configure the buffer sink - out_sample_fmts[0] = sink->encoder->format; + out_sample_fmts[0] = sink->encoder->get_format(); out_sample_fmts[1] = -1; avrc = av_opt_set_int_list( sink->buffer_sink, diff --git a/vod/filters/volume_map.c b/vod/filters/volume_map.c index acbdc729..273009a5 100644 --- a/vod/filters/volume_map.c +++ b/vod/filters/volume_map.c @@ -4,6 +4,7 @@ #include "../write_buffer.h" // constants +#define VOLUME_MAP_INPUT_SAMPLE_FORMAT (AV_SAMPLE_FMT_FLTP) #define RMS_LEVEL_PRECISION (100) #define RMS_LEVEL_FORMAT "%uD.%02uD\n" @@ -447,3 +448,9 @@ volume_map_writer_process(void* context) } } } + +enum AVSampleFormat +volume_map_encoder_get_format() +{ + return VOLUME_MAP_INPUT_SAMPLE_FORMAT; +} diff --git a/vod/filters/volume_map.h b/vod/filters/volume_map.h index 7d07846d..47e1e645 100644 --- a/vod/filters/volume_map.h +++ b/vod/filters/volume_map.h @@ -5,9 +5,6 @@ #include "../media_set.h" #include -// constants -#define VOLUME_MAP_INPUT_SAMPLE_FORMAT (AV_SAMPLE_FMT_FLTP) - // audio filter encoder functions vod_status_t volume_map_encoder_init( request_context_t* request_context, @@ -35,4 +32,6 @@ vod_status_t volume_map_writer_init( vod_status_t volume_map_writer_process( void* state); +enum AVSampleFormat volume_map_encoder_get_format(); + #endif // __VOLUME_MAP_H__