1/* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18/*
19
20 Pathname: PVMP4AudioDecoderConfig
21
22------------------------------------------------------------------------------
23 REVISION HISTORY
24
25 Description: (1) Modified to decode AudioSpecificConfig for any frame number
26                  pVars->bno
27              (2) Update the input and output descriptions
28
29 Description: Eliminated search for ADIF header
30
31 Description: Added support for AAC+
32
33 Who:                                         Date:
34 Description:
35
36------------------------------------------------------------------------------
37 INPUT AND OUTPUT DEFINITIONS
38
39 Inputs:
40    pExt = pointer to the external interface structure. See the file
41           PVMP4AudioDecoder_API.h for a description of each field.
42           Data type of pointer to a tPVMP4AudioDecoderExternal
43           structure.
44
45           pExt->pInputBuffer: pointer to input buffer containing input
46                               bitstream
47
48           pExt->inputBufferCurrentLength: number of bytes in the input buffer
49
50           pExt->inputBufferUsedLength: number of bytes already consumed in
51                                        input buffer
52
53           pExt->remainderBits: number of bits consumed in addition to
54                                pExt->inputBufferUsedLength
55
56    pMem = void pointer to hide the internal implementation of the library
57           It is cast back to a tDec_Int_File structure. This structure
58           contains information that needs to persist between calls to
59           this function, or is too big to be placed on the stack, even
60           though the data is only needed during execution of this function
61           Data type void pointer, internally pointer to a tDec_Int_File
62           structure.
63
64 Local Stores/Buffers/Pointers Needed: None
65           (The memory set aside in pMem performs this task)
66
67 Global Stores/Buffers/Pointers Needed: None
68
69 Outputs:
70     status = 0                       if no error occurred
71              MP4AUDEC_NONRECOVERABLE if a non-recoverable error occurred
72              MP4AUDEC_RECOVERABLE    if a recoverable error occurred.
73              Presently a recoverable error does not exist, but this
74              was a requirement.
75
76
77 Pointers and Buffers Modified:
78    pMem contents are modified.
79    pExt: (more detail in the file PVMP4AudioDecoder_API.h)
80    inputBufferUsedLength - number of array elements used up by the stream.
81    remainderBits - remaining bits in the next UInt32 buffer
82    samplingRate - sampling rate in samples per sec
83    encodedChannels - channels found on the file (informative)
84    frameLength - length of the frame
85
86 Local Stores Modified: None.
87
88 Global Stores Modified: None.
89
90------------------------------------------------------------------------------
91 FUNCTION DESCRIPTION
92
93
94------------------------------------------------------------------------------
95 REQUIREMENTS
96
97 PacketVideo Document # CCC-AUD-AAC-ERS-0003
98
99------------------------------------------------------------------------------
100 REFERENCES
101
102 (1) ISO/IEC 14496-3: 1999(E)
103      subclause 1.6
104
105------------------------------------------------------------------------------
106 RESOURCES USED
107   When the code is written for a specific target processor the
108     the resources used should be documented below.
109
110 STACK USAGE: [stack count for this module] + [variable to represent
111          stack usage for each subroutine called]
112
113     where: [stack usage variable] = stack usage for [subroutine
114         name] (see [filename].ext)
115
116 DATA MEMORY USED: x words
117
118 PROGRAM MEMORY USED: x words
119
120 CLOCK CYCLES: [cycle count equation for this module] + [variable
121           used to represent cycle count for each subroutine
122           called]
123
124     where: [cycle count variable] = cycle count for [subroutine
125        name] (see [filename].ext)
126
127------------------------------------------------------------------------------
128*/
129
130
131/*----------------------------------------------------------------------------
132; INCLUDES
133----------------------------------------------------------------------------*/
134#include "pv_audio_type_defs.h"
135#include "s_tdec_int_file.h"
136#include "ibstream.h"           /* where #define INBUF_ARRAY_INDEX_SHIFT */
137#include "sfb.h"                   /* Where samp_rate_info[] is declared */
138
139#include "get_audio_specific_config.h"
140#include "pvmp4audiodecoder_api.h"   /* Where this function is declared */
141
142
143/*----------------------------------------------------------------------------
144; MACROS
145; Define module specific macros here
146----------------------------------------------------------------------------*/
147
148/*----------------------------------------------------------------------------
149; DEFINES
150; Include all pre-processor statements here. Include conditional
151; compile variables also.
152----------------------------------------------------------------------------*/
153
154/*----------------------------------------------------------------------------
155; LOCAL FUNCTION DEFINITIONS
156; Function Prototype declaration
157----------------------------------------------------------------------------*/
158
159/*----------------------------------------------------------------------------
160; LOCAL STORE/BUFFER/POINTER DEFINITIONS
161; Variable declaration - defined here and used outside this module
162----------------------------------------------------------------------------*/
163
164/*----------------------------------------------------------------------------
165; EXTERNAL FUNCTION REFERENCES
166; Declare functions defined elsewhere and referenced in this module
167----------------------------------------------------------------------------*/
168
169/*----------------------------------------------------------------------------
170; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
171; Declare variables used in this module but defined elsewhere
172----------------------------------------------------------------------------*/
173
174/*----------------------------------------------------------------------------
175; FUNCTION CODE
176----------------------------------------------------------------------------*/
177
178OSCL_EXPORT_REF Int PVMP4AudioDecoderConfig(
179    tPVMP4AudioDecoderExternal  *pExt,
180    void                        *pMem)
181{
182
183    UInt           initialUsedBits;  /* Unsigned for C55x */
184    tDec_Int_File *pVars;           /* Helper pointer */
185
186    Int            status = MP4AUDEC_INCOMPLETE_FRAME;
187
188    /*
189     * Initialize "helper" pointers to existing memory.
190     */
191    pVars = (tDec_Int_File *)pMem;
192    /*
193     * Translate input buffer variables.
194     */
195    pVars->inputStream.pBuffer = pExt->pInputBuffer;
196
197    pVars->inputStream.inputBufferCurrentLength =
198        (UInt)pExt->inputBufferCurrentLength;
199
200    pVars->inputStream.availableBits =
201        (UInt)(pExt->inputBufferCurrentLength << INBUF_ARRAY_INDEX_SHIFT);
202
203    initialUsedBits =
204        (UInt)((pExt->inputBufferUsedLength << INBUF_ARRAY_INDEX_SHIFT) +
205               pExt->remainderBits);
206
207    pVars->inputStream.usedBits = initialUsedBits;
208
209    if (initialUsedBits <= pVars->inputStream.availableBits)
210    {
211
212        /*
213         * Buffer is not overrun, then
214         * decode the AudioSpecificConfig() structure
215         */
216
217        pVars->aacConfigUtilityEnabled = false;  /* set aac dec mode */
218
219        status = get_audio_specific_config(pVars);
220
221    }
222
223    byte_align(&pVars->inputStream);
224
225
226    if (status == SUCCESS)
227    {
228
229        pVars->bno++;
230
231        /*
232         * A possible improvement would be to set these values only
233         * when they change.
234         */
235        pExt->samplingRate =
236            samp_rate_info[pVars->prog_config.sampling_rate_idx].samp_rate;
237
238        /*
239         *  we default to 2 channel, even for mono files, (where channels have same content)
240         *  this is done to ensure support for enhanced aac+ with implicit signalling
241         */
242        pExt->aacPlusEnabled = pVars->aacPlusEnabled;
243
244//        pExt->encodedChannels = pVars->mc_info.nch;
245
246        pExt->encodedChannels = 2;
247
248        pExt->frameLength = pVars->frameLength;
249#ifdef AAC_PLUS
250        pExt->aacPlusUpsamplingFactor = pVars->mc_info.upsamplingFactor;
251#endif
252
253    }
254    else
255    {
256        /*
257         *  Default to nonrecoverable error status unless there is a Buffer overrun
258         */
259        status = MP4AUDEC_INVALID_FRAME;
260
261        if (pVars->inputStream.usedBits > pVars->inputStream.availableBits)
262        {
263            /* all bits were used but were not enough to complete parsing */
264            pVars->inputStream.usedBits = pVars->inputStream.availableBits;
265
266            status = MP4AUDEC_INCOMPLETE_FRAME; /* audio config too small */
267        }
268
269    }
270
271    /*
272     * Translate from units of bits back into units of words.
273     */
274
275    pExt->inputBufferUsedLength =
276        pVars->inputStream.usedBits >> INBUF_ARRAY_INDEX_SHIFT;
277
278    pExt->remainderBits = pVars->inputStream.usedBits & INBUF_BIT_MODULO_MASK;
279
280    pVars->status = status;
281
282    return (status);
283
284} /* PVMP4AudioDecoderDecodeFrame */
285
286