FFmpeg
ac3enc_fixed.c
Go to the documentation of this file.
1 /*
2  * The simplest AC-3 encoder
3  * Copyright (c) 2000 Fabrice Bellard
4  * Copyright (c) 2006-2010 Justin Ruggles <justin.ruggles@gmail.com>
5  * Copyright (c) 2006-2010 Prakash Punnoor <prakash@punnoor.de>
6  *
7  * This file is part of FFmpeg.
8  *
9  * FFmpeg is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * FFmpeg is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with FFmpeg; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23 
24 /**
25  * @file
26  * fixed-point AC-3 encoder.
27  */
28 
29 #define FFT_FLOAT 0
30 #undef CONFIG_AC3ENC_FLOAT
31 #include "internal.h"
32 #include "audiodsp.h"
33 #include "ac3enc.h"
34 #include "eac3enc.h"
35 
36 #define AC3ENC_TYPE AC3ENC_TYPE_AC3_FIXED
37 #include "ac3enc_opts_template.c"
38 
39 static const AVClass ac3enc_class = {
40  .class_name = "Fixed-Point AC-3 Encoder",
41  .item_name = av_default_item_name,
42  .option = ac3_options,
43  .version = LIBAVUTIL_VERSION_INT,
44 };
45 
46 /*
47  * Normalize the input samples to use the maximum available precision.
48  * This assumes signed 16-bit input samples.
49  */
51 {
52  int v = s->ac3dsp.ac3_max_msb_abs_int16(s->windowed_samples, AC3_WINDOW_SIZE);
53  v = 14 - av_log2(v);
54  if (v > 0)
55  s->ac3dsp.ac3_lshift_int16(s->windowed_samples, AC3_WINDOW_SIZE, v);
56  /* +6 to right-shift from 31-bit to 25-bit */
57  return v + 6;
58 }
59 
60 
61 /*
62  * Scale MDCT coefficients to 25-bit signed fixed-point.
63  */
65 {
66  int blk, ch;
67 
68  for (blk = 0; blk < s->num_blocks; blk++) {
69  AC3Block *block = &s->blocks[blk];
70  for (ch = 1; ch <= s->channels; ch++) {
71  s->ac3dsp.ac3_rshift_int32(block->mdct_coef[ch], AC3_MAX_COEFS,
72  block->coeff_shift[ch]);
73  }
74  }
75 }
76 
77 static void sum_square_butterfly(AC3EncodeContext *s, int64_t sum[4],
78  const int32_t *coef0, const int32_t *coef1,
79  int len)
80 {
81  s->ac3dsp.sum_square_butterfly_int32(sum, coef0, coef1, len);
82 }
83 
84 /*
85  * Clip MDCT coefficients to allowable range.
86  */
88  unsigned int len)
89 {
90  adsp->vector_clip_int32(coef, coef, COEF_MIN, COEF_MAX, len);
91 }
92 
93 
94 /*
95  * Calculate a single coupling coordinate.
96  */
97 static CoefType calc_cpl_coord(CoefSumType energy_ch, CoefSumType energy_cpl)
98 {
99  if (energy_cpl <= COEF_MAX) {
100  return 1048576;
101  } else {
102  uint64_t coord = energy_ch / (energy_cpl >> 24);
103  uint32_t coord32 = FFMIN(coord, 1073741824);
104  coord32 = ff_sqrt(coord32) << 9;
105  return FFMIN(coord32, COEF_MAX);
106  }
107 }
108 
109 
110 #include "ac3enc_template.c"
111 
112 
113 /**
114  * Finalize MDCT and free allocated memory.
115  *
116  * @param s AC-3 encoder private context
117  */
119 {
120  ff_mdct_end(&s->mdct);
121 }
122 
123 
124 /**
125  * Initialize MDCT tables.
126  *
127  * @param s AC-3 encoder private context
128  * @return 0 on success, negative error code on failure
129  */
131 {
132  int ret = ff_mdct_init(&s->mdct, 9, 0, -1.0);
133  s->mdct_window = ff_ac3_window;
134  return ret;
135 }
136 
137 
139 {
141  s->fixed_point = 1;
142  return ff_ac3_encode_init(avctx);
143 }
144 
145 
147  .name = "ac3_fixed",
148  .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"),
149  .type = AVMEDIA_TYPE_AUDIO,
150  .id = AV_CODEC_ID_AC3,
151  .priv_data_size = sizeof(AC3EncodeContext),
153  .encode2 = ff_ac3_fixed_encode_frame,
154  .close = ff_ac3_encode_close,
155  .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16P,
157  .priv_class = &ac3enc_class,
158  .channel_layouts = ff_ac3_channel_layouts,
159  .defaults = ac3_defaults,
160 };
AVCodec
AVCodec.
Definition: avcodec.h:3481
AV_CODEC_ID_AC3
@ AV_CODEC_ID_AC3
Definition: avcodec.h:567
init
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
COEF_MAX
#define COEF_MAX
Definition: ac3enc.h:68
sample_fmts
static enum AVSampleFormat sample_fmts[]
Definition: adpcmenc.c:686
ch
uint8_t pi<< 24) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_U8,(uint64_t)((*(const uint8_t *) pi - 0x80U))<< 56) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16,(*(const int16_t *) pi >>8)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S16,(uint64_t)(*(const int16_t *) pi)<< 48) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32,(*(const int32_t *) pi >>24)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S32,(uint64_t)(*(const int32_t *) pi)<< 32) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S64,(*(const int64_t *) pi >>56)+0x80) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S64, *(const int64_t *) pi *(1.0f/(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S64, *(const int64_t *) pi *(1.0/(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_FLT, llrintf(*(const float *) pi *(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_DBL, llrint(*(const double *) pi *(INT64_C(1)<< 63))) #define FMT_PAIR_FUNC(out, in) static conv_func_type *const fmt_pair_to_conv_functions[AV_SAMPLE_FMT_NB *AV_SAMPLE_FMT_NB]={ FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S64), };static void cpy1(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, len);} static void cpy2(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, 2 *len);} static void cpy4(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, 4 *len);} static void cpy8(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, 8 *len);} AudioConvert *swri_audio_convert_alloc(enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, const int *ch_map, int flags) { AudioConvert *ctx;conv_func_type *f=fmt_pair_to_conv_functions[av_get_packed_sample_fmt(out_fmt)+AV_SAMPLE_FMT_NB *av_get_packed_sample_fmt(in_fmt)];if(!f) return NULL;ctx=av_mallocz(sizeof(*ctx));if(!ctx) return NULL;if(channels==1){ in_fmt=av_get_planar_sample_fmt(in_fmt);out_fmt=av_get_planar_sample_fmt(out_fmt);} ctx->channels=channels;ctx->conv_f=f;ctx->ch_map=ch_map;if(in_fmt==AV_SAMPLE_FMT_U8||in_fmt==AV_SAMPLE_FMT_U8P) memset(ctx->silence, 0x80, sizeof(ctx->silence));if(out_fmt==in_fmt &&!ch_map) { switch(av_get_bytes_per_sample(in_fmt)){ case 1:ctx->simd_f=cpy1;break;case 2:ctx->simd_f=cpy2;break;case 4:ctx->simd_f=cpy4;break;case 8:ctx->simd_f=cpy8;break;} } if(HAVE_X86ASM &&1) swri_audio_convert_init_x86(ctx, out_fmt, in_fmt, channels);if(ARCH_ARM) swri_audio_convert_init_arm(ctx, out_fmt, in_fmt, channels);if(ARCH_AARCH64) swri_audio_convert_init_aarch64(ctx, out_fmt, in_fmt, channels);return ctx;} void swri_audio_convert_free(AudioConvert **ctx) { av_freep(ctx);} int swri_audio_convert(AudioConvert *ctx, AudioData *out, AudioData *in, int len) { int ch;int off=0;const int os=(out->planar ? 1 :out->ch_count) *out->bps;unsigned misaligned=0;av_assert0(ctx->channels==out->ch_count);if(ctx->in_simd_align_mask) { int planes=in->planar ? in->ch_count :1;unsigned m=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) in->ch[ch];misaligned|=m &ctx->in_simd_align_mask;} if(ctx->out_simd_align_mask) { int planes=out->planar ? out->ch_count :1;unsigned m=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) out->ch[ch];misaligned|=m &ctx->out_simd_align_mask;} if(ctx->simd_f &&!ctx->ch_map &&!misaligned){ off=len &~15;av_assert1(off >=0);av_assert1(off<=len);av_assert2(ctx->channels==SWR_CH_MAX||!in->ch[ctx->channels]);if(off >0){ if(out->planar==in->planar){ int planes=out->planar ? out->ch_count :1;for(ch=0;ch< planes;ch++){ ctx->simd_f(out-> ch ch
Definition: audioconvert.c:56
internal.h
AC3_MAX_COEFS
#define AC3_MAX_COEFS
Definition: ac3.h:35
ff_mdct_init
#define ff_mdct_init
Definition: fft.h:169
AudioDSPContext::vector_clip_int32
void(* vector_clip_int32)(int32_t *dst, const int32_t *src, int32_t min, int32_t max, unsigned int len)
Clip each element in an array of int32_t to a given minimum and maximum value.
Definition: audiodsp.h:46
ff_sqrt
#define ff_sqrt
Definition: mathops.h:206
ac3_fixed_encode_init
static av_cold int ac3_fixed_encode_init(AVCodecContext *avctx)
Definition: ac3enc_fixed.c:138
av_cold
#define av_cold
Definition: attributes.h:84
s
#define s(width, name)
Definition: cbs_vp9.c:257
ff_ac3_channel_layouts
const uint64_t ff_ac3_channel_layouts[19]
List of supported channel layouts.
Definition: ac3enc.c:81
ff_ac3_fixed_mdct_init
av_cold int ff_ac3_fixed_mdct_init(AC3EncodeContext *s)
Initialize MDCT tables.
Definition: ac3enc_fixed.c:130
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
blk
#define blk(i)
Definition: sha.c:185
int32_t
int32_t
Definition: audio_convert.c:194
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:67
ac3enc.h
CoefSumType
int64_t CoefSumType
Definition: ac3enc.h:72
COEF_MIN
#define COEF_MIN
Definition: ac3enc.h:67
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:191
AC3EncodeContext
AC-3 encoder private context.
Definition: ac3enc.h:162
ac3enc_opts_template.c
AC3Block
Data for a single audio block.
Definition: ac3enc.h:133
ff_ac3_fixed_mdct_end
av_cold void ff_ac3_fixed_mdct_end(AC3EncodeContext *s)
Finalize MDCT and free allocated memory.
Definition: ac3enc_fixed.c:118
AC3EncodeContext::adsp
AudioDSPContext adsp
Definition: ac3enc.h:167
ac3enc_template.c
clip_coefficients
static void clip_coefficients(AudioDSPContext *adsp, int32_t *coef, unsigned int len)
Definition: ac3enc_fixed.c:87
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:188
AV_SAMPLE_FMT_NONE
@ AV_SAMPLE_FMT_NONE
Definition: samplefmt.h:59
ff_mdct_end
#define ff_mdct_end
Definition: fft.h:170
FFMIN
#define FFMIN(a, b)
Definition: common.h:96
calc_cpl_coord
static CoefType calc_cpl_coord(CoefSumType energy_ch, CoefSumType energy_cpl)
Definition: ac3enc_fixed.c:97
AV_SAMPLE_FMT_S16P
@ AV_SAMPLE_FMT_S16P
signed 16 bits, planar
Definition: samplefmt.h:67
eac3enc.h
ff_ac3_fixed_encode_frame
int ff_ac3_fixed_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr)
ac3enc_class
static const AVClass ac3enc_class
Definition: ac3enc_fixed.c:39
AVSampleFormat
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
AVCodec::name
const char * name
Name of the codec implementation.
Definition: avcodec.h:3488
len
int len
Definition: vorbis_enc_data.h:452
sum_square_butterfly
static void sum_square_butterfly(AC3EncodeContext *s, int64_t sum[4], const int32_t *coef0, const int32_t *coef1, int len)
Definition: ac3enc_fixed.c:77
ret
ret
Definition: filter_design.txt:187
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:72
scale_coefficients
static void scale_coefficients(AC3EncodeContext *s)
Definition: ac3enc_fixed.c:64
AVCodecContext
main external API structure.
Definition: avcodec.h:1565
ac3_defaults
static const AVCodecDefault ac3_defaults[]
Definition: ac3enc_opts_template.c:79
CoefType
int32_t CoefType
Definition: ac3enc.h:71
ff_ac3_encode_init
av_cold int ff_ac3_encode_init(AVCodecContext *avctx)
Definition: ac3enc.c:2426
audiodsp.h
AudioDSPContext
Definition: audiodsp.h:24
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:1592
AC3EncodeContext::avctx
AVCodecContext * avctx
parent AVCodecContext
Definition: ac3enc.h:165
ff_ac3_encode_close
av_cold int ff_ac3_encode_close(AVCodecContext *avctx)
Finalize encoding and free any memory allocated by the encoder.
Definition: ac3enc.c:2017
block
The exact code depends on how similar the blocks are and how related they are to the block
Definition: filter_design.txt:207
normalize_samples
static int normalize_samples(AC3EncodeContext *s)
Definition: ac3enc_fixed.c:50
ac3_options
static const AVOption ac3_options[]
Definition: ac3enc_opts_template.c:26
av_log2
int av_log2(unsigned v)
Definition: intmath.c:26
AC3_WINDOW_SIZE
#define AC3_WINDOW_SIZE
Definition: ac3.h:39
ff_ac3_window
const int16_t ff_ac3_window[AC3_WINDOW_SIZE/2]
Definition: ac3tab.c:153
ff_ac3_fixed_encoder
AVCodec ff_ac3_fixed_encoder
Definition: ac3enc_fixed.c:146