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 - 2018 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 /**************************** AAC decoder 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 /*!
104*e5436536SAndroid Build Coastguard Worker \file
105*e5436536SAndroid Build Coastguard Worker \brief rvlc concealment
106*e5436536SAndroid Build Coastguard Worker \author Josef Hoepfl
107*e5436536SAndroid Build Coastguard Worker */
108*e5436536SAndroid Build Coastguard Worker
109*e5436536SAndroid Build Coastguard Worker #include "rvlcconceal.h"
110*e5436536SAndroid Build Coastguard Worker
111*e5436536SAndroid Build Coastguard Worker #include "block.h"
112*e5436536SAndroid Build Coastguard Worker #include "rvlc.h"
113*e5436536SAndroid Build Coastguard Worker
114*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
115*e5436536SAndroid Build Coastguard Worker function: calcRefValFwd
116*e5436536SAndroid Build Coastguard Worker
117*e5436536SAndroid Build Coastguard Worker description: The function determines the scalefactor which is closed to the
118*e5436536SAndroid Build Coastguard Worker scalefactorband conceal_min. The same is done for intensity data and noise
119*e5436536SAndroid Build Coastguard Worker energies.
120*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
121*e5436536SAndroid Build Coastguard Worker output: - reference value scf
122*e5436536SAndroid Build Coastguard Worker - reference value internsity data
123*e5436536SAndroid Build Coastguard Worker - reference value noise energy
124*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
125*e5436536SAndroid Build Coastguard Worker return: -
126*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
127*e5436536SAndroid Build Coastguard Worker */
128*e5436536SAndroid Build Coastguard Worker
calcRefValFwd(CErRvlcInfo * pRvlc,CAacDecoderChannelInfo * pAacDecoderChannelInfo,int * refIsFwd,int * refNrgFwd,int * refScfFwd)129*e5436536SAndroid Build Coastguard Worker static void calcRefValFwd(CErRvlcInfo *pRvlc,
130*e5436536SAndroid Build Coastguard Worker CAacDecoderChannelInfo *pAacDecoderChannelInfo,
131*e5436536SAndroid Build Coastguard Worker int *refIsFwd, int *refNrgFwd, int *refScfFwd) {
132*e5436536SAndroid Build Coastguard Worker int band, bnds, group, startBand;
133*e5436536SAndroid Build Coastguard Worker int idIs, idNrg, idScf;
134*e5436536SAndroid Build Coastguard Worker int conceal_min, conceal_group_min;
135*e5436536SAndroid Build Coastguard Worker int MaximumScaleFactorBands;
136*e5436536SAndroid Build Coastguard Worker
137*e5436536SAndroid Build Coastguard Worker if (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == BLOCK_SHORT)
138*e5436536SAndroid Build Coastguard Worker MaximumScaleFactorBands = 16;
139*e5436536SAndroid Build Coastguard Worker else
140*e5436536SAndroid Build Coastguard Worker MaximumScaleFactorBands = 64;
141*e5436536SAndroid Build Coastguard Worker
142*e5436536SAndroid Build Coastguard Worker conceal_min = pRvlc->conceal_min % MaximumScaleFactorBands;
143*e5436536SAndroid Build Coastguard Worker conceal_group_min = pRvlc->conceal_min / MaximumScaleFactorBands;
144*e5436536SAndroid Build Coastguard Worker
145*e5436536SAndroid Build Coastguard Worker /* calculate first reference value for approach in forward direction */
146*e5436536SAndroid Build Coastguard Worker idIs = idNrg = idScf = 1;
147*e5436536SAndroid Build Coastguard Worker
148*e5436536SAndroid Build Coastguard Worker /* set reference values */
149*e5436536SAndroid Build Coastguard Worker *refIsFwd = -SF_OFFSET;
150*e5436536SAndroid Build Coastguard Worker *refNrgFwd = pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain -
151*e5436536SAndroid Build Coastguard Worker SF_OFFSET - 90 - 256;
152*e5436536SAndroid Build Coastguard Worker *refScfFwd =
153*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain - SF_OFFSET;
154*e5436536SAndroid Build Coastguard Worker
155*e5436536SAndroid Build Coastguard Worker startBand = conceal_min - 1;
156*e5436536SAndroid Build Coastguard Worker for (group = conceal_group_min; group >= 0; group--) {
157*e5436536SAndroid Build Coastguard Worker for (band = startBand; band >= 0; band--) {
158*e5436536SAndroid Build Coastguard Worker bnds = 16 * group + band;
159*e5436536SAndroid Build Coastguard Worker switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) {
160*e5436536SAndroid Build Coastguard Worker case ZERO_HCB:
161*e5436536SAndroid Build Coastguard Worker break;
162*e5436536SAndroid Build Coastguard Worker case INTENSITY_HCB:
163*e5436536SAndroid Build Coastguard Worker case INTENSITY_HCB2:
164*e5436536SAndroid Build Coastguard Worker if (idIs) {
165*e5436536SAndroid Build Coastguard Worker *refIsFwd =
166*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
167*e5436536SAndroid Build Coastguard Worker idIs = 0; /* reference value has been set */
168*e5436536SAndroid Build Coastguard Worker }
169*e5436536SAndroid Build Coastguard Worker break;
170*e5436536SAndroid Build Coastguard Worker case NOISE_HCB:
171*e5436536SAndroid Build Coastguard Worker if (idNrg) {
172*e5436536SAndroid Build Coastguard Worker *refNrgFwd =
173*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
174*e5436536SAndroid Build Coastguard Worker idNrg = 0; /* reference value has been set */
175*e5436536SAndroid Build Coastguard Worker }
176*e5436536SAndroid Build Coastguard Worker break;
177*e5436536SAndroid Build Coastguard Worker default:
178*e5436536SAndroid Build Coastguard Worker if (idScf) {
179*e5436536SAndroid Build Coastguard Worker *refScfFwd =
180*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
181*e5436536SAndroid Build Coastguard Worker idScf = 0; /* reference value has been set */
182*e5436536SAndroid Build Coastguard Worker }
183*e5436536SAndroid Build Coastguard Worker break;
184*e5436536SAndroid Build Coastguard Worker }
185*e5436536SAndroid Build Coastguard Worker }
186*e5436536SAndroid Build Coastguard Worker startBand = pRvlc->maxSfbTransmitted - 1;
187*e5436536SAndroid Build Coastguard Worker }
188*e5436536SAndroid Build Coastguard Worker }
189*e5436536SAndroid Build Coastguard Worker
190*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
191*e5436536SAndroid Build Coastguard Worker function: calcRefValBwd
192*e5436536SAndroid Build Coastguard Worker
193*e5436536SAndroid Build Coastguard Worker description: The function determines the scalefactor which is closed to the
194*e5436536SAndroid Build Coastguard Worker scalefactorband conceal_max. The same is done for intensity data and noise
195*e5436536SAndroid Build Coastguard Worker energies.
196*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
197*e5436536SAndroid Build Coastguard Worker output: - reference value scf
198*e5436536SAndroid Build Coastguard Worker - reference value internsity data
199*e5436536SAndroid Build Coastguard Worker - reference value noise energy
200*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
201*e5436536SAndroid Build Coastguard Worker return: -
202*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
203*e5436536SAndroid Build Coastguard Worker */
204*e5436536SAndroid Build Coastguard Worker
calcRefValBwd(CErRvlcInfo * pRvlc,CAacDecoderChannelInfo * pAacDecoderChannelInfo,int * refIsBwd,int * refNrgBwd,int * refScfBwd)205*e5436536SAndroid Build Coastguard Worker static void calcRefValBwd(CErRvlcInfo *pRvlc,
206*e5436536SAndroid Build Coastguard Worker CAacDecoderChannelInfo *pAacDecoderChannelInfo,
207*e5436536SAndroid Build Coastguard Worker int *refIsBwd, int *refNrgBwd, int *refScfBwd) {
208*e5436536SAndroid Build Coastguard Worker int band, bnds, group, startBand;
209*e5436536SAndroid Build Coastguard Worker int idIs, idNrg, idScf;
210*e5436536SAndroid Build Coastguard Worker int conceal_max, conceal_group_max;
211*e5436536SAndroid Build Coastguard Worker int MaximumScaleFactorBands;
212*e5436536SAndroid Build Coastguard Worker
213*e5436536SAndroid Build Coastguard Worker if (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == BLOCK_SHORT)
214*e5436536SAndroid Build Coastguard Worker MaximumScaleFactorBands = 16;
215*e5436536SAndroid Build Coastguard Worker else
216*e5436536SAndroid Build Coastguard Worker MaximumScaleFactorBands = 64;
217*e5436536SAndroid Build Coastguard Worker
218*e5436536SAndroid Build Coastguard Worker conceal_max = pRvlc->conceal_max % MaximumScaleFactorBands;
219*e5436536SAndroid Build Coastguard Worker conceal_group_max = pRvlc->conceal_max / MaximumScaleFactorBands;
220*e5436536SAndroid Build Coastguard Worker
221*e5436536SAndroid Build Coastguard Worker /* calculate first reference value for approach in backward direction */
222*e5436536SAndroid Build Coastguard Worker idIs = idNrg = idScf = 1;
223*e5436536SAndroid Build Coastguard Worker
224*e5436536SAndroid Build Coastguard Worker /* set reference values */
225*e5436536SAndroid Build Coastguard Worker *refIsBwd = pRvlc->dpcm_is_last_position - SF_OFFSET;
226*e5436536SAndroid Build Coastguard Worker *refNrgBwd = pRvlc->rev_global_gain + pRvlc->dpcm_noise_last_position -
227*e5436536SAndroid Build Coastguard Worker SF_OFFSET - 90 - 256 + pRvlc->dpcm_noise_nrg;
228*e5436536SAndroid Build Coastguard Worker *refScfBwd = pRvlc->rev_global_gain - SF_OFFSET;
229*e5436536SAndroid Build Coastguard Worker
230*e5436536SAndroid Build Coastguard Worker startBand = conceal_max + 1;
231*e5436536SAndroid Build Coastguard Worker
232*e5436536SAndroid Build Coastguard Worker /* if needed, re-set reference values */
233*e5436536SAndroid Build Coastguard Worker for (group = conceal_group_max; group < pRvlc->numWindowGroups; group++) {
234*e5436536SAndroid Build Coastguard Worker for (band = startBand; band < pRvlc->maxSfbTransmitted; band++) {
235*e5436536SAndroid Build Coastguard Worker bnds = 16 * group + band;
236*e5436536SAndroid Build Coastguard Worker switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) {
237*e5436536SAndroid Build Coastguard Worker case ZERO_HCB:
238*e5436536SAndroid Build Coastguard Worker break;
239*e5436536SAndroid Build Coastguard Worker case INTENSITY_HCB:
240*e5436536SAndroid Build Coastguard Worker case INTENSITY_HCB2:
241*e5436536SAndroid Build Coastguard Worker if (idIs) {
242*e5436536SAndroid Build Coastguard Worker *refIsBwd =
243*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
244*e5436536SAndroid Build Coastguard Worker idIs = 0; /* reference value has been set */
245*e5436536SAndroid Build Coastguard Worker }
246*e5436536SAndroid Build Coastguard Worker break;
247*e5436536SAndroid Build Coastguard Worker case NOISE_HCB:
248*e5436536SAndroid Build Coastguard Worker if (idNrg) {
249*e5436536SAndroid Build Coastguard Worker *refNrgBwd =
250*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
251*e5436536SAndroid Build Coastguard Worker idNrg = 0; /* reference value has been set */
252*e5436536SAndroid Build Coastguard Worker }
253*e5436536SAndroid Build Coastguard Worker break;
254*e5436536SAndroid Build Coastguard Worker default:
255*e5436536SAndroid Build Coastguard Worker if (idScf) {
256*e5436536SAndroid Build Coastguard Worker *refScfBwd =
257*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
258*e5436536SAndroid Build Coastguard Worker idScf = 0; /* reference value has been set */
259*e5436536SAndroid Build Coastguard Worker }
260*e5436536SAndroid Build Coastguard Worker break;
261*e5436536SAndroid Build Coastguard Worker }
262*e5436536SAndroid Build Coastguard Worker }
263*e5436536SAndroid Build Coastguard Worker startBand = 0;
264*e5436536SAndroid Build Coastguard Worker }
265*e5436536SAndroid Build Coastguard Worker }
266*e5436536SAndroid Build Coastguard Worker
267*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
268*e5436536SAndroid Build Coastguard Worker function: BidirectionalEstimation_UseLowerScfOfCurrentFrame
269*e5436536SAndroid Build Coastguard Worker
270*e5436536SAndroid Build Coastguard Worker description: This approach by means of bidirectional estimation is generally
271*e5436536SAndroid Build Coastguard Worker performed when a single bit error has been detected, the bit error can be
272*e5436536SAndroid Build Coastguard Worker isolated between 'conceal_min' and 'conceal_max' and the 'sf_concealment' flag
273*e5436536SAndroid Build Coastguard Worker is not set. The sets of scalefactors decoded in forward and backward direction
274*e5436536SAndroid Build Coastguard Worker are compared with each other. The smaller scalefactor will be considered as the
275*e5436536SAndroid Build Coastguard Worker correct one respectively. The reconstruction of the scalefactors with this
276*e5436536SAndroid Build Coastguard Worker approach archieve good results in audio quality. The strategy must be applied to
277*e5436536SAndroid Build Coastguard Worker scalefactors, intensity data and noise energy seperately.
278*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
279*e5436536SAndroid Build Coastguard Worker output: Concealed scalefactor, noise energy and intensity data between
280*e5436536SAndroid Build Coastguard Worker conceal_min and conceal_max
281*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
282*e5436536SAndroid Build Coastguard Worker return: -
283*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
284*e5436536SAndroid Build Coastguard Worker */
285*e5436536SAndroid Build Coastguard Worker
BidirectionalEstimation_UseLowerScfOfCurrentFrame(CAacDecoderChannelInfo * pAacDecoderChannelInfo)286*e5436536SAndroid Build Coastguard Worker void BidirectionalEstimation_UseLowerScfOfCurrentFrame(
287*e5436536SAndroid Build Coastguard Worker CAacDecoderChannelInfo *pAacDecoderChannelInfo) {
288*e5436536SAndroid Build Coastguard Worker CErRvlcInfo *pRvlc =
289*e5436536SAndroid Build Coastguard Worker &pAacDecoderChannelInfo->pComData->overlay.aac.erRvlcInfo;
290*e5436536SAndroid Build Coastguard Worker int band, bnds, startBand, endBand, group;
291*e5436536SAndroid Build Coastguard Worker int conceal_min, conceal_max;
292*e5436536SAndroid Build Coastguard Worker int conceal_group_min, conceal_group_max;
293*e5436536SAndroid Build Coastguard Worker int MaximumScaleFactorBands;
294*e5436536SAndroid Build Coastguard Worker
295*e5436536SAndroid Build Coastguard Worker if (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == BLOCK_SHORT) {
296*e5436536SAndroid Build Coastguard Worker MaximumScaleFactorBands = 16;
297*e5436536SAndroid Build Coastguard Worker } else {
298*e5436536SAndroid Build Coastguard Worker MaximumScaleFactorBands = 64;
299*e5436536SAndroid Build Coastguard Worker }
300*e5436536SAndroid Build Coastguard Worker
301*e5436536SAndroid Build Coastguard Worker /* If an error was detected just in forward or backward direction, set the
302*e5436536SAndroid Build Coastguard Worker corresponding border for concealment to a appropriate scalefactor band. The
303*e5436536SAndroid Build Coastguard Worker border is set to first or last sfb respectively, because the error will
304*e5436536SAndroid Build Coastguard Worker possibly not follow directly after the corrupt bit but just after decoding
305*e5436536SAndroid Build Coastguard Worker some more (wrong) scalefactors. */
306*e5436536SAndroid Build Coastguard Worker if (pRvlc->conceal_min == CONCEAL_MIN_INIT) pRvlc->conceal_min = 0;
307*e5436536SAndroid Build Coastguard Worker
308*e5436536SAndroid Build Coastguard Worker if (pRvlc->conceal_max == CONCEAL_MAX_INIT)
309*e5436536SAndroid Build Coastguard Worker pRvlc->conceal_max =
310*e5436536SAndroid Build Coastguard Worker (pRvlc->numWindowGroups - 1) * 16 + pRvlc->maxSfbTransmitted - 1;
311*e5436536SAndroid Build Coastguard Worker
312*e5436536SAndroid Build Coastguard Worker conceal_min = pRvlc->conceal_min % MaximumScaleFactorBands;
313*e5436536SAndroid Build Coastguard Worker conceal_group_min = pRvlc->conceal_min / MaximumScaleFactorBands;
314*e5436536SAndroid Build Coastguard Worker conceal_max = pRvlc->conceal_max % MaximumScaleFactorBands;
315*e5436536SAndroid Build Coastguard Worker conceal_group_max = pRvlc->conceal_max / MaximumScaleFactorBands;
316*e5436536SAndroid Build Coastguard Worker
317*e5436536SAndroid Build Coastguard Worker if (pRvlc->conceal_min == pRvlc->conceal_max) {
318*e5436536SAndroid Build Coastguard Worker int refIsFwd, refNrgFwd, refScfFwd;
319*e5436536SAndroid Build Coastguard Worker int refIsBwd, refNrgBwd, refScfBwd;
320*e5436536SAndroid Build Coastguard Worker
321*e5436536SAndroid Build Coastguard Worker bnds = pRvlc->conceal_min;
322*e5436536SAndroid Build Coastguard Worker calcRefValFwd(pRvlc, pAacDecoderChannelInfo, &refIsFwd, &refNrgFwd,
323*e5436536SAndroid Build Coastguard Worker &refScfFwd);
324*e5436536SAndroid Build Coastguard Worker calcRefValBwd(pRvlc, pAacDecoderChannelInfo, &refIsBwd, &refNrgBwd,
325*e5436536SAndroid Build Coastguard Worker &refScfBwd);
326*e5436536SAndroid Build Coastguard Worker
327*e5436536SAndroid Build Coastguard Worker switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) {
328*e5436536SAndroid Build Coastguard Worker case ZERO_HCB:
329*e5436536SAndroid Build Coastguard Worker break;
330*e5436536SAndroid Build Coastguard Worker case INTENSITY_HCB:
331*e5436536SAndroid Build Coastguard Worker case INTENSITY_HCB2:
332*e5436536SAndroid Build Coastguard Worker if (refIsFwd < refIsBwd)
333*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = refIsFwd;
334*e5436536SAndroid Build Coastguard Worker else
335*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = refIsBwd;
336*e5436536SAndroid Build Coastguard Worker break;
337*e5436536SAndroid Build Coastguard Worker case NOISE_HCB:
338*e5436536SAndroid Build Coastguard Worker if (refNrgFwd < refNrgBwd)
339*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = refNrgFwd;
340*e5436536SAndroid Build Coastguard Worker else
341*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = refNrgBwd;
342*e5436536SAndroid Build Coastguard Worker break;
343*e5436536SAndroid Build Coastguard Worker default:
344*e5436536SAndroid Build Coastguard Worker if (refScfFwd < refScfBwd)
345*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = refScfFwd;
346*e5436536SAndroid Build Coastguard Worker else
347*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = refScfBwd;
348*e5436536SAndroid Build Coastguard Worker break;
349*e5436536SAndroid Build Coastguard Worker }
350*e5436536SAndroid Build Coastguard Worker } else {
351*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac
352*e5436536SAndroid Build Coastguard Worker .aRvlcScfFwd[pRvlc->conceal_max] =
353*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac
354*e5436536SAndroid Build Coastguard Worker .aRvlcScfBwd[pRvlc->conceal_max];
355*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac
356*e5436536SAndroid Build Coastguard Worker .aRvlcScfBwd[pRvlc->conceal_min] =
357*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac
358*e5436536SAndroid Build Coastguard Worker .aRvlcScfFwd[pRvlc->conceal_min];
359*e5436536SAndroid Build Coastguard Worker
360*e5436536SAndroid Build Coastguard Worker /* consider the smaller of the forward and backward decoded value as the
361*e5436536SAndroid Build Coastguard Worker * correct one */
362*e5436536SAndroid Build Coastguard Worker startBand = conceal_min;
363*e5436536SAndroid Build Coastguard Worker if (conceal_group_min == conceal_group_max)
364*e5436536SAndroid Build Coastguard Worker endBand = conceal_max;
365*e5436536SAndroid Build Coastguard Worker else
366*e5436536SAndroid Build Coastguard Worker endBand = pRvlc->maxSfbTransmitted - 1;
367*e5436536SAndroid Build Coastguard Worker
368*e5436536SAndroid Build Coastguard Worker for (group = conceal_group_min; group <= conceal_group_max; group++) {
369*e5436536SAndroid Build Coastguard Worker for (band = startBand; band <= endBand; band++) {
370*e5436536SAndroid Build Coastguard Worker bnds = 16 * group + band;
371*e5436536SAndroid Build Coastguard Worker if (pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds] <
372*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds])
373*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
374*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
375*e5436536SAndroid Build Coastguard Worker else
376*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
377*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
378*e5436536SAndroid Build Coastguard Worker }
379*e5436536SAndroid Build Coastguard Worker startBand = 0;
380*e5436536SAndroid Build Coastguard Worker if ((group + 1) == conceal_group_max) endBand = conceal_max;
381*e5436536SAndroid Build Coastguard Worker }
382*e5436536SAndroid Build Coastguard Worker }
383*e5436536SAndroid Build Coastguard Worker
384*e5436536SAndroid Build Coastguard Worker /* now copy all data to the output buffer which needs not to be concealed */
385*e5436536SAndroid Build Coastguard Worker if (conceal_group_min == 0)
386*e5436536SAndroid Build Coastguard Worker endBand = conceal_min;
387*e5436536SAndroid Build Coastguard Worker else
388*e5436536SAndroid Build Coastguard Worker endBand = pRvlc->maxSfbTransmitted;
389*e5436536SAndroid Build Coastguard Worker for (group = 0; group <= conceal_group_min; group++) {
390*e5436536SAndroid Build Coastguard Worker for (band = 0; band < endBand; band++) {
391*e5436536SAndroid Build Coastguard Worker bnds = 16 * group + band;
392*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
393*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
394*e5436536SAndroid Build Coastguard Worker }
395*e5436536SAndroid Build Coastguard Worker if ((group + 1) == conceal_group_min) endBand = conceal_min;
396*e5436536SAndroid Build Coastguard Worker }
397*e5436536SAndroid Build Coastguard Worker
398*e5436536SAndroid Build Coastguard Worker startBand = conceal_max + 1;
399*e5436536SAndroid Build Coastguard Worker for (group = conceal_group_max; group < pRvlc->numWindowGroups; group++) {
400*e5436536SAndroid Build Coastguard Worker for (band = startBand; band < pRvlc->maxSfbTransmitted; band++) {
401*e5436536SAndroid Build Coastguard Worker bnds = 16 * group + band;
402*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
403*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
404*e5436536SAndroid Build Coastguard Worker }
405*e5436536SAndroid Build Coastguard Worker startBand = 0;
406*e5436536SAndroid Build Coastguard Worker }
407*e5436536SAndroid Build Coastguard Worker }
408*e5436536SAndroid Build Coastguard Worker
409*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
410*e5436536SAndroid Build Coastguard Worker function: BidirectionalEstimation_UseScfOfPrevFrameAsReference
411*e5436536SAndroid Build Coastguard Worker
412*e5436536SAndroid Build Coastguard Worker description: This approach by means of bidirectional estimation is generally
413*e5436536SAndroid Build Coastguard Worker performed when a single bit error has been detected, the bit error can be
414*e5436536SAndroid Build Coastguard Worker isolated between 'conceal_min' and 'conceal_max', the 'sf_concealment' flag is
415*e5436536SAndroid Build Coastguard Worker set and the previous frame has the same block type as the current frame. The
416*e5436536SAndroid Build Coastguard Worker scalefactor decoded in forward and backward direction and the scalefactor of the
417*e5436536SAndroid Build Coastguard Worker previous frame are compared with each other. The smaller scalefactor will be
418*e5436536SAndroid Build Coastguard Worker considered as the correct one. At this the codebook of the previous and current
419*e5436536SAndroid Build Coastguard Worker frame must be of the same set (scf, nrg, is) in each scalefactorband. Otherwise
420*e5436536SAndroid Build Coastguard Worker the scalefactor of the previous frame is not considered in the minimum
421*e5436536SAndroid Build Coastguard Worker calculation. The reconstruction of the scalefactors with this approach archieve
422*e5436536SAndroid Build Coastguard Worker good results in audio quality. The strategy must be applied to scalefactors,
423*e5436536SAndroid Build Coastguard Worker intensity data and noise energy seperately.
424*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
425*e5436536SAndroid Build Coastguard Worker output: Concealed scalefactor, noise energy and intensity data between
426*e5436536SAndroid Build Coastguard Worker conceal_min and conceal_max
427*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
428*e5436536SAndroid Build Coastguard Worker return: -
429*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
430*e5436536SAndroid Build Coastguard Worker */
431*e5436536SAndroid Build Coastguard Worker
BidirectionalEstimation_UseScfOfPrevFrameAsReference(CAacDecoderChannelInfo * pAacDecoderChannelInfo,CAacDecoderStaticChannelInfo * pAacDecoderStaticChannelInfo)432*e5436536SAndroid Build Coastguard Worker void BidirectionalEstimation_UseScfOfPrevFrameAsReference(
433*e5436536SAndroid Build Coastguard Worker CAacDecoderChannelInfo *pAacDecoderChannelInfo,
434*e5436536SAndroid Build Coastguard Worker CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo) {
435*e5436536SAndroid Build Coastguard Worker CErRvlcInfo *pRvlc =
436*e5436536SAndroid Build Coastguard Worker &pAacDecoderChannelInfo->pComData->overlay.aac.erRvlcInfo;
437*e5436536SAndroid Build Coastguard Worker int band, bnds, startBand, endBand, group;
438*e5436536SAndroid Build Coastguard Worker int conceal_min, conceal_max;
439*e5436536SAndroid Build Coastguard Worker int conceal_group_min, conceal_group_max;
440*e5436536SAndroid Build Coastguard Worker int MaximumScaleFactorBands;
441*e5436536SAndroid Build Coastguard Worker SHORT commonMin;
442*e5436536SAndroid Build Coastguard Worker
443*e5436536SAndroid Build Coastguard Worker if (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == BLOCK_SHORT) {
444*e5436536SAndroid Build Coastguard Worker MaximumScaleFactorBands = 16;
445*e5436536SAndroid Build Coastguard Worker } else {
446*e5436536SAndroid Build Coastguard Worker MaximumScaleFactorBands = 64;
447*e5436536SAndroid Build Coastguard Worker }
448*e5436536SAndroid Build Coastguard Worker
449*e5436536SAndroid Build Coastguard Worker /* If an error was detected just in forward or backward direction, set the
450*e5436536SAndroid Build Coastguard Worker corresponding border for concealment to a appropriate scalefactor band. The
451*e5436536SAndroid Build Coastguard Worker border is set to first or last sfb respectively, because the error will
452*e5436536SAndroid Build Coastguard Worker possibly not follow directly after the corrupt bit but just after decoding
453*e5436536SAndroid Build Coastguard Worker some more (wrong) scalefactors. */
454*e5436536SAndroid Build Coastguard Worker if (pRvlc->conceal_min == CONCEAL_MIN_INIT) pRvlc->conceal_min = 0;
455*e5436536SAndroid Build Coastguard Worker
456*e5436536SAndroid Build Coastguard Worker if (pRvlc->conceal_max == CONCEAL_MAX_INIT)
457*e5436536SAndroid Build Coastguard Worker pRvlc->conceal_max =
458*e5436536SAndroid Build Coastguard Worker (pRvlc->numWindowGroups - 1) * 16 + pRvlc->maxSfbTransmitted - 1;
459*e5436536SAndroid Build Coastguard Worker
460*e5436536SAndroid Build Coastguard Worker conceal_min = pRvlc->conceal_min % MaximumScaleFactorBands;
461*e5436536SAndroid Build Coastguard Worker conceal_group_min = pRvlc->conceal_min / MaximumScaleFactorBands;
462*e5436536SAndroid Build Coastguard Worker conceal_max = pRvlc->conceal_max % MaximumScaleFactorBands;
463*e5436536SAndroid Build Coastguard Worker conceal_group_max = pRvlc->conceal_max / MaximumScaleFactorBands;
464*e5436536SAndroid Build Coastguard Worker
465*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac
466*e5436536SAndroid Build Coastguard Worker .aRvlcScfFwd[pRvlc->conceal_max] =
467*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac
468*e5436536SAndroid Build Coastguard Worker .aRvlcScfBwd[pRvlc->conceal_max];
469*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac
470*e5436536SAndroid Build Coastguard Worker .aRvlcScfBwd[pRvlc->conceal_min] =
471*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac
472*e5436536SAndroid Build Coastguard Worker .aRvlcScfFwd[pRvlc->conceal_min];
473*e5436536SAndroid Build Coastguard Worker
474*e5436536SAndroid Build Coastguard Worker /* consider the smaller of the forward and backward decoded value as the
475*e5436536SAndroid Build Coastguard Worker * correct one */
476*e5436536SAndroid Build Coastguard Worker startBand = conceal_min;
477*e5436536SAndroid Build Coastguard Worker if (conceal_group_min == conceal_group_max)
478*e5436536SAndroid Build Coastguard Worker endBand = conceal_max;
479*e5436536SAndroid Build Coastguard Worker else
480*e5436536SAndroid Build Coastguard Worker endBand = pRvlc->maxSfbTransmitted - 1;
481*e5436536SAndroid Build Coastguard Worker
482*e5436536SAndroid Build Coastguard Worker for (group = conceal_group_min; group <= conceal_group_max; group++) {
483*e5436536SAndroid Build Coastguard Worker for (band = startBand; band <= endBand; band++) {
484*e5436536SAndroid Build Coastguard Worker bnds = 16 * group + band;
485*e5436536SAndroid Build Coastguard Worker switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) {
486*e5436536SAndroid Build Coastguard Worker case ZERO_HCB:
487*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = 0;
488*e5436536SAndroid Build Coastguard Worker break;
489*e5436536SAndroid Build Coastguard Worker
490*e5436536SAndroid Build Coastguard Worker case INTENSITY_HCB:
491*e5436536SAndroid Build Coastguard Worker case INTENSITY_HCB2:
492*e5436536SAndroid Build Coastguard Worker if ((pAacDecoderStaticChannelInfo->concealmentInfo
493*e5436536SAndroid Build Coastguard Worker .aRvlcPreviousCodebook[bnds] == INTENSITY_HCB) ||
494*e5436536SAndroid Build Coastguard Worker (pAacDecoderStaticChannelInfo->concealmentInfo
495*e5436536SAndroid Build Coastguard Worker .aRvlcPreviousCodebook[bnds] == INTENSITY_HCB2)) {
496*e5436536SAndroid Build Coastguard Worker commonMin = fMin(
497*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],
498*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac
499*e5436536SAndroid Build Coastguard Worker .aRvlcScfBwd[bnds]);
500*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
501*e5436536SAndroid Build Coastguard Worker fMin(commonMin, pAacDecoderStaticChannelInfo->concealmentInfo
502*e5436536SAndroid Build Coastguard Worker .aRvlcPreviousScaleFactor[bnds]);
503*e5436536SAndroid Build Coastguard Worker } else {
504*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = fMin(
505*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],
506*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac
507*e5436536SAndroid Build Coastguard Worker .aRvlcScfBwd[bnds]);
508*e5436536SAndroid Build Coastguard Worker }
509*e5436536SAndroid Build Coastguard Worker break;
510*e5436536SAndroid Build Coastguard Worker
511*e5436536SAndroid Build Coastguard Worker case NOISE_HCB:
512*e5436536SAndroid Build Coastguard Worker if (pAacDecoderStaticChannelInfo->concealmentInfo
513*e5436536SAndroid Build Coastguard Worker .aRvlcPreviousCodebook[bnds] == NOISE_HCB) {
514*e5436536SAndroid Build Coastguard Worker commonMin = fMin(
515*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],
516*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac
517*e5436536SAndroid Build Coastguard Worker .aRvlcScfBwd[bnds]);
518*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
519*e5436536SAndroid Build Coastguard Worker fMin(commonMin, pAacDecoderStaticChannelInfo->concealmentInfo
520*e5436536SAndroid Build Coastguard Worker .aRvlcPreviousScaleFactor[bnds]);
521*e5436536SAndroid Build Coastguard Worker } else {
522*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = fMin(
523*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],
524*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac
525*e5436536SAndroid Build Coastguard Worker .aRvlcScfBwd[bnds]);
526*e5436536SAndroid Build Coastguard Worker }
527*e5436536SAndroid Build Coastguard Worker break;
528*e5436536SAndroid Build Coastguard Worker
529*e5436536SAndroid Build Coastguard Worker default:
530*e5436536SAndroid Build Coastguard Worker if ((pAacDecoderStaticChannelInfo->concealmentInfo
531*e5436536SAndroid Build Coastguard Worker .aRvlcPreviousCodebook[bnds] != ZERO_HCB) &&
532*e5436536SAndroid Build Coastguard Worker (pAacDecoderStaticChannelInfo->concealmentInfo
533*e5436536SAndroid Build Coastguard Worker .aRvlcPreviousCodebook[bnds] != NOISE_HCB) &&
534*e5436536SAndroid Build Coastguard Worker (pAacDecoderStaticChannelInfo->concealmentInfo
535*e5436536SAndroid Build Coastguard Worker .aRvlcPreviousCodebook[bnds] != INTENSITY_HCB) &&
536*e5436536SAndroid Build Coastguard Worker (pAacDecoderStaticChannelInfo->concealmentInfo
537*e5436536SAndroid Build Coastguard Worker .aRvlcPreviousCodebook[bnds] != INTENSITY_HCB2)) {
538*e5436536SAndroid Build Coastguard Worker commonMin = fMin(
539*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],
540*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac
541*e5436536SAndroid Build Coastguard Worker .aRvlcScfBwd[bnds]);
542*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
543*e5436536SAndroid Build Coastguard Worker fMin(commonMin, pAacDecoderStaticChannelInfo->concealmentInfo
544*e5436536SAndroid Build Coastguard Worker .aRvlcPreviousScaleFactor[bnds]);
545*e5436536SAndroid Build Coastguard Worker } else {
546*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = fMin(
547*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],
548*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac
549*e5436536SAndroid Build Coastguard Worker .aRvlcScfBwd[bnds]);
550*e5436536SAndroid Build Coastguard Worker }
551*e5436536SAndroid Build Coastguard Worker break;
552*e5436536SAndroid Build Coastguard Worker }
553*e5436536SAndroid Build Coastguard Worker }
554*e5436536SAndroid Build Coastguard Worker startBand = 0;
555*e5436536SAndroid Build Coastguard Worker if ((group + 1) == conceal_group_max) endBand = conceal_max;
556*e5436536SAndroid Build Coastguard Worker }
557*e5436536SAndroid Build Coastguard Worker
558*e5436536SAndroid Build Coastguard Worker /* now copy all data to the output buffer which needs not to be concealed */
559*e5436536SAndroid Build Coastguard Worker if (conceal_group_min == 0)
560*e5436536SAndroid Build Coastguard Worker endBand = conceal_min;
561*e5436536SAndroid Build Coastguard Worker else
562*e5436536SAndroid Build Coastguard Worker endBand = pRvlc->maxSfbTransmitted;
563*e5436536SAndroid Build Coastguard Worker for (group = 0; group <= conceal_group_min; group++) {
564*e5436536SAndroid Build Coastguard Worker for (band = 0; band < endBand; band++) {
565*e5436536SAndroid Build Coastguard Worker bnds = 16 * group + band;
566*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
567*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
568*e5436536SAndroid Build Coastguard Worker }
569*e5436536SAndroid Build Coastguard Worker if ((group + 1) == conceal_group_min) endBand = conceal_min;
570*e5436536SAndroid Build Coastguard Worker }
571*e5436536SAndroid Build Coastguard Worker
572*e5436536SAndroid Build Coastguard Worker startBand = conceal_max + 1;
573*e5436536SAndroid Build Coastguard Worker for (group = conceal_group_max; group < pRvlc->numWindowGroups; group++) {
574*e5436536SAndroid Build Coastguard Worker for (band = startBand; band < pRvlc->maxSfbTransmitted; band++) {
575*e5436536SAndroid Build Coastguard Worker bnds = 16 * group + band;
576*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
577*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
578*e5436536SAndroid Build Coastguard Worker }
579*e5436536SAndroid Build Coastguard Worker startBand = 0;
580*e5436536SAndroid Build Coastguard Worker }
581*e5436536SAndroid Build Coastguard Worker }
582*e5436536SAndroid Build Coastguard Worker
583*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
584*e5436536SAndroid Build Coastguard Worker function: StatisticalEstimation
585*e5436536SAndroid Build Coastguard Worker
586*e5436536SAndroid Build Coastguard Worker description: This approach by means of statistical estimation is generally
587*e5436536SAndroid Build Coastguard Worker performed when both the start value and the end value are different and no
588*e5436536SAndroid Build Coastguard Worker further errors have been detected. Considering the forward and backward decoded
589*e5436536SAndroid Build Coastguard Worker scalefactors, the set with the lower scalefactors in sum will be considered as
590*e5436536SAndroid Build Coastguard Worker the correct one. The scalefactors are differentially encoded. Normally it would
591*e5436536SAndroid Build Coastguard Worker reach to compare one pair of the forward and backward decoded scalefactors to
592*e5436536SAndroid Build Coastguard Worker specify the lower set. But having detected no further errors does not
593*e5436536SAndroid Build Coastguard Worker necessarily mean the absence of errors. Therefore all scalefactors decoded in
594*e5436536SAndroid Build Coastguard Worker forward and backward direction are summed up seperately. The set with the lower
595*e5436536SAndroid Build Coastguard Worker sum will be used. The strategy must be applied to scalefactors, intensity data
596*e5436536SAndroid Build Coastguard Worker and noise energy seperately.
597*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
598*e5436536SAndroid Build Coastguard Worker output: Concealed scalefactor, noise energy and intensity data
599*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
600*e5436536SAndroid Build Coastguard Worker return: -
601*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
602*e5436536SAndroid Build Coastguard Worker */
603*e5436536SAndroid Build Coastguard Worker
StatisticalEstimation(CAacDecoderChannelInfo * pAacDecoderChannelInfo)604*e5436536SAndroid Build Coastguard Worker void StatisticalEstimation(CAacDecoderChannelInfo *pAacDecoderChannelInfo) {
605*e5436536SAndroid Build Coastguard Worker CErRvlcInfo *pRvlc =
606*e5436536SAndroid Build Coastguard Worker &pAacDecoderChannelInfo->pComData->overlay.aac.erRvlcInfo;
607*e5436536SAndroid Build Coastguard Worker int band, bnds, group;
608*e5436536SAndroid Build Coastguard Worker int sumIsFwd, sumIsBwd; /* sum of intensity data forward/backward */
609*e5436536SAndroid Build Coastguard Worker int sumNrgFwd, sumNrgBwd; /* sum of noise energy data forward/backward */
610*e5436536SAndroid Build Coastguard Worker int sumScfFwd, sumScfBwd; /* sum of scalefactor data forward/backward */
611*e5436536SAndroid Build Coastguard Worker int useIsFwd, useNrgFwd, useScfFwd; /* the flags signals the elements which
612*e5436536SAndroid Build Coastguard Worker are used for the final result */
613*e5436536SAndroid Build Coastguard Worker
614*e5436536SAndroid Build Coastguard Worker sumIsFwd = sumIsBwd = sumNrgFwd = sumNrgBwd = sumScfFwd = sumScfBwd = 0;
615*e5436536SAndroid Build Coastguard Worker useIsFwd = useNrgFwd = useScfFwd = 0;
616*e5436536SAndroid Build Coastguard Worker
617*e5436536SAndroid Build Coastguard Worker /* calculate sum of each group (scf,nrg,is) of forward and backward direction
618*e5436536SAndroid Build Coastguard Worker */
619*e5436536SAndroid Build Coastguard Worker for (group = 0; group < pRvlc->numWindowGroups; group++) {
620*e5436536SAndroid Build Coastguard Worker for (band = 0; band < pRvlc->maxSfbTransmitted; band++) {
621*e5436536SAndroid Build Coastguard Worker bnds = 16 * group + band;
622*e5436536SAndroid Build Coastguard Worker switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) {
623*e5436536SAndroid Build Coastguard Worker case ZERO_HCB:
624*e5436536SAndroid Build Coastguard Worker break;
625*e5436536SAndroid Build Coastguard Worker
626*e5436536SAndroid Build Coastguard Worker case INTENSITY_HCB:
627*e5436536SAndroid Build Coastguard Worker case INTENSITY_HCB2:
628*e5436536SAndroid Build Coastguard Worker sumIsFwd +=
629*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
630*e5436536SAndroid Build Coastguard Worker sumIsBwd +=
631*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
632*e5436536SAndroid Build Coastguard Worker break;
633*e5436536SAndroid Build Coastguard Worker
634*e5436536SAndroid Build Coastguard Worker case NOISE_HCB:
635*e5436536SAndroid Build Coastguard Worker sumNrgFwd +=
636*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
637*e5436536SAndroid Build Coastguard Worker sumNrgBwd +=
638*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
639*e5436536SAndroid Build Coastguard Worker break;
640*e5436536SAndroid Build Coastguard Worker
641*e5436536SAndroid Build Coastguard Worker default:
642*e5436536SAndroid Build Coastguard Worker sumScfFwd +=
643*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
644*e5436536SAndroid Build Coastguard Worker sumScfBwd +=
645*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
646*e5436536SAndroid Build Coastguard Worker break;
647*e5436536SAndroid Build Coastguard Worker }
648*e5436536SAndroid Build Coastguard Worker }
649*e5436536SAndroid Build Coastguard Worker }
650*e5436536SAndroid Build Coastguard Worker
651*e5436536SAndroid Build Coastguard Worker /* find for each group (scf,nrg,is) the correct direction */
652*e5436536SAndroid Build Coastguard Worker if (sumIsFwd < sumIsBwd) useIsFwd = 1;
653*e5436536SAndroid Build Coastguard Worker
654*e5436536SAndroid Build Coastguard Worker if (sumNrgFwd < sumNrgBwd) useNrgFwd = 1;
655*e5436536SAndroid Build Coastguard Worker
656*e5436536SAndroid Build Coastguard Worker if (sumScfFwd < sumScfBwd) useScfFwd = 1;
657*e5436536SAndroid Build Coastguard Worker
658*e5436536SAndroid Build Coastguard Worker /* conceal each group (scf,nrg,is) */
659*e5436536SAndroid Build Coastguard Worker for (group = 0; group < pRvlc->numWindowGroups; group++) {
660*e5436536SAndroid Build Coastguard Worker for (band = 0; band < pRvlc->maxSfbTransmitted; band++) {
661*e5436536SAndroid Build Coastguard Worker bnds = 16 * group + band;
662*e5436536SAndroid Build Coastguard Worker switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) {
663*e5436536SAndroid Build Coastguard Worker case ZERO_HCB:
664*e5436536SAndroid Build Coastguard Worker break;
665*e5436536SAndroid Build Coastguard Worker
666*e5436536SAndroid Build Coastguard Worker case INTENSITY_HCB:
667*e5436536SAndroid Build Coastguard Worker case INTENSITY_HCB2:
668*e5436536SAndroid Build Coastguard Worker if (useIsFwd)
669*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
670*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
671*e5436536SAndroid Build Coastguard Worker else
672*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
673*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
674*e5436536SAndroid Build Coastguard Worker break;
675*e5436536SAndroid Build Coastguard Worker
676*e5436536SAndroid Build Coastguard Worker case NOISE_HCB:
677*e5436536SAndroid Build Coastguard Worker if (useNrgFwd)
678*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
679*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
680*e5436536SAndroid Build Coastguard Worker else
681*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
682*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
683*e5436536SAndroid Build Coastguard Worker break;
684*e5436536SAndroid Build Coastguard Worker
685*e5436536SAndroid Build Coastguard Worker default:
686*e5436536SAndroid Build Coastguard Worker if (useScfFwd)
687*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
688*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
689*e5436536SAndroid Build Coastguard Worker else
690*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
691*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
692*e5436536SAndroid Build Coastguard Worker break;
693*e5436536SAndroid Build Coastguard Worker }
694*e5436536SAndroid Build Coastguard Worker }
695*e5436536SAndroid Build Coastguard Worker }
696*e5436536SAndroid Build Coastguard Worker }
697*e5436536SAndroid Build Coastguard Worker
698*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
699*e5436536SAndroid Build Coastguard Worker description: Approach by means of predictive interpolation
700*e5436536SAndroid Build Coastguard Worker This approach by means of predictive estimation is generally
701*e5436536SAndroid Build Coastguard Worker performed when the error cannot be isolated between 'conceal_min' and
702*e5436536SAndroid Build Coastguard Worker 'conceal_max', the 'sf_concealment' flag is set and the previous frame has the
703*e5436536SAndroid Build Coastguard Worker same block type as the current frame. Check for each scalefactorband if the same
704*e5436536SAndroid Build Coastguard Worker type of data (scalefactor, internsity data, noise energies) is transmitted. If
705*e5436536SAndroid Build Coastguard Worker so use the scalefactor (intensity data, noise energy) in the current frame.
706*e5436536SAndroid Build Coastguard Worker Otherwise set the scalefactor (intensity data, noise energy) for this
707*e5436536SAndroid Build Coastguard Worker scalefactorband to zero.
708*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
709*e5436536SAndroid Build Coastguard Worker output: Concealed scalefactor, noise energy and intensity data
710*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
711*e5436536SAndroid Build Coastguard Worker return: -
712*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
713*e5436536SAndroid Build Coastguard Worker */
714*e5436536SAndroid Build Coastguard Worker
PredictiveInterpolation(CAacDecoderChannelInfo * pAacDecoderChannelInfo,CAacDecoderStaticChannelInfo * pAacDecoderStaticChannelInfo)715*e5436536SAndroid Build Coastguard Worker void PredictiveInterpolation(
716*e5436536SAndroid Build Coastguard Worker CAacDecoderChannelInfo *pAacDecoderChannelInfo,
717*e5436536SAndroid Build Coastguard Worker CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo) {
718*e5436536SAndroid Build Coastguard Worker CErRvlcInfo *pRvlc =
719*e5436536SAndroid Build Coastguard Worker &pAacDecoderChannelInfo->pComData->overlay.aac.erRvlcInfo;
720*e5436536SAndroid Build Coastguard Worker int band, bnds, group;
721*e5436536SAndroid Build Coastguard Worker SHORT commonMin;
722*e5436536SAndroid Build Coastguard Worker
723*e5436536SAndroid Build Coastguard Worker for (group = 0; group < pRvlc->numWindowGroups; group++) {
724*e5436536SAndroid Build Coastguard Worker for (band = 0; band < pRvlc->maxSfbTransmitted; band++) {
725*e5436536SAndroid Build Coastguard Worker bnds = 16 * group + band;
726*e5436536SAndroid Build Coastguard Worker switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) {
727*e5436536SAndroid Build Coastguard Worker case ZERO_HCB:
728*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = 0;
729*e5436536SAndroid Build Coastguard Worker break;
730*e5436536SAndroid Build Coastguard Worker
731*e5436536SAndroid Build Coastguard Worker case INTENSITY_HCB:
732*e5436536SAndroid Build Coastguard Worker case INTENSITY_HCB2:
733*e5436536SAndroid Build Coastguard Worker if ((pAacDecoderStaticChannelInfo->concealmentInfo
734*e5436536SAndroid Build Coastguard Worker .aRvlcPreviousCodebook[bnds] == INTENSITY_HCB) ||
735*e5436536SAndroid Build Coastguard Worker (pAacDecoderStaticChannelInfo->concealmentInfo
736*e5436536SAndroid Build Coastguard Worker .aRvlcPreviousCodebook[bnds] == INTENSITY_HCB2)) {
737*e5436536SAndroid Build Coastguard Worker commonMin = fMin(
738*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],
739*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac
740*e5436536SAndroid Build Coastguard Worker .aRvlcScfBwd[bnds]);
741*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
742*e5436536SAndroid Build Coastguard Worker fMin(commonMin, pAacDecoderStaticChannelInfo->concealmentInfo
743*e5436536SAndroid Build Coastguard Worker .aRvlcPreviousScaleFactor[bnds]);
744*e5436536SAndroid Build Coastguard Worker } else {
745*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = -110;
746*e5436536SAndroid Build Coastguard Worker }
747*e5436536SAndroid Build Coastguard Worker break;
748*e5436536SAndroid Build Coastguard Worker
749*e5436536SAndroid Build Coastguard Worker case NOISE_HCB:
750*e5436536SAndroid Build Coastguard Worker if (pAacDecoderStaticChannelInfo->concealmentInfo
751*e5436536SAndroid Build Coastguard Worker .aRvlcPreviousCodebook[bnds] == NOISE_HCB) {
752*e5436536SAndroid Build Coastguard Worker commonMin = fMin(
753*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],
754*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac
755*e5436536SAndroid Build Coastguard Worker .aRvlcScfBwd[bnds]);
756*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
757*e5436536SAndroid Build Coastguard Worker fMin(commonMin, pAacDecoderStaticChannelInfo->concealmentInfo
758*e5436536SAndroid Build Coastguard Worker .aRvlcPreviousScaleFactor[bnds]);
759*e5436536SAndroid Build Coastguard Worker } else {
760*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = -110;
761*e5436536SAndroid Build Coastguard Worker }
762*e5436536SAndroid Build Coastguard Worker break;
763*e5436536SAndroid Build Coastguard Worker
764*e5436536SAndroid Build Coastguard Worker default:
765*e5436536SAndroid Build Coastguard Worker if ((pAacDecoderStaticChannelInfo->concealmentInfo
766*e5436536SAndroid Build Coastguard Worker .aRvlcPreviousCodebook[bnds] != ZERO_HCB) &&
767*e5436536SAndroid Build Coastguard Worker (pAacDecoderStaticChannelInfo->concealmentInfo
768*e5436536SAndroid Build Coastguard Worker .aRvlcPreviousCodebook[bnds] != NOISE_HCB) &&
769*e5436536SAndroid Build Coastguard Worker (pAacDecoderStaticChannelInfo->concealmentInfo
770*e5436536SAndroid Build Coastguard Worker .aRvlcPreviousCodebook[bnds] != INTENSITY_HCB) &&
771*e5436536SAndroid Build Coastguard Worker (pAacDecoderStaticChannelInfo->concealmentInfo
772*e5436536SAndroid Build Coastguard Worker .aRvlcPreviousCodebook[bnds] != INTENSITY_HCB2)) {
773*e5436536SAndroid Build Coastguard Worker commonMin = fMin(
774*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],
775*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pComData->overlay.aac
776*e5436536SAndroid Build Coastguard Worker .aRvlcScfBwd[bnds]);
777*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
778*e5436536SAndroid Build Coastguard Worker fMin(commonMin, pAacDecoderStaticChannelInfo->concealmentInfo
779*e5436536SAndroid Build Coastguard Worker .aRvlcPreviousScaleFactor[bnds]);
780*e5436536SAndroid Build Coastguard Worker } else {
781*e5436536SAndroid Build Coastguard Worker pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = 0;
782*e5436536SAndroid Build Coastguard Worker }
783*e5436536SAndroid Build Coastguard Worker break;
784*e5436536SAndroid Build Coastguard Worker }
785*e5436536SAndroid Build Coastguard Worker }
786*e5436536SAndroid Build Coastguard Worker }
787*e5436536SAndroid Build Coastguard Worker }
788