You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-04 22:03:09 +02:00
avcodec/mpegaudioenc_{fixed,float}: Merge encoders
Most of the encoders is the same. So deduplicate them. This reduces code size from 22410B to 12637B here. The data in mpegaudiotab.h is also automatically deduplicated. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This commit is contained in:
@ -529,10 +529,10 @@ OBJS-$(CONFIG_MOVTEXT_ENCODER) += movtextenc.o ass_split.o
|
||||
OBJS-$(CONFIG_MP1_DECODER) += mpegaudiodec_fixed.o
|
||||
OBJS-$(CONFIG_MP1FLOAT_DECODER) += mpegaudiodec_float.o
|
||||
OBJS-$(CONFIG_MP2_DECODER) += mpegaudiodec_fixed.o
|
||||
OBJS-$(CONFIG_MP2_ENCODER) += mpegaudioenc_float.o mpegaudio.o \
|
||||
OBJS-$(CONFIG_MP2_ENCODER) += mpegaudioenc.o mpegaudio.o \
|
||||
mpegaudiodata.o mpegaudiodsp_data.o \
|
||||
mpegaudiotabs.o
|
||||
OBJS-$(CONFIG_MP2FIXED_ENCODER) += mpegaudioenc_fixed.o mpegaudio.o \
|
||||
OBJS-$(CONFIG_MP2FIXED_ENCODER) += mpegaudioenc.o mpegaudio.o \
|
||||
mpegaudiodata.o mpegaudiodsp_data.o \
|
||||
mpegaudiotabs.o
|
||||
OBJS-$(CONFIG_MP2FLOAT_DECODER) += mpegaudiodec_float.o
|
||||
|
@ -24,10 +24,14 @@
|
||||
* The simplest mpeg audio layer 2 encoder.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "config_components.h"
|
||||
|
||||
#include "libavutil/avassert.h"
|
||||
#include "libavutil/channel_layout.h"
|
||||
|
||||
#include "avcodec.h"
|
||||
#include "codec_internal.h"
|
||||
#include "encode.h"
|
||||
#include "put_bits.h"
|
||||
|
||||
@ -52,6 +56,7 @@ typedef struct MpegAudioContext {
|
||||
int bitrate_index; /* bit rate */
|
||||
int freq_index;
|
||||
int frame_size; /* frame size, in bits, without padding */
|
||||
int is_fixed;
|
||||
/* padding computation */
|
||||
int frame_frac, frame_frac_incr, do_padding;
|
||||
short samples_buf[MPA_MAX_CHANNELS][SAMPLES_BUF_SIZE]; /* buffer for filter */
|
||||
@ -65,15 +70,18 @@ typedef struct MpegAudioContext {
|
||||
int16_t filter_bank[512];
|
||||
int scale_factor_table[64];
|
||||
unsigned char scale_diff_table[128];
|
||||
#if USE_FLOATS
|
||||
float scale_factor_inv_table[64];
|
||||
#else
|
||||
int8_t scale_factor_shift[64];
|
||||
unsigned short scale_factor_mult[64];
|
||||
#endif
|
||||
union {
|
||||
float scale_factor_inv_table[64];
|
||||
struct {
|
||||
int8_t scale_factor_shift[64];
|
||||
unsigned short scale_factor_mult[64];
|
||||
};
|
||||
};
|
||||
unsigned short total_quant_bits[17]; /* total number of bits per allocation group */
|
||||
} MpegAudioContext;
|
||||
|
||||
#define IS_FIXED(s) (CONFIG_MP2_ENCODER && CONFIG_MP2FIXED_ENCODER ? (s)->is_fixed : CONFIG_MP2FIXED_ENCODER)
|
||||
|
||||
static av_cold int MPA_encode_init(AVCodecContext *avctx)
|
||||
{
|
||||
MpegAudioContext *s = avctx->priv_data;
|
||||
@ -157,13 +165,13 @@ static av_cold int MPA_encode_init(AVCodecContext *avctx)
|
||||
if (v <= 0)
|
||||
v = 1;
|
||||
s->scale_factor_table[i] = v;
|
||||
#if USE_FLOATS
|
||||
s->scale_factor_inv_table[i] = exp2(-(3 - i) / 3.0) / (float)(1 << 20);
|
||||
#else
|
||||
if (IS_FIXED(s)) {
|
||||
#define P 15
|
||||
s->scale_factor_shift[i] = 21 - P - (i / 3);
|
||||
s->scale_factor_mult[i] = (1 << P) * exp2((i % 3) / 3.0);
|
||||
#endif
|
||||
s->scale_factor_shift[i] = 21 - P - (i / 3);
|
||||
s->scale_factor_mult[i] = (1 << P) * exp2((i % 3) / 3.0);
|
||||
} else {
|
||||
s->scale_factor_inv_table[i] = exp2(-(3 - i) / 3.0) / (float)(1 << 20);
|
||||
}
|
||||
}
|
||||
for(i=0;i<128;i++) {
|
||||
v = i - 64;
|
||||
@ -592,6 +600,70 @@ static void compute_bit_allocation(MpegAudioContext *s,
|
||||
av_assert0(*padding >= 0);
|
||||
}
|
||||
|
||||
/// Quantization & write sub band samples
|
||||
static av_always_inline void encode_subbands(MpegAudioContext *const s,
|
||||
PutBitContext *const p,
|
||||
const uint8_t bit_alloc[MPA_MAX_CHANNELS][SBLIMIT],
|
||||
int is_fixed)
|
||||
{
|
||||
for (int k = 0; k < 3; ++k) {
|
||||
for (int l = 0; l < 12; l += 3) {
|
||||
for (int i = 0, j = 0; i < s->sblimit; ++i) {
|
||||
const int bit_alloc_bits = s->alloc_table[j];
|
||||
for (int ch = 0; ch < s->nb_channels; ++ch) {
|
||||
const int b = bit_alloc[ch][i];
|
||||
if (b) {
|
||||
/* we encode 3 sub band samples of the same sub band at a time */
|
||||
const int qindex = s->alloc_table[j + b];
|
||||
const int steps = ff_mpa_quant_steps[qindex];
|
||||
int q[3];
|
||||
|
||||
for (int m = 0; m < 3; ++m) {
|
||||
const int sample = s->sb_samples[ch][k][l + m][i];
|
||||
/* divide by scale factor */
|
||||
if (!is_fixed) {
|
||||
float a = (float)sample * s->scale_factor_inv_table[s->scale_factors[ch][i][k]];
|
||||
q[m] = (int)((a + 1.0) * steps * 0.5);
|
||||
} else {
|
||||
const int e = s->scale_factors[ch][i][k];
|
||||
const int shift = s->scale_factor_shift[e];
|
||||
const int mult = s->scale_factor_mult[e];
|
||||
int q1;
|
||||
|
||||
/* normalize to P bits */
|
||||
if (shift < 0)
|
||||
q1 = sample * (1 << -shift);
|
||||
else
|
||||
q1 = sample >> shift;
|
||||
q1 = (q1 * mult) >> P;
|
||||
q1 += 1 << P;
|
||||
if (q1 < 0)
|
||||
q1 = 0;
|
||||
q[m] = (q1 * (unsigned)steps) >> (P + 1);
|
||||
}
|
||||
if (q[m] >= steps)
|
||||
q[m] = steps - 1;
|
||||
av_assert2(q[m] >= 0 && q[m] < steps);
|
||||
}
|
||||
const int bits = ff_mpa_quant_bits[qindex];
|
||||
if (bits < 0) {
|
||||
/* group the 3 values to save bits */
|
||||
put_bits(p, -bits,
|
||||
q[0] + steps * (q[1] + steps * q[2]));
|
||||
} else {
|
||||
put_bits(p, bits, q[0]);
|
||||
put_bits(p, bits, q[1]);
|
||||
put_bits(p, bits, q[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* next subband in alloc table */
|
||||
j += 1 << bit_alloc_bits;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Output the MPEG audio layer 2 frame. Note how the code is small
|
||||
* compared to other encoders :-)
|
||||
@ -600,9 +672,8 @@ static void encode_frame(MpegAudioContext *s,
|
||||
unsigned char bit_alloc[MPA_MAX_CHANNELS][SBLIMIT],
|
||||
int padding)
|
||||
{
|
||||
int i, j, k, l, bit_alloc_bits, b, ch;
|
||||
int i, j, bit_alloc_bits, ch;
|
||||
unsigned char *sf;
|
||||
int q[3];
|
||||
PutBitContext *p = &s->pb;
|
||||
|
||||
/* header */
|
||||
@ -663,69 +734,14 @@ static void encode_frame(MpegAudioContext *s,
|
||||
}
|
||||
}
|
||||
|
||||
/* quantization & write sub band samples */
|
||||
|
||||
for(k=0;k<3;k++) {
|
||||
for(l=0;l<12;l+=3) {
|
||||
j = 0;
|
||||
for(i=0;i<s->sblimit;i++) {
|
||||
bit_alloc_bits = s->alloc_table[j];
|
||||
for(ch=0;ch<s->nb_channels;ch++) {
|
||||
b = bit_alloc[ch][i];
|
||||
if (b) {
|
||||
int qindex, steps, m, sample, bits;
|
||||
/* we encode 3 sub band samples of the same sub band at a time */
|
||||
qindex = s->alloc_table[j+b];
|
||||
steps = ff_mpa_quant_steps[qindex];
|
||||
for(m=0;m<3;m++) {
|
||||
sample = s->sb_samples[ch][k][l + m][i];
|
||||
/* divide by scale factor */
|
||||
#if USE_FLOATS
|
||||
{
|
||||
float a;
|
||||
a = (float)sample * s->scale_factor_inv_table[s->scale_factors[ch][i][k]];
|
||||
q[m] = (int)((a + 1.0) * steps * 0.5);
|
||||
}
|
||||
#if CONFIG_SMALL
|
||||
encode_subbands(s, p, bit_alloc, IS_FIXED(s));
|
||||
#else
|
||||
{
|
||||
int q1, e, shift, mult;
|
||||
e = s->scale_factors[ch][i][k];
|
||||
shift = s->scale_factor_shift[e];
|
||||
mult = s->scale_factor_mult[e];
|
||||
|
||||
/* normalize to P bits */
|
||||
if (shift < 0)
|
||||
q1 = sample * (1 << -shift);
|
||||
else
|
||||
q1 = sample >> shift;
|
||||
q1 = (q1 * mult) >> P;
|
||||
q1 += 1 << P;
|
||||
if (q1 < 0)
|
||||
q1 = 0;
|
||||
q[m] = (q1 * (unsigned)steps) >> (P + 1);
|
||||
}
|
||||
if (IS_FIXED(s))
|
||||
encode_subbands(s, p, bit_alloc, 1);
|
||||
else
|
||||
encode_subbands(s, p, bit_alloc, 0);
|
||||
#endif
|
||||
if (q[m] >= steps)
|
||||
q[m] = steps - 1;
|
||||
av_assert2(q[m] >= 0 && q[m] < steps);
|
||||
}
|
||||
bits = ff_mpa_quant_bits[qindex];
|
||||
if (bits < 0) {
|
||||
/* group the 3 values to save bits */
|
||||
put_bits(p, -bits,
|
||||
q[0] + steps * (q[1] + steps * q[2]));
|
||||
} else {
|
||||
put_bits(p, bits, q[0]);
|
||||
put_bits(p, bits, q[1]);
|
||||
put_bits(p, bits, q[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* next subband in alloc table */
|
||||
j += 1 << bit_alloc_bits;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* padding */
|
||||
for(i=0;i<padding;i++)
|
||||
@ -777,3 +793,44 @@ static const FFCodecDefault mp2_defaults[] = {
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
#if CONFIG_MP2_ENCODER
|
||||
const FFCodec ff_mp2_encoder = {
|
||||
.p.name = "mp2",
|
||||
CODEC_LONG_NAME("MP2 (MPEG audio layer 2)"),
|
||||
.p.type = AVMEDIA_TYPE_AUDIO,
|
||||
.p.id = AV_CODEC_ID_MP2,
|
||||
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
|
||||
.priv_data_size = sizeof(MpegAudioContext),
|
||||
.init = MPA_encode_init,
|
||||
FF_CODEC_ENCODE_CB(MPA_encode_frame),
|
||||
CODEC_SAMPLEFMTS(AV_SAMPLE_FMT_S16),
|
||||
CODEC_SAMPLERATES(44100, 48000, 32000, 22050, 24000, 16000),
|
||||
CODEC_CH_LAYOUTS(AV_CHANNEL_LAYOUT_MONO, AV_CHANNEL_LAYOUT_STEREO),
|
||||
.defaults = mp2_defaults,
|
||||
};
|
||||
#endif
|
||||
|
||||
#if CONFIG_MP2FIXED_ENCODER
|
||||
static av_cold int mpa_fixed_encode_init(AVCodecContext *avctx)
|
||||
{
|
||||
MpegAudioContext *s = avctx->priv_data;
|
||||
|
||||
s->is_fixed = 1;
|
||||
return MPA_encode_init(avctx);
|
||||
}
|
||||
|
||||
const FFCodec ff_mp2fixed_encoder = {
|
||||
.p.name = "mp2fixed",
|
||||
CODEC_LONG_NAME("MP2 fixed point (MPEG audio layer 2)"),
|
||||
.p.type = AVMEDIA_TYPE_AUDIO,
|
||||
.p.id = AV_CODEC_ID_MP2,
|
||||
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
|
||||
.priv_data_size = sizeof(MpegAudioContext),
|
||||
.init = mpa_fixed_encode_init,
|
||||
FF_CODEC_ENCODE_CB(MPA_encode_frame),
|
||||
CODEC_SAMPLEFMTS(AV_SAMPLE_FMT_S16),
|
||||
CODEC_SAMPLERATES(44100, 48000, 32000, 22050, 24000, 16000),
|
||||
CODEC_CH_LAYOUTS(AV_CHANNEL_LAYOUT_MONO, AV_CHANNEL_LAYOUT_STEREO),
|
||||
.defaults = mp2_defaults,
|
||||
};
|
||||
#endif
|
@ -1,39 +0,0 @@
|
||||
/*
|
||||
* The simplest mpeg audio layer 2 encoder
|
||||
* Copyright (c) 2000, 2001 Fabrice Bellard
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "libavutil/channel_layout.h"
|
||||
#include "codec_internal.h"
|
||||
#include "mpegaudioenc_template.c"
|
||||
|
||||
const FFCodec ff_mp2fixed_encoder = {
|
||||
.p.name = "mp2fixed",
|
||||
CODEC_LONG_NAME("MP2 fixed point (MPEG audio layer 2)"),
|
||||
.p.type = AVMEDIA_TYPE_AUDIO,
|
||||
.p.id = AV_CODEC_ID_MP2,
|
||||
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
|
||||
.priv_data_size = sizeof(MpegAudioContext),
|
||||
.init = MPA_encode_init,
|
||||
FF_CODEC_ENCODE_CB(MPA_encode_frame),
|
||||
CODEC_SAMPLEFMTS(AV_SAMPLE_FMT_S16),
|
||||
CODEC_SAMPLERATES(44100, 48000, 32000, 22050, 24000, 16000),
|
||||
CODEC_CH_LAYOUTS(AV_CHANNEL_LAYOUT_MONO, AV_CHANNEL_LAYOUT_STEREO),
|
||||
.defaults = mp2_defaults,
|
||||
};
|
@ -1,40 +0,0 @@
|
||||
/*
|
||||
* The simplest mpeg audio layer 2 encoder
|
||||
* Copyright (c) 2000, 2001 Fabrice Bellard
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "libavutil/channel_layout.h"
|
||||
#define USE_FLOATS 1
|
||||
#include "codec_internal.h"
|
||||
#include "mpegaudioenc_template.c"
|
||||
|
||||
const FFCodec ff_mp2_encoder = {
|
||||
.p.name = "mp2",
|
||||
CODEC_LONG_NAME("MP2 (MPEG audio layer 2)"),
|
||||
.p.type = AVMEDIA_TYPE_AUDIO,
|
||||
.p.id = AV_CODEC_ID_MP2,
|
||||
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
|
||||
.priv_data_size = sizeof(MpegAudioContext),
|
||||
.init = MPA_encode_init,
|
||||
FF_CODEC_ENCODE_CB(MPA_encode_frame),
|
||||
CODEC_SAMPLEFMTS(AV_SAMPLE_FMT_S16),
|
||||
CODEC_SAMPLERATES(44100, 48000, 32000, 22050, 24000, 16000),
|
||||
CODEC_CH_LAYOUTS(AV_CHANNEL_LAYOUT_MONO, AV_CHANNEL_LAYOUT_STEREO),
|
||||
.defaults = mp2_defaults,
|
||||
};
|
Reference in New Issue
Block a user