This checks if all strategies are the the frame exponent strategy table, and
if so, writes the table indices instead of each strategy.
---
 libavcodec/ac3enc.c       |   90 +++++++++++++++++++++++++++++++++++++++------
 libavcodec/ac3tab.c       |   38 +++++++++++++++++++
 libavcodec/ac3tab.h       |    1 +
 libavcodec/eac3dec_data.c |   38 -------------------
 libavcodec/eac3dec_data.h |    1 -
 5 files changed, 117 insertions(+), 51 deletions(-)

diff --git a/libavcodec/ac3enc.c b/libavcodec/ac3enc.c
index 5285874..8cc6c3d 100644
--- a/libavcodec/ac3enc.c
+++ b/libavcodec/ac3enc.c
@@ -219,6 +219,8 @@ typedef struct AC3EncodeContext {
     uint8_t *cpl_coord_mant_buffer;
 
     uint8_t exp_strategy[AC3_MAX_CHANNELS][AC3_MAX_BLOCKS]; ///< exponent strategies
+    uint8_t frame_exp_strategy[AC3_MAX_CHANNELS];
+    int use_frame_exp_strategy;
 
     DECLARE_ALIGNED(32, SampleType, windowed_samples)[AC3_WINDOW_SIZE];
 } AC3EncodeContext;
@@ -293,6 +295,13 @@ static uint8_t exponent_group_tab[2][3][256];
 
 
 /**
+ * LUT for finding a matching frame exponent strategy from a set of per-block
+ * exponent strategies.
+ */
+static int8_t frame_expstr_search_tab[3][4][4][4][4][4];
+
+
+/**
  * List of supported channel layouts.
  */
 static const int64_t ac3_channel_layouts[] = {
@@ -466,6 +475,7 @@ static void compute_coupling_strategy(AC3EncodeContext *s)
 {
     int blk, ch;
     int got_cpl_snr;
+    int num_cpl_blocks;
 
     /* set coupling use flags for each block/channel */
     /* TODO: turn coupling on/off and adjust start band based on bit usage */
@@ -478,12 +488,14 @@ static void compute_coupling_strategy(AC3EncodeContext *s)
     /* enable coupling for each block if at least 2 channels have coupling
        enabled for that block */
     got_cpl_snr = 0;
+    num_cpl_blocks = 0;
     for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
         AC3Block *block = &s->blocks[blk];
         block->num_cpl_channels = 0;
         for (ch = 1; ch <= s->fbw_channels; ch++)
             block->num_cpl_channels += block->channel_in_cpl[ch];
         block->cpl_in_use = block->num_cpl_channels > 1;
+        num_cpl_blocks += block->cpl_in_use;
         if (!block->cpl_in_use) {
             block->num_cpl_channels = 0;
             for (ch = 1; ch <= s->fbw_channels; ch++)
@@ -509,6 +521,8 @@ static void compute_coupling_strategy(AC3EncodeContext *s)
             block->new_snr_offsets = 0;
         }
     }
+    if (!num_cpl_blocks)
+        s->cpl_on = 0;
 
     /* set bandwidth for each channel */
     for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
@@ -886,6 +900,16 @@ static av_cold void exponent_init(AC3EncodeContext *s)
     }
     /* LFE */
     exponent_group_tab[0][0][7] = 2;
+
+    memset(frame_expstr_search_tab, -1, sizeof(frame_expstr_search_tab));
+    for (i = 0; i < 32; i++) {
+        frame_expstr_search_tab[ff_eac3_frm_expstr[i][0]-1]
+                               [ff_eac3_frm_expstr[i][1]]
+                               [ff_eac3_frm_expstr[i][2]]
+                               [ff_eac3_frm_expstr[i][3]]
+                               [ff_eac3_frm_expstr[i][4]]
+                               [ff_eac3_frm_expstr[i][5]] = i;
+    }
 }
 
 
