summaryrefslogtreecommitdiff
path: root/libavcodec/ac3enc_combined.c
diff options
context:
space:
mode:
Diffstat (limited to 'libavcodec/ac3enc_combined.c')
-rw-r--r--libavcodec/ac3enc_combined.c90
1 files changed, 90 insertions, 0 deletions
diff --git a/libavcodec/ac3enc_combined.c b/libavcodec/ac3enc_combined.c
new file mode 100644
index 0000000000..3d6b3d9335
--- /dev/null
+++ b/libavcodec/ac3enc_combined.c
@@ -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,
+};