| |
| #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; |
| |
| #define OFFSET(param) offsetof(CombineContext, options.param) |
| #define AC3ENC_PARAM (AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM) |
| |
| #define AC3ENC_TYPE_AC3_FIXED 0 |
| #define AC3ENC_TYPE_AC3 1 |
| #define AC3ENC_TYPE_EAC3 2 |
| |
| #define AC3ENC_TYPE 12354 |
| #include "ac3enc_opts_template.c" |
| |
| static AVClass ac3enc_class = { "AC-3 Encoder", av_default_item_name, |
| eac3_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, |
| }; |