On 4/4/2018 11:09 AM, Paul B Mahol wrote: > Signed-off-by: Paul B Mahol <one...@gmail.com> > --- > libavcodec/Makefile | 1 + > libavcodec/allcodecs.c | 1 + > libavcodec/avcodec.h | 1 + > libavcodec/codec_desc.c | 8 + > libavcodec/siren.c | 847 > ++++++++++++++++++++++++++++++++++++++++++++++++ > 5 files changed, 858 insertions(+) > create mode 100644 libavcodec/siren.c
[...] > +static av_cold int siren_init(AVCodecContext *avctx) > +{ > + SirenContext *s = avctx->priv_data; > + int i; > + > + avctx->channels = 1; > + avctx->channel_layout = AV_CH_LAYOUT_MONO; > + avctx->sample_fmt = AV_SAMPLE_FMT_S16; > + > + s->number_of_coefs = 320; > + s->rate_control_bits = 4; > + s->rate_control_possibilities = 16; > + s->checksum_bits = 0; > + s->esf_adjustment = 7; > + s->number_of_regions = 14; > + s->scale_factor = 1; > + s->bits_per_frame = avctx->sample_rate / 50; > + s->region_size = 20; > + s->dw1 = s->dw2 = s->dw3 = s->dw4 = 1; > + > + for (i = 0; i < 64; i++) { > + float region_power = powf(10, (i - 24) * STEPSIZE); > + > + s->standard_deviation[i] = sqrtf(region_power); > + s->deviation_inverse[i] = 1.f / s->standard_deviation[i]; > + } > + > + for (i = 0; i < 320; i++) { > + float angle = ((i + 0.5f) * M_PI_2) / 320.f; > + s->window[i] = sinf(angle); > + } > + > + ff_fft_init(&s->fft_ctx, 10, 0); Missing fft dependency in configure. > + > + return 0; > +} [...] > + > +static int categorize_regions(int number_of_regions, int > number_of_available_bits, > + int *absolute_region_power_index, int > *power_categories, > + int *category_balance) > +{ > + int region, delta, i, temp; > + int expected_number_of_code_bits; > + int min, max; > + int offset, > + num_rate_control_possibilities, > + raw_value, raw_max_idx = 0, raw_min_idx = 0; > + int max_rate_categories[28]; > + int min_rate_categories[28]; > + int temp_category_balances[64]; > + int *min_rate_ptr = NULL; > + int *max_rate_ptr = NULL; > + > + if (number_of_regions == 14) { > + num_rate_control_possibilities = 16; > + if (number_of_available_bits > 320) > + number_of_available_bits = > + ((number_of_available_bits - 320) * 5 / 8) + 320; > + } else { > + num_rate_control_possibilities = 32; > + if (number_of_regions == 28 && number_of_available_bits > 640) > + number_of_available_bits = > + ((number_of_available_bits - 640) * 5 / 8) + 640; > + } > + > + offset = -32; > + for (delta = 32; number_of_regions > 0 && delta > 0; delta /= 2) { > + expected_number_of_code_bits = 0; > + for (region = 0; region < number_of_regions; region++) { > + i = (delta + offset - > + absolute_region_power_index[region]) >> 1; > + if (i > 7) > + i = 7; > + else if (i < 0) > + i = 0; av_clip_uintp2() > + > + power_categories[region] = i; > + expected_number_of_code_bits += expected_bits_table[i]; > + > + } > + if (expected_number_of_code_bits >= number_of_available_bits - 32) > + offset += delta; > + } > + > + expected_number_of_code_bits = 0; > + for (region = 0; region < number_of_regions; region++) { > + i = (offset - absolute_region_power_index[region]) >> 1; > + if (i > 7) > + i = 7; > + else if (i < 0) > + i = 0; Same. > + max_rate_categories[region] = min_rate_categories[region] = > + power_categories[region] = i; > + expected_number_of_code_bits += expected_bits_table[i]; > + } [...] > +static int siren_decode(AVCodecContext *avctx, void *data, > + int *got_frame, AVPacket *pkt) > +{ > + SirenContext *s = avctx->priv_data; > + AVFrame *frame = data; > + int number_of_valid_coefs = 20 * s->number_of_regions; > + int number_of_available_bits = > + s->bits_per_frame - s->sample_rate_bits - s->checksum_bits; s->checksum_bits seems to always be 0, unless I'm missing something. > + int envelope_bits, ret; > + int frame_error = 0, i, rate_control = 0; > + int checksum, calculated_checksum; > + > + if (s->checksum_bits > 0) > + memcpy(s->input_frame, pkt->data, FFMIN(pkt->size, 80)); sizeof(s->input_frame) instead of 80? > + if ((ret = init_get_bits8(&s->gb, pkt->data, pkt->size)) < 0) > + return ret; > + > + envelope_bits = > + decode_envelope(s, &s->gb, s->number_of_regions, > + s->decoder_standard_deviation, > + s->absolute_region_power_index, s->esf_adjustment); > + > + number_of_available_bits -= envelope_bits; > + > + for (i = 0; i < s->rate_control_bits; i++) { > + rate_control <<= 1; > + rate_control |= get_bits1(&s->gb); > + } > + > + number_of_available_bits -= s->rate_control_bits; > + > + categorize_regions(s->number_of_regions, number_of_available_bits, > + s->absolute_region_power_index, s->power_categories, > + s->category_balance); > + > + for (i = 0; i < rate_control; i++) { > + s->power_categories[s->category_balance[i]]++; > + } > + > + number_of_available_bits = > + decode_vector(s, s->number_of_regions, number_of_available_bits, > + s->decoder_standard_deviation, s->power_categories, > + s->coefs, s->scale_factor); > + > + if (number_of_available_bits > 0) { > + for (i = 0; i < number_of_available_bits; i++) { > + if (!get_bits1(&s->gb)) > + frame_error = 1; > + } > + } else if (number_of_available_bits < 0 > + && rate_control + 1 < s->rate_control_possibilities) { > + frame_error |= 2; > + } > + > + for (i = 0; i < s->number_of_regions; i++) { > + if (s->absolute_region_power_index[i] > 33 > + || s->absolute_region_power_index[i] < -31) > + frame_error |= 4; > + } > + > + if (s->checksum_bits > 0) { > + int idx = 0, sum = 0; > + > + s->bits_per_frame >>= 4; > + checksum = s->input_frame[s->bits_per_frame - 1] & ((1 << > s->checksum_bits) - 1); > + s->input_frame[s->bits_per_frame - 1] &= ~checksum; > + do { > + sum ^= (s->input_frame[idx] & 0xFFFF) << (idx % 15); > + } while (++idx < s->bits_per_frame); > + > + sum = (sum >> 15) ^ (sum & 0x7FFF); > + calculated_checksum = 0; > + for (i = 0; i < 4; i++) { > + int j, temp1 = checksum_table[i] & sum; > + for (j = 8; j > 0; j >>= 1) { > + int temp2 = temp1 >> j; > + temp1 ^= temp2; > + } > + calculated_checksum <<= 1; > + calculated_checksum |= temp1 & 1; > + } AVCRC? > + > + if (checksum != calculated_checksum) > + frame_error |= 8; > + } > + > + if (frame_error != 0) { > + for (i = 0; i < number_of_valid_coefs; i++) { > + s->coefs[i] = s->backup_frame[i]; > + s->backup_frame[i] = 0; > + } > + } else { > + for (i = 0; i < number_of_valid_coefs; i++) > + s->backup_frame[i] = s->coefs[i]; > + } > + > + for (i = number_of_valid_coefs; i < s->number_of_coefs; i++) > + s->coefs[i] = 0; > + > + *got_frame = decode_samples(s, s->coefs, s->context, s->number_of_coefs, > s->output_frame); > + if (*got_frame) { > + int16_t *dst; > + > + frame->nb_samples = 320; > + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) > + return ret; > + dst = (int16_t *)frame->data[0]; > + > + for (i = 0; i < frame->nb_samples; i++) { > + dst[i] = av_clip_int16(s->output_frame[i]); Can't you clip them in decode_samples() instead, so you can replace this with a memcpy? > + } > + } > + > + return pkt->size; > +} > + > +static av_cold int siren_close(AVCodecContext *avctx) > +{ > + SirenContext *s = avctx->priv_data; > + > + ff_fft_end(&s->fft_ctx); > + > + return 0; > +} > + > +AVCodec ff_siren_decoder = { > + .name = "siren", > + .long_name = NULL_IF_CONFIG_SMALL("Siren"), > + .priv_data_size = sizeof(SirenContext), > + .type = AVMEDIA_TYPE_AUDIO, > + .id = AV_CODEC_ID_SIREN, > + .init = siren_init, > + .close = siren_close, > + .decode = siren_decode, > + .capabilities = AV_CODEC_CAP_DR1, > +}; > _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel