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_MP1_DECODER) += mpegaudiodec_fixed.o
|
||||||
OBJS-$(CONFIG_MP1FLOAT_DECODER) += mpegaudiodec_float.o
|
OBJS-$(CONFIG_MP1FLOAT_DECODER) += mpegaudiodec_float.o
|
||||||
OBJS-$(CONFIG_MP2_DECODER) += mpegaudiodec_fixed.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 \
|
mpegaudiodata.o mpegaudiodsp_data.o \
|
||||||
mpegaudiotabs.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 \
|
mpegaudiodata.o mpegaudiodsp_data.o \
|
||||||
mpegaudiotabs.o
|
mpegaudiotabs.o
|
||||||
OBJS-$(CONFIG_MP2FLOAT_DECODER) += mpegaudiodec_float.o
|
OBJS-$(CONFIG_MP2FLOAT_DECODER) += mpegaudiodec_float.o
|
||||||
|
@ -24,10 +24,14 @@
|
|||||||
* The simplest mpeg audio layer 2 encoder.
|
* The simplest mpeg audio layer 2 encoder.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "config_components.h"
|
||||||
|
|
||||||
#include "libavutil/avassert.h"
|
#include "libavutil/avassert.h"
|
||||||
#include "libavutil/channel_layout.h"
|
#include "libavutil/channel_layout.h"
|
||||||
|
|
||||||
#include "avcodec.h"
|
#include "avcodec.h"
|
||||||
|
#include "codec_internal.h"
|
||||||
#include "encode.h"
|
#include "encode.h"
|
||||||
#include "put_bits.h"
|
#include "put_bits.h"
|
||||||
|
|
||||||
@ -52,6 +56,7 @@ typedef struct MpegAudioContext {
|
|||||||
int bitrate_index; /* bit rate */
|
int bitrate_index; /* bit rate */
|
||||||
int freq_index;
|
int freq_index;
|
||||||
int frame_size; /* frame size, in bits, without padding */
|
int frame_size; /* frame size, in bits, without padding */
|
||||||
|
int is_fixed;
|
||||||
/* padding computation */
|
/* padding computation */
|
||||||
int frame_frac, frame_frac_incr, do_padding;
|
int frame_frac, frame_frac_incr, do_padding;
|
||||||
short samples_buf[MPA_MAX_CHANNELS][SAMPLES_BUF_SIZE]; /* buffer for filter */
|
short samples_buf[MPA_MAX_CHANNELS][SAMPLES_BUF_SIZE]; /* buffer for filter */
|
||||||
@ -65,15 +70,18 @@ typedef struct MpegAudioContext {
|
|||||||
int16_t filter_bank[512];
|
int16_t filter_bank[512];
|
||||||
int scale_factor_table[64];
|
int scale_factor_table[64];
|
||||||
unsigned char scale_diff_table[128];
|
unsigned char scale_diff_table[128];
|
||||||
#if USE_FLOATS
|
union {
|
||||||
float scale_factor_inv_table[64];
|
float scale_factor_inv_table[64];
|
||||||
#else
|
struct {
|
||||||
int8_t scale_factor_shift[64];
|
int8_t scale_factor_shift[64];
|
||||||
unsigned short scale_factor_mult[64];
|
unsigned short scale_factor_mult[64];
|
||||||
#endif
|
};
|
||||||
|
};
|
||||||
unsigned short total_quant_bits[17]; /* total number of bits per allocation group */
|
unsigned short total_quant_bits[17]; /* total number of bits per allocation group */
|
||||||
} MpegAudioContext;
|
} 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)
|
static av_cold int MPA_encode_init(AVCodecContext *avctx)
|
||||||
{
|
{
|
||||||
MpegAudioContext *s = avctx->priv_data;
|
MpegAudioContext *s = avctx->priv_data;
|
||||||
@ -157,13 +165,13 @@ static av_cold int MPA_encode_init(AVCodecContext *avctx)
|
|||||||
if (v <= 0)
|
if (v <= 0)
|
||||||
v = 1;
|
v = 1;
|
||||||
s->scale_factor_table[i] = v;
|
s->scale_factor_table[i] = v;
|
||||||
#if USE_FLOATS
|
if (IS_FIXED(s)) {
|
||||||
s->scale_factor_inv_table[i] = exp2(-(3 - i) / 3.0) / (float)(1 << 20);
|
|
||||||
#else
|
|
||||||
#define P 15
|
#define P 15
|
||||||
s->scale_factor_shift[i] = 21 - P - (i / 3);
|
s->scale_factor_shift[i] = 21 - P - (i / 3);
|
||||||
s->scale_factor_mult[i] = (1 << P) * exp2((i % 3) / 3.0);
|
s->scale_factor_mult[i] = (1 << P) * exp2((i % 3) / 3.0);
|
||||||
#endif
|
} else {
|
||||||
|
s->scale_factor_inv_table[i] = exp2(-(3 - i) / 3.0) / (float)(1 << 20);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for(i=0;i<128;i++) {
|
for(i=0;i<128;i++) {
|
||||||
v = i - 64;
|
v = i - 64;
|
||||||
@ -592,6 +600,70 @@ static void compute_bit_allocation(MpegAudioContext *s,
|
|||||||
av_assert0(*padding >= 0);
|
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
|
* Output the MPEG audio layer 2 frame. Note how the code is small
|
||||||
* compared to other encoders :-)
|
* compared to other encoders :-)
|
||||||
@ -600,9 +672,8 @@ static void encode_frame(MpegAudioContext *s,
|
|||||||
unsigned char bit_alloc[MPA_MAX_CHANNELS][SBLIMIT],
|
unsigned char bit_alloc[MPA_MAX_CHANNELS][SBLIMIT],
|
||||||
int padding)
|
int padding)
|
||||||
{
|
{
|
||||||
int i, j, k, l, bit_alloc_bits, b, ch;
|
int i, j, bit_alloc_bits, ch;
|
||||||
unsigned char *sf;
|
unsigned char *sf;
|
||||||
int q[3];
|
|
||||||
PutBitContext *p = &s->pb;
|
PutBitContext *p = &s->pb;
|
||||||
|
|
||||||
/* header */
|
/* header */
|
||||||
@ -663,69 +734,14 @@ static void encode_frame(MpegAudioContext *s,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* quantization & write sub band samples */
|
#if CONFIG_SMALL
|
||||||
|
encode_subbands(s, p, bit_alloc, IS_FIXED(s));
|
||||||
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);
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
{
|
if (IS_FIXED(s))
|
||||||
int q1, e, shift, mult;
|
encode_subbands(s, p, bit_alloc, 1);
|
||||||
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
|
else
|
||||||
q1 = sample >> shift;
|
encode_subbands(s, p, bit_alloc, 0);
|
||||||
q1 = (q1 * mult) >> P;
|
|
||||||
q1 += 1 << P;
|
|
||||||
if (q1 < 0)
|
|
||||||
q1 = 0;
|
|
||||||
q[m] = (q1 * (unsigned)steps) >> (P + 1);
|
|
||||||
}
|
|
||||||
#endif
|
#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 */
|
/* padding */
|
||||||
for(i=0;i<padding;i++)
|
for(i=0;i<padding;i++)
|
||||||
@ -777,3 +793,44 @@ static const FFCodecDefault mp2_defaults[] = {
|
|||||||
{ NULL },
|
{ 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