Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

audio filter: support additional codecs #1550

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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__
Loading