#include "libavutil/tx.h"
#include "libavutil/float_dsp.h"
+#include "libavutil/mem_internal.h"
#include "avcodec.h"
#include "get_bits.h"
{ 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;
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];
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++) {
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++) {
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];
}
}
}
}
+ if (raw_value == -99)
+ return AVERROR_INVALIDDATA;
*min_rate_ptr++ = raw_min_idx;
min +=
expected_bits_table[min_rate_categories[raw_min_idx] + 1] -
}
}
}
+ if (raw_value == 99)
+ return AVERROR_INVALIDDATA;
*--max_rate_ptr = raw_max_idx;
max += expected_bits_table[max_rate_categories[raw_max_idx] - 1] -
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];
}
}
- 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);
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]]++;
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),
.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,
};