]> git.sesse.net Git - ffmpeg/blob - libavcodec/ac3enc_combined.c
Merge remote-tracking branch 'qatar/master'
[ffmpeg] / libavcodec / ac3enc_combined.c
1
2 #include "libavutil/opt.h"
3 #include "libavutil/samplefmt.h"
4 #include "avcodec.h"
5 #include "ac3.h"
6
7 typedef struct CombineContext{
8     AVClass *av_class;                      ///< AVClass used for AVOption
9     AC3EncOptions options;                  ///< encoding options
10     void *ctx;
11     AVCodec *codec;
12 }CombineContext;
13
14 #define OFFSET(param) offsetof(CombineContext, options.param)
15 #define AC3ENC_PARAM (AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
16
17 #define AC3ENC_TYPE_AC3_FIXED   0
18 #define AC3ENC_TYPE_AC3         1
19 #define AC3ENC_TYPE_EAC3        2
20
21 #define AC3ENC_TYPE 12354
22 #include "ac3enc_opts_template.c"
23
24 static AVClass ac3enc_class = { "AC-3 Encoder", av_default_item_name,
25                                 eac3_options, LIBAVUTIL_VERSION_INT };
26
27 static av_cold AVCodec *get_codec(enum AVSampleFormat s){
28 #if CONFIG_AC3_FIXED_ENCODER
29     if(s==AV_SAMPLE_FMT_S16) return &ff_ac3_fixed_encoder;
30 #endif
31 #if CONFIG_AC3_FLOAT_ENCODER
32     if(s==AV_SAMPLE_FMT_FLT) return &ff_ac3_float_encoder;
33 #endif
34     return NULL;
35 }
36
37
38 static av_cold int encode_init(AVCodecContext *avctx)
39 {
40     CombineContext *c= avctx->priv_data;
41     int ret;
42     int offset= (uint8_t*)&c->options - (uint8_t*)c;
43
44     c->codec= get_codec(avctx->sample_fmt);
45     if(!c->codec){
46         av_log(avctx, AV_LOG_ERROR, "Unsupported sample format\n");
47         return -1;
48     }
49     c->ctx= av_mallocz(c->codec->priv_data_size);
50     memcpy((uint8_t*)c->ctx + offset, &c->options, (uint8_t*)&c->ctx - (uint8_t*)&c->options);
51     FFSWAP(void *,avctx->priv_data, c->ctx);
52     ret= c->codec->init(avctx);
53     FFSWAP(void *,avctx->priv_data, c->ctx);
54     return ret;
55 }
56
57 static int encode_frame(AVCodecContext *avctx, unsigned char *frame,
58                         int buf_size, void *data)
59 {
60     CombineContext *c= avctx->priv_data;
61     int ret;
62
63     FFSWAP(void *,avctx->priv_data, c->ctx);
64     ret= c->codec->encode(avctx, frame, buf_size, data);
65     FFSWAP(void *,avctx->priv_data, c->ctx);
66     return ret;
67 }
68
69 static av_cold int encode_close(AVCodecContext *avctx)
70 {
71     CombineContext *c= avctx->priv_data;
72     int ret;
73
74     FFSWAP(void *,avctx->priv_data, c->ctx);
75     ret= c->codec->close(avctx);
76     FFSWAP(void *,avctx->priv_data, c->ctx);
77     return ret;
78 }
79
80 AVCodec ff_ac3_encoder = {
81     "ac3",
82     AVMEDIA_TYPE_AUDIO,
83     CODEC_ID_AC3,
84     sizeof(CombineContext),
85     encode_init,
86     encode_frame,
87     encode_close,
88     NULL,
89     .sample_fmts = (const enum AVSampleFormat[]){
90 #if CONFIG_AC3_FLOAT_ENCODER
91         AV_SAMPLE_FMT_FLT,
92 #endif
93 #if CONFIG_AC3_FIXED_ENCODER
94         AV_SAMPLE_FMT_S16,
95 #endif
96         AV_SAMPLE_FMT_NONE},
97     .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"),
98     .priv_class = &ac3enc_class,
99     .channel_layouts = ff_ac3_channel_layouts,
100 };