Go to the documentation of this file.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 };