mirror of https://github.com/FFmpeg/FFmpeg.git
There is no need to have 2 encoders, the input sample format can,does and should choose which is used Signed-off-by: Michael Niedermayer <michaelni@gmx.at>oldabi
parent
bdf3d3bf9d
commit
1aeb88b77d
7 changed files with 145 additions and 40 deletions
@ -0,0 +1,90 @@ |
||||
|
||||
#include "libavutil/opt.h" |
||||
#include "libavutil/samplefmt.h" |
||||
#include "avcodec.h" |
||||
#include "ac3.h" |
||||
|
||||
typedef struct CombineContext{ |
||||
AVClass *av_class; ///< AVClass used for AVOption
|
||||
AC3EncOptions options; ///< encoding options
|
||||
void *ctx; |
||||
AVCodec *codec; |
||||
}CombineContext; |
||||
|
||||
static AVClass ac3enc_class = { "AC-3 Encoder", av_default_item_name, |
||||
ff_ac3_options, LIBAVUTIL_VERSION_INT }; |
||||
|
||||
static av_cold AVCodec *get_codec(enum AVSampleFormat s){ |
||||
#if CONFIG_AC3_FIXED_ENCODER |
||||
if(s==AV_SAMPLE_FMT_S16) return &ff_ac3_fixed_encoder; |
||||
#endif |
||||
#if CONFIG_AC3_FLOAT_ENCODER |
||||
if(s==AV_SAMPLE_FMT_FLT) return &ff_ac3_float_encoder; |
||||
#endif |
||||
return NULL; |
||||
} |
||||
|
||||
|
||||
static av_cold int encode_init(AVCodecContext *avctx) |
||||
{ |
||||
CombineContext *c= avctx->priv_data; |
||||
int ret; |
||||
int offset= (uint8_t*)&c->options - (uint8_t*)c; |
||||
|
||||
c->codec= get_codec(avctx->sample_fmt); |
||||
if(!c->codec){ |
||||
av_log(avctx, AV_LOG_ERROR, "Unsupported sample format\n"); |
||||
return -1; |
||||
} |
||||
c->ctx= av_mallocz(c->codec->priv_data_size); |
||||
memcpy((uint8_t*)c->ctx + offset, &c->options, (uint8_t*)&c->ctx - (uint8_t*)&c->options); |
||||
FFSWAP(void *,avctx->priv_data, c->ctx); |
||||
ret= c->codec->init(avctx); |
||||
FFSWAP(void *,avctx->priv_data, c->ctx); |
||||
return ret; |
||||
} |
||||
|
||||
static int encode_frame(AVCodecContext *avctx, unsigned char *frame, |
||||
int buf_size, void *data) |
||||
{ |
||||
CombineContext *c= avctx->priv_data; |
||||
int ret; |
||||
|
||||
FFSWAP(void *,avctx->priv_data, c->ctx); |
||||
ret= c->codec->encode(avctx, frame, buf_size, data); |
||||
FFSWAP(void *,avctx->priv_data, c->ctx); |
||||
return ret; |
||||
} |
||||
|
||||
static av_cold int encode_close(AVCodecContext *avctx) |
||||
{ |
||||
CombineContext *c= avctx->priv_data; |
||||
int ret; |
||||
|
||||
FFSWAP(void *,avctx->priv_data, c->ctx); |
||||
ret= c->codec->close(avctx); |
||||
FFSWAP(void *,avctx->priv_data, c->ctx); |
||||
return ret; |
||||
} |
||||
|
||||
AVCodec ff_ac3_encoder = { |
||||
"ac3", |
||||
AVMEDIA_TYPE_AUDIO, |
||||
CODEC_ID_AC3, |
||||
sizeof(CombineContext), |
||||
encode_init, |
||||
encode_frame, |
||||
encode_close, |
||||
NULL, |
||||
.sample_fmts = (const enum AVSampleFormat[]){ |
||||
#if CONFIG_AC3_FLOAT_ENCODER |
||||
AV_SAMPLE_FMT_FLT, |
||||
#endif |
||||
#if CONFIG_AC3_FIXED_ENCODER |
||||
AV_SAMPLE_FMT_S16, |
||||
#endif |
||||
AV_SAMPLE_FMT_NONE}, |
||||
.long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"), |
||||
.priv_class = &ac3enc_class, |
||||
.channel_layouts = ff_ac3_channel_layouts, |
||||
}; |
Loading…
Reference in new issue