1*e5436536SAndroid Build Coastguard Worker /* -----------------------------------------------------------------------------
2*e5436536SAndroid Build Coastguard Worker Software License for The Fraunhofer FDK AAC Codec Library for Android
3*e5436536SAndroid Build Coastguard Worker
4*e5436536SAndroid Build Coastguard Worker © Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
5*e5436536SAndroid Build Coastguard Worker Forschung e.V. All rights reserved.
6*e5436536SAndroid Build Coastguard Worker
7*e5436536SAndroid Build Coastguard Worker 1. INTRODUCTION
8*e5436536SAndroid Build Coastguard Worker The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
9*e5436536SAndroid Build Coastguard Worker that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
10*e5436536SAndroid Build Coastguard Worker scheme for digital audio. This FDK AAC Codec software is intended to be used on
11*e5436536SAndroid Build Coastguard Worker a wide variety of Android devices.
12*e5436536SAndroid Build Coastguard Worker
13*e5436536SAndroid Build Coastguard Worker AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
14*e5436536SAndroid Build Coastguard Worker general perceptual audio codecs. AAC-ELD is considered the best-performing
15*e5436536SAndroid Build Coastguard Worker full-bandwidth communications codec by independent studies and is widely
16*e5436536SAndroid Build Coastguard Worker deployed. AAC has been standardized by ISO and IEC as part of the MPEG
17*e5436536SAndroid Build Coastguard Worker specifications.
18*e5436536SAndroid Build Coastguard Worker
19*e5436536SAndroid Build Coastguard Worker Patent licenses for necessary patent claims for the FDK AAC Codec (including
20*e5436536SAndroid Build Coastguard Worker those of Fraunhofer) may be obtained through Via Licensing
21*e5436536SAndroid Build Coastguard Worker (www.vialicensing.com) or through the respective patent owners individually for
22*e5436536SAndroid Build Coastguard Worker the purpose of encoding or decoding bit streams in products that are compliant
23*e5436536SAndroid Build Coastguard Worker with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
24*e5436536SAndroid Build Coastguard Worker Android devices already license these patent claims through Via Licensing or
25*e5436536SAndroid Build Coastguard Worker directly from the patent owners, and therefore FDK AAC Codec software may
26*e5436536SAndroid Build Coastguard Worker already be covered under those patent licenses when it is used for those
27*e5436536SAndroid Build Coastguard Worker licensed purposes only.
28*e5436536SAndroid Build Coastguard Worker
29*e5436536SAndroid Build Coastguard Worker Commercially-licensed AAC software libraries, including floating-point versions
30*e5436536SAndroid Build Coastguard Worker with enhanced sound quality, are also available from Fraunhofer. Users are
31*e5436536SAndroid Build Coastguard Worker encouraged to check the Fraunhofer website for additional applications
32*e5436536SAndroid Build Coastguard Worker information and documentation.
33*e5436536SAndroid Build Coastguard Worker
34*e5436536SAndroid Build Coastguard Worker 2. COPYRIGHT LICENSE
35*e5436536SAndroid Build Coastguard Worker
36*e5436536SAndroid Build Coastguard Worker Redistribution and use in source and binary forms, with or without modification,
37*e5436536SAndroid Build Coastguard Worker are permitted without payment of copyright license fees provided that you
38*e5436536SAndroid Build Coastguard Worker satisfy the following conditions:
39*e5436536SAndroid Build Coastguard Worker
40*e5436536SAndroid Build Coastguard Worker You must retain the complete text of this software license in redistributions of
41*e5436536SAndroid Build Coastguard Worker the FDK AAC Codec or your modifications thereto in source code form.
42*e5436536SAndroid Build Coastguard Worker
43*e5436536SAndroid Build Coastguard Worker You must retain the complete text of this software license in the documentation
44*e5436536SAndroid Build Coastguard Worker and/or other materials provided with redistributions of the FDK AAC Codec or
45*e5436536SAndroid Build Coastguard Worker your modifications thereto in binary form. You must make available free of
46*e5436536SAndroid Build Coastguard Worker charge copies of the complete source code of the FDK AAC Codec and your
47*e5436536SAndroid Build Coastguard Worker modifications thereto to recipients of copies in binary form.
48*e5436536SAndroid Build Coastguard Worker
49*e5436536SAndroid Build Coastguard Worker The name of Fraunhofer may not be used to endorse or promote products derived
50*e5436536SAndroid Build Coastguard Worker from this library without prior written permission.
51*e5436536SAndroid Build Coastguard Worker
52*e5436536SAndroid Build Coastguard Worker You may not charge copyright license fees for anyone to use, copy or distribute
53*e5436536SAndroid Build Coastguard Worker the FDK AAC Codec software or your modifications thereto.
54*e5436536SAndroid Build Coastguard Worker
55*e5436536SAndroid Build Coastguard Worker Your modified versions of the FDK AAC Codec must carry prominent notices stating
56*e5436536SAndroid Build Coastguard Worker that you changed the software and the date of any change. For modified versions
57*e5436536SAndroid Build Coastguard Worker of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
58*e5436536SAndroid Build Coastguard Worker must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
59*e5436536SAndroid Build Coastguard Worker AAC Codec Library for Android."
60*e5436536SAndroid Build Coastguard Worker
61*e5436536SAndroid Build Coastguard Worker 3. NO PATENT LICENSE
62*e5436536SAndroid Build Coastguard Worker
63*e5436536SAndroid Build Coastguard Worker NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
64*e5436536SAndroid Build Coastguard Worker limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
65*e5436536SAndroid Build Coastguard Worker Fraunhofer provides no warranty of patent non-infringement with respect to this
66*e5436536SAndroid Build Coastguard Worker software.
67*e5436536SAndroid Build Coastguard Worker
68*e5436536SAndroid Build Coastguard Worker You may use this FDK AAC Codec software or modifications thereto only for
69*e5436536SAndroid Build Coastguard Worker purposes that are authorized by appropriate patent licenses.
70*e5436536SAndroid Build Coastguard Worker
71*e5436536SAndroid Build Coastguard Worker 4. DISCLAIMER
72*e5436536SAndroid Build Coastguard Worker
73*e5436536SAndroid Build Coastguard Worker This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
74*e5436536SAndroid Build Coastguard Worker holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
75*e5436536SAndroid Build Coastguard Worker including but not limited to the implied warranties of merchantability and
76*e5436536SAndroid Build Coastguard Worker fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
77*e5436536SAndroid Build Coastguard Worker CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
78*e5436536SAndroid Build Coastguard Worker or consequential damages, including but not limited to procurement of substitute
79*e5436536SAndroid Build Coastguard Worker goods or services; loss of use, data, or profits, or business interruption,
80*e5436536SAndroid Build Coastguard Worker however caused and on any theory of liability, whether in contract, strict
81*e5436536SAndroid Build Coastguard Worker liability, or tort (including negligence), arising in any way out of the use of
82*e5436536SAndroid Build Coastguard Worker this software, even if advised of the possibility of such damage.
83*e5436536SAndroid Build Coastguard Worker
84*e5436536SAndroid Build Coastguard Worker 5. CONTACT INFORMATION
85*e5436536SAndroid Build Coastguard Worker
86*e5436536SAndroid Build Coastguard Worker Fraunhofer Institute for Integrated Circuits IIS
87*e5436536SAndroid Build Coastguard Worker Attention: Audio and Multimedia Departments - FDK AAC LL
88*e5436536SAndroid Build Coastguard Worker Am Wolfsmantel 33
89*e5436536SAndroid Build Coastguard Worker 91058 Erlangen, Germany
90*e5436536SAndroid Build Coastguard Worker
91*e5436536SAndroid Build Coastguard Worker www.iis.fraunhofer.de/amm
92*e5436536SAndroid Build Coastguard Worker [email protected]
93*e5436536SAndroid Build Coastguard Worker ----------------------------------------------------------------------------- */
94*e5436536SAndroid Build Coastguard Worker
95*e5436536SAndroid Build Coastguard Worker /******************* MPEG transport format encoder library *********************
96*e5436536SAndroid Build Coastguard Worker
97*e5436536SAndroid Build Coastguard Worker Author(s):
98*e5436536SAndroid Build Coastguard Worker
99*e5436536SAndroid Build Coastguard Worker Description:
100*e5436536SAndroid Build Coastguard Worker
101*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
102*e5436536SAndroid Build Coastguard Worker
103*e5436536SAndroid Build Coastguard Worker #include "tp_data.h"
104*e5436536SAndroid Build Coastguard Worker
105*e5436536SAndroid Build Coastguard Worker #include "tpenc_lib.h"
106*e5436536SAndroid Build Coastguard Worker #include "tpenc_asc.h"
107*e5436536SAndroid Build Coastguard Worker #include "FDK_bitstream.h"
108*e5436536SAndroid Build Coastguard Worker #include "genericStds.h"
109*e5436536SAndroid Build Coastguard Worker
110*e5436536SAndroid Build Coastguard Worker #include "FDK_crc.h"
111*e5436536SAndroid Build Coastguard Worker
112*e5436536SAndroid Build Coastguard Worker #define PCE_HEIGHT_EXT_SYNC (0xAC)
113*e5436536SAndroid Build Coastguard Worker #define HEIGHT_NORMAL 0
114*e5436536SAndroid Build Coastguard Worker #define HEIGHT_TOP 1
115*e5436536SAndroid Build Coastguard Worker #define HEIGHT_BOTTOM 2
116*e5436536SAndroid Build Coastguard Worker #define MAX_FRONT_ELEMENTS 8
117*e5436536SAndroid Build Coastguard Worker #define MAX_SIDE_ELEMENTS 3
118*e5436536SAndroid Build Coastguard Worker #define MAX_BACK_ELEMENTS 4
119*e5436536SAndroid Build Coastguard Worker
120*e5436536SAndroid Build Coastguard Worker /**
121*e5436536SAndroid Build Coastguard Worker * Describe additional PCE height information for front, side and back channel
122*e5436536SAndroid Build Coastguard Worker * elements.
123*e5436536SAndroid Build Coastguard Worker */
124*e5436536SAndroid Build Coastguard Worker typedef struct {
125*e5436536SAndroid Build Coastguard Worker UCHAR
126*e5436536SAndroid Build Coastguard Worker num_front_height_channel_elements[2]; /*!< Number of front channel
127*e5436536SAndroid Build Coastguard Worker elements in top [0] and bottom
128*e5436536SAndroid Build Coastguard Worker [1] plane. */
129*e5436536SAndroid Build Coastguard Worker UCHAR num_side_height_channel_elements[2]; /*!< Number of side channel
130*e5436536SAndroid Build Coastguard Worker elements in top [0] and bottom
131*e5436536SAndroid Build Coastguard Worker [1] plane. */
132*e5436536SAndroid Build Coastguard Worker UCHAR num_back_height_channel_elements[2]; /*!< Number of back channel
133*e5436536SAndroid Build Coastguard Worker elements in top [0] and bottom
134*e5436536SAndroid Build Coastguard Worker [1] plane. */
135*e5436536SAndroid Build Coastguard Worker } PCE_HEIGHT_NUM;
136*e5436536SAndroid Build Coastguard Worker
137*e5436536SAndroid Build Coastguard Worker /**
138*e5436536SAndroid Build Coastguard Worker * Describe a PCE based on placed channel elements and element type sequence.
139*e5436536SAndroid Build Coastguard Worker */
140*e5436536SAndroid Build Coastguard Worker typedef struct {
141*e5436536SAndroid Build Coastguard Worker UCHAR num_front_channel_elements; /*!< Number of front channel elements. */
142*e5436536SAndroid Build Coastguard Worker UCHAR num_side_channel_elements; /*!< Number of side channel elements. */
143*e5436536SAndroid Build Coastguard Worker UCHAR num_back_channel_elements; /*!< Number of back channel elements. */
144*e5436536SAndroid Build Coastguard Worker UCHAR num_lfe_channel_elements; /*!< Number of lfe channel elements. */
145*e5436536SAndroid Build Coastguard Worker const MP4_ELEMENT_ID
146*e5436536SAndroid Build Coastguard Worker *pEl_type; /*!< List contains sequence describing the elements
147*e5436536SAndroid Build Coastguard Worker in present channel mode. (MPEG order) */
148*e5436536SAndroid Build Coastguard Worker const PCE_HEIGHT_NUM *pHeight_num;
149*e5436536SAndroid Build Coastguard Worker } PCE_CONFIGURATION;
150*e5436536SAndroid Build Coastguard Worker
151*e5436536SAndroid Build Coastguard Worker /**
152*e5436536SAndroid Build Coastguard Worker * Map an incoming channel mode to a existing PCE configuration entry.
153*e5436536SAndroid Build Coastguard Worker */
154*e5436536SAndroid Build Coastguard Worker typedef struct {
155*e5436536SAndroid Build Coastguard Worker CHANNEL_MODE channel_mode; /*!< Present channel mode. */
156*e5436536SAndroid Build Coastguard Worker PCE_CONFIGURATION
157*e5436536SAndroid Build Coastguard Worker pce_configuration; /*!< Program config element description. */
158*e5436536SAndroid Build Coastguard Worker
159*e5436536SAndroid Build Coastguard Worker } CHANNEL_CONFIGURATION;
160*e5436536SAndroid Build Coastguard Worker
161*e5436536SAndroid Build Coastguard Worker /**
162*e5436536SAndroid Build Coastguard Worker * The following arrays provide the IDs of the consecutive elements for each
163*e5436536SAndroid Build Coastguard Worker * mode.
164*e5436536SAndroid Build Coastguard Worker */
165*e5436536SAndroid Build Coastguard Worker static const MP4_ELEMENT_ID elType_1[] = {ID_SCE};
166*e5436536SAndroid Build Coastguard Worker static const MP4_ELEMENT_ID elType_2[] = {ID_CPE};
167*e5436536SAndroid Build Coastguard Worker static const MP4_ELEMENT_ID elType_1_2[] = {ID_SCE, ID_CPE};
168*e5436536SAndroid Build Coastguard Worker static const MP4_ELEMENT_ID elType_1_2_1[] = {ID_SCE, ID_CPE, ID_SCE};
169*e5436536SAndroid Build Coastguard Worker static const MP4_ELEMENT_ID elType_1_2_2[] = {ID_SCE, ID_CPE, ID_CPE};
170*e5436536SAndroid Build Coastguard Worker static const MP4_ELEMENT_ID elType_1_2_2_1[] = {ID_SCE, ID_CPE, ID_CPE, ID_LFE};
171*e5436536SAndroid Build Coastguard Worker static const MP4_ELEMENT_ID elType_1_2_2_2_1[] = {ID_SCE, ID_CPE, ID_CPE,
172*e5436536SAndroid Build Coastguard Worker ID_CPE, ID_LFE};
173*e5436536SAndroid Build Coastguard Worker static const MP4_ELEMENT_ID elType_6_1[] = {ID_SCE, ID_CPE, ID_CPE, ID_SCE,
174*e5436536SAndroid Build Coastguard Worker ID_LFE};
175*e5436536SAndroid Build Coastguard Worker static const MP4_ELEMENT_ID elType_7_1_back[] = {ID_SCE, ID_CPE, ID_CPE, ID_CPE,
176*e5436536SAndroid Build Coastguard Worker ID_LFE};
177*e5436536SAndroid Build Coastguard Worker static const MP4_ELEMENT_ID elType_7_1_top_front[] = {ID_SCE, ID_CPE, ID_CPE,
178*e5436536SAndroid Build Coastguard Worker ID_LFE, ID_CPE};
179*e5436536SAndroid Build Coastguard Worker static const MP4_ELEMENT_ID elType_7_1_rear_surround[] = {
180*e5436536SAndroid Build Coastguard Worker ID_SCE, ID_CPE, ID_CPE, ID_CPE, ID_LFE};
181*e5436536SAndroid Build Coastguard Worker static const MP4_ELEMENT_ID elType_7_1_front_center[] = {ID_SCE, ID_CPE, ID_CPE,
182*e5436536SAndroid Build Coastguard Worker ID_CPE, ID_LFE};
183*e5436536SAndroid Build Coastguard Worker
184*e5436536SAndroid Build Coastguard Worker /**
185*e5436536SAndroid Build Coastguard Worker * The following arrays provide information on how many front, side and back
186*e5436536SAndroid Build Coastguard Worker * elements are assigned to the top or bottom plane for each mode that comprises
187*e5436536SAndroid Build Coastguard Worker * height information.
188*e5436536SAndroid Build Coastguard Worker */
189*e5436536SAndroid Build Coastguard Worker static const PCE_HEIGHT_NUM heightNum_7_1_top_front = {{1, 0}, {0, 0}, {0, 0}};
190*e5436536SAndroid Build Coastguard Worker
191*e5436536SAndroid Build Coastguard Worker /**
192*e5436536SAndroid Build Coastguard Worker * \brief Table contains all supported channel modes and according PCE
193*e5436536SAndroid Build Coastguard Worker configuration description.
194*e5436536SAndroid Build Coastguard Worker *
195*e5436536SAndroid Build Coastguard Worker * The mode identifier is followed by the number of front, side, back, and LFE
196*e5436536SAndroid Build Coastguard Worker elements.
197*e5436536SAndroid Build Coastguard Worker * These are followed by a pointer to the IDs of the consecutive elements
198*e5436536SAndroid Build Coastguard Worker (ID_SCE, ID_CPE, ID_LFE).
199*e5436536SAndroid Build Coastguard Worker *
200*e5436536SAndroid Build Coastguard Worker * For some modes (MODE_7_1_TOP_FRONT and MODE_22_2) additional height
201*e5436536SAndroid Build Coastguard Worker information is transmitted.
202*e5436536SAndroid Build Coastguard Worker * In this case the additional pointer provides information on how many front,
203*e5436536SAndroid Build Coastguard Worker side and back elements
204*e5436536SAndroid Build Coastguard Worker * are assigned to the top or bottom plane.The elements are arranged in the
205*e5436536SAndroid Build Coastguard Worker following order: normal height (front, side, back, LFE), top height (front,
206*e5436536SAndroid Build Coastguard Worker side, back), bottom height (front, side, back).
207*e5436536SAndroid Build Coastguard Worker *
208*e5436536SAndroid Build Coastguard Worker *
209*e5436536SAndroid Build Coastguard Worker * E.g. MODE_7_1_TOP_FRONT means:
210*e5436536SAndroid Build Coastguard Worker * - 3 elements are front channel elements.
211*e5436536SAndroid Build Coastguard Worker * - 0 elements are side channel elements.
212*e5436536SAndroid Build Coastguard Worker * - 1 element is back channel element.
213*e5436536SAndroid Build Coastguard Worker * - 1 element is an LFE channel element.
214*e5436536SAndroid Build Coastguard Worker * - the element order is ID_SCE, ID_CPE, ID_CPE,
215*e5436536SAndroid Build Coastguard Worker ID_LFE, ID_CPE.
216*e5436536SAndroid Build Coastguard Worker * - 1 of the front elements is in the top plane.
217*e5436536SAndroid Build Coastguard Worker *
218*e5436536SAndroid Build Coastguard Worker * This leads to the following mapping for the cconsecutive elements in the
219*e5436536SAndroid Build Coastguard Worker MODE_7_1_TOP_FRONT bitstream:
220*e5436536SAndroid Build Coastguard Worker * - ID_SCE -> normal height front,
221*e5436536SAndroid Build Coastguard Worker - ID_CPE -> normal height front,
222*e5436536SAndroid Build Coastguard Worker - ID_CPE -> normal height back,
223*e5436536SAndroid Build Coastguard Worker - ID_LFE -> normal height LFE,
224*e5436536SAndroid Build Coastguard Worker - ID_CPE -> top height front.
225*e5436536SAndroid Build Coastguard Worker */
226*e5436536SAndroid Build Coastguard Worker static const CHANNEL_CONFIGURATION pceConfigTab[] = {
227*e5436536SAndroid Build Coastguard Worker {MODE_1,
228*e5436536SAndroid Build Coastguard Worker {1, 0, 0, 0, elType_1,
229*e5436536SAndroid Build Coastguard Worker NULL}}, /* don't transmit height information in this mode */
230*e5436536SAndroid Build Coastguard Worker {MODE_2,
231*e5436536SAndroid Build Coastguard Worker {1, 0, 0, 0, elType_2,
232*e5436536SAndroid Build Coastguard Worker NULL}}, /* don't transmit height information in this mode */
233*e5436536SAndroid Build Coastguard Worker {MODE_1_2,
234*e5436536SAndroid Build Coastguard Worker {2, 0, 0, 0, elType_1_2,
235*e5436536SAndroid Build Coastguard Worker NULL}}, /* don't transmit height information in this mode */
236*e5436536SAndroid Build Coastguard Worker {MODE_1_2_1,
237*e5436536SAndroid Build Coastguard Worker {2, 0, 1, 0, elType_1_2_1,
238*e5436536SAndroid Build Coastguard Worker NULL}}, /* don't transmit height information in this mode */
239*e5436536SAndroid Build Coastguard Worker {MODE_1_2_2,
240*e5436536SAndroid Build Coastguard Worker {2, 0, 1, 0, elType_1_2_2,
241*e5436536SAndroid Build Coastguard Worker NULL}}, /* don't transmit height information in this mode */
242*e5436536SAndroid Build Coastguard Worker {MODE_1_2_2_1,
243*e5436536SAndroid Build Coastguard Worker {2, 0, 1, 1, elType_1_2_2_1,
244*e5436536SAndroid Build Coastguard Worker NULL}}, /* don't transmit height information in this mode */
245*e5436536SAndroid Build Coastguard Worker {MODE_1_2_2_2_1,
246*e5436536SAndroid Build Coastguard Worker {3, 0, 1, 1, elType_1_2_2_2_1,
247*e5436536SAndroid Build Coastguard Worker NULL}}, /* don't transmit height information in this mode */
248*e5436536SAndroid Build Coastguard Worker
249*e5436536SAndroid Build Coastguard Worker {MODE_6_1,
250*e5436536SAndroid Build Coastguard Worker {2, 0, 2, 1, elType_6_1,
251*e5436536SAndroid Build Coastguard Worker NULL}}, /* don't transmit height information in this mode */
252*e5436536SAndroid Build Coastguard Worker {MODE_7_1_BACK,
253*e5436536SAndroid Build Coastguard Worker {2, 0, 2, 1, elType_7_1_back,
254*e5436536SAndroid Build Coastguard Worker NULL}}, /* don't transmit height information in this mode */
255*e5436536SAndroid Build Coastguard Worker {MODE_7_1_TOP_FRONT,
256*e5436536SAndroid Build Coastguard Worker {3, 0, 1, 1, elType_7_1_top_front, &heightNum_7_1_top_front}},
257*e5436536SAndroid Build Coastguard Worker
258*e5436536SAndroid Build Coastguard Worker {MODE_7_1_REAR_SURROUND,
259*e5436536SAndroid Build Coastguard Worker {2, 0, 2, 1, elType_7_1_rear_surround,
260*e5436536SAndroid Build Coastguard Worker NULL}}, /* don't transmit height information in this mode */
261*e5436536SAndroid Build Coastguard Worker {MODE_7_1_FRONT_CENTER,
262*e5436536SAndroid Build Coastguard Worker {3, 0, 1, 1, elType_7_1_front_center,
263*e5436536SAndroid Build Coastguard Worker NULL}} /* don't transmit height information in this mode */
264*e5436536SAndroid Build Coastguard Worker };
265*e5436536SAndroid Build Coastguard Worker
266*e5436536SAndroid Build Coastguard Worker /**
267*e5436536SAndroid Build Coastguard Worker * \brief Get program config element description for existing channel mode.
268*e5436536SAndroid Build Coastguard Worker *
269*e5436536SAndroid Build Coastguard Worker * \param channel_mode Current channel mode.
270*e5436536SAndroid Build Coastguard Worker *
271*e5436536SAndroid Build Coastguard Worker * \return
272*e5436536SAndroid Build Coastguard Worker * - Pointer to PCE_CONFIGURATION entry, on success.
273*e5436536SAndroid Build Coastguard Worker * - NULL, on failure.
274*e5436536SAndroid Build Coastguard Worker */
getPceEntry(const CHANNEL_MODE channel_mode)275*e5436536SAndroid Build Coastguard Worker static const PCE_CONFIGURATION *getPceEntry(const CHANNEL_MODE channel_mode) {
276*e5436536SAndroid Build Coastguard Worker UINT i;
277*e5436536SAndroid Build Coastguard Worker const PCE_CONFIGURATION *pce_config = NULL;
278*e5436536SAndroid Build Coastguard Worker
279*e5436536SAndroid Build Coastguard Worker for (i = 0; i < (sizeof(pceConfigTab) / sizeof(CHANNEL_CONFIGURATION)); i++) {
280*e5436536SAndroid Build Coastguard Worker if (pceConfigTab[i].channel_mode == channel_mode) {
281*e5436536SAndroid Build Coastguard Worker pce_config = &pceConfigTab[i].pce_configuration;
282*e5436536SAndroid Build Coastguard Worker break;
283*e5436536SAndroid Build Coastguard Worker }
284*e5436536SAndroid Build Coastguard Worker }
285*e5436536SAndroid Build Coastguard Worker
286*e5436536SAndroid Build Coastguard Worker return pce_config;
287*e5436536SAndroid Build Coastguard Worker }
288*e5436536SAndroid Build Coastguard Worker
getChannelConfig(const CHANNEL_MODE channel_mode,const UCHAR channel_config_zero)289*e5436536SAndroid Build Coastguard Worker int getChannelConfig(const CHANNEL_MODE channel_mode,
290*e5436536SAndroid Build Coastguard Worker const UCHAR channel_config_zero) {
291*e5436536SAndroid Build Coastguard Worker INT chan_config = 0;
292*e5436536SAndroid Build Coastguard Worker
293*e5436536SAndroid Build Coastguard Worker if (channel_config_zero != 0) {
294*e5436536SAndroid Build Coastguard Worker chan_config = 0;
295*e5436536SAndroid Build Coastguard Worker } else {
296*e5436536SAndroid Build Coastguard Worker switch (channel_mode) {
297*e5436536SAndroid Build Coastguard Worker case MODE_1:
298*e5436536SAndroid Build Coastguard Worker chan_config = 1;
299*e5436536SAndroid Build Coastguard Worker break;
300*e5436536SAndroid Build Coastguard Worker case MODE_2:
301*e5436536SAndroid Build Coastguard Worker chan_config = 2;
302*e5436536SAndroid Build Coastguard Worker break;
303*e5436536SAndroid Build Coastguard Worker case MODE_1_2:
304*e5436536SAndroid Build Coastguard Worker chan_config = 3;
305*e5436536SAndroid Build Coastguard Worker break;
306*e5436536SAndroid Build Coastguard Worker case MODE_1_2_1:
307*e5436536SAndroid Build Coastguard Worker chan_config = 4;
308*e5436536SAndroid Build Coastguard Worker break;
309*e5436536SAndroid Build Coastguard Worker case MODE_1_2_2:
310*e5436536SAndroid Build Coastguard Worker chan_config = 5;
311*e5436536SAndroid Build Coastguard Worker break;
312*e5436536SAndroid Build Coastguard Worker case MODE_1_2_2_1:
313*e5436536SAndroid Build Coastguard Worker chan_config = 6;
314*e5436536SAndroid Build Coastguard Worker break;
315*e5436536SAndroid Build Coastguard Worker case MODE_1_2_2_2_1:
316*e5436536SAndroid Build Coastguard Worker chan_config = 7;
317*e5436536SAndroid Build Coastguard Worker break;
318*e5436536SAndroid Build Coastguard Worker case MODE_6_1:
319*e5436536SAndroid Build Coastguard Worker chan_config = 11;
320*e5436536SAndroid Build Coastguard Worker break;
321*e5436536SAndroid Build Coastguard Worker case MODE_7_1_BACK:
322*e5436536SAndroid Build Coastguard Worker chan_config = 12;
323*e5436536SAndroid Build Coastguard Worker break;
324*e5436536SAndroid Build Coastguard Worker case MODE_7_1_TOP_FRONT:
325*e5436536SAndroid Build Coastguard Worker chan_config = 14;
326*e5436536SAndroid Build Coastguard Worker break;
327*e5436536SAndroid Build Coastguard Worker default:
328*e5436536SAndroid Build Coastguard Worker chan_config = 0;
329*e5436536SAndroid Build Coastguard Worker }
330*e5436536SAndroid Build Coastguard Worker }
331*e5436536SAndroid Build Coastguard Worker
332*e5436536SAndroid Build Coastguard Worker return chan_config;
333*e5436536SAndroid Build Coastguard Worker }
334*e5436536SAndroid Build Coastguard Worker
transportEnc_GetChannelMode(int noChannels)335*e5436536SAndroid Build Coastguard Worker CHANNEL_MODE transportEnc_GetChannelMode(int noChannels) {
336*e5436536SAndroid Build Coastguard Worker CHANNEL_MODE chMode;
337*e5436536SAndroid Build Coastguard Worker
338*e5436536SAndroid Build Coastguard Worker if (noChannels <= 8 && noChannels > 0)
339*e5436536SAndroid Build Coastguard Worker chMode = (CHANNEL_MODE)(
340*e5436536SAndroid Build Coastguard Worker (noChannels == 8) ? 7
341*e5436536SAndroid Build Coastguard Worker : noChannels); /* see : iso/mpeg4 v1 audio subpart1*/
342*e5436536SAndroid Build Coastguard Worker else
343*e5436536SAndroid Build Coastguard Worker chMode = MODE_UNKNOWN;
344*e5436536SAndroid Build Coastguard Worker
345*e5436536SAndroid Build Coastguard Worker return chMode;
346*e5436536SAndroid Build Coastguard Worker }
347*e5436536SAndroid Build Coastguard Worker
transportEnc_writePCE(HANDLE_FDK_BITSTREAM hBs,CHANNEL_MODE channelMode,INT sampleRate,int instanceTagPCE,int profile,int matrixMixdownA,int pseudoSurroundEnable,UINT alignAnchor)348*e5436536SAndroid Build Coastguard Worker int transportEnc_writePCE(HANDLE_FDK_BITSTREAM hBs, CHANNEL_MODE channelMode,
349*e5436536SAndroid Build Coastguard Worker INT sampleRate, int instanceTagPCE, int profile,
350*e5436536SAndroid Build Coastguard Worker int matrixMixdownA, int pseudoSurroundEnable,
351*e5436536SAndroid Build Coastguard Worker UINT alignAnchor) {
352*e5436536SAndroid Build Coastguard Worker int sampleRateIndex, i;
353*e5436536SAndroid Build Coastguard Worker const PCE_CONFIGURATION *config = NULL;
354*e5436536SAndroid Build Coastguard Worker const MP4_ELEMENT_ID *pEl_list = NULL;
355*e5436536SAndroid Build Coastguard Worker UCHAR cpeCnt = 0, sceCnt = 0, lfeCnt = 0, frntCnt = 0, sdCnt = 0, bckCnt = 0,
356*e5436536SAndroid Build Coastguard Worker isCpe = 0, tag = 0, normalFrontEnd = 0, normalSideEnd = 0,
357*e5436536SAndroid Build Coastguard Worker normalBackEnd = 0, topFrontEnd = 0, topSideEnd = 0, topBackEnd = 0,
358*e5436536SAndroid Build Coastguard Worker bottomFrontEnd = 0, bottomSideEnd = 0;
359*e5436536SAndroid Build Coastguard Worker #ifdef FDK_ASSERT_ENABLE
360*e5436536SAndroid Build Coastguard Worker UCHAR bottomBackEnd = 0;
361*e5436536SAndroid Build Coastguard Worker #endif
362*e5436536SAndroid Build Coastguard Worker enum elementDepth { FRONT, SIDE, BACK } elDepth;
363*e5436536SAndroid Build Coastguard Worker
364*e5436536SAndroid Build Coastguard Worker sampleRateIndex = getSamplingRateIndex(sampleRate, 4);
365*e5436536SAndroid Build Coastguard Worker if (sampleRateIndex == 15) {
366*e5436536SAndroid Build Coastguard Worker return -1;
367*e5436536SAndroid Build Coastguard Worker }
368*e5436536SAndroid Build Coastguard Worker
369*e5436536SAndroid Build Coastguard Worker if ((config = getPceEntry(channelMode)) == NULL) {
370*e5436536SAndroid Build Coastguard Worker return -1;
371*e5436536SAndroid Build Coastguard Worker }
372*e5436536SAndroid Build Coastguard Worker
373*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(config->num_front_channel_elements <= MAX_FRONT_ELEMENTS);
374*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(config->num_side_channel_elements <= MAX_SIDE_ELEMENTS);
375*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(config->num_back_channel_elements <= MAX_BACK_ELEMENTS);
376*e5436536SAndroid Build Coastguard Worker
377*e5436536SAndroid Build Coastguard Worker UCHAR frontIsCpe[MAX_FRONT_ELEMENTS] = {0},
378*e5436536SAndroid Build Coastguard Worker frontTag[MAX_FRONT_ELEMENTS] = {0}, sideIsCpe[MAX_SIDE_ELEMENTS] = {0},
379*e5436536SAndroid Build Coastguard Worker sideTag[MAX_SIDE_ELEMENTS] = {0}, backIsCpe[MAX_BACK_ELEMENTS] = {0},
380*e5436536SAndroid Build Coastguard Worker backTag[MAX_BACK_ELEMENTS] = {0};
381*e5436536SAndroid Build Coastguard Worker
382*e5436536SAndroid Build Coastguard Worker /* Write general information */
383*e5436536SAndroid Build Coastguard Worker
384*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, instanceTagPCE, 4); /* Element instance tag */
385*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, profile, 2); /* Object type */
386*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, sampleRateIndex, 4); /* Sample rate index*/
387*e5436536SAndroid Build Coastguard Worker
388*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, config->num_front_channel_elements,
389*e5436536SAndroid Build Coastguard Worker 4); /* Front channel Elements */
390*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, config->num_side_channel_elements,
391*e5436536SAndroid Build Coastguard Worker 4); /* No Side Channel Elements */
392*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, config->num_back_channel_elements,
393*e5436536SAndroid Build Coastguard Worker 4); /* No Back channel Elements */
394*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, config->num_lfe_channel_elements,
395*e5436536SAndroid Build Coastguard Worker 2); /* No Lfe channel elements */
396*e5436536SAndroid Build Coastguard Worker
397*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, 0, 3); /* No assoc data elements */
398*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, 0, 4); /* No valid cc elements */
399*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, 0, 1); /* Mono mixdown present */
400*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, 0, 1); /* Stereo mixdown present */
401*e5436536SAndroid Build Coastguard Worker
402*e5436536SAndroid Build Coastguard Worker if (matrixMixdownA != 0 &&
403*e5436536SAndroid Build Coastguard Worker ((channelMode == MODE_1_2_2) || (channelMode == MODE_1_2_2_1))) {
404*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, 1, 1); /* Matrix mixdown present */
405*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, (matrixMixdownA - 1) & 0x3, 2); /* matrix_mixdown_idx */
406*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, (pseudoSurroundEnable) ? 1 : 0,
407*e5436536SAndroid Build Coastguard Worker 1); /* pseudo_surround_enable */
408*e5436536SAndroid Build Coastguard Worker } else {
409*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, 0, 1); /* Matrix mixdown not present */
410*e5436536SAndroid Build Coastguard Worker }
411*e5436536SAndroid Build Coastguard Worker
412*e5436536SAndroid Build Coastguard Worker if (config->pHeight_num != NULL) {
413*e5436536SAndroid Build Coastguard Worker /* we have up to three different height levels, and in each height level we
414*e5436536SAndroid Build Coastguard Worker * may have front, side and back channels. We need to know where each
415*e5436536SAndroid Build Coastguard Worker * section ends to correctly count the tags */
416*e5436536SAndroid Build Coastguard Worker normalFrontEnd = config->num_front_channel_elements -
417*e5436536SAndroid Build Coastguard Worker config->pHeight_num->num_front_height_channel_elements[0] -
418*e5436536SAndroid Build Coastguard Worker config->pHeight_num->num_front_height_channel_elements[1];
419*e5436536SAndroid Build Coastguard Worker normalSideEnd = normalFrontEnd + config->num_side_channel_elements -
420*e5436536SAndroid Build Coastguard Worker config->pHeight_num->num_side_height_channel_elements[0] -
421*e5436536SAndroid Build Coastguard Worker config->pHeight_num->num_side_height_channel_elements[1];
422*e5436536SAndroid Build Coastguard Worker normalBackEnd = normalSideEnd + config->num_back_channel_elements -
423*e5436536SAndroid Build Coastguard Worker config->pHeight_num->num_back_height_channel_elements[0] -
424*e5436536SAndroid Build Coastguard Worker config->pHeight_num->num_back_height_channel_elements[1];
425*e5436536SAndroid Build Coastguard Worker
426*e5436536SAndroid Build Coastguard Worker topFrontEnd =
427*e5436536SAndroid Build Coastguard Worker normalBackEnd + config->num_lfe_channel_elements +
428*e5436536SAndroid Build Coastguard Worker config->pHeight_num->num_front_height_channel_elements[0]; /* only
429*e5436536SAndroid Build Coastguard Worker normal
430*e5436536SAndroid Build Coastguard Worker height
431*e5436536SAndroid Build Coastguard Worker LFEs
432*e5436536SAndroid Build Coastguard Worker assumed */
433*e5436536SAndroid Build Coastguard Worker topSideEnd =
434*e5436536SAndroid Build Coastguard Worker topFrontEnd + config->pHeight_num->num_side_height_channel_elements[0];
435*e5436536SAndroid Build Coastguard Worker topBackEnd =
436*e5436536SAndroid Build Coastguard Worker topSideEnd + config->pHeight_num->num_back_height_channel_elements[0];
437*e5436536SAndroid Build Coastguard Worker
438*e5436536SAndroid Build Coastguard Worker bottomFrontEnd =
439*e5436536SAndroid Build Coastguard Worker topBackEnd + config->pHeight_num->num_front_height_channel_elements[1];
440*e5436536SAndroid Build Coastguard Worker bottomSideEnd = bottomFrontEnd +
441*e5436536SAndroid Build Coastguard Worker config->pHeight_num->num_side_height_channel_elements[1];
442*e5436536SAndroid Build Coastguard Worker #ifdef FDK_ASSERT_ENABLE
443*e5436536SAndroid Build Coastguard Worker bottomBackEnd = bottomSideEnd +
444*e5436536SAndroid Build Coastguard Worker config->pHeight_num->num_back_height_channel_elements[1];
445*e5436536SAndroid Build Coastguard Worker #endif
446*e5436536SAndroid Build Coastguard Worker
447*e5436536SAndroid Build Coastguard Worker } else {
448*e5436536SAndroid Build Coastguard Worker /* we have only one height level, so we don't care about top or bottom */
449*e5436536SAndroid Build Coastguard Worker normalFrontEnd = config->num_front_channel_elements;
450*e5436536SAndroid Build Coastguard Worker normalSideEnd = normalFrontEnd + config->num_side_channel_elements;
451*e5436536SAndroid Build Coastguard Worker normalBackEnd = normalSideEnd + config->num_back_channel_elements;
452*e5436536SAndroid Build Coastguard Worker }
453*e5436536SAndroid Build Coastguard Worker
454*e5436536SAndroid Build Coastguard Worker /* assign cpe and tag information to either front, side or back channels */
455*e5436536SAndroid Build Coastguard Worker
456*e5436536SAndroid Build Coastguard Worker pEl_list = config->pEl_type;
457*e5436536SAndroid Build Coastguard Worker
458*e5436536SAndroid Build Coastguard Worker for (i = 0; i < config->num_front_channel_elements +
459*e5436536SAndroid Build Coastguard Worker config->num_side_channel_elements +
460*e5436536SAndroid Build Coastguard Worker config->num_back_channel_elements +
461*e5436536SAndroid Build Coastguard Worker config->num_lfe_channel_elements;
462*e5436536SAndroid Build Coastguard Worker i++) {
463*e5436536SAndroid Build Coastguard Worker if (*pEl_list == ID_LFE) {
464*e5436536SAndroid Build Coastguard Worker pEl_list++;
465*e5436536SAndroid Build Coastguard Worker continue;
466*e5436536SAndroid Build Coastguard Worker }
467*e5436536SAndroid Build Coastguard Worker isCpe = (*pEl_list++ == ID_CPE) ? 1 : 0;
468*e5436536SAndroid Build Coastguard Worker tag = (isCpe) ? cpeCnt++ : sceCnt++;
469*e5436536SAndroid Build Coastguard Worker
470*e5436536SAndroid Build Coastguard Worker if (i < normalFrontEnd)
471*e5436536SAndroid Build Coastguard Worker elDepth = FRONT;
472*e5436536SAndroid Build Coastguard Worker else if (i < normalSideEnd)
473*e5436536SAndroid Build Coastguard Worker elDepth = SIDE;
474*e5436536SAndroid Build Coastguard Worker else if (i < normalBackEnd)
475*e5436536SAndroid Build Coastguard Worker elDepth = BACK;
476*e5436536SAndroid Build Coastguard Worker else if (i < topFrontEnd)
477*e5436536SAndroid Build Coastguard Worker elDepth = FRONT;
478*e5436536SAndroid Build Coastguard Worker else if (i < topSideEnd)
479*e5436536SAndroid Build Coastguard Worker elDepth = SIDE;
480*e5436536SAndroid Build Coastguard Worker else if (i < topBackEnd)
481*e5436536SAndroid Build Coastguard Worker elDepth = BACK;
482*e5436536SAndroid Build Coastguard Worker else if (i < bottomFrontEnd)
483*e5436536SAndroid Build Coastguard Worker elDepth = FRONT;
484*e5436536SAndroid Build Coastguard Worker else if (i < bottomSideEnd)
485*e5436536SAndroid Build Coastguard Worker elDepth = SIDE;
486*e5436536SAndroid Build Coastguard Worker else {
487*e5436536SAndroid Build Coastguard Worker elDepth = BACK;
488*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(i < bottomBackEnd); /* won't fail if implementation of pce
489*e5436536SAndroid Build Coastguard Worker configuration table is correct */
490*e5436536SAndroid Build Coastguard Worker }
491*e5436536SAndroid Build Coastguard Worker
492*e5436536SAndroid Build Coastguard Worker switch (elDepth) {
493*e5436536SAndroid Build Coastguard Worker case FRONT:
494*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(frntCnt < config->num_front_channel_elements);
495*e5436536SAndroid Build Coastguard Worker frontIsCpe[frntCnt] = isCpe;
496*e5436536SAndroid Build Coastguard Worker frontTag[frntCnt++] = tag;
497*e5436536SAndroid Build Coastguard Worker break;
498*e5436536SAndroid Build Coastguard Worker case SIDE:
499*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(sdCnt < config->num_side_channel_elements);
500*e5436536SAndroid Build Coastguard Worker sideIsCpe[sdCnt] = isCpe;
501*e5436536SAndroid Build Coastguard Worker sideTag[sdCnt++] = tag;
502*e5436536SAndroid Build Coastguard Worker break;
503*e5436536SAndroid Build Coastguard Worker case BACK:
504*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(bckCnt < config->num_back_channel_elements);
505*e5436536SAndroid Build Coastguard Worker backIsCpe[bckCnt] = isCpe;
506*e5436536SAndroid Build Coastguard Worker backTag[bckCnt++] = tag;
507*e5436536SAndroid Build Coastguard Worker break;
508*e5436536SAndroid Build Coastguard Worker }
509*e5436536SAndroid Build Coastguard Worker }
510*e5436536SAndroid Build Coastguard Worker
511*e5436536SAndroid Build Coastguard Worker /* Write front channel isCpe and tags */
512*e5436536SAndroid Build Coastguard Worker for (i = 0; i < config->num_front_channel_elements; i++) {
513*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, frontIsCpe[i], 1);
514*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, frontTag[i], 4);
515*e5436536SAndroid Build Coastguard Worker }
516*e5436536SAndroid Build Coastguard Worker /* Write side channel isCpe and tags */
517*e5436536SAndroid Build Coastguard Worker for (i = 0; i < config->num_side_channel_elements; i++) {
518*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, sideIsCpe[i], 1);
519*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, sideTag[i], 4);
520*e5436536SAndroid Build Coastguard Worker }
521*e5436536SAndroid Build Coastguard Worker /* Write back channel isCpe and tags */
522*e5436536SAndroid Build Coastguard Worker for (i = 0; i < config->num_back_channel_elements; i++) {
523*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, backIsCpe[i], 1);
524*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, backTag[i], 4);
525*e5436536SAndroid Build Coastguard Worker }
526*e5436536SAndroid Build Coastguard Worker /* Write LFE information */
527*e5436536SAndroid Build Coastguard Worker for (i = 0; i < config->num_lfe_channel_elements; i++) {
528*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, lfeCnt++, 4); /* LFE channel Instance Tag. */
529*e5436536SAndroid Build Coastguard Worker }
530*e5436536SAndroid Build Coastguard Worker
531*e5436536SAndroid Build Coastguard Worker /* - num_valid_cc_elements always 0.
532*e5436536SAndroid Build Coastguard Worker - num_assoc_data_elements always 0. */
533*e5436536SAndroid Build Coastguard Worker
534*e5436536SAndroid Build Coastguard Worker /* Byte alignment: relative to alignAnchor
535*e5436536SAndroid Build Coastguard Worker ADTS: align with respect to the first bit of the raw_data_block()
536*e5436536SAndroid Build Coastguard Worker ADIF: align with respect to the first bit of the header
537*e5436536SAndroid Build Coastguard Worker LATM: align with respect to the first bit of the ASC */
538*e5436536SAndroid Build Coastguard Worker FDKbyteAlign(hBs, alignAnchor); /* Alignment */
539*e5436536SAndroid Build Coastguard Worker
540*e5436536SAndroid Build Coastguard Worker /* Write comment information */
541*e5436536SAndroid Build Coastguard Worker
542*e5436536SAndroid Build Coastguard Worker if (config->pHeight_num != NULL) {
543*e5436536SAndroid Build Coastguard Worker /* embed height information in comment field */
544*e5436536SAndroid Build Coastguard Worker
545*e5436536SAndroid Build Coastguard Worker INT commentBytes =
546*e5436536SAndroid Build Coastguard Worker 1 /* PCE_HEIGHT_EXT_SYNC */
547*e5436536SAndroid Build Coastguard Worker + ((((config->num_front_channel_elements +
548*e5436536SAndroid Build Coastguard Worker config->num_side_channel_elements +
549*e5436536SAndroid Build Coastguard Worker config->num_back_channel_elements)
550*e5436536SAndroid Build Coastguard Worker << 1) +
551*e5436536SAndroid Build Coastguard Worker 7) >>
552*e5436536SAndroid Build Coastguard Worker 3) /* 2 bit height info per element, round up to full bytes */
553*e5436536SAndroid Build Coastguard Worker + 1; /* CRC */
554*e5436536SAndroid Build Coastguard Worker
555*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, commentBytes, 8); /* comment size. */
556*e5436536SAndroid Build Coastguard Worker
557*e5436536SAndroid Build Coastguard Worker FDK_CRCINFO crcInfo; /* CRC state info */
558*e5436536SAndroid Build Coastguard Worker INT crcReg;
559*e5436536SAndroid Build Coastguard Worker
560*e5436536SAndroid Build Coastguard Worker FDKcrcInit(&crcInfo, 0x07, 0xFF, 8);
561*e5436536SAndroid Build Coastguard Worker crcReg = FDKcrcStartReg(&crcInfo, hBs, 0);
562*e5436536SAndroid Build Coastguard Worker
563*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, PCE_HEIGHT_EXT_SYNC, 8); /* indicate height extension */
564*e5436536SAndroid Build Coastguard Worker
565*e5436536SAndroid Build Coastguard Worker /* front channel height information */
566*e5436536SAndroid Build Coastguard Worker for (i = 0;
567*e5436536SAndroid Build Coastguard Worker i < config->num_front_channel_elements -
568*e5436536SAndroid Build Coastguard Worker config->pHeight_num->num_front_height_channel_elements[0] -
569*e5436536SAndroid Build Coastguard Worker config->pHeight_num->num_front_height_channel_elements[1];
570*e5436536SAndroid Build Coastguard Worker i++)
571*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, HEIGHT_NORMAL, 2);
572*e5436536SAndroid Build Coastguard Worker for (i = 0; i < config->pHeight_num->num_front_height_channel_elements[0];
573*e5436536SAndroid Build Coastguard Worker i++)
574*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, HEIGHT_TOP, 2);
575*e5436536SAndroid Build Coastguard Worker for (i = 0; i < config->pHeight_num->num_front_height_channel_elements[1];
576*e5436536SAndroid Build Coastguard Worker i++)
577*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, HEIGHT_BOTTOM, 2);
578*e5436536SAndroid Build Coastguard Worker
579*e5436536SAndroid Build Coastguard Worker /* side channel height information */
580*e5436536SAndroid Build Coastguard Worker for (i = 0;
581*e5436536SAndroid Build Coastguard Worker i < config->num_side_channel_elements -
582*e5436536SAndroid Build Coastguard Worker config->pHeight_num->num_side_height_channel_elements[0] -
583*e5436536SAndroid Build Coastguard Worker config->pHeight_num->num_side_height_channel_elements[1];
584*e5436536SAndroid Build Coastguard Worker i++)
585*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, HEIGHT_NORMAL, 2);
586*e5436536SAndroid Build Coastguard Worker for (i = 0; i < config->pHeight_num->num_side_height_channel_elements[0];
587*e5436536SAndroid Build Coastguard Worker i++)
588*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, HEIGHT_TOP, 2);
589*e5436536SAndroid Build Coastguard Worker for (i = 0; i < config->pHeight_num->num_side_height_channel_elements[1];
590*e5436536SAndroid Build Coastguard Worker i++)
591*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, HEIGHT_BOTTOM, 2);
592*e5436536SAndroid Build Coastguard Worker
593*e5436536SAndroid Build Coastguard Worker /* back channel height information */
594*e5436536SAndroid Build Coastguard Worker for (i = 0;
595*e5436536SAndroid Build Coastguard Worker i < config->num_back_channel_elements -
596*e5436536SAndroid Build Coastguard Worker config->pHeight_num->num_back_height_channel_elements[0] -
597*e5436536SAndroid Build Coastguard Worker config->pHeight_num->num_back_height_channel_elements[1];
598*e5436536SAndroid Build Coastguard Worker i++)
599*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, HEIGHT_NORMAL, 2);
600*e5436536SAndroid Build Coastguard Worker for (i = 0; i < config->pHeight_num->num_back_height_channel_elements[0];
601*e5436536SAndroid Build Coastguard Worker i++)
602*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, HEIGHT_TOP, 2);
603*e5436536SAndroid Build Coastguard Worker for (i = 0; i < config->pHeight_num->num_back_height_channel_elements[1];
604*e5436536SAndroid Build Coastguard Worker i++)
605*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, HEIGHT_BOTTOM, 2);
606*e5436536SAndroid Build Coastguard Worker
607*e5436536SAndroid Build Coastguard Worker FDKbyteAlign(hBs, alignAnchor); /* Alignment */
608*e5436536SAndroid Build Coastguard Worker
609*e5436536SAndroid Build Coastguard Worker FDKcrcEndReg(&crcInfo, hBs, crcReg);
610*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, FDKcrcGetCRC(&crcInfo), 8);
611*e5436536SAndroid Build Coastguard Worker
612*e5436536SAndroid Build Coastguard Worker } else {
613*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, 0,
614*e5436536SAndroid Build Coastguard Worker 8); /* Do no write any comment or height information. */
615*e5436536SAndroid Build Coastguard Worker }
616*e5436536SAndroid Build Coastguard Worker
617*e5436536SAndroid Build Coastguard Worker return 0;
618*e5436536SAndroid Build Coastguard Worker }
619*e5436536SAndroid Build Coastguard Worker
transportEnc_GetPCEBits(CHANNEL_MODE channelMode,int matrixMixdownA,int bits)620*e5436536SAndroid Build Coastguard Worker int transportEnc_GetPCEBits(CHANNEL_MODE channelMode, int matrixMixdownA,
621*e5436536SAndroid Build Coastguard Worker int bits) {
622*e5436536SAndroid Build Coastguard Worker const PCE_CONFIGURATION *config = NULL;
623*e5436536SAndroid Build Coastguard Worker
624*e5436536SAndroid Build Coastguard Worker if ((config = getPceEntry(channelMode)) == NULL) {
625*e5436536SAndroid Build Coastguard Worker return -1; /* unsupported channelmapping */
626*e5436536SAndroid Build Coastguard Worker }
627*e5436536SAndroid Build Coastguard Worker
628*e5436536SAndroid Build Coastguard Worker bits +=
629*e5436536SAndroid Build Coastguard Worker 4 + 2 + 4; /* Element instance tag + Object type + Sample rate index */
630*e5436536SAndroid Build Coastguard Worker bits += 4 + 4 + 4 + 2; /* No (front + side + back + lfe channel) elements */
631*e5436536SAndroid Build Coastguard Worker bits += 3 + 4; /* No (assoc data + valid cc) elements */
632*e5436536SAndroid Build Coastguard Worker bits += 1 + 1 + 1; /* Mono + Stereo + Matrix mixdown present */
633*e5436536SAndroid Build Coastguard Worker
634*e5436536SAndroid Build Coastguard Worker if (matrixMixdownA != 0 &&
635*e5436536SAndroid Build Coastguard Worker ((channelMode == MODE_1_2_2) || (channelMode == MODE_1_2_2_1))) {
636*e5436536SAndroid Build Coastguard Worker bits += 3; /* matrix_mixdown_idx + pseudo_surround_enable */
637*e5436536SAndroid Build Coastguard Worker }
638*e5436536SAndroid Build Coastguard Worker
639*e5436536SAndroid Build Coastguard Worker bits += (1 + 4) * (INT)config->num_front_channel_elements;
640*e5436536SAndroid Build Coastguard Worker bits += (1 + 4) * (INT)config->num_side_channel_elements;
641*e5436536SAndroid Build Coastguard Worker bits += (1 + 4) * (INT)config->num_back_channel_elements;
642*e5436536SAndroid Build Coastguard Worker bits += (4) * (INT)config->num_lfe_channel_elements;
643*e5436536SAndroid Build Coastguard Worker
644*e5436536SAndroid Build Coastguard Worker /* - num_valid_cc_elements always 0.
645*e5436536SAndroid Build Coastguard Worker - num_assoc_data_elements always 0. */
646*e5436536SAndroid Build Coastguard Worker
647*e5436536SAndroid Build Coastguard Worker if ((bits % 8) != 0) {
648*e5436536SAndroid Build Coastguard Worker bits += (8 - (bits % 8)); /* Alignment */
649*e5436536SAndroid Build Coastguard Worker }
650*e5436536SAndroid Build Coastguard Worker
651*e5436536SAndroid Build Coastguard Worker bits += 8; /* Comment field bytes */
652*e5436536SAndroid Build Coastguard Worker
653*e5436536SAndroid Build Coastguard Worker if (config->pHeight_num != NULL) {
654*e5436536SAndroid Build Coastguard Worker /* Comment field (height extension) */
655*e5436536SAndroid Build Coastguard Worker
656*e5436536SAndroid Build Coastguard Worker bits +=
657*e5436536SAndroid Build Coastguard Worker 8 /* PCE_HEIGHT_EXT_SYNC */
658*e5436536SAndroid Build Coastguard Worker +
659*e5436536SAndroid Build Coastguard Worker ((config->num_front_channel_elements +
660*e5436536SAndroid Build Coastguard Worker config->num_side_channel_elements + config->num_back_channel_elements)
661*e5436536SAndroid Build Coastguard Worker << 1) /* 2 bit height info per element */
662*e5436536SAndroid Build Coastguard Worker + 8; /* CRC */
663*e5436536SAndroid Build Coastguard Worker
664*e5436536SAndroid Build Coastguard Worker if ((bits % 8) != 0) {
665*e5436536SAndroid Build Coastguard Worker bits += (8 - (bits % 8)); /* Alignment */
666*e5436536SAndroid Build Coastguard Worker }
667*e5436536SAndroid Build Coastguard Worker }
668*e5436536SAndroid Build Coastguard Worker
669*e5436536SAndroid Build Coastguard Worker return bits;
670*e5436536SAndroid Build Coastguard Worker }
671*e5436536SAndroid Build Coastguard Worker
writeAot(HANDLE_FDK_BITSTREAM hBitstreamBuffer,AUDIO_OBJECT_TYPE aot)672*e5436536SAndroid Build Coastguard Worker static void writeAot(HANDLE_FDK_BITSTREAM hBitstreamBuffer,
673*e5436536SAndroid Build Coastguard Worker AUDIO_OBJECT_TYPE aot) {
674*e5436536SAndroid Build Coastguard Worker int tmp = (int)aot;
675*e5436536SAndroid Build Coastguard Worker
676*e5436536SAndroid Build Coastguard Worker if (tmp > 31) {
677*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBitstreamBuffer, AOT_ESCAPE, 5);
678*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBitstreamBuffer, tmp - 32, 6); /* AudioObjectType */
679*e5436536SAndroid Build Coastguard Worker } else {
680*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBitstreamBuffer, tmp, 5);
681*e5436536SAndroid Build Coastguard Worker }
682*e5436536SAndroid Build Coastguard Worker }
683*e5436536SAndroid Build Coastguard Worker
writeSampleRate(HANDLE_FDK_BITSTREAM hBs,int sampleRate,int nBits)684*e5436536SAndroid Build Coastguard Worker static void writeSampleRate(HANDLE_FDK_BITSTREAM hBs, int sampleRate,
685*e5436536SAndroid Build Coastguard Worker int nBits) {
686*e5436536SAndroid Build Coastguard Worker int srIdx = getSamplingRateIndex(sampleRate, nBits);
687*e5436536SAndroid Build Coastguard Worker
688*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, srIdx, nBits);
689*e5436536SAndroid Build Coastguard Worker if (srIdx == (1 << nBits) - 1) {
690*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, sampleRate, 24);
691*e5436536SAndroid Build Coastguard Worker }
692*e5436536SAndroid Build Coastguard Worker }
693*e5436536SAndroid Build Coastguard Worker
transportEnc_writeGASpecificConfig(HANDLE_FDK_BITSTREAM asc,CODER_CONFIG * config,int extFlg,UINT alignAnchor)694*e5436536SAndroid Build Coastguard Worker static int transportEnc_writeGASpecificConfig(HANDLE_FDK_BITSTREAM asc,
695*e5436536SAndroid Build Coastguard Worker CODER_CONFIG *config, int extFlg,
696*e5436536SAndroid Build Coastguard Worker UINT alignAnchor) {
697*e5436536SAndroid Build Coastguard Worker int aot = config->aot;
698*e5436536SAndroid Build Coastguard Worker int samplesPerFrame = config->samplesPerFrame;
699*e5436536SAndroid Build Coastguard Worker
700*e5436536SAndroid Build Coastguard Worker /* start of GASpecificConfig according to ISO/IEC 14496-3 Subpart 4, 4.4.1 */
701*e5436536SAndroid Build Coastguard Worker FDKwriteBits(asc,
702*e5436536SAndroid Build Coastguard Worker ((samplesPerFrame == 960 || samplesPerFrame == 480) ? 1 : 0),
703*e5436536SAndroid Build Coastguard Worker 1); /* frameLengthFlag: 1 for a 960/480 (I)MDCT, 0 for a 1024/512
704*e5436536SAndroid Build Coastguard Worker (I)MDCT*/
705*e5436536SAndroid Build Coastguard Worker FDKwriteBits(asc, 0,
706*e5436536SAndroid Build Coastguard Worker 1); /* dependsOnCoreCoder: Sampling Rate Coder Specific, see in
707*e5436536SAndroid Build Coastguard Worker ISO/IEC 14496-3 Subpart 4, 4.4.1 */
708*e5436536SAndroid Build Coastguard Worker FDKwriteBits(asc, extFlg,
709*e5436536SAndroid Build Coastguard Worker 1); /* Extension Flag: Shall be 1 for aot = 17,19,20,21,22,23 */
710*e5436536SAndroid Build Coastguard Worker
711*e5436536SAndroid Build Coastguard Worker /* Write PCE if channel config is not 1-7 */
712*e5436536SAndroid Build Coastguard Worker if (getChannelConfig(config->channelMode, config->channelConfigZero) == 0) {
713*e5436536SAndroid Build Coastguard Worker transportEnc_writePCE(asc, config->channelMode, config->samplingRate, 0, 1,
714*e5436536SAndroid Build Coastguard Worker config->matrixMixdownA,
715*e5436536SAndroid Build Coastguard Worker (config->flags & CC_PSEUDO_SURROUND) ? 1 : 0,
716*e5436536SAndroid Build Coastguard Worker alignAnchor);
717*e5436536SAndroid Build Coastguard Worker }
718*e5436536SAndroid Build Coastguard Worker if ((aot == AOT_AAC_SCAL) || (aot == AOT_ER_AAC_SCAL)) {
719*e5436536SAndroid Build Coastguard Worker FDKwriteBits(asc, 0, 3); /* layerNr */
720*e5436536SAndroid Build Coastguard Worker }
721*e5436536SAndroid Build Coastguard Worker if (extFlg) {
722*e5436536SAndroid Build Coastguard Worker if (aot == AOT_ER_BSAC) {
723*e5436536SAndroid Build Coastguard Worker FDKwriteBits(asc, config->BSACnumOfSubFrame, 5); /* numOfSubFrame */
724*e5436536SAndroid Build Coastguard Worker FDKwriteBits(asc, config->BSAClayerLength, 11); /* layer_length */
725*e5436536SAndroid Build Coastguard Worker }
726*e5436536SAndroid Build Coastguard Worker if ((aot == AOT_ER_AAC_LC) || (aot == AOT_ER_AAC_LTP) ||
727*e5436536SAndroid Build Coastguard Worker (aot == AOT_ER_AAC_SCAL) || (aot == AOT_ER_AAC_LD)) {
728*e5436536SAndroid Build Coastguard Worker FDKwriteBits(asc, (config->flags & CC_VCB11) ? 1 : 0,
729*e5436536SAndroid Build Coastguard Worker 1); /* aacSectionDataResillienceFlag */
730*e5436536SAndroid Build Coastguard Worker FDKwriteBits(asc, (config->flags & CC_RVLC) ? 1 : 0,
731*e5436536SAndroid Build Coastguard Worker 1); /* aacScaleFactorDataResillienceFlag */
732*e5436536SAndroid Build Coastguard Worker FDKwriteBits(asc, (config->flags & CC_HCR) ? 1 : 0,
733*e5436536SAndroid Build Coastguard Worker 1); /* aacSpectralDataResillienceFlag */
734*e5436536SAndroid Build Coastguard Worker }
735*e5436536SAndroid Build Coastguard Worker FDKwriteBits(asc, 0, 1); /* extensionFlag3: reserved. Shall be '0' */
736*e5436536SAndroid Build Coastguard Worker }
737*e5436536SAndroid Build Coastguard Worker return 0;
738*e5436536SAndroid Build Coastguard Worker }
739*e5436536SAndroid Build Coastguard Worker
transportEnc_writeELDSpecificConfig(HANDLE_FDK_BITSTREAM hBs,CODER_CONFIG * config,int epConfig,CSTpCallBacks * cb)740*e5436536SAndroid Build Coastguard Worker static int transportEnc_writeELDSpecificConfig(HANDLE_FDK_BITSTREAM hBs,
741*e5436536SAndroid Build Coastguard Worker CODER_CONFIG *config,
742*e5436536SAndroid Build Coastguard Worker int epConfig,
743*e5436536SAndroid Build Coastguard Worker CSTpCallBacks *cb) {
744*e5436536SAndroid Build Coastguard Worker UINT frameLengthFlag = 0;
745*e5436536SAndroid Build Coastguard Worker switch (config->samplesPerFrame) {
746*e5436536SAndroid Build Coastguard Worker case 512:
747*e5436536SAndroid Build Coastguard Worker case 256:
748*e5436536SAndroid Build Coastguard Worker case 128:
749*e5436536SAndroid Build Coastguard Worker case 64:
750*e5436536SAndroid Build Coastguard Worker frameLengthFlag = 0;
751*e5436536SAndroid Build Coastguard Worker break;
752*e5436536SAndroid Build Coastguard Worker case 480:
753*e5436536SAndroid Build Coastguard Worker case 240:
754*e5436536SAndroid Build Coastguard Worker case 160:
755*e5436536SAndroid Build Coastguard Worker case 120:
756*e5436536SAndroid Build Coastguard Worker case 60:
757*e5436536SAndroid Build Coastguard Worker frameLengthFlag = 1;
758*e5436536SAndroid Build Coastguard Worker break;
759*e5436536SAndroid Build Coastguard Worker }
760*e5436536SAndroid Build Coastguard Worker
761*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, frameLengthFlag, 1);
762*e5436536SAndroid Build Coastguard Worker
763*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, (config->flags & CC_VCB11) ? 1 : 0, 1);
764*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, (config->flags & CC_RVLC) ? 1 : 0, 1);
765*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, (config->flags & CC_HCR) ? 1 : 0, 1);
766*e5436536SAndroid Build Coastguard Worker
767*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, (config->flags & CC_SBR) ? 1 : 0, 1); /* SBR header flag */
768*e5436536SAndroid Build Coastguard Worker if ((config->flags & CC_SBR)) {
769*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, (config->samplingRate == config->extSamplingRate) ? 0 : 1,
770*e5436536SAndroid Build Coastguard Worker 1); /* Samplerate Flag */
771*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, (config->flags & CC_SBRCRC) ? 1 : 0, 1); /* SBR CRC flag*/
772*e5436536SAndroid Build Coastguard Worker
773*e5436536SAndroid Build Coastguard Worker if (cb->cbSbr != NULL) {
774*e5436536SAndroid Build Coastguard Worker const PCE_CONFIGURATION *pPce;
775*e5436536SAndroid Build Coastguard Worker int e, sbrElementIndex = 0;
776*e5436536SAndroid Build Coastguard Worker
777*e5436536SAndroid Build Coastguard Worker pPce = getPceEntry(config->channelMode);
778*e5436536SAndroid Build Coastguard Worker
779*e5436536SAndroid Build Coastguard Worker for (e = 0; e < pPce->num_front_channel_elements +
780*e5436536SAndroid Build Coastguard Worker pPce->num_side_channel_elements +
781*e5436536SAndroid Build Coastguard Worker pPce->num_back_channel_elements +
782*e5436536SAndroid Build Coastguard Worker pPce->num_lfe_channel_elements;
783*e5436536SAndroid Build Coastguard Worker e++) {
784*e5436536SAndroid Build Coastguard Worker if ((pPce->pEl_type[e] == ID_SCE) || (pPce->pEl_type[e] == ID_CPE)) {
785*e5436536SAndroid Build Coastguard Worker cb->cbSbr(cb->cbSbrData, hBs, 0, 0, 0, config->aot, pPce->pEl_type[e],
786*e5436536SAndroid Build Coastguard Worker sbrElementIndex, 0, 0, 0, NULL, 1);
787*e5436536SAndroid Build Coastguard Worker sbrElementIndex++;
788*e5436536SAndroid Build Coastguard Worker }
789*e5436536SAndroid Build Coastguard Worker }
790*e5436536SAndroid Build Coastguard Worker }
791*e5436536SAndroid Build Coastguard Worker }
792*e5436536SAndroid Build Coastguard Worker
793*e5436536SAndroid Build Coastguard Worker if ((config->flags & CC_SAC) && (cb->cbSsc != NULL)) {
794*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, ELDEXT_LDSAC, 4);
795*e5436536SAndroid Build Coastguard Worker
796*e5436536SAndroid Build Coastguard Worker const INT eldExtLen =
797*e5436536SAndroid Build Coastguard Worker (cb->cbSsc(cb->cbSscData, NULL, config->aot, config->extSamplingRate, 0,
798*e5436536SAndroid Build Coastguard Worker 0, 0, 0, 0, 0, NULL) +
799*e5436536SAndroid Build Coastguard Worker 7) >>
800*e5436536SAndroid Build Coastguard Worker 3;
801*e5436536SAndroid Build Coastguard Worker INT cnt = eldExtLen;
802*e5436536SAndroid Build Coastguard Worker
803*e5436536SAndroid Build Coastguard Worker if (cnt < 0xF) {
804*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, cnt, 4);
805*e5436536SAndroid Build Coastguard Worker } else {
806*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, 0xF, 4);
807*e5436536SAndroid Build Coastguard Worker cnt -= 0xF;
808*e5436536SAndroid Build Coastguard Worker
809*e5436536SAndroid Build Coastguard Worker if (cnt < 0xFF) {
810*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, cnt, 8);
811*e5436536SAndroid Build Coastguard Worker } else {
812*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, 0xFF, 8);
813*e5436536SAndroid Build Coastguard Worker cnt -= 0xFF;
814*e5436536SAndroid Build Coastguard Worker
815*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(cnt <= 0xFFFF);
816*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, cnt, 16);
817*e5436536SAndroid Build Coastguard Worker }
818*e5436536SAndroid Build Coastguard Worker }
819*e5436536SAndroid Build Coastguard Worker
820*e5436536SAndroid Build Coastguard Worker cb->cbSsc(cb->cbSscData, hBs, config->aot, config->extSamplingRate, 0, 0, 0,
821*e5436536SAndroid Build Coastguard Worker 0, 0, 0, NULL);
822*e5436536SAndroid Build Coastguard Worker }
823*e5436536SAndroid Build Coastguard Worker
824*e5436536SAndroid Build Coastguard Worker if (config->downscaleSamplingRate != 0 &&
825*e5436536SAndroid Build Coastguard Worker config->downscaleSamplingRate != config->extSamplingRate) {
826*e5436536SAndroid Build Coastguard Worker /* downscale active */
827*e5436536SAndroid Build Coastguard Worker
828*e5436536SAndroid Build Coastguard Worker /* eldExtLenDsc: Number of bytes for the ELD downscale extension (srIdx
829*e5436536SAndroid Build Coastguard Worker needs 1 byte
830*e5436536SAndroid Build Coastguard Worker + downscaleSamplingRate needs additional 3 bytes) */
831*e5436536SAndroid Build Coastguard Worker int eldExtLenDsc = 1;
832*e5436536SAndroid Build Coastguard Worker int downscaleSamplingRate = config->downscaleSamplingRate;
833*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, ELDEXT_DOWNSCALEINFO, 4); /* ELDEXT_DOWNSCALEINFO */
834*e5436536SAndroid Build Coastguard Worker
835*e5436536SAndroid Build Coastguard Worker if ((downscaleSamplingRate != 96000) && (downscaleSamplingRate != 88200) &&
836*e5436536SAndroid Build Coastguard Worker (downscaleSamplingRate != 64000) && (downscaleSamplingRate != 48000) &&
837*e5436536SAndroid Build Coastguard Worker (downscaleSamplingRate != 44100) && (downscaleSamplingRate != 32000) &&
838*e5436536SAndroid Build Coastguard Worker (downscaleSamplingRate != 24000) && (downscaleSamplingRate != 22050) &&
839*e5436536SAndroid Build Coastguard Worker (downscaleSamplingRate != 16000) && (downscaleSamplingRate != 12000) &&
840*e5436536SAndroid Build Coastguard Worker (downscaleSamplingRate != 11025) && (downscaleSamplingRate != 8000) &&
841*e5436536SAndroid Build Coastguard Worker (downscaleSamplingRate != 7350)) {
842*e5436536SAndroid Build Coastguard Worker eldExtLenDsc = 4; /* length extends to 4 if downscaleSamplingRate's value
843*e5436536SAndroid Build Coastguard Worker is not one of the listed values */
844*e5436536SAndroid Build Coastguard Worker }
845*e5436536SAndroid Build Coastguard Worker
846*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, eldExtLenDsc, 4);
847*e5436536SAndroid Build Coastguard Worker writeSampleRate(hBs, downscaleSamplingRate, 4);
848*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, 0x0, 4); /* fill_nibble */
849*e5436536SAndroid Build Coastguard Worker }
850*e5436536SAndroid Build Coastguard Worker
851*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, ELDEXT_TERM, 4); /* ELDEXT_TERM */
852*e5436536SAndroid Build Coastguard Worker
853*e5436536SAndroid Build Coastguard Worker return 0;
854*e5436536SAndroid Build Coastguard Worker }
855*e5436536SAndroid Build Coastguard Worker
transportEnc_writeUsacSpecificConfig(HANDLE_FDK_BITSTREAM hBs,int extFlag,CODER_CONFIG * cc,CSTpCallBacks * cb)856*e5436536SAndroid Build Coastguard Worker static int transportEnc_writeUsacSpecificConfig(HANDLE_FDK_BITSTREAM hBs,
857*e5436536SAndroid Build Coastguard Worker int extFlag, CODER_CONFIG *cc,
858*e5436536SAndroid Build Coastguard Worker CSTpCallBacks *cb) {
859*e5436536SAndroid Build Coastguard Worker FDK_BITSTREAM usacConf;
860*e5436536SAndroid Build Coastguard Worker int usacConfigBits = cc->rawConfigBits;
861*e5436536SAndroid Build Coastguard Worker
862*e5436536SAndroid Build Coastguard Worker if ((usacConfigBits <= 0) ||
863*e5436536SAndroid Build Coastguard Worker ((usacConfigBits + 7) / 8 > (int)sizeof(cc->rawConfig))) {
864*e5436536SAndroid Build Coastguard Worker return TRANSPORTENC_UNSUPPORTED_FORMAT;
865*e5436536SAndroid Build Coastguard Worker }
866*e5436536SAndroid Build Coastguard Worker FDKinitBitStream(&usacConf, cc->rawConfig, BUFSIZE_DUMMY_VALUE,
867*e5436536SAndroid Build Coastguard Worker usacConfigBits, BS_READER);
868*e5436536SAndroid Build Coastguard Worker
869*e5436536SAndroid Build Coastguard Worker for (; usacConfigBits > 0; usacConfigBits--) {
870*e5436536SAndroid Build Coastguard Worker UINT tmp = FDKreadBit(&usacConf);
871*e5436536SAndroid Build Coastguard Worker FDKwriteBits(hBs, tmp, 1);
872*e5436536SAndroid Build Coastguard Worker }
873*e5436536SAndroid Build Coastguard Worker FDKsyncCache(hBs);
874*e5436536SAndroid Build Coastguard Worker
875*e5436536SAndroid Build Coastguard Worker return TRANSPORTENC_OK;
876*e5436536SAndroid Build Coastguard Worker }
877*e5436536SAndroid Build Coastguard Worker
transportEnc_writeASC(HANDLE_FDK_BITSTREAM asc,CODER_CONFIG * config,CSTpCallBacks * cb)878*e5436536SAndroid Build Coastguard Worker int transportEnc_writeASC(HANDLE_FDK_BITSTREAM asc, CODER_CONFIG *config,
879*e5436536SAndroid Build Coastguard Worker CSTpCallBacks *cb) {
880*e5436536SAndroid Build Coastguard Worker UINT extFlag = 0;
881*e5436536SAndroid Build Coastguard Worker int err;
882*e5436536SAndroid Build Coastguard Worker int epConfig = 0;
883*e5436536SAndroid Build Coastguard Worker
884*e5436536SAndroid Build Coastguard Worker /* Required for the PCE. */
885*e5436536SAndroid Build Coastguard Worker UINT alignAnchor = FDKgetValidBits(asc);
886*e5436536SAndroid Build Coastguard Worker
887*e5436536SAndroid Build Coastguard Worker /* Extension Flag: Shall be 1 for aot = 17,19,20,21,22,23,39 */
888*e5436536SAndroid Build Coastguard Worker switch (config->aot) {
889*e5436536SAndroid Build Coastguard Worker case AOT_ER_AAC_LC:
890*e5436536SAndroid Build Coastguard Worker case AOT_ER_AAC_LTP:
891*e5436536SAndroid Build Coastguard Worker case AOT_ER_AAC_SCAL:
892*e5436536SAndroid Build Coastguard Worker case AOT_ER_TWIN_VQ:
893*e5436536SAndroid Build Coastguard Worker case AOT_ER_BSAC:
894*e5436536SAndroid Build Coastguard Worker case AOT_ER_AAC_LD:
895*e5436536SAndroid Build Coastguard Worker case AOT_ER_AAC_ELD:
896*e5436536SAndroid Build Coastguard Worker case AOT_USAC:
897*e5436536SAndroid Build Coastguard Worker extFlag = 1;
898*e5436536SAndroid Build Coastguard Worker break;
899*e5436536SAndroid Build Coastguard Worker default:
900*e5436536SAndroid Build Coastguard Worker break;
901*e5436536SAndroid Build Coastguard Worker }
902*e5436536SAndroid Build Coastguard Worker
903*e5436536SAndroid Build Coastguard Worker if (config->sbrSignaling == SIG_EXPLICIT_HIERARCHICAL && config->sbrPresent)
904*e5436536SAndroid Build Coastguard Worker writeAot(asc, config->extAOT);
905*e5436536SAndroid Build Coastguard Worker else
906*e5436536SAndroid Build Coastguard Worker writeAot(asc, config->aot);
907*e5436536SAndroid Build Coastguard Worker
908*e5436536SAndroid Build Coastguard Worker /* In case of USAC it is the output not the core sampling rate */
909*e5436536SAndroid Build Coastguard Worker writeSampleRate(asc, config->samplingRate, 4);
910*e5436536SAndroid Build Coastguard Worker
911*e5436536SAndroid Build Coastguard Worker /* Try to guess a reasonable channel mode if not given */
912*e5436536SAndroid Build Coastguard Worker if (config->channelMode == MODE_INVALID) {
913*e5436536SAndroid Build Coastguard Worker config->channelMode = transportEnc_GetChannelMode(config->noChannels);
914*e5436536SAndroid Build Coastguard Worker if (config->channelMode == MODE_INVALID) return -1;
915*e5436536SAndroid Build Coastguard Worker }
916*e5436536SAndroid Build Coastguard Worker
917*e5436536SAndroid Build Coastguard Worker FDKwriteBits(
918*e5436536SAndroid Build Coastguard Worker asc, getChannelConfig(config->channelMode, config->channelConfigZero), 4);
919*e5436536SAndroid Build Coastguard Worker
920*e5436536SAndroid Build Coastguard Worker if (config->sbrSignaling == SIG_EXPLICIT_HIERARCHICAL && config->sbrPresent) {
921*e5436536SAndroid Build Coastguard Worker writeSampleRate(asc, config->extSamplingRate, 4);
922*e5436536SAndroid Build Coastguard Worker writeAot(asc, config->aot);
923*e5436536SAndroid Build Coastguard Worker }
924*e5436536SAndroid Build Coastguard Worker
925*e5436536SAndroid Build Coastguard Worker switch (config->aot) {
926*e5436536SAndroid Build Coastguard Worker case AOT_AAC_MAIN:
927*e5436536SAndroid Build Coastguard Worker case AOT_AAC_LC:
928*e5436536SAndroid Build Coastguard Worker case AOT_AAC_SSR:
929*e5436536SAndroid Build Coastguard Worker case AOT_AAC_LTP:
930*e5436536SAndroid Build Coastguard Worker case AOT_AAC_SCAL:
931*e5436536SAndroid Build Coastguard Worker case AOT_TWIN_VQ:
932*e5436536SAndroid Build Coastguard Worker case AOT_ER_AAC_LC:
933*e5436536SAndroid Build Coastguard Worker case AOT_ER_AAC_LTP:
934*e5436536SAndroid Build Coastguard Worker case AOT_ER_AAC_SCAL:
935*e5436536SAndroid Build Coastguard Worker case AOT_ER_TWIN_VQ:
936*e5436536SAndroid Build Coastguard Worker case AOT_ER_BSAC:
937*e5436536SAndroid Build Coastguard Worker case AOT_ER_AAC_LD:
938*e5436536SAndroid Build Coastguard Worker err =
939*e5436536SAndroid Build Coastguard Worker transportEnc_writeGASpecificConfig(asc, config, extFlag, alignAnchor);
940*e5436536SAndroid Build Coastguard Worker if (err) return err;
941*e5436536SAndroid Build Coastguard Worker break;
942*e5436536SAndroid Build Coastguard Worker case AOT_ER_AAC_ELD:
943*e5436536SAndroid Build Coastguard Worker err = transportEnc_writeELDSpecificConfig(asc, config, epConfig, cb);
944*e5436536SAndroid Build Coastguard Worker if (err) return err;
945*e5436536SAndroid Build Coastguard Worker break;
946*e5436536SAndroid Build Coastguard Worker case AOT_USAC:
947*e5436536SAndroid Build Coastguard Worker err = transportEnc_writeUsacSpecificConfig(asc, extFlag, config, cb);
948*e5436536SAndroid Build Coastguard Worker if (err) {
949*e5436536SAndroid Build Coastguard Worker return err;
950*e5436536SAndroid Build Coastguard Worker }
951*e5436536SAndroid Build Coastguard Worker break;
952*e5436536SAndroid Build Coastguard Worker default:
953*e5436536SAndroid Build Coastguard Worker return -1;
954*e5436536SAndroid Build Coastguard Worker }
955*e5436536SAndroid Build Coastguard Worker
956*e5436536SAndroid Build Coastguard Worker switch (config->aot) {
957*e5436536SAndroid Build Coastguard Worker case AOT_ER_AAC_LC:
958*e5436536SAndroid Build Coastguard Worker case AOT_ER_AAC_LTP:
959*e5436536SAndroid Build Coastguard Worker case AOT_ER_AAC_SCAL:
960*e5436536SAndroid Build Coastguard Worker case AOT_ER_TWIN_VQ:
961*e5436536SAndroid Build Coastguard Worker case AOT_ER_BSAC:
962*e5436536SAndroid Build Coastguard Worker case AOT_ER_AAC_LD:
963*e5436536SAndroid Build Coastguard Worker case AOT_ER_CELP:
964*e5436536SAndroid Build Coastguard Worker case AOT_ER_HVXC:
965*e5436536SAndroid Build Coastguard Worker case AOT_ER_HILN:
966*e5436536SAndroid Build Coastguard Worker case AOT_ER_PARA:
967*e5436536SAndroid Build Coastguard Worker case AOT_ER_AAC_ELD:
968*e5436536SAndroid Build Coastguard Worker FDKwriteBits(asc, 0, 2); /* epconfig 0 */
969*e5436536SAndroid Build Coastguard Worker break;
970*e5436536SAndroid Build Coastguard Worker default:
971*e5436536SAndroid Build Coastguard Worker break;
972*e5436536SAndroid Build Coastguard Worker }
973*e5436536SAndroid Build Coastguard Worker
974*e5436536SAndroid Build Coastguard Worker /* backward compatible explicit signaling of extension AOT */
975*e5436536SAndroid Build Coastguard Worker if (config->sbrSignaling == SIG_EXPLICIT_BW_COMPATIBLE) {
976*e5436536SAndroid Build Coastguard Worker TP_ASC_EXTENSION_ID ascExtId = ASCEXT_UNKOWN;
977*e5436536SAndroid Build Coastguard Worker
978*e5436536SAndroid Build Coastguard Worker if (config->sbrPresent) {
979*e5436536SAndroid Build Coastguard Worker ascExtId = ASCEXT_SBR;
980*e5436536SAndroid Build Coastguard Worker FDKwriteBits(asc, ascExtId, 11);
981*e5436536SAndroid Build Coastguard Worker writeAot(asc, config->extAOT);
982*e5436536SAndroid Build Coastguard Worker FDKwriteBits(asc, 1, 1); /* sbrPresentFlag=1 */
983*e5436536SAndroid Build Coastguard Worker writeSampleRate(asc, config->extSamplingRate, 4);
984*e5436536SAndroid Build Coastguard Worker if (config->psPresent) {
985*e5436536SAndroid Build Coastguard Worker ascExtId = ASCEXT_PS;
986*e5436536SAndroid Build Coastguard Worker FDKwriteBits(asc, ascExtId, 11);
987*e5436536SAndroid Build Coastguard Worker FDKwriteBits(asc, 1, 1); /* psPresentFlag=1 */
988*e5436536SAndroid Build Coastguard Worker }
989*e5436536SAndroid Build Coastguard Worker }
990*e5436536SAndroid Build Coastguard Worker }
991*e5436536SAndroid Build Coastguard Worker
992*e5436536SAndroid Build Coastguard Worker /* Make sure all bits are sync'ed */
993*e5436536SAndroid Build Coastguard Worker FDKsyncCache(asc);
994*e5436536SAndroid Build Coastguard Worker
995*e5436536SAndroid Build Coastguard Worker return 0;
996*e5436536SAndroid Build Coastguard Worker }
997