On 4/4/18, James Almer <jamr...@gmail.com> wrote: > 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.
ok > >> + >> + 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() ok > >> + >> + 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. ok > >> + 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? > ok >> + 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? What? > >> + >> + 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? I do not think so. > >> + } >> + } >> + >> + 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 > _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel