Skip to content

Commit

Permalink
audio filter: support additional codecs
Browse files Browse the repository at this point in the history
support additional input codecs in audio filters, output is currently
hardcoded to AAC
  • Loading branch information
erankor committed Nov 9, 2024
1 parent 26f0687 commit 245901a
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 55 deletions.
53 changes: 36 additions & 17 deletions vod/filters/audio_decoder.c
Original file line number Diff line number Diff line change
@@ -1,36 +1,62 @@
#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
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);
Expand Down Expand Up @@ -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
Expand Down
41 changes: 13 additions & 28 deletions vod/filters/audio_encoder.c
Original file line number Diff line number Diff line change
@@ -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)
Expand All @@ -14,31 +15,14 @@ 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",
"aac",
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)
{
Expand Down Expand Up @@ -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
Expand All @@ -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");
Expand All @@ -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;
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -357,3 +336,9 @@ audio_encoder_update_media_info(

return VOD_OK;
}

enum AVSampleFormat
audio_encoder_get_format()
{
return audio_encoder_format;
}
5 changes: 2 additions & 3 deletions vod/filters/audio_encoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@
#include "../media_format.h"
#include <libavcodec/avcodec.h>

// constants
#define AUDIO_ENCODER_INPUT_SAMPLE_FORMAT (AV_SAMPLE_FMT_S16)

//typedefs
typedef struct
{
Expand Down Expand Up @@ -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__
8 changes: 4 additions & 4 deletions vod/filters/audio_filter.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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,
Expand Down
7 changes: 7 additions & 0 deletions vod/filters/volume_map.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -447,3 +448,9 @@ volume_map_writer_process(void* context)
}
}
}

enum AVSampleFormat
volume_map_encoder_get_format()
{
return VOLUME_MAP_INPUT_SAMPLE_FORMAT;
}
5 changes: 2 additions & 3 deletions vod/filters/volume_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@
#include "../media_set.h"
#include <libavcodec/avcodec.h>

// 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,
Expand Down Expand Up @@ -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__

0 comments on commit 245901a

Please sign in to comment.