@@ -933,8 +957,15 @@ static void compute_exp_strategy(AC3EncodeContext *s)
         exp_strategy[0] = EXP_NEW;
         exp += AC3_MAX_COEFS;
         for (blk = 1; blk < AC3_MAX_BLOCKS; blk++, exp += AC3_MAX_COEFS) {
-            if ((ch == CPL_CH && (!s->blocks[blk].cpl_in_use || !s->blocks[blk-1].cpl_in_use)) ||
-                (ch  > CPL_CH && (s->blocks[blk].channel_in_cpl[ch] != s->blocks[blk-1].channel_in_cpl[ch]))) {
+            if (ch == CPL_CH) {
+                if (!s->blocks[blk-1].cpl_in_use) {
+                    exp_strategy[blk] = EXP_NEW;
+                    continue;
+                } else if (!s->blocks[blk].cpl_in_use) {
+                    exp_strategy[blk] = EXP_REUSE;
+                    continue;
+                }
+            } else if (s->blocks[blk].channel_in_cpl[ch] != s->blocks[blk-1].channel_in_cpl[ch]) {
                 exp_strategy[blk] = EXP_NEW;
                 continue;
             }
@@ -968,6 +999,24 @@ static void compute_exp_strategy(AC3EncodeContext *s)
         for (blk = 1; blk < AC3_MAX_BLOCKS; blk++)
             s->exp_strategy[ch][blk] = EXP_REUSE;
     }
+
+    /* determine frame exponent strategy use for E-AC-3 */
+    if (s->eac3) {
+        s->use_frame_exp_strategy = 1;
+        for (ch = !s->cpl_on; ch <= s->fbw_channels; ch++) {
+            int expstr = frame_expstr_search_tab[s->exp_strategy[ch][0]-1]
+                                                [s->exp_strategy[ch][1]]
+                                                [s->exp_strategy[ch][2]]
+                                                [s->exp_strategy[ch][3]]
+                                                [s->exp_strategy[ch][4]]
+                                                [s->exp_strategy[ch][5]];
+            if (expstr < 0) {
+                s->use_frame_exp_strategy = 0;
+                break;
+            }
+            s->frame_exp_strategy[ch] = expstr;
+        }
+    }
 }
 
 
@@ -1199,8 +1248,12 @@ static void count_frame_bits_fixed(AC3EncodeContext *s)
         frame_bits += 2;
         frame_bits += 10;
         /* exponent strategy */
-        for (blk = 0; blk < AC3_MAX_BLOCKS; blk++)
-            frame_bits += 2 * s->fbw_channels + s->lfe_on;
+        if (s->use_frame_exp_strategy)
+            frame_bits += 5 * s->fbw_channels;
+        else
+            frame_bits += 2 * AC3_MAX_BLOCKS * s->fbw_channels;
+        /* lfe exponent strategy */
+        frame_bits += s->lfe_on;
         /* converter exponent strategy */
         frame_bits += s->fbw_channels * 5;
         /* snr offsets */
@@ -1323,8 +1376,12 @@ static void count_frame_bits(AC3EncodeContext *s)
             }
         }
         /* coupling exponent strategy */
-        for (blk = 0; blk < AC3_MAX_BLOCKS; blk++)
-            frame_bits += 2 * s->blocks[blk].cpl_in_use;
+        if (s->use_frame_exp_strategy) {
+            frame_bits += 5 * s->cpl_on;
+        } else {
+            for (blk = 0; blk < AC3_MAX_BLOCKS; blk++)
+                frame_bits += 2 * s->blocks[blk].cpl_in_use;
+        }
     } else {
         if (opt->audio_production_info)
             frame_bits += 7;
@@ -1920,7 +1977,7 @@ static void eac3_output_frame_header(AC3EncodeContext *s)
     put_bits(&s->pb, 1, 0);                         /* no additional bit stream info */
 
     /* frame header */
-    put_bits(&s->pb, 1, 1);                         /* exponent strategy syntax = each block */
+    put_bits(&s->pb, 1, !s->use_frame_exp_strategy); /* exponent strategy syntax */
     put_bits(&s->pb, 1, 0);                         /* aht enabled = no */
     put_bits(&s->pb, 2, 0);                         /* snr offset strategy = 1 */
     put_bits(&s->pb, 1, 0);                         /* transient pre-noise processing enabled = no */
@@ -1942,16 +1999,25 @@ static void eac3_output_frame_header(AC3EncodeContext *s)
         }
     }
     /* exponent strategy */
