xref: /aosp_15_r20/external/libxaac/encoder/ixheaace_write_adts_adif.c (revision 15dc779a375ca8b5125643b829a8aa4b70d7f451)
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 
ia_enhaacplus_enc_putbit(ixheaace_bitstream_params * pstr_bitstream,UWORD32 data,WORD32 num_bit)38 static VOID ia_enhaacplus_enc_putbit(ixheaace_bitstream_params *pstr_bitstream, UWORD32 data,
39                                        WORD32 num_bit) {
40   WORD32 num, max_num, curr_num;
41   WORD32 num_used, idx;
42   unsigned long bits;
43   WORD32 current_bitstream_bit;
44   UWORD8 *bitstream_data;
45 
46   if (num_bit == 0) return;
47 
48   current_bitstream_bit = pstr_bitstream->current_bit;
49   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   num = 0;
60   num_used = current_bitstream_bit & 7;
61   max_num = BYTE_NUMBIT - num_used;
62   curr_num = MIN(num_bit, max_num);
63   bits = data >> (num_bit - curr_num);
64 
65   idx = (current_bitstream_bit >> 3);
66 
67   if (num_used == 0) bitstream_data[idx] = 0;
68 
69   bitstream_data[idx] |= (bits & ((1 << curr_num) - 1)) << (max_num - curr_num);
70   current_bitstream_bit += curr_num;
71   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   while ((num + 8) < num_bit) {
81     num += 8;
82     current_bitstream_bit += 8;
83     bits = data >> (num_bit - num);
84     bitstream_data[++idx] = (UWORD8)bits;
85   }
86 
87   /*
88       Stage #3: Write remainder bits from the data
89   */
90   if (num < num_bit) {
91     curr_num = num_bit - num;
92     num_used = current_bitstream_bit & 7;
93     max_num = BYTE_NUMBIT - num_used;
94     idx = current_bitstream_bit >> 3;
95     if (num_used == 0) bitstream_data[idx] = 0;
96     bitstream_data[idx] |= (data & ((1 << curr_num) - 1)) << (max_num - curr_num);
97     current_bitstream_bit += curr_num;
98   }
99 
100   pstr_bitstream->current_bit = current_bitstream_bit;
101   pstr_bitstream->num_bit = current_bitstream_bit;
102 }
103 
ia_enhaacplus_enc_get_sample_rate_index(WORD32 sample_rate)104 static WORD16 ia_enhaacplus_enc_get_sample_rate_index(WORD32 sample_rate) {
105   if (92017 <= sample_rate) {
106     return 0;
107   }
108   if (75132 <= sample_rate) {
109     return 1;
110   }
111   if (55426 <= sample_rate) {
112     return 2;
113   }
114   if (46009 <= sample_rate) {
115     return 3;
116   }
117   if (37566 <= sample_rate) {
118     return 4;
119   }
120   if (27713 <= sample_rate) {
121     return 5;
122   }
123   if (23004 <= sample_rate) {
124     return 6;
125   }
126   if (18783 <= sample_rate) {
127     return 7;
128   }
129   if (13856 <= sample_rate) {
130     return 8;
131   }
132   if (11502 <= sample_rate) {
133     return 9;
134   }
135   if (9391 <= sample_rate) {
136     return 10;
137   }
138   return 11;
139 }
140 
ia_enhaacplus_enc_write_pce(WORD32 samp_rate,WORD32 ch_mask,WORD32 num_core_coder_chans,ixheaace_bit_buf_handle pstr_bit_stream_handle)141 WORD32 ia_enhaacplus_enc_write_pce(WORD32 samp_rate, WORD32 ch_mask, WORD32 num_core_coder_chans,
142                                    ixheaace_bit_buf_handle pstr_bit_stream_handle) {
143   UWORD32 object_type = 0;
144   UWORD8 buffer[200];
145   ixheaace_bitstream_params bitstream_temp;
146   ixheaace_bitstream_params *pstr_bitstream = &bitstream_temp;
147   WORD32 write_flag = 1;
148   WORD32 start_bits = pstr_bit_stream_handle->cnt_bits, end_bits;
149   pstr_bitstream->data = buffer;
150   pstr_bitstream->num_bit = 8;
151   pstr_bitstream->current_bit = 0;
152 
153   object_type = 01;
154 
155   if (write_flag) {
156     WORD32 i;
157     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     ixheaace_write_bits(pstr_bit_stream_handle, 0x00, 4);
161 
162     /* object type --> LC / LTP / any other */
163     ixheaace_write_bits(pstr_bit_stream_handle, object_type, 2);
164 
165     /* sampling freq index */
166     ixheaace_write_bits(pstr_bit_stream_handle,
167                         ia_enhaacplus_enc_get_sample_rate_index(samp_rate), 4);
168 
169     /*  num_front_channel_elements --> only this present for mono / stereo */
170     num_front_chan_ele = 0;
171 
172     if (ch_mask & 0x3) {
173       num_front_chan_ele++; /*Front Left and Right Present*/
174     }
175     if (ch_mask & 0x4) {
176       num_front_chan_ele++; /*Front Center Present*/
177     }
178     ixheaace_write_bits(pstr_bit_stream_handle, num_front_chan_ele, 4);
179 
180     /*	num_side_channel_elements 4 */
181     num_side_chan_ele = 0;
182 
183     if (ch_mask & 0xC0) {
184       num_side_chan_ele++; /*Back Left and Right Present*/
185     }
186     ixheaace_write_bits(pstr_bit_stream_handle, num_side_chan_ele, 4);
187 
188     /*	num_back_channel_elements 4  */
189     num_back_chan_ele = 0;
190 
191     if (ch_mask & 0x30) {
192       num_back_chan_ele++; /*Back Left and Right of center Present*/
193     }
194     ixheaace_write_bits(pstr_bit_stream_handle, num_back_chan_ele, 4);
195 
196     /*	num_lfe_channel_elements 2  */
197     num_lfe_chan_ele = 0;
198 
199     if (ch_mask & 0x8) {
200       num_lfe_chan_ele++; /*LFE channel Present*/
201     }
202     ixheaace_write_bits(pstr_bit_stream_handle, num_lfe_chan_ele, 2);
203 
204     /*	num_assoc_data_elements 3  */
205     ixheaace_write_bits(pstr_bit_stream_handle, 0x00, 3);
206 
207     /*	num_valid_cc_elements 4 */
208     ixheaace_write_bits(pstr_bit_stream_handle, num_core_coder_chans, 4);
209 
210     /* mono mix down is zero */
211     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     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     ixheaace_write_bits(pstr_bit_stream_handle, 0x00, 1);
222 
223     {
224       /* stereo --> 1 mono --> 0 */
225       if (ch_mask & 0x4) {
226         ixheaace_write_bits(pstr_bit_stream_handle, 0x00, 1);
227         /* element tag select */
228         ixheaace_write_bits(pstr_bit_stream_handle, 0x00, 4);
229       }
230       if (ch_mask & 0x3) {
231         if ((ch_mask & 0x3) == 0x3) {
232           /* stereo channel */
233           ixheaace_write_bits(pstr_bit_stream_handle, 0x01, 1);
234         } else {
235           /* mono channel */
236           ixheaace_write_bits(pstr_bit_stream_handle, 0x00, 1);
237         }
238 
239         /* element tag select */
240         ixheaace_write_bits(pstr_bit_stream_handle, 0x00, 4);
241       }
242     }
243 
244     for (i = 0; i < num_side_chan_ele; i++) {
245       if ((ch_mask & 0xC0) == 0xC0) {
246         /* stereo channel */
247         ixheaace_write_bits(pstr_bit_stream_handle, 0x01, 1);
248       } else {
249         /* mono channel */
250         ixheaace_write_bits(pstr_bit_stream_handle, 0x00, 1);
251       }
252 
253       /* element tag select */
254       ixheaace_write_bits(pstr_bit_stream_handle, 0x02, 4);
255     }
256 
257     for (i = 0; i < num_back_chan_ele; i++) {
258       if ((ch_mask & 0x30) == 0x30) {
259         /* stereo channel */
260         ixheaace_write_bits(pstr_bit_stream_handle, 0x01, 1);
261       } else {
262         /* mono channel */
263         ixheaace_write_bits(pstr_bit_stream_handle, 0x00, 1);
264       }
265 
266       /* element tag select */
267       ixheaace_write_bits(pstr_bit_stream_handle, 0x01, 4);
268     }
269 
270     for (i = 0; i < num_lfe_chan_ele; i++) {
271       /* element tag select */
272       ixheaace_write_bits(pstr_bit_stream_handle, 0x00, 4);
273     }
274 
275     /* loop for independent coupling elements */
276     for (i = 0; i < num_core_coder_chans; i++) {
277       /* It is independent coupling channel */
278       ixheaace_write_bits(pstr_bit_stream_handle, 0x01, 1);
279 
280       /* element tag select */
281       ixheaace_write_bits(pstr_bit_stream_handle, num_core_coder_chans - i - 1, 4);
282     }
283 
284     /* byte align the stream */
285     ixheaace_write_bits(pstr_bit_stream_handle, 0,
286                         (UWORD8)((8 - (pstr_bit_stream_handle->cnt_bits % 8)) % 8));
287     /* comment field types --> do not quite know what this is */
288     ixheaace_write_bits(pstr_bit_stream_handle, 0x00, 8);
289   }
290 
291   end_bits = pstr_bit_stream_handle->cnt_bits;
292 
293   return (end_bits - start_bits);
294 }
295 
ia_enhaacplus_enc_write_ADTS_header(pUWORD8 buffer,WORD32 bytes_used,WORD32 samp_rate,WORD32 num_ch)296 WORD32 ia_enhaacplus_enc_write_ADTS_header(pUWORD8 buffer, WORD32 bytes_used, WORD32 samp_rate,
297                                            WORD32 num_ch) {
298   WORD32 bits = 56;
299   UWORD32 object_type = 0;
300   ixheaace_bitstream_params bitstream_temp;
301   ixheaace_bitstream_params *pstr_bitstream = &bitstream_temp;
302   WORD32 write_flag = 1;
303   pstr_bitstream->data = buffer;
304   pstr_bitstream->num_bit = 8;
305 
306   pstr_bitstream->current_bit = 0;
307   ;
308   object_type = 01;
309 
310   if (write_flag) {
311     /* Fixed ADTS header */
312     ia_enhaacplus_enc_putbit(pstr_bitstream, 0xFFFF, 12); /* 12 bit Syncword */
313     ia_enhaacplus_enc_putbit(pstr_bitstream, 1 /*aacStateStruct->aacConfigSturct.mpegVersion*/,
314                              1);                    /* ID == 0 for MPEG4 AAC, 1 for MPEG2 AAC */
315     ia_enhaacplus_enc_putbit(pstr_bitstream, 0, 2); /* layer == 0 */
316     ia_enhaacplus_enc_putbit(pstr_bitstream, 1, 1); /* protection absent */
317     ia_enhaacplus_enc_putbit(pstr_bitstream, object_type, 2); /* profile */
318     ia_enhaacplus_enc_putbit(
319         pstr_bitstream,
320         ia_enhaacplus_enc_get_sample_rate_index(samp_rate) /*aacStateStruct->sampleRateIdx*/,
321         4);                                         /* sampling rate */
322     ia_enhaacplus_enc_putbit(pstr_bitstream, 0, 1); /* private bit */
323     ia_enhaacplus_enc_putbit(pstr_bitstream, num_ch /*aacStateStruct->aacConfigSturct.ch*/,
324                              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     ia_enhaacplus_enc_putbit(pstr_bitstream, 0, 1); /* original/copy */
329     ia_enhaacplus_enc_putbit(pstr_bitstream, 0, 1); /* home */
330 
331     /* Variable ADTS header */
332     ia_enhaacplus_enc_putbit(pstr_bitstream, 0, 1); /* copyr. id. bit */
333     ia_enhaacplus_enc_putbit(pstr_bitstream, 0, 1); /* copyr. id. start */
334     ia_enhaacplus_enc_putbit(pstr_bitstream, /*aacStateStruct->*/ bytes_used + 7, 13);
335     ia_enhaacplus_enc_putbit(pstr_bitstream, 0x7FF, 11); /* buffer fullness (0x7FF for VBR) */
336 
337     ia_enhaacplus_enc_putbit(pstr_bitstream, 0, 2); /* raw data blocks (0+1=1) */
338   }
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   return bits / 8;
345 }
346