Coverage Report

Created: 2025-07-11 06:38

/src/libxaac/encoder/ixheaace_fd_qc_util.c
Line
Count
Source (jump to first uncovered line)
1
/******************************************************************************
2
 *                                                                            *
3
 * Copyright (C) 2023 The Android Open Source Project
4
 *
5
 * Licensed under the Apache License, Version 2.0 (the "License");
6
 * you may not use this file except in compliance with the License.
7
 * You may obtain a copy of the License at:
8
 *
9
 * http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 *
17
 *****************************************************************************
18
 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19
 */
20
21
#include <string.h>
22
#include <math.h>
23
#include <stdlib.h>
24
#include "iusace_type_def.h"
25
#include "iusace_cnst.h"
26
#include "iusace_bitbuffer.h"
27
#include "impd_drc_common_enc.h"
28
#include "impd_drc_uni_drc.h"
29
#include "impd_drc_api.h"
30
#include "impd_drc_uni_drc_eq.h"
31
#include "impd_drc_uni_drc_filter_bank.h"
32
#include "impd_drc_gain_enc.h"
33
#include "impd_drc_struct_def.h"
34
35
#include "ixheaace_memory_standards.h"
36
#include "iusace_tns_usac.h"
37
#include "iusace_psy_mod.h"
38
#include "iusace_config.h"
39
#include "ixheaace_adjust_threshold_data.h"
40
#include "iusace_fd_qc_util.h"
41
#include "iusace_fd_qc_adjthr.h"
42
43
5.15k
VOID iusace_qc_create(ia_qc_main_struct *pstr_qc_main) {
44
5.15k
  WORD32 i = 0;
45
5.15k
  memset(pstr_qc_main, 0, sizeof(ia_qc_main_struct));
46
47
15.4k
  for (i = 0; i < 2; i++) {
48
10.3k
    memset(pstr_qc_main->str_qc_out.str_qc_out_chan[i].quant_spec, 0,
49
10.3k
           sizeof(WORD16) * FRAME_LEN_LONG);
50
10.3k
    memset(pstr_qc_main->str_qc_out.str_qc_out_chan[i].scalefactor, 0,
51
10.3k
           sizeof(WORD16) * FRAME_LEN_LONG);
52
10.3k
  }
53
5.15k
  return;
54
5.15k
}
55
56
VOID iusace_qc_init(ia_qc_data_struct *pstr_qc_data, const WORD32 max_bits, WORD32 sample_rate,
57
5.14k
                    WORD32 bw_limit, WORD32 channels, WORD32 ccfl) {
58
5.14k
  FLOAT32 mean_pe;
59
5.14k
  pstr_qc_data->tot_avg_bits = pstr_qc_data->avg_bits;
60
5.14k
  pstr_qc_data->static_bits = 1;
61
5.14k
  pstr_qc_data->avg_bits = (pstr_qc_data->avg_bits - pstr_qc_data->static_bits);
62
5.14k
  pstr_qc_data->max_bits = channels * max_bits;
63
5.14k
  pstr_qc_data->max_bitres_bits = channels * max_bits - pstr_qc_data->tot_avg_bits;
64
5.14k
  pstr_qc_data->max_bitres_bits =
65
5.14k
      pstr_qc_data->max_bitres_bits - (pstr_qc_data->max_bitres_bits % 8);
66
5.14k
  pstr_qc_data->bit_res_lvl = pstr_qc_data->max_bitres_bits;
67
5.14k
  pstr_qc_data->padding = sample_rate;
68
69
5.14k
  pstr_qc_data->max_bit_fac =
70
5.14k
      (FLOAT32)channels * (max_bits - 744) /
71
5.14k
      (FLOAT32)(pstr_qc_data->tot_avg_bits ? pstr_qc_data->tot_avg_bits : 1);
72
5.14k
  mean_pe = 10.0f * ccfl * bw_limit / (sample_rate / 2.0f);
73
74
5.14k
  iusace_adj_thr_init(&pstr_qc_data->str_adj_thr_ele, mean_pe,
75
5.14k
                      (channels > 0) ? pstr_qc_data->ch_bitrate / channels : 0);
76
77
5.14k
  return;
78
5.14k
}
79
80
static WORD32 iusace_calc_frame_len(WORD32 bit_rate, WORD32 sample_rate, WORD32 mode,
81
436k
                                    WORD32 ccfl) {
82
436k
  WORD32 result;
83
84
436k
  result = ((ccfl) >> 3) * (bit_rate);
85
436k
  switch (mode) {
86
218k
    case FRAME_LEN_BYTES_MODULO:
87
218k
      result %= sample_rate;
88
218k
      break;
89
218k
    case FRAME_LEN_BYTES_INT:
90
218k
      result /= sample_rate;
91
218k
      break;
92
436k
  }
93
94
436k
  return (result);
95
436k
}
96
97
static WORD32 iusace_get_frame_padding(WORD32 bit_rate, WORD32 sample_rate, WORD32 *padding,
98
218k
                                       WORD32 ccfl) {
99
218k
  WORD32 padding_on = 0;
100
218k
  WORD32 difference;
101
102
218k
  difference = iusace_calc_frame_len(bit_rate, sample_rate, FRAME_LEN_BYTES_MODULO, ccfl);
103
104
218k
  *padding -= difference;
105
106
218k
  if (*padding <= 0) {
107
43.2k
    padding_on = 1;
108
43.2k
    *padding += sample_rate;
109
43.2k
  }
110
111
218k
  return padding_on;
112
218k
}
113
114
VOID iusace_adj_bitrate(ia_qc_data_struct *pstr_qc_data, WORD32 bit_rate, WORD32 sample_rate,
115
218k
                        WORD32 ccfl) {
116
218k
  WORD32 padding_on;
117
218k
  WORD32 frame_len;
118
218k
  WORD32 code_bits;
119
218k
  WORD32 code_bits_prev;
120
218k
  WORD32 total_bits = 0;
121
122
218k
  padding_on = iusace_get_frame_padding(bit_rate, sample_rate, &pstr_qc_data->padding, ccfl);
123
218k
  frame_len =
124
218k
      padding_on + iusace_calc_frame_len(bit_rate, sample_rate, FRAME_LEN_BYTES_INT, ccfl);
125
126
218k
  frame_len <<= 3;
127
218k
  code_bits_prev = pstr_qc_data->tot_avg_bits - pstr_qc_data->static_bits;
128
218k
  code_bits = frame_len - pstr_qc_data->static_bits;
129
130
218k
  if (code_bits != code_bits_prev) {
131
44.9k
    pstr_qc_data->avg_bits = (WORD32)code_bits;
132
44.9k
    total_bits += pstr_qc_data->avg_bits;
133
44.9k
    pstr_qc_data->avg_bits += code_bits - total_bits;
134
44.9k
  }
135
136
218k
  pstr_qc_data->tot_avg_bits = frame_len;
137
138
218k
  return;
139
218k
}
140
141
WORD32 iusace_calc_max_val_in_sfb(WORD32 sfb_count, WORD32 max_sfb_per_grp, WORD32 sfb_per_group,
142
450k
                                  WORD32 *ptr_sfb_offset, WORD16 *ptr_quant_spec) {
143
450k
  WORD32 sfb;
144
450k
  WORD32 max = 0;
145
450k
  WORD32 sfb_offs;
146
147
1.68M
  for (sfb_offs = 0; sfb_offs < sfb_count; sfb_offs += sfb_per_group) {
148
20.0M
    for (sfb = 0; sfb < max_sfb_per_grp; sfb++) {
149
18.7M
      WORD32 line;
150
18.7M
      WORD32 local_max = 0;
151
327M
      for (line = ptr_sfb_offset[sfb + sfb_offs]; line < ptr_sfb_offset[sfb + sfb_offs + 1];
152
308M
           line++) {
153
308M
        if (abs(ptr_quant_spec[line]) > local_max) {
154
15.7M
          local_max = abs(ptr_quant_spec[line]);
155
15.7M
        }
156
308M
      }
157
18.7M
      if (local_max > max) {
158
660k
        max = local_max;
159
660k
      }
160
18.7M
    }
161
1.23M
  }
162
163
450k
  return max;
164
450k
}