-    for (blk = 0; blk < AC3_MAX_BLOCKS; blk++)
-        for (ch = !s->blocks[blk].cpl_in_use; ch <= s->fbw_channels; ch++)
-            put_bits(&s->pb, 2, s->exp_strategy[ch][blk]);
+    if (s->use_frame_exp_strategy) {
+        for (ch = !s->cpl_on; ch <= s->fbw_channels; ch++)
+            put_bits(&s->pb, 5, s->frame_exp_strategy[ch]);
+    } else {
+        for (blk = 0; blk < AC3_MAX_BLOCKS; blk++)
+            for (ch = !s->blocks[blk].cpl_in_use; ch <= s->fbw_channels; ch++)
+                put_bits(&s->pb, 2, s->exp_strategy[ch][blk]);
+    }
     if (s->lfe_on) {
         for (blk = 0; blk < AC3_MAX_BLOCKS; blk++)
             put_bits(&s->pb, 1, s->exp_strategy[s->lfe_channel][blk]);
     }
     /* E-AC-3 to AC-3 converter exponent strategy (unfortunately not optional...) */
-    for (ch = 1; ch <= s->fbw_channels; ch++)
-        put_bits(&s->pb, 5, 0);
+    for (ch = 1; ch <= s->fbw_channels; ch++) {
+        if (s->use_frame_exp_strategy)
+            put_bits(&s->pb, 5, s->frame_exp_strategy[ch]);
+        else
+            put_bits(&s->pb, 5, 0);
+    }
     /* snr offsets */
     put_bits(&s->pb, 6, s->coarse_snr_offset);
     put_bits(&s->pb, 4, s->fine_snr_offset[1]);
diff --git a/libavcodec/ac3tab.c b/libavcodec/ac3tab.c
index 7df3d82..327f953 100644
--- a/libavcodec/ac3tab.c
+++ b/libavcodec/ac3tab.c
@@ -312,3 +312,41 @@ const uint16_t ff_eac3_default_chmap[8] = {
     AC3_CHMAP_L |               AC3_CHMAP_R | AC3_CHMAP_L_SUR |                  AC3_CHMAP_R_SUR,
     AC3_CHMAP_L | AC3_CHMAP_C | AC3_CHMAP_R | AC3_CHMAP_L_SUR |                  AC3_CHMAP_R_SUR
 };
