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" 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 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 */ 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 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 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 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 */ 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 */ 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 */ 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 */ 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 */ 489 OSCL_EXPORT_REF void CDecoder_AAC::DisableSbrDecodingL(tPVMP4AudioDecoderExternal * pExt) 490 { 491 PVMP4AudioDecoderDisableAacPlus(pExt, pMem); 492 } 493 494 495 496 497