00001 00002 #include "libavutil/opt.h" 00003 #include "libavutil/samplefmt.h" 00004 #include "avcodec.h" 00005 #include "ac3.h" 00006 00007 typedef struct CombineContext{ 00008 AVClass *av_class; 00009 AC3EncOptions options; 00010 void *ctx; 00011 AVCodec *codec; 00012 }CombineContext; 00013 00014 #define OFFSET(param) offsetof(CombineContext, options.param) 00015 #define AC3ENC_PARAM (AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM) 00016 00017 #define AC3ENC_TYPE_AC3_FIXED 0 00018 #define AC3ENC_TYPE_AC3 1 00019 #define AC3ENC_TYPE_EAC3 2 00020 00021 #define AC3ENC_TYPE 12354 00022 #include "ac3enc_opts_template.c" 00023 00024 static AVClass ac3enc_class = { "AC-3 Encoder", av_default_item_name, 00025 eac3_options, LIBAVUTIL_VERSION_INT }; 00026 00027 static av_cold AVCodec *get_codec(enum AVSampleFormat s){ 00028 #if CONFIG_AC3_FIXED_ENCODER 00029 if(s==AV_SAMPLE_FMT_S16) return &ff_ac3_fixed_encoder; 00030 #endif 00031 #if CONFIG_AC3_FLOAT_ENCODER 00032 if(s==AV_SAMPLE_FMT_FLT) return &ff_ac3_float_encoder; 00033 #endif 00034 return NULL; 00035 } 00036 00037 00038 static av_cold int encode_init(AVCodecContext *avctx) 00039 { 00040 CombineContext *c= avctx->priv_data; 00041 int ret; 00042 int offset= (uint8_t*)&c->options - (uint8_t*)c; 00043 00044 c->codec= get_codec(avctx->sample_fmt); 00045 if(!c->codec){ 00046 av_log(avctx, AV_LOG_ERROR, "Unsupported sample format\n"); 00047 return -1; 00048 } 00049 c->ctx= av_mallocz(c->codec->priv_data_size); 00050 memcpy((uint8_t*)c->ctx + offset, &c->options, (uint8_t*)&c->ctx - (uint8_t*)&c->options); 00051 FFSWAP(void *,avctx->priv_data, c->ctx); 00052 ret= c->codec->init(avctx); 00053 FFSWAP(void *,avctx->priv_data, c->ctx); 00054 return ret; 00055 } 00056 00057 static int encode_frame(AVCodecContext *avctx, unsigned char *frame, 00058 int buf_size, void *data) 00059 { 00060 CombineContext *c= avctx->priv_data; 00061 int ret; 00062 00063 FFSWAP(void *,avctx->priv_data, c->ctx); 00064 ret= c->codec->encode(avctx, frame, buf_size, data); 00065 FFSWAP(void *,avctx->priv_data, c->ctx); 00066 return ret; 00067 } 00068 00069 static av_cold int encode_close(AVCodecContext *avctx) 00070 { 00071 CombineContext *c= avctx->priv_data; 00072 int ret; 00073 00074 FFSWAP(void *,avctx->priv_data, c->ctx); 00075 ret= c->codec->close(avctx); 00076 FFSWAP(void *,avctx->priv_data, c->ctx); 00077 return ret; 00078 } 00079 00080 AVCodec ff_ac3_encoder = { 00081 "ac3", 00082 AVMEDIA_TYPE_AUDIO, 00083 CODEC_ID_AC3, 00084 sizeof(CombineContext), 00085 encode_init, 00086 encode_frame, 00087 encode_close, 00088 NULL, 00089 .sample_fmts = (const enum AVSampleFormat[]){ 00090 #if CONFIG_AC3_FLOAT_ENCODER 00091 AV_SAMPLE_FMT_FLT, 00092 #endif 00093 #if CONFIG_AC3_FIXED_ENCODER 00094 AV_SAMPLE_FMT_S16, 00095 #endif 00096 AV_SAMPLE_FMT_NONE}, 00097 .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"), 00098 .priv_class = &ac3enc_class, 00099 .channel_layouts = ff_ac3_channel_layouts, 00100 };