+
+/**
+ * Table E2.14 Frame Exponent Strategy Combinations
+ */
+const uint8_t ff_eac3_frm_expstr[32][6] = {
+{    EXP_D15,  EXP_REUSE,  EXP_REUSE,  EXP_REUSE,  EXP_REUSE,  EXP_REUSE},
+{    EXP_D15,  EXP_REUSE,  EXP_REUSE,  EXP_REUSE,  EXP_REUSE,    EXP_D45},
+{    EXP_D15,  EXP_REUSE,  EXP_REUSE,  EXP_REUSE,    EXP_D25,  EXP_REUSE},
+{    EXP_D15,  EXP_REUSE,  EXP_REUSE,  EXP_REUSE,    EXP_D45,    EXP_D45},
+{    EXP_D25,  EXP_REUSE,  EXP_REUSE,    EXP_D25,  EXP_REUSE,  EXP_REUSE},
+{    EXP_D25,  EXP_REUSE,  EXP_REUSE,    EXP_D25,  EXP_REUSE,    EXP_D45},
+{    EXP_D25,  EXP_REUSE,  EXP_REUSE,    EXP_D45,    EXP_D25,  EXP_REUSE},
+{    EXP_D25,  EXP_REUSE,  EXP_REUSE,    EXP_D45,    EXP_D45,    EXP_D45},
+{    EXP_D25,  EXP_REUSE,    EXP_D15,  EXP_REUSE,  EXP_REUSE,  EXP_REUSE},
+{    EXP_D25,  EXP_REUSE,    EXP_D25,  EXP_REUSE,  EXP_REUSE,    EXP_D45},
+{    EXP_D25,  EXP_REUSE,    EXP_D25,  EXP_REUSE,    EXP_D25,  EXP_REUSE},
+{    EXP_D25,  EXP_REUSE,    EXP_D25,  EXP_REUSE,    EXP_D45,    EXP_D45},
+{    EXP_D25,  EXP_REUSE,    EXP_D45,    EXP_D25,  EXP_REUSE,  EXP_REUSE},
+{    EXP_D25,  EXP_REUSE,    EXP_D45,    EXP_D25,  EXP_REUSE,    EXP_D45},
+{    EXP_D25,  EXP_REUSE,    EXP_D45,    EXP_D45,    EXP_D25,  EXP_REUSE},
+{    EXP_D25,  EXP_REUSE,    EXP_D45,    EXP_D45,    EXP_D45,    EXP_D45},
+{    EXP_D45,    EXP_D15,  EXP_REUSE,  EXP_REUSE,  EXP_REUSE,  EXP_REUSE},
+{    EXP_D45,    EXP_D15,  EXP_REUSE,  EXP_REUSE,  EXP_REUSE,    EXP_D45},
+{    EXP_D45,    EXP_D25,  EXP_REUSE,  EXP_REUSE,    EXP_D25,  EXP_REUSE},
+{    EXP_D45,    EXP_D25,  EXP_REUSE,  EXP_REUSE,    EXP_D45,    EXP_D45},
+{    EXP_D45,    EXP_D25,  EXP_REUSE,    EXP_D25,  EXP_REUSE,  EXP_REUSE},
+{    EXP_D45,    EXP_D25,  EXP_REUSE,    EXP_D25,  EXP_REUSE,    EXP_D45},
+{    EXP_D45,    EXP_D25,  EXP_REUSE,    EXP_D45,    EXP_D25,  EXP_REUSE},
+{    EXP_D45,    EXP_D25,  EXP_REUSE,    EXP_D45,    EXP_D45,    EXP_D45},
+{    EXP_D45,    EXP_D45,    EXP_D15,  EXP_REUSE,  EXP_REUSE,  EXP_REUSE},
+{    EXP_D45,    EXP_D45,    EXP_D25,  EXP_REUSE,  EXP_REUSE,    EXP_D45},
+{    EXP_D45,    EXP_D45,    EXP_D25,  EXP_REUSE,    EXP_D25,  EXP_REUSE},
+{    EXP_D45,    EXP_D45,    EXP_D25,  EXP_REUSE,    EXP_D45,    EXP_D45},
+{    EXP_D45,    EXP_D45,    EXP_D45,    EXP_D25,  EXP_REUSE,  EXP_REUSE},
+{    EXP_D45,    EXP_D45,    EXP_D45,    EXP_D25,  EXP_REUSE,    EXP_D45},
+{    EXP_D45,    EXP_D45,    EXP_D45,    EXP_D45,    EXP_D25,  EXP_REUSE},
+{    EXP_D45,    EXP_D45,    EXP_D45,    EXP_D45,    EXP_D45,    EXP_D45},
+};
diff --git a/libavcodec/ac3tab.h b/libavcodec/ac3tab.h
index e5cd368..35ee5a8 100644
--- a/libavcodec/ac3tab.h
+++ b/libavcodec/ac3tab.h
@@ -53,6 +53,7 @@ extern const uint16_t ff_ac3_fast_gain_tab[8];
 extern const uint16_t ff_eac3_default_chmap[8];
 extern const uint8_t  ff_ac3_band_start_tab[AC3_CRITICAL_BANDS+1];
 extern HCONST uint8_t ff_ac3_bin_to_band_tab[253];
