/src/libxaac/encoder/ixheaace_write_adts_adif.c
Line | Count | Source |
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 "ixheaac_type_def.h" |
22 | | #include "ixheaac_constants.h" |
23 | | #include "ixheaace_psy_const.h" |
24 | | #include "ixheaace_tns.h" |
25 | | #include "ixheaace_tns_params.h" |
26 | | #include "ixheaace_rom.h" |
27 | | #include "ixheaace_common_rom.h" |
28 | | #include "ixheaace_bitbuffer.h" |
29 | | #include "ixheaace_aac_constants.h" |
30 | | #include "ixheaace_write_adts_adif.h" |
31 | | |
32 | | #include "ixheaac_basic_ops32.h" |
33 | | #include "ixheaac_basic_ops16.h" |
34 | | #include "ixheaac_basic_ops40.h" |
35 | | #include "ixheaac_basic_ops.h" |
36 | | #include "ixheaace_common_utils.h" |
37 | | |
38 | | static VOID ia_enhaacplus_enc_putbit(ixheaace_bitstream_params *pstr_bitstream, UWORD32 data, |
39 | 1.42M | WORD32 num_bit) { |
40 | 1.42M | WORD32 num, max_num, curr_num; |
41 | 1.42M | WORD32 num_used, idx; |
42 | 1.42M | unsigned long bits; |
43 | 1.42M | WORD32 current_bitstream_bit; |
44 | 1.42M | UWORD8 *bitstream_data; |
45 | | |
46 | 1.42M | if (num_bit == 0) return; |
47 | | |
48 | 1.42M | current_bitstream_bit = pstr_bitstream->current_bit; |
49 | 1.42M | bitstream_data = pstr_bitstream->data; |
50 | | |
51 | | /* |
52 | | Functionality of Writing bits to the bitstream is split into 3 stages. |
53 | | */ |
54 | | |
55 | | /* |
56 | | Stage #1: Write remainder bits to the partially filled byte |
57 | | */ |
58 | | |
59 | 1.42M | num = 0; |
60 | 1.42M | num_used = current_bitstream_bit & 7; |
61 | 1.42M | max_num = BYTE_NUMBIT - num_used; |
62 | 1.42M | curr_num = MIN(num_bit, max_num); |
63 | 1.42M | bits = data >> (num_bit - curr_num); |
64 | | |
65 | 1.42M | idx = (current_bitstream_bit >> 3); |
66 | | |
67 | 1.42M | if (num_used == 0) bitstream_data[idx] = 0; |
68 | | |
69 | 1.42M | bitstream_data[idx] |= (bits & ((1 << curr_num) - 1)) << (max_num - curr_num); |
70 | 1.42M | current_bitstream_bit += curr_num; |
71 | 1.42M | num += curr_num; |
72 | | |
73 | | /* |
74 | | Stage #2: |
75 | | At this point, (num + num_used), will be a multiple of 8 |
76 | | Now the bytes can be written directly to bitstream_data[], as long |
77 | | as (num + 8) < num_bit |
78 | | */ |
79 | | |
80 | 1.52M | while ((num + 8) < num_bit) { |
81 | 95.1k | num += 8; |
82 | 95.1k | current_bitstream_bit += 8; |
83 | 95.1k | bits = data >> (num_bit - num); |
84 | 95.1k | bitstream_data[++idx] = (UWORD8)bits; |
85 | 95.1k | } |
86 | | |
87 | | /* |
88 | | Stage #3: Write remainder bits from the data |
89 | | */ |
90 | 1.42M | if (num < num_bit) { |
91 | 380k | curr_num = num_bit - num; |
92 | 380k | num_used = current_bitstream_bit & 7; |
93 | 380k | max_num = BYTE_NUMBIT - num_used; |
94 | 380k | idx = current_bitstream_bit >> 3; |
95 | 380k | if (num_used == 0) bitstream_data[idx] = 0; |
96 | 380k | bitstream_data[idx] |= (data & ((1 << curr_num) - 1)) << (max_num - curr_num); |
97 | 380k | current_bitstream_bit += curr_num; |
98 | 380k | } |
99 | | |
100 | 1.42M | pstr_bitstream->current_bit = current_bitstream_bit; |
101 | 1.42M | pstr_bitstream->num_bit = current_bitstream_bit; |
102 | 1.42M | } |
103 | | |
104 | 95.1k | static WORD16 ia_enhaacplus_enc_get_sample_rate_index(WORD32 sample_rate) { |
105 | 95.1k | if (92017 <= sample_rate) { |
106 | 4.85k | return 0; |
107 | 4.85k | } |
108 | 90.2k | if (75132 <= sample_rate) { |
109 | 21.8k | return 1; |
110 | 21.8k | } |
111 | 68.4k | if (55426 <= sample_rate) { |
112 | 3.76k | return 2; |
113 | 3.76k | } |
114 | 64.7k | if (46009 <= sample_rate) { |
115 | 1.97k | return 3; |
116 | 1.97k | } |
117 | 62.7k | if (37566 <= sample_rate) { |
118 | 4.33k | return 4; |
119 | 4.33k | } |
120 | 58.4k | if (27713 <= sample_rate) { |
121 | 576 | return 5; |
122 | 576 | } |
123 | 57.8k | if (23004 <= sample_rate) { |
124 | 8.83k | return 6; |
125 | 8.83k | } |
126 | 49.0k | if (18783 <= sample_rate) { |
127 | 15.9k | return 7; |
128 | 15.9k | } |
129 | 33.0k | if (13856 <= sample_rate) { |
130 | 21.7k | return 8; |
131 | 21.7k | } |
132 | 11.3k | if (11502 <= sample_rate) { |
133 | 7.60k | return 9; |
134 | 7.60k | } |
135 | 3.76k | if (9391 <= sample_rate) { |
136 | 1.96k | return 10; |
137 | 1.96k | } |
138 | 1.79k | return 11; |
139 | 3.76k | } |
140 | | |
141 | | WORD32 ia_enhaacplus_enc_write_pce(WORD32 samp_rate, WORD32 ch_mask, WORD32 num_core_coder_chans, |
142 | 0 | ixheaace_bit_buf_handle pstr_bit_stream_handle) { |
143 | 0 | UWORD32 object_type = 0; |
144 | 0 | UWORD8 buffer[200]; |
145 | 0 | ixheaace_bitstream_params bitstream_temp; |
146 | 0 | ixheaace_bitstream_params *pstr_bitstream = &bitstream_temp; |
147 | 0 | WORD32 write_flag = 1; |
148 | 0 | WORD32 start_bits = pstr_bit_stream_handle->cnt_bits, end_bits; |
149 | 0 | pstr_bitstream->data = buffer; |
150 | 0 | pstr_bitstream->num_bit = 8; |
151 | 0 | pstr_bitstream->current_bit = 0; |
152 | |
|
153 | 0 | object_type = 01; |
154 | |
|
155 | 0 | if (write_flag) { |
156 | 0 | WORD32 i; |
157 | 0 | WORD32 num_front_chan_ele, num_side_chan_ele, num_back_chan_ele, num_lfe_chan_ele; |
158 | | |
159 | | /* element instance tag can be anything... writing 0 */ |
160 | 0 | ixheaace_write_bits(pstr_bit_stream_handle, 0x00, 4); |
161 | | |
162 | | /* object type --> LC / LTP / any other */ |
163 | 0 | ixheaace_write_bits(pstr_bit_stream_handle, object_type, 2); |
164 | | |
165 | | /* sampling freq index */ |
166 | 0 | ixheaace_write_bits(pstr_bit_stream_handle, |
167 | 0 | ia_enhaacplus_enc_get_sample_rate_index(samp_rate), 4); |
168 | | |
169 | | /* num_front_channel_elements --> only this present for mono / stereo */ |
170 | 0 | num_front_chan_ele = 0; |
171 | |
|
172 | 0 | if (ch_mask & 0x3) { |
173 | 0 | num_front_chan_ele++; /*Front Left and Right Present*/ |
174 | 0 | } |
175 | 0 | if (ch_mask & 0x4) { |
176 | 0 | num_front_chan_ele++; /*Front Center Present*/ |
177 | 0 | } |
178 | 0 | ixheaace_write_bits(pstr_bit_stream_handle, num_front_chan_ele, 4); |
179 | | |
180 | | /* num_side_channel_elements 4 */ |
181 | 0 | num_side_chan_ele = 0; |
182 | |
|
183 | 0 | if (ch_mask & 0xC0) { |
184 | 0 | num_side_chan_ele++; /*Back Left and Right Present*/ |
185 | 0 | } |
186 | 0 | ixheaace_write_bits(pstr_bit_stream_handle, num_side_chan_ele, 4); |
187 | | |
188 | | /* num_back_channel_elements 4 */ |
189 | 0 | num_back_chan_ele = 0; |
190 | |
|
191 | 0 | if (ch_mask & 0x30) { |
192 | 0 | num_back_chan_ele++; /*Back Left and Right of center Present*/ |
193 | 0 | } |
194 | 0 | ixheaace_write_bits(pstr_bit_stream_handle, num_back_chan_ele, 4); |
195 | | |
196 | | /* num_lfe_channel_elements 2 */ |
197 | 0 | num_lfe_chan_ele = 0; |
198 | |
|
199 | 0 | if (ch_mask & 0x8) { |
200 | 0 | num_lfe_chan_ele++; /*LFE channel Present*/ |
201 | 0 | } |
202 | 0 | ixheaace_write_bits(pstr_bit_stream_handle, num_lfe_chan_ele, 2); |
203 | | |
204 | | /* num_assoc_data_elements 3 */ |
205 | 0 | ixheaace_write_bits(pstr_bit_stream_handle, 0x00, 3); |
206 | | |
207 | | /* num_valid_cc_elements 4 */ |
208 | 0 | ixheaace_write_bits(pstr_bit_stream_handle, num_core_coder_chans, 4); |
209 | | |
210 | | /* mono mix down is zero */ |
211 | 0 | ixheaace_write_bits(pstr_bit_stream_handle, 0x00, 1); |
212 | | |
213 | | /* mono_mixdown_element_number 4 if mono_mixdown_present == 1 */ |
214 | | |
215 | | /* stereo_mixdown_present is zero */ |
216 | 0 | ixheaace_write_bits(pstr_bit_stream_handle, 0x00, 1); |
217 | | |
218 | | /* stereo_mixdown_element_number 4 if stereo_mixdown_present == 1 */ |
219 | | |
220 | | /* matrix_mixdown_idx_present is zero */ |
221 | 0 | ixheaace_write_bits(pstr_bit_stream_handle, 0x00, 1); |
222 | |
|
223 | 0 | { |
224 | | /* stereo --> 1 mono --> 0 */ |
225 | 0 | if (ch_mask & 0x4) { |
226 | 0 | ixheaace_write_bits(pstr_bit_stream_handle, 0x00, 1); |
227 | | /* element tag select */ |
228 | 0 | ixheaace_write_bits(pstr_bit_stream_handle, 0x00, 4); |
229 | 0 | } |
230 | 0 | if (ch_mask & 0x3) { |
231 | 0 | if ((ch_mask & 0x3) == 0x3) { |
232 | | /* stereo channel */ |
233 | 0 | ixheaace_write_bits(pstr_bit_stream_handle, 0x01, 1); |
234 | 0 | } else { |
235 | | /* mono channel */ |
236 | 0 | ixheaace_write_bits(pstr_bit_stream_handle, 0x00, 1); |
237 | 0 | } |
238 | | |
239 | | /* element tag select */ |
240 | 0 | ixheaace_write_bits(pstr_bit_stream_handle, 0x00, 4); |
241 | 0 | } |
242 | 0 | } |
243 | |
|
244 | 0 | for (i = 0; i < num_side_chan_ele; i++) { |
245 | 0 | if ((ch_mask & 0xC0) == 0xC0) { |
246 | | /* stereo channel */ |
247 | 0 | ixheaace_write_bits(pstr_bit_stream_handle, 0x01, 1); |
248 | 0 | } else { |
249 | | /* mono channel */ |
250 | 0 | ixheaace_write_bits(pstr_bit_stream_handle, 0x00, 1); |
251 | 0 | } |
252 | | |
253 | | /* element tag select */ |
254 | 0 | ixheaace_write_bits(pstr_bit_stream_handle, 0x02, 4); |
255 | 0 | } |
256 | |
|
257 | 0 | for (i = 0; i < num_back_chan_ele; i++) { |
258 | 0 | if ((ch_mask & 0x30) == 0x30) { |
259 | | /* stereo channel */ |
260 | 0 | ixheaace_write_bits(pstr_bit_stream_handle, 0x01, 1); |
261 | 0 | } else { |
262 | | /* mono channel */ |
263 | 0 | ixheaace_write_bits(pstr_bit_stream_handle, 0x00, 1); |
264 | 0 | } |
265 | | |
266 | | /* element tag select */ |
267 | 0 | ixheaace_write_bits(pstr_bit_stream_handle, 0x01, 4); |
268 | 0 | } |
269 | |
|
270 | 0 | for (i = 0; i < num_lfe_chan_ele; i++) { |
271 | | /* element tag select */ |
272 | 0 | ixheaace_write_bits(pstr_bit_stream_handle, 0x00, 4); |
273 | 0 | } |
274 | | |
275 | | /* loop for independent coupling elements */ |
276 | 0 | for (i = 0; i < num_core_coder_chans; i++) { |
277 | | /* It is independent coupling channel */ |
278 | 0 | ixheaace_write_bits(pstr_bit_stream_handle, 0x01, 1); |
279 | | |
280 | | /* element tag select */ |
281 | 0 | ixheaace_write_bits(pstr_bit_stream_handle, num_core_coder_chans - i - 1, 4); |
282 | 0 | } |
283 | | |
284 | | /* byte align the stream */ |
285 | 0 | ixheaace_write_bits(pstr_bit_stream_handle, 0, |
286 | 0 | (UWORD8)((8 - (pstr_bit_stream_handle->cnt_bits % 8)) % 8)); |
287 | | /* comment field types --> do not quite know what this is */ |
288 | 0 | ixheaace_write_bits(pstr_bit_stream_handle, 0x00, 8); |
289 | 0 | } |
290 | |
|
291 | 0 | end_bits = pstr_bit_stream_handle->cnt_bits; |
292 | |
|
293 | 0 | return (end_bits - start_bits); |
294 | 0 | } |
295 | | |
296 | | WORD32 ia_enhaacplus_enc_write_ADTS_header(pUWORD8 buffer, WORD32 bytes_used, WORD32 samp_rate, |
297 | 95.1k | WORD32 num_ch) { |
298 | 95.1k | WORD32 bits = 56; |
299 | 95.1k | UWORD32 object_type = 0; |
300 | 95.1k | ixheaace_bitstream_params bitstream_temp; |
301 | 95.1k | ixheaace_bitstream_params *pstr_bitstream = &bitstream_temp; |
302 | 95.1k | WORD32 write_flag = 1; |
303 | 95.1k | pstr_bitstream->data = buffer; |
304 | 95.1k | pstr_bitstream->num_bit = 8; |
305 | | |
306 | 95.1k | pstr_bitstream->current_bit = 0; |
307 | 95.1k | ; |
308 | 95.1k | object_type = 01; |
309 | | |
310 | 95.1k | if (write_flag) { |
311 | | /* Fixed ADTS header */ |
312 | 95.1k | ia_enhaacplus_enc_putbit(pstr_bitstream, 0xFFFF, 12); /* 12 bit Syncword */ |
313 | 95.1k | ia_enhaacplus_enc_putbit(pstr_bitstream, 1 /*aacStateStruct->aacConfigSturct.mpegVersion*/, |
314 | 95.1k | 1); /* ID == 0 for MPEG4 AAC, 1 for MPEG2 AAC */ |
315 | 95.1k | ia_enhaacplus_enc_putbit(pstr_bitstream, 0, 2); /* layer == 0 */ |
316 | 95.1k | ia_enhaacplus_enc_putbit(pstr_bitstream, 1, 1); /* protection absent */ |
317 | 95.1k | ia_enhaacplus_enc_putbit(pstr_bitstream, object_type, 2); /* profile */ |
318 | 95.1k | ia_enhaacplus_enc_putbit( |
319 | 95.1k | pstr_bitstream, |
320 | 95.1k | ia_enhaacplus_enc_get_sample_rate_index(samp_rate) /*aacStateStruct->sampleRateIdx*/, |
321 | 95.1k | 4); /* sampling rate */ |
322 | 95.1k | ia_enhaacplus_enc_putbit(pstr_bitstream, 0, 1); /* private bit */ |
323 | 95.1k | ia_enhaacplus_enc_putbit(pstr_bitstream, num_ch /*aacStateStruct->aacConfigSturct.ch*/, |
324 | 95.1k | 3); /* ch. aacConfigSturct (must be > 0) */ |
325 | | /* simply using num_channels only works for |
326 | | 6 channels or less, else a channel |
327 | | configuration should be written */ |
328 | 95.1k | ia_enhaacplus_enc_putbit(pstr_bitstream, 0, 1); /* original/copy */ |
329 | 95.1k | ia_enhaacplus_enc_putbit(pstr_bitstream, 0, 1); /* home */ |
330 | | |
331 | | /* Variable ADTS header */ |
332 | 95.1k | ia_enhaacplus_enc_putbit(pstr_bitstream, 0, 1); /* copyr. id. bit */ |
333 | 95.1k | ia_enhaacplus_enc_putbit(pstr_bitstream, 0, 1); /* copyr. id. start */ |
334 | 95.1k | ia_enhaacplus_enc_putbit(pstr_bitstream, /*aacStateStruct->*/ bytes_used + 7, 13); |
335 | 95.1k | ia_enhaacplus_enc_putbit(pstr_bitstream, 0x7FF, 11); /* buffer fullness (0x7FF for VBR) */ |
336 | | |
337 | 95.1k | ia_enhaacplus_enc_putbit(pstr_bitstream, 0, 2); /* raw data blocks (0+1=1) */ |
338 | 95.1k | } |
339 | | |
340 | | /* |
341 | | * MPEG2 says byte_aligment() here, but ADTS always is multiple of 8 bits |
342 | | * MPEG4 has no byte_alignment() here |
343 | | */ |
344 | 95.1k | return bits / 8; |
345 | 95.1k | } |