History

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.

Andreas Rheinhardt committed 1 year ago

Commit db759551 parent 13a0d0a4 files · +134 −156Browse files

Unified · Split

4 files
  1. libavcodec/Makefile +2 −2
  2. libavcodec/mpegaudioenc.c +132 −75
  3. libavcodec/mpegaudioenc_fixed.c +0 −39
  4. libavcodec/mpegaudioenc_float.c +0 −40
libavcodec/Makefile+2−2
@@ -529,10 +529,10 @@ OBJS-$(CONFIG_MOVTEXT_ENCODER) += movtextenc.o ass_split.o · 528 unmodified lines
529529 OBJS-$(CONFIG_MP1_DECODER) += mpegaudiodec_fixed.o
530530 OBJS-$(CONFIG_MP1FLOAT_DECODER) += mpegaudiodec_float.o
531531 OBJS-$(CONFIG_MP2_DECODER) += mpegaudiodec_fixed.o
532−OBJS-$(CONFIG_MP2_ENCODER) += mpegaudioenc_float.o mpegaudio.o \
532+OBJS-$(CONFIG_MP2_ENCODER) += mpegaudioenc.o mpegaudio.o \
533533 mpegaudiodata.o mpegaudiodsp_data.o \
534534 mpegaudiotabs.o
535−OBJS-$(CONFIG_MP2FIXED_ENCODER) += mpegaudioenc_fixed.o mpegaudio.o \
535+OBJS-$(CONFIG_MP2FIXED_ENCODER) += mpegaudioenc.o mpegaudio.o \
536536 mpegaudiodata.o mpegaudiodsp_data.o \
537537 mpegaudiotabs.o
538538 OBJS-$(CONFIG_MP2FLOAT_DECODER) += mpegaudiodec_float.o
libavcodec/mpegaudioenc.crenamed from libavcodec/mpegaudioenc_template.c+132−75
@@ -24,10 +24,14 @@ · 23 unmodified lines
2424 * The simplest mpeg audio layer 2 encoder.
2525 */
2626
27+#include "config.h"
28+#include "config_components.h"
29+
2730 #include "libavutil/avassert.h"
2831 #include "libavutil/channel_layout.h"
2932
3033 #include "avcodec.h"
34+#include "codec_internal.h"
3135 #include "encode.h"
3236 #include "put_bits.h"
3337
@@ -52,6 +56,7 @@ typedef struct MpegAudioContext { · 18 unmodified lines
5256 int bitrate_index; /* bit rate */
5357 int freq_index;
5458 int frame_size; /* frame size, in bits, without padding */
59+ int is_fixed;
5560 /* padding computation */
5661 int frame_frac, frame_frac_incr, do_padding;
5762 short samples_buf[MPA_MAX_CHANNELS][SAMPLES_BUF_SIZE]; /* buffer for filter */
@@ -65,15 +70,18 @@ typedef struct MpegAudioContext { · 7 unmodified lines
6570 int16_t filter_bank[512];
6671 int scale_factor_table[64];
6772 unsigned char scale_diff_table[128];
68−#if USE_FLOATS
69− float scale_factor_inv_table[64];
70−#else
71− int8_t scale_factor_shift[64];
72− unsigned short scale_factor_mult[64];
73−#endif
73+ union {
74+ float scale_factor_inv_table[64];
75+ struct {
76+ int8_t scale_factor_shift[64];
77+ unsigned short scale_factor_mult[64];
78+ };
79+ };
7480 unsigned short total_quant_bits[17]; /* total number of bits per allocation group */
7581 } MpegAudioContext;
7682
83+#define IS_FIXED(s) (CONFIG_MP2_ENCODER && CONFIG_MP2FIXED_ENCODER ? (s)->is_fixed : CONFIG_MP2FIXED_ENCODER)
84+
7785 static av_cold int MPA_encode_init(AVCodecContext *avctx)
7886 {
7987 MpegAudioContext *s = avctx->priv_data;
@@ -157,13 +165,13 @@ static av_cold int MPA_encode_init(AVCodecContext *avctx) · 77 unmodified lines
157165 if (v <= 0)
158166 v = 1;
159167 s->scale_factor_table[i] = v;
160−#if USE_FLOATS
161− s->scale_factor_inv_table[i] = exp2(-(3 - i) / 3.0) / (float)(1 << 20);
162−#else
168+ if (IS_FIXED(s)) {
163169 #define P 15
164− s->scale_factor_shift[i] = 21 - P - (i / 3);
165− s->scale_factor_mult[i] = (1 << P) * exp2((i % 3) / 3.0);
166−#endif
170+ s->scale_factor_shift[i] = 21 - P - (i / 3);
171+ s->scale_factor_mult[i] = (1 << P) * exp2((i % 3) / 3.0);
172+ } else {
173+ s->scale_factor_inv_table[i] = exp2(-(3 - i) / 3.0) / (float)(1 << 20);
174+ }
167175 }
168176 for(i=0;i<128;i++) {
169177 v = i - 64;
@@ -592,6 +600,70 @@ static void compute_bit_allocation(MpegAudioContext *s, · 422 unmodified lines
592600 av_assert0(*padding >= 0);
593601 }
594602
603+/// Quantization & write sub band samples
604+static av_always_inline void encode_subbands(MpegAudioContext *const s,
605+ PutBitContext *const p,
606+ const uint8_t bit_alloc[MPA_MAX_CHANNELS][SBLIMIT],
607+ int is_fixed)
608+{
609+ for (int k = 0; k < 3; ++k) {
610+ for (int l = 0; l < 12; l += 3) {
611+ for (int i = 0, j = 0; i < s->sblimit; ++i) {
612+ const int bit_alloc_bits = s->alloc_table[j];
613+ for (int ch = 0; ch < s->nb_channels; ++ch) {
614+ const int b = bit_alloc[ch][i];
615+ if (b) {
616+ /* we encode 3 sub band samples of the same sub band at a time */
617+ const int qindex = s->alloc_table[j + b];
618+ const int steps = ff_mpa_quant_steps[qindex];
619+ int q[3];
620+
621+ for (int m = 0; m < 3; ++m) {
622+ const int sample = s->sb_samples[ch][k][l + m][i];
623+ /* divide by scale factor */
624+ if (!is_fixed) {
625+ float a = (float)sample * s->scale_factor_inv_table[s->scale_factors[ch][i][k]];
626+ q[m] = (int)((a + 1.0) * steps * 0.5);
627+ } else {
628+ const int e = s->scale_factors[ch][i][k];
629+ const int shift = s->scale_factor_shift[e];
630+ const int mult = s->scale_factor_mult[e];
631+ int q1;
632+
633+ /* normalize to P bits */
634+ if (shift < 0)
635+ q1 = sample * (1 << -shift);
636+ else
637+ q1 = sample >> shift;
638+ q1 = (q1 * mult) >> P;
639+ q1 += 1 << P;
640+ if (q1 < 0)
641+ q1 = 0;
642+ q[m] = (q1 * (unsigned)steps) >> (P + 1);
643+ }
644+ if (q[m] >= steps)
645+ q[m] = steps - 1;
646+ av_assert2(q[m] >= 0 && q[m] < steps);
647+ }
648+ const int bits = ff_mpa_quant_bits[qindex];
649+ if (bits < 0) {
650+ /* group the 3 values to save bits */
651+ put_bits(p, -bits,
652+ q[0] + steps * (q[1] + steps * q[2]));
653+ } else {
654+ put_bits(p, bits, q[0]);
655+ put_bits(p, bits, q[1]);
656+ put_bits(p, bits, q[2]);
657+ }
658+ }
659+ }
660+ /* next subband in alloc table */
661+ j += 1 << bit_alloc_bits;
662+ }
663+ }
664+ }
665+}
666+
595667 /*
596668 * Output the MPEG audio layer 2 frame. Note how the code is small
597669 * compared to other encoders :-)
@@ -600,9 +672,8 @@ static void encode_frame(MpegAudioContext *s, · 2 unmodified lines
600672 unsigned char bit_alloc[MPA_MAX_CHANNELS][SBLIMIT],
601673 int padding)
602674 {
603− int i, j, k, l, bit_alloc_bits, b, ch;
675+ int i, j, bit_alloc_bits, ch;
604676 unsigned char *sf;
605− int q[3];
606677 PutBitContext *p = &s->pb;
607678
608679 /* header */
@@ -663,69 +734,14 @@ static void encode_frame(MpegAudioContext *s, · 54 unmodified lines
663734 }
664735 }
665736
666− /* quantization & write sub band samples */
667−
668− for(k=0;k<3;k++) {
669− for(l=0;l<12;l+=3) {
670− j = 0;
671− for(i=0;i<s->sblimit;i++) {
672− bit_alloc_bits = s->alloc_table[j];
673− for(ch=0;ch<s->nb_channels;ch++) {
674− b = bit_alloc[ch][i];
675− if (b) {
676− int qindex, steps, m, sample, bits;
677− /* we encode 3 sub band samples of the same sub band at a time */
678− qindex = s->alloc_table[j+b];
679− steps = ff_mpa_quant_steps[qindex];
680− for(m=0;m<3;m++) {
681− sample = s->sb_samples[ch][k][l + m][i];
682− /* divide by scale factor */
683−#if USE_FLOATS
684− {
685− float a;
686− a = (float)sample * s->scale_factor_inv_table[s->scale_factors[ch][i][k]];
687− q[m] = (int)((a + 1.0) * steps * 0.5);
688− }
737+#if CONFIG_SMALL
738+ encode_subbands(s, p, bit_alloc, IS_FIXED(s));
689739 #else
690− {
691− int q1, e, shift, mult;
692− e = s->scale_factors[ch][i][k];
693− shift = s->scale_factor_shift[e];
694− mult = s->scale_factor_mult[e];
695−
696− /* normalize to P bits */
697− if (shift < 0)
698− q1 = sample * (1 << -shift);
699− else
700− q1 = sample >> shift;
701− q1 = (q1 * mult) >> P;
702− q1 += 1 << P;
703− if (q1 < 0)
704− q1 = 0;
705− q[m] = (q1 * (unsigned)steps) >> (P + 1);
706− }
740+ if (IS_FIXED(s))
741+ encode_subbands(s, p, bit_alloc, 1);
742+ else
743+ encode_subbands(s, p, bit_alloc, 0);
707744 #endif
708− if (q[m] >= steps)
709− q[m] = steps - 1;
710− av_assert2(q[m] >= 0 && q[m] < steps);
711− }
712− bits = ff_mpa_quant_bits[qindex];
713− if (bits < 0) {
714− /* group the 3 values to save bits */
715− put_bits(p, -bits,
716− q[0] + steps * (q[1] + steps * q[2]));
717− } else {
718− put_bits(p, bits, q[0]);
719− put_bits(p, bits, q[1]);
720− put_bits(p, bits, q[2]);
721− }
722− }
723− }
724− /* next subband in alloc table */
725− j += 1 << bit_alloc_bits;
726− }
727− }
728− }
729745
730746 /* padding */
731747 for(i=0;i<padding;i++)
@@ -777,3 +793,44 @@ static const FFCodecDefault mp2_defaults[] = { · 45 unmodified lines
777793 { NULL },
778794 };
779795
796+#if CONFIG_MP2_ENCODER
797+const FFCodec ff_mp2_encoder = {
798+ .p.name = "mp2",
799+ CODEC_LONG_NAME("MP2 (MPEG audio layer 2)"),
800+ .p.type = AVMEDIA_TYPE_AUDIO,
801+ .p.id = AV_CODEC_ID_MP2,
802+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
803+ .priv_data_size = sizeof(MpegAudioContext),
804+ .init = MPA_encode_init,
805+ FF_CODEC_ENCODE_CB(MPA_encode_frame),
806+ CODEC_SAMPLEFMTS(AV_SAMPLE_FMT_S16),
807+ CODEC_SAMPLERATES(44100, 48000, 32000, 22050, 24000, 16000),
808+ CODEC_CH_LAYOUTS(AV_CHANNEL_LAYOUT_MONO, AV_CHANNEL_LAYOUT_STEREO),
809+ .defaults = mp2_defaults,
810+};
811+#endif
812+
813+#if CONFIG_MP2FIXED_ENCODER
814+static av_cold int mpa_fixed_encode_init(AVCodecContext *avctx)
815+{
816+ MpegAudioContext *s = avctx->priv_data;
817+
818+ s->is_fixed = 1;
819+ return MPA_encode_init(avctx);
820+}
821+
822+const FFCodec ff_mp2fixed_encoder = {
823+ .p.name = "mp2fixed",
824+ CODEC_LONG_NAME("MP2 fixed point (MPEG audio layer 2)"),
825+ .p.type = AVMEDIA_TYPE_AUDIO,
826+ .p.id = AV_CODEC_ID_MP2,
827+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
828+ .priv_data_size = sizeof(MpegAudioContext),
829+ .init = mpa_fixed_encode_init,
830+ FF_CODEC_ENCODE_CB(MPA_encode_frame),
831+ CODEC_SAMPLEFMTS(AV_SAMPLE_FMT_S16),
832+ CODEC_SAMPLERATES(44100, 48000, 32000, 22050, 24000, 16000),
833+ CODEC_CH_LAYOUTS(AV_CHANNEL_LAYOUT_MONO, AV_CHANNEL_LAYOUT_STEREO),
834+ .defaults = mp2_defaults,
835+};
836+#endif
libavcodec/mpegaudioenc_fixed.c+0−39
@@ -1,39 +0,0 @@
1−/*
2− * The simplest mpeg audio layer 2 encoder
3− * Copyright (c) 2000, 2001 Fabrice Bellard
4− *
5− * This file is part of FFmpeg.
6− *
7− * FFmpeg is free software; you can redistribute it and/or
8− * modify it under the terms of the GNU Lesser General Public
9− * License as published by the Free Software Foundation; either
10− * version 2.1 of the License, or (at your option) any later version.
11− *
12− * FFmpeg is distributed in the hope that it will be useful,
13− * but WITHOUT ANY WARRANTY; without even the implied warranty of
14− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15− * Lesser General Public License for more details.
16− *
17− * You should have received a copy of the GNU Lesser General Public
18− * License along with FFmpeg; if not, write to the Free Software
19− * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20− */
21−
22−#include "libavutil/channel_layout.h"
23−#include "codec_internal.h"
24−#include "mpegaudioenc_template.c"
25−
26−const FFCodec ff_mp2fixed_encoder = {
27− .p.name = "mp2fixed",
28− CODEC_LONG_NAME("MP2 fixed point (MPEG audio layer 2)"),
29− .p.type = AVMEDIA_TYPE_AUDIO,
30− .p.id = AV_CODEC_ID_MP2,
31− .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
32− .priv_data_size = sizeof(MpegAudioContext),
33− .init = MPA_encode_init,
34− FF_CODEC_ENCODE_CB(MPA_encode_frame),
35− CODEC_SAMPLEFMTS(AV_SAMPLE_FMT_S16),
36− CODEC_SAMPLERATES(44100, 48000, 32000, 22050, 24000, 16000),
37− CODEC_CH_LAYOUTS(AV_CHANNEL_LAYOUT_MONO, AV_CHANNEL_LAYOUT_STEREO),
38− .defaults = mp2_defaults,
39−};
libavcodec/mpegaudioenc_float.c+0−40
@@ -1,40 +0,0 @@
1−/*
2− * The simplest mpeg audio layer 2 encoder
3− * Copyright (c) 2000, 2001 Fabrice Bellard
4− *
5− * This file is part of FFmpeg.
6− *
7− * FFmpeg is free software; you can redistribute it and/or
8− * modify it under the terms of the GNU Lesser General Public
9− * License as published by the Free Software Foundation; either
10− * version 2.1 of the License, or (at your option) any later version.
11− *
12− * FFmpeg is distributed in the hope that it will be useful,
13− * but WITHOUT ANY WARRANTY; without even the implied warranty of
14− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15− * Lesser General Public License for more details.
16− *
17− * You should have received a copy of the GNU Lesser General Public
18− * License along with FFmpeg; if not, write to the Free Software
19− * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20− */
21−
22−#include "libavutil/channel_layout.h"
23−#define USE_FLOATS 1
24−#include "codec_internal.h"
25−#include "mpegaudioenc_template.c"
26−
27−const FFCodec ff_mp2_encoder = {
28− .p.name = "mp2",
29− CODEC_LONG_NAME("MP2 (MPEG audio layer 2)"),
30− .p.type = AVMEDIA_TYPE_AUDIO,
31− .p.id = AV_CODEC_ID_MP2,
32− .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
33− .priv_data_size = sizeof(MpegAudioContext),
34− .init = MPA_encode_init,
35− FF_CODEC_ENCODE_CB(MPA_encode_frame),
36− CODEC_SAMPLEFMTS(AV_SAMPLE_FMT_S16),
37− CODEC_SAMPLERATES(44100, 48000, 32000, 22050, 24000, 16000),
38− CODEC_CH_LAYOUTS(AV_CHANNEL_LAYOUT_MONO, AV_CHANNEL_LAYOUT_STEREO),
39− .defaults = mp2_defaults,
40−};

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t