+extern const uint8_t  ff_eac3_frm_expstr[32][6];
 
 /** Custom channel map locations bitmask
  *  Other channels described in documentation:
diff --git a/libavcodec/eac3dec_data.c b/libavcodec/eac3dec_data.c
index 4cea26f..0b1f57d 100644
--- a/libavcodec/eac3dec_data.c
+++ b/libavcodec/eac3dec_data.c
@@ -1057,44 +1057,6 @@ const int16_t (* const ff_eac3_mantissa_vq[8])[6] = {
 };
 
 /**
- * Table E2.14 Frame Exponent Strategy Combinations
- */
-const uint8_t ff_eac3_frm_expstr[32][6] = {
-{    EXP_D15,  EXP_REUSE,  EXP_REUSE,  EXP_REUSE,  EXP_REUSE,  EXP_REUSE},
-{    EXP_D15,  EXP_REUSE,  EXP_REUSE,  EXP_REUSE,  EXP_REUSE,    EXP_D45},
-{    EXP_D15,  EXP_REUSE,  EXP_REUSE,  EXP_REUSE,    EXP_D25,  EXP_REUSE},
-{    EXP_D15,  EXP_REUSE,  EXP_REUSE,  EXP_REUSE,    EXP_D45,    EXP_D45},
-{    EXP_D25,  EXP_REUSE,  EXP_REUSE,    EXP_D25,  EXP_REUSE,  EXP_REUSE},
-{    EXP_D25,  EXP_REUSE,  EXP_REUSE,    EXP_D25,  EXP_REUSE,    EXP_D45},
-{    EXP_D25,  EXP_REUSE,  EXP_REUSE,    EXP_D45,    EXP_D25,  EXP_REUSE},
-{    EXP_D25,  EXP_REUSE,  EXP_REUSE,    EXP_D45,    EXP_D45,    EXP_D45},
-{    EXP_D25,  EXP_REUSE,    EXP_D15,  EXP_REUSE,  EXP_REUSE,  EXP_REUSE},
-{    EXP_D25,  EXP_REUSE,    EXP_D25,  EXP_REUSE,  EXP_REUSE,    EXP_D45},
-{    EXP_D25,  EXP_REUSE,    EXP_D25,  EXP_REUSE,    EXP_D25,  EXP_REUSE},
-{    EXP_D25,  EXP_REUSE,    EXP_D25,  EXP_REUSE,    EXP_D45,    EXP_D45},
-{    EXP_D25,  EXP_REUSE,    EXP_D45,    EXP_D25,  EXP_REUSE,  EXP_REUSE},
-{    EXP_D25,  EXP_REUSE,    EXP_D45,    EXP_D25,  EXP_REUSE,    EXP_D45},
-{    EXP_D25,  EXP_REUSE,    EXP_D45,    EXP_D45,    EXP_D25,  EXP_REUSE},
-{    EXP_D25,  EXP_REUSE,    EXP_D45,    EXP_D45,    EXP_D45,    EXP_D45},
-{    EXP_D45,    EXP_D15,  EXP_REUSE,  EXP_REUSE,  EXP_REUSE,  EXP_REUSE},
-{    EXP_D45,    EXP_D15,  EXP_REUSE,  EXP_REUSE,  EXP_REUSE,    EXP_D45},
-{    EXP_D45,    EXP_D25,  EXP_REUSE,  EXP_REUSE,    EXP_D25,  EXP_REUSE},
-{    EXP_D45,    EXP_D25,  EXP_REUSE,  EXP_REUSE,    EXP_D45,    EXP_D45},
-{    EXP_D45,    EXP_D25,  EXP_REUSE,    EXP_D25,  EXP_REUSE,  EXP_REUSE},
-{    EXP_D45,    EXP_D25,  EXP_REUSE,    EXP_D25,  EXP_REUSE,    EXP_D45},
-{    EXP_D45,    EXP_D25,  EXP_REUSE,    EXP_D45,    EXP_D25,  EXP_REUSE},
-{    EXP_D45,    EXP_D25,  EXP_REUSE,    EXP_D45,    EXP_D45,    EXP_D45},
-{    EXP_D45,    EXP_D45,    EXP_D15,  EXP_REUSE,  EXP_REUSE,  EXP_REUSE},
-{    EXP_D45,    EXP_D45,    EXP_D25,  EXP_REUSE,  EXP_REUSE,    EXP_D45},
-{    EXP_D45,    EXP_D45,    EXP_D25,  EXP_REUSE,    EXP_D25,  EXP_REUSE},
-{    EXP_D45,    EXP_D45,    EXP_D25,  EXP_REUSE,    EXP_D45,    EXP_D45},
-{    EXP_D45,    EXP_D45,    EXP_D45,    EXP_D25,  EXP_REUSE,  EXP_REUSE},
-{    EXP_D45,    EXP_D45,    EXP_D45,    EXP_D25,  EXP_REUSE,    EXP_D45},
-{    EXP_D45,    EXP_D45,    EXP_D45,    EXP_D45,    EXP_D25,  EXP_REUSE},
-{    EXP_D45,    EXP_D45,    EXP_D45,    EXP_D45,    EXP_D45,    EXP_D45},
-};
-
-/**
  * Table E.25: Spectral Extension Attenuation Table
  * ff_eac3_spx_atten_tab[code][bin]=pow(2.0,(bin+1)*(code+1)/-15.0);
  */
diff --git a/libavcodec/eac3dec_data.h b/libavcodec/eac3dec_data.h
index 91892a3..029cc9e 100644
--- a/libavcodec/eac3dec_data.h
+++ b/libavcodec/eac3dec_data.h
@@ -30,7 +30,6 @@ extern const int16_t ff_eac3_gaq_remap_2_4_a[9][2];
 extern const int16_t ff_eac3_gaq_remap_2_4_b[9][2];
 
 extern const int16_t (* const ff_eac3_mantissa_vq[8])[6];
-extern const uint8_t ff_eac3_frm_expstr[32][6];
 extern const float   ff_eac3_spx_atten_tab[32][3];
 
 #endif /* AVCODEC_EAC3DEC_DATA_H */
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to