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
529OBJS-$(CONFIG_MP1_DECODER) += mpegaudiodec_fixed.o529OBJS-$(CONFIG_MP1_DECODER) += mpegaudiodec_fixed.o
530OBJS-$(CONFIG_MP1FLOAT_DECODER) += mpegaudiodec_float.o530OBJS-$(CONFIG_MP1FLOAT_DECODER) += mpegaudiodec_float.o
531OBJS-$(CONFIG_MP2_DECODER) += mpegaudiodec_fixed.o531OBJS-$(CONFIG_MP2_DECODER) += mpegaudiodec_fixed.o
532OBJS-$(CONFIG_MP2_ENCODER) += mpegaudioenc_float.o mpegaudio.o \532OBJS-$(CONFIG_MP2_ENCODER) += mpegaudioenc.o mpegaudio.o \
533 mpegaudiodata.o mpegaudiodsp_data.o \533 mpegaudiodata.o mpegaudiodsp_data.o \
534 mpegaudiotabs.o534 mpegaudiotabs.o
535OBJS-$(CONFIG_MP2FIXED_ENCODER) += mpegaudioenc_fixed.o mpegaudio.o \535OBJS-$(CONFIG_MP2FIXED_ENCODER) += mpegaudioenc.o mpegaudio.o \
536 mpegaudiodata.o mpegaudiodsp_data.o \536 mpegaudiodata.o mpegaudiodsp_data.o \
537 mpegaudiotabs.o537 mpegaudiotabs.o
538OBJS-$(CONFIG_MP2FLOAT_DECODER) += mpegaudiodec_float.o538OBJS-$(CONFIG_MP2FLOAT_DECODER) += mpegaudiodec_float.o
libavcodec/mpegaudioenc.crenamed from libavcodec/mpegaudioenc_template.c+132−75
@@ -24,10 +24,14 @@ · 23 unmodified lines
24 * The simplest mpeg audio layer 2 encoder.24 * The simplest mpeg audio layer 2 encoder.
25 */25 */
26 26
27#include "config.h"
28#include "config_components.h"
29
27#include "libavutil/avassert.h"30#include "libavutil/avassert.h"
28#include "libavutil/channel_layout.h"31#include "libavutil/channel_layout.h"
29 32
30#include "avcodec.h"33#include "avcodec.h"
34#include "codec_internal.h"
31#include "encode.h"35#include "encode.h"
32#include "put_bits.h"36#include "put_bits.h"
33 37
@@ -52,6 +56,7 @@ typedef struct MpegAudioContext { · 18 unmodified lines
52 int bitrate_index; /* bit rate */56 int bitrate_index; /* bit rate */
53 int freq_index;57 int freq_index;
54 int frame_size; /* frame size, in bits, without padding */58 int frame_size; /* frame size, in bits, without padding */
59 int is_fixed;
55 /* padding computation */60 /* padding computation */
56 int frame_frac, frame_frac_incr, do_padding;61 int frame_frac, frame_frac_incr, do_padding;
57 short samples_buf[MPA_MAX_CHANNELS][SAMPLES_BUF_SIZE]; /* buffer for filter */62 short samples_buf[MPA_MAX_CHANNELS][SAMPLES_BUF_SIZE]; /* buffer for filter */
@@ -65,15 +70,18 @@ typedef struct MpegAudioContext { · 7 unmodified lines
65 int16_t filter_bank[512];70 int16_t filter_bank[512];
66 int scale_factor_table[64];71 int scale_factor_table[64];
67 unsigned char scale_diff_table[128];72 unsigned char scale_diff_table[128];
68#if USE_FLOATS73 union {
69 float scale_factor_inv_table[64];74 float scale_factor_inv_table[64];
70#else75 struct {
71 int8_t scale_factor_shift[64];76 int8_t scale_factor_shift[64];
72 unsigned short scale_factor_mult[64];77 unsigned short scale_factor_mult[64];
73#endif78 };
79 };
74 unsigned short total_quant_bits[17]; /* total number of bits per allocation group */80 unsigned short total_quant_bits[17]; /* total number of bits per allocation group */
75} MpegAudioContext;81} MpegAudioContext;
76 82
83#define IS_FIXED(s) (CONFIG_MP2_ENCODER && CONFIG_MP2FIXED_ENCODER ? (s)->is_fixed : CONFIG_MP2FIXED_ENCODER)
84
77static av_cold int MPA_encode_init(AVCodecContext *avctx)85static av_cold int MPA_encode_init(AVCodecContext *avctx)
78{86{
79 MpegAudioContext *s = avctx->priv_data;87 MpegAudioContext *s = avctx->priv_data;
@@ -157,13 +165,13 @@ static av_cold int MPA_encode_init(AVCodecContext *avctx) · 77 unmodified lines
157 if (v <= 0)165 if (v <= 0)
158 v = 1;166 v = 1;
159 s->scale_factor_table[i] = v;167 s->scale_factor_table[i] = v;
160#if USE_FLOATS168 if (IS_FIXED(s)) {
161 s->scale_factor_inv_table[i] = exp2(-(3 - i) / 3.0) / (float)(1 << 20);
162#else
163#define P 15169#define P 15
164 s->scale_factor_shift[i] = 21 - P - (i / 3);170 s->scale_factor_shift[i] = 21 - P - (i / 3);
165 s->scale_factor_mult[i] = (1 << P) * exp2((i % 3) / 3.0);171 s->scale_factor_mult[i] = (1 << P) * exp2((i % 3) / 3.0);
166#endif172 } else {
173 s->scale_factor_inv_table[i] = exp2(-(3 - i) / 3.0) / (float)(1 << 20);
174 }
167 }175 }
168 for(i=0;i<128;i++) {176 for(i=0;i<128;i++) {
169 v = i - 64;177 v = i - 64;
@@ -592,6 +600,70 @@ static void compute_bit_allocation(MpegAudioContext *s, · 422 unmodified lines
592 av_assert0(*padding >= 0);600 av_assert0(*padding >= 0);
593}601}
594 602
603/// Quantization & write sub band samples
604static 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
595/*667/*
596 * Output the MPEG audio layer 2 frame. Note how the code is small668 * Output the MPEG audio layer 2 frame. Note how the code is small
597 * compared to other encoders :-)669 * compared to other encoders :-)
@@ -600,9 +672,8 @@ static void encode_frame(MpegAudioContext *s, · 2 unmodified lines
600 unsigned char bit_alloc[MPA_MAX_CHANNELS][SBLIMIT],672 unsigned char bit_alloc[MPA_MAX_CHANNELS][SBLIMIT],
601 int padding)673 int padding)
602{674{
603 int i, j, k, l, bit_alloc_bits, b, ch;675 int i, j, bit_alloc_bits, ch;
604 unsigned char *sf;676 unsigned char *sf;
605 int q[3];
606 PutBitContext *p = &s->pb;677 PutBitContext *p = &s->pb;
607 678
608 /* header */679 /* header */
@@ -663,69 +734,14 @@ static void encode_frame(MpegAudioContext *s, · 54 unmodified lines
663 }734 }
664 }735 }
665 736
666 /* quantization & write sub band samples */737#if CONFIG_SMALL
667 738 encode_subbands(s, p, bit_alloc, IS_FIXED(s));
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 }
689#else739#else
690 {740 if (IS_FIXED(s))
691 int q1, e, shift, mult;741 encode_subbands(s, p, bit_alloc, 1);
692 e = s->scale_factors[ch][i][k];742 else
693 shift = s->scale_factor_shift[e];743 encode_subbands(s, p, bit_alloc, 0);
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 }
707#endif744#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 }
729 745
730 /* padding */746 /* padding */
731 for(i=0;i<padding;i++)747 for(i=0;i<padding;i++)
@@ -777,3 +793,44 @@ static const FFCodecDefault mp2_defaults[] = { · 45 unmodified lines
777 { NULL },793 { NULL },
778};794};
779 795
796#if CONFIG_MP2_ENCODER
797const 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
814static 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
822const 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
26const 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
27const 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