[FFmpeg-cvslog] aacdec: separate out scalefactor dequantization from decoding

Lynne git at videolan.org
Tue Apr 23 09:58:21 EEST 2024


ffmpeg | branch: master | Lynne <dev at lynne.ee> | Wed Mar 13 07:11:22 2024 +0100| [60b60dd635a4e69e43ead19f10f90ac03aa83ee1] | committer: Lynne

aacdec: separate out scalefactor dequantization from decoding

Allows to template away dequantization.

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=60b60dd635a4e69e43ead19f10f90ac03aa83ee1
---

 libavcodec/aacdec.h          |  1 +
 libavcodec/aacdec_template.c | 79 ++++++++++++++++++++++++++++++++++----------
 2 files changed, 63 insertions(+), 17 deletions(-)

diff --git a/libavcodec/aacdec.h b/libavcodec/aacdec.h
index 052ed59e01..9078c2a4e6 100644
--- a/libavcodec/aacdec.h
+++ b/libavcodec/aacdec.h
@@ -147,6 +147,7 @@ typedef struct SingleChannelElement {
     TemporalNoiseShaping tns;
     enum BandType band_type[128];                   ///< band types
     int band_type_run_end[120];                     ///< band type run end points
+    int sfo[120];                                   ///< scalefactor offsets
     INTFLOAT_UNION(sf, [120]);                      ///< scalefactors
     INTFLOAT_ALIGNED_UNION(32, coeffs,    1024);    ///< coefficients for IMDCT, maybe processed
     INTFLOAT_ALIGNED_UNION(32, saved,     1536);    ///< overlap
diff --git a/libavcodec/aacdec_template.c b/libavcodec/aacdec_template.c
index 3adb4ebdf1..5f3be074f7 100644
--- a/libavcodec/aacdec_template.c
+++ b/libavcodec/aacdec_template.c
@@ -1446,7 +1446,8 @@ static int decode_band_types(AACDecContext *ac, enum BandType band_type[120],
  *
  * @return  Returns error status. 0 - OK, !0 - error
  */
-static int decode_scalefactors(AACDecContext *ac, INTFLOAT sf[120], GetBitContext *gb,
+static int decode_scalefactors(AACDecContext *ac, int sfo[120],
+                               GetBitContext *gb,
                                unsigned int global_gain,
                                IndividualChannelStream *ics,
                                enum BandType band_type[120],
@@ -1461,7 +1462,7 @@ static int decode_scalefactors(AACDecContext *ac, INTFLOAT sf[120], GetBitContex
             int run_end = band_type_run_end[idx];
             if (band_type[idx] == ZERO_BT) {
                 for (; i < run_end; i++, idx++)
-                    sf[idx] = FIXR(0.);
+                    sfo[idx] = 0;
             } else if ((band_type[idx] == INTENSITY_BT) ||
                        (band_type[idx] == INTENSITY_BT2)) {
                 for (; i < run_end; i++, idx++) {
@@ -1473,11 +1474,7 @@ static int decode_scalefactors(AACDecContext *ac, INTFLOAT sf[120], GetBitContex
                                               "Clipped intensity stereo position (%d -> %d)",
                                               offset[2], clipped_offset);
                     }
-#if USE_FIXED
-                    sf[idx] = 100 - clipped_offset;
-#else
-                    sf[idx] = ff_aac_pow2sf_tab[-clipped_offset + POW_SF2_ZERO];
-#endif /* USE_FIXED */
+                    sfo[idx] = clipped_offset;
                 }
             } else if (band_type[idx] == NOISE_BT) {
                 for (; i < run_end; i++, idx++) {
@@ -1492,11 +1489,7 @@ static int decode_scalefactors(AACDecContext *ac, INTFLOAT sf[120], GetBitContex
                                               "Clipped noise gain (%d -> %d)",
                                               offset[1], clipped_offset);
                     }
-#if USE_FIXED
-                    sf[idx] = -(100 + clipped_offset);
-#else
-                    sf[idx] = -ff_aac_pow2sf_tab[clipped_offset + POW_SF2_ZERO];
-#endif /* USE_FIXED */
+                    sfo[idx] = clipped_offset;
                 }
             } else {
                 for (; i < run_end; i++, idx++) {
@@ -1506,16 +1499,66 @@ static int decode_scalefactors(AACDecContext *ac, INTFLOAT sf[120], GetBitContex
                                "Scalefactor (%d) out of range.\n", offset[0]);
                         return AVERROR_INVALIDDATA;
                     }
+                    sfo[idx] = offset[0];
+                }
+            }
+        }
+    }
+    return 0;
+}
+
+/**
+ * Convert integer scalefactors to the decoder's native expected
+ * scalefactor values.
+ */
+static void dequant_scalefactors(SingleChannelElement *sce)
+{
+    IndividualChannelStream *ics = &sce->ics;
+    const enum BandType *band_type = sce->band_type;
+    const int *band_type_run_end = sce->band_type_run_end;
+    const int *sfo = sce->sfo;
+    INTFLOAT *sf = sce->AAC_RENAME(sf);
+
+    int g, i, idx = 0;
+    for (g = 0; g < ics->num_window_groups; g++) {
+        for (i = 0; i < ics->max_sfb;) {
+            int run_end = band_type_run_end[idx];
+            switch (band_type[idx]) {
+            case ZERO_BT:
+                for (; i < run_end; i++, idx++)
+                    sf[idx] = FIXR(0.);
+                break;
+            case INTENSITY_BT: /* fallthrough */
+            case INTENSITY_BT2:
+                for (; i < run_end; i++, idx++) {
 #if USE_FIXED
-                    sf[idx] = -offset[0];
+                    sf[idx] = 100 - sfo[idx];
 #else
-                    sf[idx] = -ff_aac_pow2sf_tab[offset[0] - 100 + POW_SF2_ZERO];
+                    sf[idx] = ff_aac_pow2sf_tab[-sfo[idx] + POW_SF2_ZERO];
 #endif /* USE_FIXED */
                 }
+                break;
+            case NOISE_BT:
+                for (; i < run_end; i++, idx++) {
+#if USE_FIXED
+                    sf[idx] = -(100 + sfo[idx]);
+#else
+                    sf[idx] = -ff_aac_pow2sf_tab[sfo[idx] + POW_SF2_ZERO];
+#endif /* USE_FIXED */
+                }
+                break;
+            default:
+                for (; i < run_end; i++, idx++) {
+#if USE_FIXED
+                    sf[idx] = -sfo[idx];
+#else
+                    sf[idx] = -ff_aac_pow2sf_tab[sfo[idx] - 100 + POW_SF2_ZERO];
+#endif /* USE_FIXED */
+                }
+                break;
             }
         }
     }
-    return 0;
 }
 
 /**
@@ -2007,10 +2050,12 @@ static int decode_ics(AACDecContext *ac, SingleChannelElement *sce,
     if ((ret = decode_band_types(ac, sce->band_type,
                                  sce->band_type_run_end, gb, ics)) < 0)
         goto fail;
-    if ((ret = decode_scalefactors(ac, sce->AAC_RENAME(sf), gb, global_gain, ics,
-                                  sce->band_type, sce->band_type_run_end)) < 0)
+    if ((ret = decode_scalefactors(ac, sce->sfo, gb, global_gain, ics,
+                                   sce->band_type, sce->band_type_run_end)) < 0)
         goto fail;
 
+    dequant_scalefactors(sce);
+
     pulse_present = 0;
     if (!scale_flag) {
         if (!eld_syntax && (pulse_present = get_bits1(gb))) {



More information about the ffmpeg-cvslog mailing list