static int write_predictor_data(uintptr_t h_bs, aacenc_ctx_t *s, int write_flag)
{
    /*unsigned long h_bs = s->h_bitstream;*/
    int bits = 0;

    /* Write global predictor data present */
    short predictorDataPresent = s->pred_global_flag;
    int numBands = FA_MIN(s->max_pred_sfb, s->nr_of_sfb);

    if (write_flag) {
        if (predictorDataPresent) {
            int b;
            if (s->reset_group_number == -1) {
                fa_bitstream_putbits(h_bs, 0, LEN_PRED_RST); /* No prediction reset */
            } else {
                fa_bitstream_putbits(h_bs, 1, LEN_PRED_RST);
                fa_bitstream_putbits(h_bs, (unsigned long)s->reset_group_number,
                    LEN_PRED_RSTGRP);
            }

            for (b=0;b<numBands;b++) {
                fa_bitstream_putbits(h_bs, s->pred_sfb_flag[b], LEN_PRED_ENAB);
            }
        }
    }
    bits += (predictorDataPresent) ?
        (LEN_PRED_RST +
        ((s->reset_group_number)!=-1)*LEN_PRED_RSTGRP +
        numBands*LEN_PRED_ENAB) : 0;

    return bits;
}
Exemple #2
0
static void scalefactor_recalculate(fa_aacenc_ctx_t *f, int chn_num)
{
    int i;
    int gr, sfb, sfb_num;
    aacenc_ctx_t *s;

    for (i = 0; i < chn_num ; i++) {
        s = &(f->ctx[i]);
        if (s->block_type == ONLY_SHORT_BLOCK) 
            sfb_num = fa_mdctline_get_sfbnum(s->h_mdctq_short);
        else 
            sfb_num = fa_mdctline_get_sfbnum(s->h_mdctq_long);

        for (gr = 0; gr < s->num_window_groups; gr++) {
            for (sfb = 0; sfb < sfb_num; sfb++) {
                s->scalefactor[gr][sfb] = s->common_scalefac - s->scalefactor[gr][sfb] + GAIN_ADJUST + SF_OFFSET;
                s->scalefactor[gr][sfb] = FA_MAX(s->scalefactor[gr][sfb], 0);
                s->scalefactor[gr][sfb] = FA_MIN(s->scalefactor[gr][sfb], 255);
            }
        }
        s->common_scalefac = s->scalefactor[0][0];
    }


}
/*fill the bitstream buffer using buf, return how many bytes filled*/
int  fa_bitstream_fillbuffer(uintptr_t handle, unsigned char *buf, int num_bytes)
{
    fa_bitstream_t *f = (fa_bitstream_t *)handle;
    int fill_bytes;

    fill_bytes = FA_MIN(num_bytes, f->num_bytes);

    memcpy(f->data, buf, fill_bytes);

    return fill_bytes;
}
/* calculate bit_allocation based on PE */
int calculate_bit_allocation(float pe, int block_type)
{
    float pe1;
    float pe2;
    float bit_allocation;
    int bits_alloc;

    if (block_type == ONLY_SHORT_BLOCK) {
        pe1 = 0.6;
        pe2 = 24.0;
    } else {
        pe1 = 0.3;
        pe2 = 6.0;
    }
    bit_allocation = pe1 * pe + pe2 * sqrt(pe);
    bit_allocation = FA_MIN(FA_MAX(0.0, bit_allocation), 6144.0);

    bits_alloc = (int)(bit_allocation + 0.5);
    if (bits_alloc > 3000)
        bits_alloc = 3000;

    return bits_alloc;
}
int fa_noiseless_huffman_bitcount(int *x_quant, int sfb_num,  int *sfb_offset,
                                  int *quant_hufftab_no, int *quant_bits)
{
    int i, j;
    int max_sfb_quant;
    int tmp_quant;
    int quant_hufftab_no1, quant_bits1;
    int quant_hufftab_no2, quant_bits2;
    int quant_hufftab_best, quant_bits_best;
    int sfb_width;
    int total_bits;

    total_bits = 0;

    for (i = 0; i < sfb_num; i++) {
        sfb_width = sfb_offset[i+1] - sfb_offset[i];
        /*first get the max value of x_quant, and use this to decide which huffman tab will be use*/
        max_sfb_quant = 0;
        for (j = sfb_offset[i]; j < sfb_offset[i+1]; j++) {
            tmp_quant = FA_ABS(x_quant[j]);
            if (tmp_quant > max_sfb_quant) 
                max_sfb_quant = tmp_quant; 
        }

        /*using max_sfb_quant to decide which huffman table will be used*/
        if (max_sfb_quant == 0) {
            quant_bits_best    = calculate_huff_bits(0, x_quant, sfb_offset[i], sfb_width);
            quant_hufftab_best = 0;
        }else if (max_sfb_quant < 2) {
            quant_hufftab_no1 = 1;
            quant_hufftab_no2 = 2;
        }else if (max_sfb_quant < 3) {
            quant_hufftab_no1 = 3;
            quant_hufftab_no2 = 4;
        }else if (max_sfb_quant < 5) {
            quant_hufftab_no1 = 5;
            quant_hufftab_no2 = 6;
        }else if (max_sfb_quant < 8) {
            quant_hufftab_no1 = 7;
            quant_hufftab_no2 = 8;
        }else if (max_sfb_quant < 13) {
            quant_hufftab_no1 = 9;
            quant_hufftab_no2 = 10;
        }else {
            quant_bits_best    = calculate_huff_bits(11, x_quant, sfb_offset[i], sfb_width);
            quant_hufftab_best = 11;
        }

        if (max_sfb_quant > 0 && max_sfb_quant < 13) {
            quant_bits1 = calculate_huff_bits(quant_hufftab_no1, x_quant, sfb_offset[i], sfb_width);
            quant_bits2 = calculate_huff_bits(quant_hufftab_no2, x_quant, sfb_offset[i], sfb_width);
            quant_bits_best = FA_MIN(quant_bits1, quant_bits2);
            if (quant_bits_best == quant_bits1)
                quant_hufftab_best = quant_hufftab_no1;
            else 
                quant_hufftab_best = quant_hufftab_no2;
        }

        quant_hufftab_no[i] = quant_hufftab_best;
        quant_bits[i]       = quant_bits_best;

        total_bits += quant_bits_best;
    }


    return total_bits;
}
static void quant_innerloop(fa_aacenc_ctx_t *f, int outer_loop_count)
{
    int i, chn;
    int chn_num;
    aacenc_ctx_t *s, *sl, *sr;
    int counted_bits;
    int available_bits;
    int available_bits_l, available_bits_r;
    int find_globalgain;
    int head_end_sideinfo_avg;
    int inner_loop_cnt = 0;

    chn_num = f->cfg.chn_num;
    head_end_sideinfo_avg = fa_bits_sideinfo_est(chn_num);

    i = 0;
    chn = 1;
    while (i < chn_num) {
        inner_loop_cnt = 0;
        s = &(f->ctx[i]);

        if (s->chn_info.cpe == 1) {
            chn = 2;
            sl = s;
            sr = &(f->ctx[i+1]);
            find_globalgain = 0;
            init_quant_change(outer_loop_count, sl);
            init_quant_change(outer_loop_count, sr);
        } else {
            chn = 1;
            find_globalgain = 0;
            init_quant_change(outer_loop_count, s);
        }

        do {
            if (s->chn_info.cpe == 1) {
                if (sl->chn_info.common_window == 1) {
                    if (sl->quant_ok && sr->quant_ok) 
                        break;

                    if (s->block_type == ONLY_SHORT_BLOCK) {
                        fa_mdctline_quant(sl->h_mdctq_short, sl->common_scalefac, sl->x_quant);
                        sl->spectral_count = fa_mdctline_encode(sl->h_mdctq_short, sl->x_quant, sl->num_window_groups, sl->window_group_length, 
                                                                sl->hufftab_no, &(sl->max_sfb), sl->x_quant_code, sl->x_quant_bits);
                        fa_mdctline_quant(sr->h_mdctq_short, sr->common_scalefac, sr->x_quant);
                        sr->spectral_count = fa_mdctline_encode(sr->h_mdctq_short, sr->x_quant, sr->num_window_groups, sr->window_group_length, 
                                                                sr->hufftab_no, &(sr->max_sfb), sr->x_quant_code, sr->x_quant_bits);
                    } else {
                        fa_mdctline_quant(sl->h_mdctq_long, sl->common_scalefac, sl->x_quant);
                        sl->spectral_count = fa_mdctline_encode(sl->h_mdctq_long, sl->x_quant, sl->num_window_groups, sl->window_group_length, 
                                                                sl->hufftab_no, &(sl->max_sfb), sl->x_quant_code, sl->x_quant_bits);
                        fa_mdctline_quant(sr->h_mdctq_long, sr->common_scalefac, sr->x_quant);
                        sr->spectral_count = fa_mdctline_encode(sr->h_mdctq_long, sr->x_quant, sr->num_window_groups, sr->window_group_length, 
                                                                sr->hufftab_no, &(sr->max_sfb), sr->x_quant_code, sr->x_quant_bits);
                    }
                    
                    sr->max_sfb = FA_MAX(sr->max_sfb, sl->max_sfb);
                    sl->max_sfb = sr->max_sfb;

                } else {
                    if (sl->quant_ok && sr->quant_ok)
                        break;

                    if (sl->block_type == ONLY_SHORT_BLOCK) {
                        fa_mdctline_quant(sl->h_mdctq_short, sl->common_scalefac, sl->x_quant);
                        sl->spectral_count = fa_mdctline_encode(sl->h_mdctq_short, sl->x_quant, sl->num_window_groups, sl->window_group_length, 
                                                                sl->hufftab_no, &(sl->max_sfb), sl->x_quant_code, sl->x_quant_bits);
                    } else {
                        fa_mdctline_quant(sl->h_mdctq_long, sl->common_scalefac, sl->x_quant);
                        sl->spectral_count = fa_mdctline_encode(sl->h_mdctq_long, sl->x_quant, sl->num_window_groups, sl->window_group_length, 
                                                                sl->hufftab_no, &(sl->max_sfb), sl->x_quant_code, sl->x_quant_bits);
                    }

                    if (sr->block_type == ONLY_SHORT_BLOCK) {
                        fa_mdctline_quant(sr->h_mdctq_short, sr->common_scalefac, sr->x_quant);
                        sr->spectral_count = fa_mdctline_encode(sr->h_mdctq_short, sr->x_quant, sr->num_window_groups, sr->window_group_length, 
                                                                sr->hufftab_no, &(sr->max_sfb), sr->x_quant_code, sr->x_quant_bits);
                    } else {
                        fa_mdctline_quant(sr->h_mdctq_long, sr->common_scalefac, sr->x_quant);
                        sr->spectral_count = fa_mdctline_encode(sr->h_mdctq_long, sr->x_quant, sr->num_window_groups, sr->window_group_length, 
                                                                sr->hufftab_no, &(sr->max_sfb), sr->x_quant_code, sr->x_quant_bits);
                    }

                }

                counted_bits  = fa_bits_count(f->h_bitstream, &f->cfg, sl, sr) + head_end_sideinfo_avg*2;
                available_bits_l = get_avaiable_bits(sl->bits_average, sl->bits_more, sl->bits_res_size, sl->bits_res_maxsize);
                available_bits_r = get_avaiable_bits(sr->bits_average, sr->bits_more, sr->bits_res_size, sr->bits_res_maxsize);
                available_bits = available_bits_l + available_bits_r;

                if (counted_bits > available_bits) { 
                    sl->common_scalefac += sl->quant_change;
                    sr->common_scalefac += sr->quant_change;
                    sl->common_scalefac = FA_MIN(sl->common_scalefac, 255);
                    sr->common_scalefac = FA_MIN(sr->common_scalefac, 255);
                } else {
                    if (sl->quant_change > 1) {
                        sl->common_scalefac -= sl->quant_change;
                        sl->common_scalefac = FA_MAX(sl->common_scalefac, 0);
                    }
                    if (sr->quant_change > 1) {
                        sr->common_scalefac -= sr->quant_change;
                        sr->common_scalefac = FA_MAX(sr->common_scalefac, 0);
                    }
                }

                sl->quant_change >>= 1;
                sr->quant_change >>= 1;

                if (sl->quant_change == 0 && sr->quant_change == 0 &&
                   counted_bits>available_bits) {
                   sl->quant_change = 1;
                   sr->quant_change = 1;
                }

                if (sl->quant_change == 0 && sr->quant_change == 0)
                    find_globalgain = 1;
                else 
                    find_globalgain = 0;

            } else if (s->chn_info.sce == 1 || s->chn_info.lfe == 1) {
                chn = 1;
                if (s->quant_ok)
                    break;
                if (s->block_type == ONLY_SHORT_BLOCK) {
                    fa_mdctline_quant(s->h_mdctq_short, s->common_scalefac, s->x_quant);
                    s->spectral_count = fa_mdctline_encode(s->h_mdctq_short, s->x_quant, s->num_window_groups, s->window_group_length, 
                                                           s->hufftab_no, &(s->max_sfb), s->x_quant_code, s->x_quant_bits);
                } else {
                    fa_mdctline_quant(s->h_mdctq_long, s->common_scalefac, s->x_quant);
                    s->spectral_count = fa_mdctline_encode(s->h_mdctq_long, s->x_quant, s->num_window_groups, s->window_group_length, 
                                                           s->hufftab_no, &(s->max_sfb), s->x_quant_code, s->x_quant_bits);
                }


                counted_bits  = fa_bits_count(f->h_bitstream, &f->cfg, s, NULL) + head_end_sideinfo_avg;

                available_bits = get_avaiable_bits(s->bits_average, s->bits_more, s->bits_res_size, s->bits_res_maxsize);
                if (counted_bits > available_bits) {
                    s->common_scalefac += s->quant_change;
                    s->common_scalefac = FA_MIN(s->common_scalefac, 255);
                }
                else {
                    if (s->quant_change > 1) {
                        s->common_scalefac -= s->quant_change;
                        s->common_scalefac = FA_MAX(s->common_scalefac, 0);
                    }
                }

                s->quant_change >>= 1;

                if (s->quant_change == 0 && 
                   counted_bits>available_bits)
                    s->quant_change = 1;
 
                if (s->quant_change == 0)
                    find_globalgain = 1;
                else 
                    find_globalgain = 0;

            } else {