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 // File: decoder_aac.cpp //
21 // //
22 //////////////////////////////////////////////////////////////////////////////////
23
24
25 #include "decoder_aac.h"
26 #include "oscl_error_codes.h"
27 #include "oscl_exception.h"
28
29 #include "e_tmp4audioobjecttype.h"
30
31 // Use default DLL entry point
32 #include "oscl_dll.h"
OSCL_DLL_ENTRY_POINT_DEFAULT()33 OSCL_DLL_ENTRY_POINT_DEFAULT()
34
35
36 OSCL_EXPORT_REF CDecoder_AAC *CDecoder_AAC::NewL()
37 {
38 CDecoder_AAC *dec = new CDecoder_AAC;
39
40 if (dec == NULL)
41 {
42 OSCL_LEAVE(OsclErrNoMemory);
43 }
44 else
45 {
46 dec->ConstructL();
47 }
48
49 return dec;
50 }
51
52
ConstructL()53 OSCL_EXPORT_REF void CDecoder_AAC::ConstructL()
54 {
55 // Initialize member variables
56 iFirstFrame = true;
57 iNumSamplesPerFrame = KAAC_NUM_SAMPLES_PER_FRAME;
58 pMem = NULL;
59 iAllocateInputBuffer = true;
60 iAllocateOutputBuffer = true;
61 iInputBuf = NULL;
62 iOutputBuf = NULL;
63 }
64
65
66 /*
67 -----------------------------------------------------------------------------
68
69 CDecoder_AAC
70
71 ~CDecoder_AAC
72
73 Empty decoder destructor.
74
75 Parameters: none
76
77 Return Values: none
78
79 -----------------------------------------------------------------------------
80 */
~CDecoder_AAC()81 OSCL_EXPORT_REF CDecoder_AAC::~CDecoder_AAC()
82 {
83 if (pMem != NULL)
84 {
85 OSCL_ARRAY_DELETE(pMem);
86 pMem = NULL;
87 }
88
89 if (iAllocateInputBuffer && iInputBuf)
90 {
91 OSCL_ARRAY_DELETE(iInputBuf);
92 iInputBuf = NULL;
93 }
94
95 if (iAllocateOutputBuffer && iOutputBuf)
96 {
97 OSCL_ARRAY_DELETE(iOutputBuf);
98 iOutputBuf = NULL;
99 }
100 }
101
102
103 /*
104 -----------------------------------------------------------------------------
105
106 CDecoder_AAC
107
108 StartL
109
110 Start decoder object. Initialize codec status.
111
112 Parameters: none
113
114 Return Values: status
115
116 -----------------------------------------------------------------------------
117 */
118
StartL(tPVMP4AudioDecoderExternal * pExt,uint8 num_channels,bool aAllocateInputBuffer,bool aAllocateOutputBuffer,Int upsamplingFactor,Int samp_rate,tMP4AudioObjectType audioObjectType)119 OSCL_EXPORT_REF int32 CDecoder_AAC::StartL(tPVMP4AudioDecoderExternal * pExt,
120 uint8 num_channels,
121 bool aAllocateInputBuffer,
122 bool aAllocateOutputBuffer,
123 Int upsamplingFactor,
124 Int samp_rate,
125 tMP4AudioObjectType audioObjectType)
126 {
127 iFirstFrame = true;
128
129 iAllocateInputBuffer = aAllocateInputBuffer;
130 iAllocateOutputBuffer = aAllocateOutputBuffer;
131
132 if (iAllocateInputBuffer)
133 {
134 iInputBuf = OSCL_ARRAY_NEW(uint8, KAAC_MAX_STREAMING_BUFFER_SIZE);
135 if (iInputBuf == NULL)
136 {
137 return KCAI_CODEC_INIT_FAILURE;
138 }
139 pExt->pInputBuffer = iInputBuf;
140 pExt->inputBufferMaxLength = KAAC_MAX_STREAMING_BUFFER_SIZE;
141 }
142 else
143 {
144 pExt->pInputBuffer = NULL;
145 pExt->inputBufferMaxLength = 0;
146 }
147
148 if (iAllocateOutputBuffer)
149 {
150 #ifdef AAC_PLUS
151 iOutputBuf = OSCL_ARRAY_NEW(int16, 4096);
152 #else
153 iOutputBuf = OSCL_ARRAY_NEW(int16, 2048);
154 #endif
155
156 if (iOutputBuf == NULL)
157 {
158 return KCAI_CODEC_INIT_FAILURE;
159 }
160
161 pExt->pOutputBuffer = iOutputBuf;
162 #ifdef AAC_PLUS
163 pExt->pOutputBuffer_plus = &iOutputBuf[2048];
164 #else
165 pExt->pOutputBuffer_plus = NULL;
166 #endif
167 }
168 else
169 {
170 pExt->pOutputBuffer = NULL;
171 pExt->pOutputBuffer_plus = NULL;
172 }
173
174 pExt->desiredChannels = num_channels;
175 pExt->inputBufferCurrentLength = 0;
176 pExt->outputFormat = OUTPUTFORMAT_16PCM_INTERLEAVED;
177 pExt->repositionFlag = TRUE;
178 pExt->inputBufferUsedLength = 0;
179 pExt->remainderBits = 0;
180
181 int32 memreq = PVMP4AudioDecoderGetMemRequirements();
182
183 pMem = OSCL_ARRAY_NEW(uint8 , memreq);
184
185 if (pMem == 0)
186 {
187 return KCAI_CODEC_NO_MEMORY;
188 }
189
190 if (PVMP4AudioDecoderInitLibrary(pExt, pMem) != 0)
191 {
192 return(KCAI_CODEC_INIT_FAILURE);
193 }
194
195
196 if (PVMP4SetAudioConfig(pExt,
197 pMem,
198 upsamplingFactor,
199 samp_rate,
200 num_channels,
201 audioObjectType) != SUCCESS)
202 {
203 return KCAI_CODEC_INIT_FAILURE;
204 }
205
206 iNumSamplesPerFrame = KAAC_NUM_SAMPLES_PER_FRAME;
207
208 pExt->desiredChannels = pExt->encodedChannels;
209
210 iFirstFrame = false;
211
212 return SUCCESS;
213 }
214
215
216 /*
217 -----------------------------------------------------------------------------
218
219 CDecoder_AAC
220
221 StartL
222
223 Start decoder object. Initialize codec status.
224
225 Parameters: none
226
227 Return Values: status
228
229 -----------------------------------------------------------------------------
230 */
231
232
233
234
StartL(tPVMP4AudioDecoderExternal * pExt,uint8 num_channels,bool aAllocateInputBuffer,bool aAllocateOutputBuffer,bool aAacplusEnabler)235 OSCL_EXPORT_REF int32 CDecoder_AAC::StartL(tPVMP4AudioDecoderExternal * pExt,
236 uint8 num_channels,
237 bool aAllocateInputBuffer,
238 bool aAllocateOutputBuffer,
239 bool aAacplusEnabler)
240 {
241 iFirstFrame = true;
242
243 iAllocateInputBuffer = aAllocateInputBuffer;
244 iAllocateOutputBuffer = aAllocateOutputBuffer;
245
246 if (iAllocateInputBuffer)
247 {
248 iInputBuf = OSCL_ARRAY_NEW(uint8, KAAC_MAX_STREAMING_BUFFER_SIZE);
249 if (iInputBuf == NULL)
250 {
251 return KCAI_CODEC_INIT_FAILURE;
252 }
253 pExt->pInputBuffer = iInputBuf;
254 pExt->inputBufferMaxLength = KAAC_MAX_STREAMING_BUFFER_SIZE;
255 }
256 else
257 {
258 pExt->pInputBuffer = NULL;
259 pExt->inputBufferMaxLength = 0;
260 }
261
262 if (iAllocateOutputBuffer)
263 {
264 #ifdef AAC_PLUS
265 iOutputBuf = OSCL_ARRAY_NEW(int16, 4096);
266 #else
267 iOutputBuf = OSCL_ARRAY_NEW(int16, 2048);
268 #endif
269
270 if (iOutputBuf == NULL)
271 {
272 return KCAI_CODEC_INIT_FAILURE;
273 }
274
275 pExt->pOutputBuffer = iOutputBuf;
276 #ifdef AAC_PLUS
277 pExt->pOutputBuffer_plus = &iOutputBuf[2048];
278 #else
279 pExt->pOutputBuffer_plus = NULL;
280 #endif
281 }
282 else
283 {
284 pExt->pOutputBuffer = NULL;
285 pExt->pOutputBuffer_plus = NULL;
286 }
287
288 pExt->desiredChannels = num_channels;
289 pExt->inputBufferCurrentLength = 0;
290 pExt->outputFormat = OUTPUTFORMAT_16PCM_INTERLEAVED;
291 pExt->repositionFlag = TRUE;
292 pExt->aacPlusEnabled = aAacplusEnabler; /* Dynamically enable AAC+ decoding */
293 pExt->inputBufferUsedLength = 0;
294 pExt->remainderBits = 0;
295
296 int32 memreq = PVMP4AudioDecoderGetMemRequirements();
297
298 pMem = OSCL_ARRAY_NEW(uint8 , memreq);
299
300 if (pMem == 0)
301 {
302 return KCAI_CODEC_NO_MEMORY;
303 }
304
305 return SUCCESS;
306 }
307
308
309 /*
310 -----------------------------------------------------------------------------
311
312 CDecoder_AAC
313
314 ExecuteL
315
316 Execute decoder object. Read one encoded aac frame from the input
317 stream, decode it and write the decoded frame to output stream.
318
319 Parameters:
320
321 Return Values: status
322
323
324 -----------------------------------------------------------------------------
325 */
326
ExecuteL(tPVMP4AudioDecoderExternal * pExt)327 OSCL_EXPORT_REF int32 CDecoder_AAC::ExecuteL(tPVMP4AudioDecoderExternal * pExt)
328 {
329 int32 nResult = FALSE;
330
331 if (iFirstFrame == false)
332 {
333 nResult = PVMP4AudioDecodeFrame(pExt, pMem);
334 }
335 else
336 {
337 if (PVMP4AudioDecoderInitLibrary(pExt, pMem) != 0)
338 {
339 return(KCAI_CODEC_INIT_FAILURE);
340 }
341 // set samples/frame to default value (right now this is the only one supported)
342
343 if (PVMP4AudioDecoderConfig(pExt, pMem) != SUCCESS)
344 {
345 nResult = PVMP4AudioDecodeFrame(pExt, pMem); /* could be ADIF type */
346 }
347
348 iNumSamplesPerFrame = KAAC_NUM_SAMPLES_PER_FRAME;
349
350 pExt->desiredChannels = pExt->encodedChannels;
351
352 iFirstFrame = false;
353 }
354
355 return nResult;
356 }
357
358 /*
359 -----------------------------------------------------------------------------
360
361 CDecoder_AAC
362
363 StopL
364
365 Stop decoder object. Flush out last frame
366
367 Parameters: none
368
369 Return Values: none
370
371 -----------------------------------------------------------------------------
372 */
StopL()373 OSCL_EXPORT_REF void CDecoder_AAC::StopL()
374 {
375 PVMP4AudioDecoderResetBuffer(pMem);
376 }
377
378 /*
379 -----------------------------------------------------------------------------
380
381 CDecoder_AAC
382
383 ResetDecoderL
384
385 Stop decoder object. Reset decoder.
386
387 Parameters: none
388
389 Return Values: status
390
391 -----------------------------------------------------------------------------
392 */
ResetDecoderL()393 OSCL_EXPORT_REF void CDecoder_AAC::ResetDecoderL()
394 {
395 PVMP4AudioDecoderResetBuffer(pMem);
396 }
397
398
399 /*
400 -----------------------------------------------------------------------------
401
402 CDecoder_AAC
403
404 TerminateDecoderL
405
406 Stop decoder object. close decoder.
407
408 Parameters: none
409
410 Return Values: none
411
412 -----------------------------------------------------------------------------
413 */
TerminateDecoderL()414 OSCL_EXPORT_REF void CDecoder_AAC::TerminateDecoderL()
415 {
416 if (pMem != NULL)
417 {
418 OSCL_ARRAY_DELETE(pMem);
419 pMem = NULL;
420 }
421
422 if (iAllocateInputBuffer && iInputBuf)
423 {
424 OSCL_ARRAY_DELETE(iInputBuf);
425 iInputBuf = NULL;
426 }
427
428 if (iAllocateOutputBuffer && iOutputBuf)
429 {
430 OSCL_ARRAY_DELETE(iOutputBuf);
431 iOutputBuf = NULL;
432 }
433 }
434
435
436
437 /*
438 -----------------------------------------------------------------------------
439
440 CDecoder_AAC
441
442 RetrieveDecodedStreamTypeL
443
444 Utility to extract the decoding aac stream type being decoded.
445
446 Parameters: none
447
448 Return Values: status
449
450 -----------------------------------------------------------------------------
451 */
RetrieveDecodedStreamTypeL(tPVMP4AudioDecoderExternal * pExt)452 OSCL_EXPORT_REF int32 CDecoder_AAC::RetrieveDecodedStreamTypeL(tPVMP4AudioDecoderExternal * pExt)
453 {
454
455 if ((pExt->extendedAudioObjectType == MP4AUDIO_AAC_LC) ||
456 (pExt->extendedAudioObjectType == MP4AUDIO_LTP))
457 {
458 return AAC; /* AAC */
459 }
460 else if (pExt->extendedAudioObjectType == MP4AUDIO_SBR)
461 {
462 return AACPLUS; /* AAC+ */
463 }
464 else if (pExt->extendedAudioObjectType == MP4AUDIO_PS)
465 {
466 return ENH_AACPLUS; /* AAC++ */
467 }
468
469 return -1; /* Error evaluating the stream type */
470 }
471
472
473
474 /*
475 -----------------------------------------------------------------------------
476
477 CDecoder_AAC
478
479 DisableSbrDecodingL
480
481 Disable aac+/eaac+ decoding.
482
483 Parameters: none
484
485 Return Values: none
486
487 -----------------------------------------------------------------------------
488 */
DisableSbrDecodingL(tPVMP4AudioDecoderExternal * pExt)489 OSCL_EXPORT_REF void CDecoder_AAC::DisableSbrDecodingL(tPVMP4AudioDecoderExternal * pExt)
490 {
491 PVMP4AudioDecoderDisableAacPlus(pExt, pMem);
492 }
493
494
495
496
497