]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/siren.c
avcodec: Constify AVCodecs
[ffmpeg] / libavcodec / siren.c
index 2577ff52dd16dfefa68cd2e9ad172182dcebd55f..5937f0d56c86f40951189fb3b491fb5e4a8ba1b0 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "libavutil/tx.h"
 #include "libavutil/float_dsp.h"
+#include "libavutil/mem_internal.h"
 
 #include "avcodec.h"
 #include "get_bits.h"
@@ -341,17 +342,18 @@ static const float mlt_quant[7][14] = {
     { 0.0f, 1.964f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }
 };
 
-static const float noise_category5[20] = {
+static const float noise_category5[21] = {
     0.70711f, 0.6179f, 0.5005f, 0.3220f, 0.17678f, 0.17678f, 0.17678f, 0.17678f, 0.17678f, 0.17678f, 0.17678f,
     0.17678f, 0.17678f, 0.17678f, 0.17678f, 0.17678f, 0.17678f, 0.17678f, 0.17678f, 0.17678f
 };
 
-static const float noise_category6[20] = {
+static const float noise_category6[21] = {
     0.70711f, 0.5686f, 0.3563f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f,
     0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f
 };
 
 #define FRAME_SIZE 320
+#define REGION_SIZE 20
 
 typedef struct SirenContext {
     GetBitContext gb;
@@ -361,9 +363,8 @@ typedef struct SirenContext {
     int number_of_regions;
     int scale_factor;
     int sample_rate_bits;
-    int region_size;
 
-    int dw1, dw2, dw3, dw4;
+    unsigned dw1, dw2, dw3, dw4;
 
     int absolute_region_power_index[32];
     float decoder_standard_deviation[32];
@@ -402,7 +403,6 @@ static av_cold int siren_init(AVCodecContext *avctx)
     s->esf_adjustment = 7;
     s->number_of_regions = 14;
     s->scale_factor = 22;
-    s->region_size = 20;
     s->dw1 = s->dw2 = s->dw3 = s->dw4 = 1;
 
     for (i = 0; i < 64; i++) {
@@ -428,6 +428,7 @@ static int decode_envelope(SirenContext *s, GetBitContext *gb,
                            int *absolute_region_power_index, int esf_adjustment)
 {
     absolute_region_power_index[0] = (int)get_bits(gb, 5) - esf_adjustment;
+    absolute_region_power_index[0] = av_clip(absolute_region_power_index[0], -24, 39);
     decoder_standard_deviation[0] = s->standard_deviation[absolute_region_power_index[0] + 24];
 
     for (int i = 1; i < number_of_regions; i++) {
@@ -437,7 +438,7 @@ static int decode_envelope(SirenContext *s, GetBitContext *gb,
             index = differential_decoder_tree[i - 1][index][get_bits1(gb)];
         } while (index > 0);
 
-        absolute_region_power_index[i] = absolute_region_power_index[i - 1] - index - 12;
+        absolute_region_power_index[i] = av_clip(absolute_region_power_index[i - 1] - index - 12, -24, 39);
         decoder_standard_deviation[i] = s->standard_deviation[absolute_region_power_index[i] + 24];
     }
 
@@ -500,6 +501,8 @@ static int categorize_regions(int number_of_regions, int number_of_available_bit
                     }
                 }
             }
+            if (raw_value == -99)
+                return AVERROR_INVALIDDATA;
             *min_rate_ptr++ = raw_min_idx;
             min +=
                 expected_bits_table[min_rate_categories[raw_min_idx] + 1] -
@@ -518,6 +521,8 @@ static int categorize_regions(int number_of_regions, int number_of_available_bit
                     }
                 }
             }
+            if (raw_value == 99)
+                return AVERROR_INVALIDDATA;
 
             *--max_rate_ptr = raw_max_idx;
             max += expected_bits_table[max_rate_categories[raw_max_idx] - 1] -
@@ -569,7 +574,7 @@ static int decode_vector(SirenContext *s, int number_of_regions,
 
     for (region = 0; region < number_of_regions; region++) {
         category = power_categories[region];
-        coefs_ptr = coefs + (region * s->region_size);
+        coefs_ptr = coefs + (region * REGION_SIZE);
 
         if (category >= 0 && category < 7) {
             decoder_tree = decoder_tables[category];
@@ -618,32 +623,27 @@ static int decode_vector(SirenContext *s, int number_of_regions,
             }
         }
 
-        coefs_ptr = coefs + (region * s->region_size);
+        coefs_ptr = coefs + (region * REGION_SIZE);
 
-        if (category == 5) {
+        if (category == 5 || category == 6) {
             i = 0;
-            for (j = 0; j < s->region_size; j++) {
+            for (j = 0; j < REGION_SIZE; j++) {
                 if (*coefs_ptr != 0)
                     i++;
                 coefs_ptr++;
             }
 
-            noise = decoder_standard_deviation[region] * noise_category5[i];
-        } else if (category == 6) {
-            i = 0;
-            for (j = 0; j < s->region_size; j++) {
-                if (*coefs_ptr++ != 0)
-                    i++;
-            }
-
-            noise = decoder_standard_deviation[region] * noise_category6[i];
+            if (category == 5) {
+                noise = decoder_standard_deviation[region] * noise_category5[i];
+            } else
+                noise = decoder_standard_deviation[region] * noise_category6[i];
         } else if (category == 7) {
             noise = decoder_standard_deviation[region] * 0.70711f;
         } else {
             noise = 0;
         }
 
-        coefs_ptr = coefs + (region * s->region_size);
+        coefs_ptr = coefs + (region * REGION_SIZE);
 
         if (category == 5 || category == 6 || category == 7) {
             dw1 = get_dw(s);
@@ -684,9 +684,11 @@ static int siren_decode(AVCodecContext *avctx, void *data,
 
     rate_control = get_bits(gb, 4);
 
-    categorize_regions(s->number_of_regions, get_bits_left(gb),
-                       s->absolute_region_power_index, s->power_categories,
-                       s->category_balance);
+    ret = categorize_regions(s->number_of_regions, get_bits_left(gb),
+                             s->absolute_region_power_index, s->power_categories,
+                             s->category_balance);
+    if (ret < 0)
+        return ret;
 
     for (int i = 0; i < rate_control; i++)
         s->power_categories[s->category_balance[i]]++;
@@ -757,7 +759,7 @@ static av_cold int siren_close(AVCodecContext *avctx)
     return 0;
 }
 
-AVCodec ff_siren_decoder = {
+const AVCodec ff_siren_decoder = {
     .name           = "siren",
     .long_name      = NULL_IF_CONFIG_SMALL("Siren"),
     .priv_data_size = sizeof(SirenContext),
@@ -767,7 +769,8 @@ AVCodec ff_siren_decoder = {
     .close          = siren_close,
     .decode         = siren_decode,
     .flush          = siren_flush,
-    .capabilities   = AV_CODEC_CAP_DR1,
+    .capabilities   = AV_CODEC_CAP_CHANNEL_CONF |
+                      AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE |
                       FF_CODEC_CAP_INIT_CLEANUP,
 };