On Thu, Jul 21, 2016 at 6:18 PM, Michael Niedermayer <mich...@niedermayer.cc> wrote: > On Sun, Jul 17, 2016 at 12:06:03AM +0530, Umair Khan wrote: >> Hi, >> >> Patch attached. >> >> - Umair > >> libavcodec/Makefile | 2 >> libavcodec/alsdec.c | 284 >> +++++++++++++++++++++++++++++++++++++++++- >> libavcodec/mlz.c | 171 +++++++++++++++++++++++++ >> libavcodec/mlz.h | 69 ++++++++++ >> libavutil/softfloat_ieee754.h | 115 +++++++++++++++++ >> 5 files changed, 638 insertions(+), 3 deletions(-) >> 0282267108d74681f1bff6b5e6a85c603ac7052e >> 0001-avcodec-alsdec-implement-floating-point-decoding.patch >> From 70e65b26cc3f84c9c664c30808b43a5e1cf16eaa Mon Sep 17 00:00:00 2001 >> From: Umair Khan <omerj...@gmail.com> >> Date: Sat, 16 Jul 2016 23:52:39 +0530 >> Subject: [PATCH 1/1] avcodec/alsdec: implement floating point decoding >> >> It conforms to RM22 version of the reference codec. >> >> Signed-off-by: Umair Khan <omerj...@gmail.com> >> --- >> libavcodec/Makefile | 2 +- >> libavcodec/alsdec.c | 284 >> +++++++++++++++++++++++++++++++++++++++++- >> libavcodec/mlz.c | 171 +++++++++++++++++++++++++ >> libavcodec/mlz.h | 69 ++++++++++ >> libavutil/softfloat_ieee754.h | 115 +++++++++++++++++ > > missing update to Changelog > > [...] >> @@ -1356,6 +1366,237 @@ static int revert_channel_correlation(ALSDecContext >> *ctx, ALSBlockData *bd, >> } >> >> >> +/** multiply two softfloats and handle the rounding off >> + */ >> +static SoftFloat_IEEE754 multiply(SoftFloat_IEEE754 a, SoftFloat_IEEE754 b) >> { >> + uint64_t mantissa_temp; >> + uint64_t mask_64; >> + int bit_count; >> + int cutoff_bit_count; >> + unsigned char last_2_bits; >> + unsigned int mantissa; >> + uint32_t return_val = 0; >> + int32_t sign; >> + >> + sign = a.sign ^ b.sign; >> + >> + // Multiply mantissa bits in a 64-bit register >> + mantissa_temp = (uint64_t)a.mant * (uint64_t)b.mant; >> + >> + // Count the valid bit count > >> + for (bit_count=48, mask_64=(uint64_t)0x1 << 47; !(mantissa_temp & >> mask_64) && mask_64; bit_count--, mask_64>>=1); > > this needs some newlines for readability > > >> + >> + // Round off >> + cutoff_bit_count = bit_count - 24; >> + if (cutoff_bit_count > 0) { >> + last_2_bits = (unsigned char)(((unsigned int)mantissa_temp >> >> (cutoff_bit_count - 1)) & 0x3 ); >> + if ((last_2_bits == 0x3) || ((last_2_bits == 0x1) && ((unsigned >> int)mantissa_temp & ((0x1UL << (cutoff_bit_count - 1)) - 1)))) { >> + // Need to round up >> + mantissa_temp += (uint64_t)0x1 << cutoff_bit_count; >> + } >> + } >> + >> + mantissa = (unsigned int)(mantissa_temp >> cutoff_bit_count); >> + >> + // Need one more shift? >> + if (mantissa & 0x01000000ul) { >> + bit_count++; >> + mantissa >>= 1; >> + } >> + >> + if (!sign) { >> + return_val = 0x80000000U; >> + } >> + >> + return_val |= (a.exp + b.exp + bit_count - 47) << 23; >> + return_val |= mantissa; >> + return av_bits2sf_ieee754(return_val); >> +} >> + >> + >> +/** Read and decode the floating point sample data >> + */ >> +static int read_diff_float_data(ALSDecContext *ctx, unsigned int ra_frame) { >> + AVCodecContext *avctx = ctx->avctx; >> + GetBitContext *gb = &ctx->gb; >> + SoftFloat_IEEE754 *acf = ctx->acf; >> + int *shift_value = ctx->shift_value; >> + int *last_shift_value = ctx->last_shift_value; >> + int *last_acf_mantissa = ctx->last_acf_mantissa; >> + int **raw_mantissa = ctx->raw_mantissa; >> + int *nbits = ctx->nbits; >> + unsigned char *larray = ctx->larray; >> + int frame_length = ctx->cur_frame_length; >> + SoftFloat_IEEE754 scale = av_int2sf_ieee754(0x1u, 23); >> + unsigned int partA_flag; >> + unsigned int highest_byte; >> + unsigned int shift_amp; >> + uint32_t tmp_32; >> + int use_acf; >> + int nchars; >> + int i; >> + int c; >> + long k; >> + long nbits_aligned; >> + unsigned long acc; >> + unsigned long j; >> + uint32_t sign; >> + uint32_t e; >> + uint32_t mantissa; >> + >> + skip_bits_long(gb, 32); //num_bytes_diff_float >> + use_acf = get_bits1(gb); >> + >> + if (ra_frame) { > >> + for (c = 0; c < avctx->channels; ++c) { >> + last_acf_mantissa[c] = 0; >> + last_shift_value[c] = 0; >> + } > > memset() > > >> + ff_mlz_flush_dict(ctx->mlz); >> + } >> + >> + for (c = 0; c < avctx->channels; ++c) { >> + if (use_acf) { >> + //acf_flag >> + if (get_bits1(gb)) { >> + tmp_32 = get_bits(gb, 23); >> + last_acf_mantissa[c] = tmp_32; >> + } else { >> + tmp_32 = last_acf_mantissa[c]; >> + } >> + acf[c] = av_bits2sf_ieee754(tmp_32); >> + } else { >> + acf[c] = FLOAT_1; >> + } >> + >> + highest_byte = get_bits(gb, 2); >> + partA_flag = get_bits1(gb); >> + shift_amp = get_bits1(gb); >> + >> + if (shift_amp) { >> + shift_value[c] = get_bits(gb, 8); >> + last_shift_value[c] = shift_value[c]; >> + } else { >> + shift_value[c] = last_shift_value[c]; >> + } >> + >> + if (partA_flag) { >> + if (!get_bits1(gb)) { //uncompressed >> + for (i = 0; i < frame_length; ++i) { >> + if (ctx->raw_samples[c][i] == 0) { >> + ctx->raw_mantissa[c][i] = get_bits_long(gb, 32); >> + } >> + } >> + } else { //compressed >> + nchars = 0; >> + for (i = 0; i < frame_length; ++i) { >> + if (ctx->raw_samples[c][i] == 0) { >> + nchars += 4; >> + } >> + } >> + >> + tmp_32 = ff_mlz_decompression(ctx->mlz, gb, nchars, larray); >> + if(tmp_32 != nchars) { >> + av_log(ctx->avctx, AV_LOG_ERROR, "Error in MLZ >> decompression (%d, %d).\n", tmp_32, nchars); >> + return AVERROR_INVALIDDATA; >> + } >> + >> + for (i = 0; i < frame_length; ++i) { > >> + tmp_32 = (larray[i] << 24) | larray[i+1] << 16 | >> larray[i+2] << 8 | larray[i+3]; > > AV_RB32() > > >> + ctx->raw_mantissa[c][i] = tmp_32; >> + } >> + } >> + } >> + >> + //decode part B >> + if (highest_byte) { >> + for (i = 0; i < frame_length; ++i) { >> + if (ctx->raw_samples[c][i] != 0) { >> + //The following logic is taken from Tabel 14.45 and >> 14.46 from the ISO spec >> + if (av_cmp_sf_ieee754(acf[c], FLOAT_1)) { >> + nbits[i] = 23 - >> av_log2(abs(ctx->raw_samples[c][i])); >> + } else { >> + nbits[i] = 23; >> + } >> + nbits[i] = FFMIN(nbits[i], highest_byte*8); >> + } >> + } >> + >> + if (!get_bits1(gb)) { //uncompressed >> + for (i = 0; i < frame_length; ++i) { >> + if (ctx->raw_samples[c][i] != 0) { >> + raw_mantissa[c][i] = get_bits(gb, nbits[i]); >> + } >> + } >> + } else { //compressed >> + nchars = 0; >> + for (i = 0; i < frame_length; ++i) { >> + if (ctx->raw_samples[c][i]) { >> + nchars += (int) nbits[i] / 8; > >> + if (nbits[i] % 8 > 0) { > > can nbits[] be < 0 ? > if not then &7 is better than %8 > > > [...] >> +static int decode_string(MLZDict *dict, unsigned char *buff, int >> string_code, int *first_char_code, unsigned long bufsize) { >> + unsigned long count, offset; >> + int current_code, parent_code, tmp_code; >> + >> + count = 0; >> + current_code = string_code; >> + *first_char_code = CODE_UNSET; >> + >> + while (count < bufsize) { >> + switch (current_code) { >> + case CODE_UNSET: >> + return count; >> + break; >> + default: >> + if (current_code < FIRST_CODE) { >> + *first_char_code = current_code; >> + buff[0] = current_code; >> + count++; >> + return count; >> + } else { >> + offset = dict[current_code].match_len - 1; >> + tmp_code = dict[current_code].char_code; >> + buff[offset] = tmp_code; >> + count++; >> + } >> + current_code = dict[current_code].parent_code; >> + if ((current_code < 0) || (current_code > (DIC_INDEX_MAX - 1))) >> { > >> + av_log(NULL, AV_LOG_ERROR, "MLZ dic index error.\n"); > > it would be ideal if all av_log() would have a context instead of NULL
How to go ahead with this? Should I create MLZContext or something? If yes, could you please tell how? - Umair _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel