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 // -*- c++ -*- 19 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 20 21 // A A C F I L E P A R S E R 22 23 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 24 25 /** 26 * @file aacfileparser.cpp 27 * @brief This file contains the implementation of the raw AAC file parser. 28 */ 29 30 //---------------------------------------------------------------------------- 31 // INCLUDES 32 //---------------------------------------------------------------------------- 33 #include "aacfileparser.h" 34 #include "pv_audio_type_defs.h" 35 #include "getactualaacconfig.h" 36 #include "media_clock_converter.h" 37 #include "pvmp4audiodecoder_api.h" 38 39 // Use default DLL entry point for Symbian 40 #include "oscl_dll.h" 41 OSCL_DLL_ENTRY_POINT_DEFAULT() 42 43 //! specially used in ResetPlayback(), re-poition the file pointer 44 int32 AACBitstreamObject::reset(int32 filePos) 45 { 46 iBytesRead = filePos; // set the initial value 47 iBytesProcessed = filePos; 48 if (ipAACFile) 49 { 50 ipAACFile->Seek(filePos, Oscl_File::SEEKSET); 51 } 52 iPos = AACBitstreamObject::MAIN_BUFF_SIZE; 53 return refill(); 54 } 55 56 //! read data from bitstream, this is the only function to read data from file 57 int32 AACBitstreamObject::refill() 58 { 59 if (iBytesRead > 0 && iFileSize > 0 && iBytesRead >= iFileSize) 60 { 61 //At this point we're near the end of data. 62 //Quit reading data but don't return EOF until all data is processed. 63 if (iBytesProcessed < iBytesRead) 64 { 65 return AACBitstreamObject::EVERYTHING_OK; 66 } 67 else 68 { 69 return AACBitstreamObject::END_OF_FILE; 70 } 71 } 72 73 if (!ipAACFile) 74 { 75 PVMF_AACPARSER_LOGERROR((0, "AACBitstreamObject::refill- Misc Error")); 76 return AACBitstreamObject::MISC_ERROR; 77 } 78 79 // Get file size at the very first time 80 if (iFileSize == 0) 81 { 82 if (ipAACFile->Seek(0, Oscl_File::SEEKSET)) 83 { 84 PVMF_AACPARSER_LOGERROR((0, "AACBitstreamObject::refill- Misc Error")); 85 return AACBitstreamObject::MISC_ERROR; 86 } 87 ipAACFile->GetRemainingBytes((uint32&)iFileSize); 88 if (iFileSize <= 0) 89 { 90 PVMF_AACPARSER_LOGERROR((0, "AACBitstreamObject::refill- Misc Error")); 91 return AACBitstreamObject::MISC_ERROR; 92 } 93 // first-time read, set the initial value of iPos 94 iPos = AACBitstreamObject::MAIN_BUFF_SIZE; 95 } 96 97 int32 remain_bytes = AACBitstreamObject::MAIN_BUFF_SIZE - iPos; 98 if (remain_bytes > 0) 99 { 100 // move the remaining stuff to the beginning of iBuffer 101 oscl_memcpy(&iBuffer[0], &iBuffer[iPos], remain_bytes); 102 } 103 104 // read data 105 if ((iActual_size = ipAACFile->Read(&iBuffer[remain_bytes], 1, iMax_size - remain_bytes)) == 0) 106 { 107 return AACBitstreamObject::READ_ERROR; 108 } 109 110 iBytesRead += iActual_size; 111 iActual_size += remain_bytes; 112 iPos = 0; 113 114 return AACBitstreamObject::EVERYTHING_OK; 115 } 116 117 //! get frame size and number of data blocks for the next frame, in preparation of getNextFrame() 118 int32 AACBitstreamObject::getNextFrameInfo(int32& frame_size, int32& numDateBlocks) 119 { 120 int32 ret_value = AACBitstreamObject::EVERYTHING_OK; 121 122 // Need to refill? 123 if (iFileSize == 0 || iPos + 4 >= iActual_size) 124 { 125 ret_value = refill(); 126 if (ret_value) 127 { 128 return ret_value; 129 } 130 } 131 132 // Search the 12 bit sync-word 0xff + 0xf0 133 while (!(iBuffer[iPos] == 0xff && 134 (iBuffer[iPos+1] & 0xf0) == 0xf0 && 135 iBuffer[iPos+1] == iAACHeaderBuffer[1] && 136 iBuffer[iPos+2] == iAACHeaderBuffer[2] && 137 iBuffer[iPos+3] == iAACHeaderBuffer[3])) 138 { 139 if (iPos + 4 >= iActual_size) 140 { 141 ret_value = refill(); 142 if (ret_value) 143 { 144 return ret_value; 145 } 146 } 147 iPos++; 148 iBytesProcessed++; 149 } 150 if (iPos + ADTS_HEADER_LENGTH + 2 >= iActual_size) 151 { 152 ret_value = refill(); 153 if (ret_value) 154 { 155 return ret_value; 156 } 157 } 158 159 // parse the header and get frame size plus the number of data blocks 160 uint8 *pBuffer = &iBuffer[iPos]; 161 frame_size = (int32)((pBuffer[3] & 0x03) << 11) | // take the lowest 2 bits in the 4th byte of the header 162 (int32)(pBuffer[4] << 3) | // take the whole 5th byte(8 bits) of the header 163 (int32)((pBuffer[5] & 0xe0) >> 5); // take the highest 3 bits in the 6th byte of the header 164 165 if (ibCRC_Check) 166 { 167 frame_size -= (ADTS_HEADER_LENGTH + 2); 168 } 169 else 170 { 171 frame_size -= ADTS_HEADER_LENGTH; 172 } 173 174 numDateBlocks = (pBuffer[6] & 0x03) + 1; // take the lowest 2 bits in the 7th byte of the header 175 176 // update CRC check 177 ibCRC_Check = ((pBuffer[1] & 0x01) ? false : true); 178 179 return ret_value; 180 } 181 182 //! most important function to get one frame data plus frame type, used in getNextBundledAccessUnits() 183 int32 AACBitstreamObject::getNextFrame(uint8* frameBuffer, int32& frame_size, int32& aHdrSize, bool bHeaderIncluded) 184 { 185 aHdrSize = 0; 186 if (!frameBuffer || (frame_size <= 0 || frame_size > MAX_AAC_FRAME_SIZE)) 187 { 188 PVMF_AACPARSER_LOGERROR((0, "AACBitstreamObject::getNextFrame- Misc Error")); 189 return AACBitstreamObject::MISC_ERROR; 190 } 191 192 int32 ret_value = AACBitstreamObject::EVERYTHING_OK; 193 194 if (iAACFormat == EAACADTS) //ADTS 195 { 196 // Need to refill? 197 if (iFileSize == 0 || iPos + ADTS_HEADER_LENGTH + 2 + frame_size >= iActual_size) 198 { 199 ret_value = refill(); 200 if (ret_value) 201 { 202 return ret_value; 203 } 204 } 205 206 // copy the header to the buffer if needed 207 uint8 *pBuffer = &iBuffer[iPos]; 208 int32 header_size = (ibCRC_Check ? ADTS_HEADER_LENGTH + 2 : ADTS_HEADER_LENGTH); 209 if (bHeaderIncluded) 210 { 211 oscl_memcpy(frameBuffer, pBuffer, header_size); 212 frameBuffer += header_size; 213 aHdrSize = header_size; 214 } 215 216 // copy the data to the given buffer 217 oscl_memcpy(frameBuffer, &pBuffer[header_size], frame_size); 218 iPos += (header_size + frame_size); 219 iBytesProcessed += (header_size + frame_size); 220 } 221 222 else if (iAACFormat == EAACADIF || iAACFormat == EAACRaw) //ADIF or raw bitstream 223 { 224 if (iFileSize == 0 || iPos + frame_size >= iActual_size) 225 { 226 ret_value = refill(); 227 if (ret_value) 228 { 229 return ret_value; 230 } 231 } 232 233 uint8 *pBuffer = &iBuffer[iPos]; 234 if ((iBytesRead >= iFileSize) && (frame_size > (iBytesRead - iBytesProcessed))) 235 { 236 frame_size = iBytesRead - iBytesProcessed; 237 } 238 239 // copy the data to the given buffer 240 oscl_memcpy(frameBuffer, pBuffer, frame_size); 241 iPos += frame_size; 242 iBytesProcessed += frame_size; 243 } 244 245 return ret_value; 246 } 247 248 void AACBitstreamObject::parseID3Header(PVFile& aFile) 249 { 250 if (!ipAACFile 251 || !ipAACFile->IsOpen()) 252 return;//error 253 254 int32 curpos = aFile.Tell(); 255 aFile.Seek(0, Oscl_File::SEEKSET); 256 id3Parser->ParseID3Tag(&aFile); 257 aFile.Seek(curpos, Oscl_File::SEEKSET); 258 } 259 260 int32 AACBitstreamObject::isAACFile() 261 { 262 if (!ipAACFile || !ipAACFile->IsOpen()) 263 { 264 return AACBitstreamObject::READ_ERROR; 265 } 266 267 int32 retVal = AACBitstreamObject::EVERYTHING_OK; 268 269 // save current file pointer location 270 int32 curPos = ipAACFile->Tell(); 271 ipAACFile->Seek(0, Oscl_File::SEEKSET); 272 273 // check for ID3v2 tag at the beginning of file 274 uint32 tagSize = 0; 275 if (true == id3Parser->IsID3V2Present(ipAACFile, tagSize)) 276 { 277 // skip over ID3v2 tag 278 // move the file read pointer to beginning of audio data 279 // but first make sure the data is there 280 uint32 aCurrentSize = 0; 281 uint32 aRemBytes = 0; 282 if (ipAACFile->GetRemainingBytes(aRemBytes)) 283 { 284 uint32 currPos_2 = (uint32)(ipAACFile->Tell()); 285 aCurrentSize = currPos_2 + aRemBytes; 286 287 if (aCurrentSize >= tagSize) 288 { 289 if (ipAACFile->Seek(tagSize, Oscl_File::SEEKSET) != 0) 290 { 291 retVal = AACBitstreamObject::READ_ERROR; 292 } 293 } 294 else 295 { 296 // data has not arrived yet 297 retVal = AACBitstreamObject::INSUFFICIENT_DATA; 298 } 299 } 300 else 301 { 302 retVal = AACBitstreamObject::READ_ERROR; 303 } 304 } 305 306 // file pointer should be at the audio data 307 // can be ADTS, ADIF or raw AAC 308 // - it takes 8192 bytes (max AAC frame size) to determine that is is ADTS 309 // - it takes 4 bytes to determine that it is ADIF 310 // - it takes 1536 bytes to determine that it is raw AAC 311 312 // make sure there are at least 8192 bytes left in the file 313 if (AACBitstreamObject::EVERYTHING_OK == retVal) 314 { 315 uint32 aRemBytes = 0; 316 if (ipAACFile->GetRemainingBytes(aRemBytes)) 317 { 318 int32 currPos_2 = ipAACFile->Tell(); 319 retVal = reset(currPos_2); 320 321 if (AACBitstreamObject::EVERYTHING_OK == retVal) 322 { 323 uint8 *pBuffer = &iBuffer[iPos]; 324 325 // default to not enough data 326 retVal = AACBitstreamObject::INSUFFICIENT_DATA; 327 if (aRemBytes >= MAX_ADTS_PACKET_LENGTH) 328 { 329 // check for possible ADTS sync word 330 int32 index = find_adts_syncword(pBuffer); 331 if (index != -1) 332 { 333 // definitely ADTS 334 retVal = AACBitstreamObject::EVERYTHING_OK; 335 } 336 } 337 338 if (AACBitstreamObject::INSUFFICIENT_DATA == retVal) 339 { 340 // not enough data to determine if it is ADTS 341 // see if it is ADIF 342 if (aRemBytes >= 4) 343 { 344 // check for ADIF header 345 if (pBuffer[0] == 0x41 && // 'A' 346 pBuffer[1] == 0x44 && // 'D' 347 pBuffer[2] == 0x49 && // 'I' 348 pBuffer[3] == 0x46) // 'F' 349 { 350 // definitely ADIF 351 retVal = AACBitstreamObject::EVERYTHING_OK; 352 } 353 else 354 { 355 // non-recognized format, 356 retVal = AACBitstreamObject::MISC_ERROR; 357 } 358 } 359 } 360 } 361 } 362 else 363 { 364 retVal = AACBitstreamObject::READ_ERROR; 365 } 366 } 367 368 // retore file pointer 369 ipAACFile->Seek(curPos, Oscl_File::SEEKSET); 370 return retVal; 371 } 372 373 374 //! Search for adts synchronization word 375 376 int32 AACBitstreamObject::find_adts_syncword(uint8 *pBuffer) 377 { 378 379 380 uint32 test_for_syncword = 0; 381 382 383 384 uint32 i; 385 uint32 buff_length; 386 387 388 buff_length = OSCL_MIN(MAX_ADTS_PACKET_LENGTH, iActual_size); 389 390 391 for (i = 0; i < buff_length - 1; i++) 392 { 393 /* 394 * Sync word is always byte aligned, sync word == 0xFFF 395 */ 396 if (pBuffer[i] == 0xFF) 397 { 398 if ((pBuffer[i+1] & 0xF0) == 0xF0) 399 { 400 test_for_syncword = 1; /* flag found sync adts word */ 401 break; 402 } 403 } 404 } 405 406 if (test_for_syncword) // get here only if match is found 407 { 408 uint32 index = i; 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 // extract the aac frame lenght where the next sync word should be 437 if ((index + 5) < buff_length) 438 { 439 uint32 length = (uint32)((pBuffer[index + 3] & 0x03) << 11); // lowest 2 bits in the 4th byte of the header 440 length |= (uint32)(pBuffer[index + 4] << 3); // whole 5th byte(8 bits) of the header 441 length |= (uint32)((pBuffer[index + 5] & 0xe0) >> 5); // highest 3 bits in the 6th byte of the header 442 443 444 // Verify for false sync word in non-adts files, by validating next 2 sync word 445 if ((length > ADTS_HEADER_LENGTH) && 446 (length < buff_length - index) && // buff_length should account for up to 4 aac frames 447 (pBuffer[index + length ] == 0xff) && 448 ((pBuffer[index + length + 1] & 0xf0) == 0xf0)) 449 { 450 // extract the second aac frame lenght to predict next adts header 451 length += index; 452 uint32 length_2 = (uint32)((pBuffer[length + 3] & 0x03) << 11); 453 length_2 |= (uint32)(pBuffer[length + 4] << 3); 454 length_2 |= (uint32)((pBuffer[length+ 5] & 0xe0) >> 5); 455 456 457 if ((length_2 > ADTS_HEADER_LENGTH) && 458 (length_2 < buff_length - length) && 459 (pBuffer[length + length_2] == 0xff) && 460 ((pBuffer[length + length_2 + 1] & 0xf0) == 0xf0)) 461 462 { 463 464 return (index); // sure this is adts 465 } 466 iPosSyncAdtsFound = index - 1; // allow overlapping on extended search 467 return (-1); // false adts synchronization, it is adif or raw 468 } 469 else 470 { 471 iPosSyncAdtsFound = index - 1; // allow overlapping on extended search 472 return (-1); // it was a false adts synchronization, it could be adif or raw 473 } 474 } 475 else 476 { 477 iPosSyncAdtsFound = index - 1; // allow overlapping on extended search 478 return (-1); // not enough data to validate synchronization 479 } 480 } 481 else 482 { 483 iPosSyncAdtsFound = i - 1; // allow overlapping on extended search 484 return (-1); // no adts synchronization, it could be adif or raw 485 } 486 } 487 488 //! get clip information: file size, format(ADTS or ADIF) and sampling rate index 489 int32 AACBitstreamObject::getFileInfo(int32& fileSize, TAACFormat& format, uint8& sampleFreqIndex, uint32& bitRate, uint32& HeaderLen, OSCL_wString&/*aClip*/) 490 { 491 uint32 id; 492 uint32 bitstreamType; 493 uint32 numProgConfigElem; 494 int32 i; 495 uint32 ADIFHeaderLen; 496 uint32 numFrontChanElem; 497 uint32 numSideChanElem; 498 uint32 numBackChanElem; 499 uint32 numLfeChanElem; 500 uint32 numAssocDataElem; 501 uint32 numValidCCElem; 502 uint32 commentFieldBytes; 503 uint32 offset; 504 uint32 bitIndex; 505 uint8 tmp; 506 507 bitRate = 0; 508 HeaderLen = 0; 509 iChannelConfig = 0; 510 511 format = EAACUnrecognized; 512 fileSize = sampleFreqIndex = 0; 513 int32 ret_value = AACBitstreamObject::EVERYTHING_OK; 514 515 if (iFileSize == 0) 516 { 517 ret_value = reset(0); 518 if (ret_value == AACBitstreamObject::EVERYTHING_OK) 519 { 520 //retrieve the ID3 meta-data from the file 521 parseID3Header(*ipAACFile); 522 523 if (id3Parser->GetByteOffsetToStartOfAudioFrames() > 0) 524 { 525 //skip past the ID3 header. 526 ret_value = reset(id3Parser->GetByteOffsetToStartOfAudioFrames()); 527 if (ret_value != AACBitstreamObject::EVERYTHING_OK) 528 { 529 return ret_value; 530 } 531 } 532 533 fileSize = iFileSize; 534 535 uint8 *pBuffer = &iBuffer[iPos]; 536 537 // Check for possible adts sync word 538 int32 index = find_adts_syncword(pBuffer); 539 if (index != -1) 540 { 541 //ADTS format 542 iAACFormat = format = EAACADTS; 543 // get sample frequency index 544 iSampleFreqIndex = sampleFreqIndex = (uint8)((pBuffer[2 + index] & 0x3c) >> 2); 545 546 // check the crc_check field 547 ibCRC_Check = ((pBuffer[1 + index] & 0x01) ? false : true); 548 549 // get ADTS fixed header part to iAACHeaderBuffer 550 oscl_memcpy(iAACHeaderBuffer, &pBuffer[index], PACKET_INDICATOR_LENGTH); 551 552 } 553 else if (iFileSize >= 4 && 554 pBuffer[0] == 0x41 && // 'A' 555 pBuffer[1] == 0x44 && // 'D' 556 pBuffer[2] == 0x49 && // 'I' 557 pBuffer[3] == 0x46) // 'F' 558 { 559 // ADIF format 560 iAACFormat = format = EAACADIF; 561 562 ADIFHeaderLen = 32; // adif_id 4 bytes 563 564 // check copyright_id_present (1 bit) 565 id = pBuffer[4] & 0x80; 566 567 if (id != 0) //copyright ID is presented 568 { 569 ADIFHeaderLen += 75; // copyright_id_present 1 bit 570 // copyright_id 72 bits, 571 // original_copy 1 bit, 572 // home 1 bit, 573 574 // check bitstream type 575 bitstreamType = pBuffer[13] & 0x10; 576 577 // get number of program config. element 578 numProgConfigElem = (pBuffer[16] & 0x1E) >> 1; 579 580 // get bitrate (max for variable rate bitstream) 581 iBitrate = bitRate = ((pBuffer[13] & 0xF0) << 15) | 582 (pBuffer[14] << 11) | 583 (pBuffer[15] << 3) | 584 ((pBuffer[16] & 0xE0) >> 5); 585 586 if (iBitrate == 0) //bitrate is not known 587 { 588 PVMF_AACPARSER_LOGERROR((0, "AACBitstreamObject::getFileInfo- Misc Error")); 589 return AACBitstreamObject::MISC_ERROR; 590 } 591 592 ADIFHeaderLen += 28; // bitstream_type 1 bit, 593 // bitrate 23 bits 594 // num_program_config_elements 4 bits 595 596 for (i = 0; i < (int32)numProgConfigElem + 1; i++) 597 { 598 if (bitstreamType == 0) //bistream type is constant rate bitstream 599 { 600 ADIFHeaderLen += 20; //adif_buffer_fullness 20 bits 601 602 // get audio object type 603 iAudioObjectType = (uint8)(((pBuffer[19] & 0x1) << 1) | ((pBuffer[20] & 0x80) >> 7)); 604 605 // get sampling rate index 606 iSampleFreqIndex = sampleFreqIndex = (uint8)((pBuffer[20] & 0x78) >> 3); 607 608 // get number of front channel elements 609 numFrontChanElem = (uint32)(((pBuffer[20] & 0x7) << 1) | ((pBuffer[21] & 0x80) >> 7)); 610 611 // get number of side channel elements 612 numSideChanElem = (uint32)((pBuffer[21] & 0x78) >> 3); 613 614 // get number of back channel elements 615 numBackChanElem = (uint32)(((pBuffer[21] & 0x7) << 1) | ((pBuffer[22] & 0x80) >> 7)); 616 617 // get number of LFE channel elements 618 numLfeChanElem = (uint32)((pBuffer[22] & 0x60) >> 5); 619 620 // get number of assoc data elements 621 numAssocDataElem = (uint32)((pBuffer[22] & 0x1C) >> 2); 622 623 // get number of valid CC elements 624 numValidCCElem = (uint32)(((pBuffer[22] & 0x3) << 2) | ((pBuffer[23] & 0xC0) >> 6)); 625 626 ADIFHeaderLen += 31; //element_instance_tag 4 bits, 627 //object_type 2 bits, 628 //sampling_frequency_index 4 bits, 629 //num_front_channel_elements 4 bits, 630 //num_side_channel_elements 4 bits, 631 //num_back_channel_elements 4 bits, 632 //num_lfe_channel_elements 2 bits, 633 //num_assoc_data_elements 3 bits, 634 //num_valid_cc_elements 4 bits 635 636 // check mono_mixdown_present 637 if ((pBuffer[23] & 0x20) != 0) //mono mixdown is presented 638 { 639 ADIFHeaderLen += 5; //mono_mixdown_present 1 bit 640 //mono_mixdown_element_number 4 bits 641 642 //check stereo_mixdown_present 643 if ((pBuffer[23] & 0x1) != 0) //stereo mixdown is presented 644 { 645 ADIFHeaderLen += 5; //stereo_mixdown_present 1 bit 646 //stereo_mixdown_element_number 4 bits 647 648 //check matrix_mixdown_idx_present 649 if ((pBuffer[24] & 0x8) != 0) //matrix mixdown is presented 650 { 651 ADIFHeaderLen += 4; //matrix_mixdown_idx_present 1 bit 652 //matrix_mixdown_idx 2 bits 653 //pseudo_surround_enable 1 bit 654 } 655 else //matrix mixdown is not presented 656 { 657 ADIFHeaderLen += 1; //matrix_mixdown_idx_present 1 bit 658 } 659 } 660 else //stereo mixdown is not presented 661 { 662 ADIFHeaderLen += 1; //stereo_mixdown_present 1 bit 663 664 //check matrix_mixdown_idx_present 665 if ((pBuffer[24] & 0x80) != 0) //matrix mixdown is presented 666 { 667 ADIFHeaderLen += 4; //matrix_mixdown_idx_present 1 bit 668 //matrix_mixdown_idx 2 bits 669 //pseudo_surround_enable 1 bit 670 } 671 else //matrix mixdown is not presented 672 { 673 ADIFHeaderLen += 1; //matrix_mixdown_idx_present 1 bit 674 } 675 }//if ((pBuffer[23] & 0x1) != 0) 676 } 677 else //mono mixdown is not presented 678 { 679 ADIFHeaderLen += 1; //mono_mixdown_present 1 bit 680 681 //check stereo_mixdown_present 682 if ((pBuffer[23] & 0x10) != 0) //stereo mixdown is presented 683 { 684 ADIFHeaderLen += 5; //stereo_mixdown_present 1 bit 685 //stereo_mixdown_element_number 4 bits 686 687 //check matrix_mixdown_idx_present 688 if ((pBuffer[24] & 0x80) != 0) //matrix mixdown is presented 689 { 690 ADIFHeaderLen += 4; //matrix_mixdown_idx_present 1 bit 691 //matrix_mixdown_idx 2 bits 692 //pseudo_surround_enable 1 bit 693 } 694 else //matrix mixdown is not presented 695 { 696 ADIFHeaderLen += 1; //matrix_mixdown_idx_present 1 bit 697 } 698 } 699 else //stereo mixdown is not presented 700 { 701 ADIFHeaderLen += 1; //stereo_mixdown_present 1 bit 702 703 //check matrix_mixdown_idx_present 704 if ((pBuffer[23] & 0x8) != 0) //matrix mixdown is presented 705 { 706 ADIFHeaderLen += 4; //matrix_mixdown_idx_present 1 bit 707 //matrix_mixdown_idx 2 bits 708 //pseudo_surround_enable 1 bit 709 } 710 else //matrix mixdown is not presented 711 { 712 ADIFHeaderLen += 1; //matrix_mixdown_idx_present 1 bit 713 } 714 }//if ((pBuffer[23] & 0x10) != 0) 715 716 }//if ((pBuffer[23] & 0x20) != 0) 717 718 } 719 else //bistream type is variable rate bitstream 720 { 721 // get audio object type 722 iAudioObjectType = (uint8)((pBuffer[17] & 0x18) >> 3); 723 724 // get sampling rate index 725 iSampleFreqIndex = sampleFreqIndex = (uint8)(((pBuffer[17] & 0x7) << 1) | ((pBuffer[18] & 0x80) >> 7)); 726 727 // get number of front channel elements 728 numFrontChanElem = (uint32)((pBuffer[18] & 0x78) >> 3); 729 730 // get number of side channel elements 731 numSideChanElem = (uint32)(((pBuffer[18] & 0x7) << 1) | ((pBuffer[19] & 0x80) >> 7)); 732 733 // get number of back channel elements 734 numBackChanElem = (uint32)((pBuffer[19] & 0x78) >> 3); 735 736 // get number of LFE channel elements 737 numLfeChanElem = (uint32)((pBuffer[19] & 0x6) >> 1); 738 739 // get number of assoc data elements 740 numAssocDataElem = (uint32)(((pBuffer[19] & 0x1) << 2) | ((pBuffer[20] & 0xC0) >> 6)); 741 742 // get number of valid CC elements 743 numValidCCElem = (uint32)((pBuffer[20] & 0x3C) >> 2); 744 745 ADIFHeaderLen += 31; //element_instance_tag 4 bits, 746 //object_type 2 bits, 747 //sampling_frequency_index 4 bits, 748 //num_front_channel_elements 4 bits, 749 //num_side_channel_elements 4 bits, 750 //num_back_channel_elements 4 bits, 751 //num_lfe_channel_elements 2 bits, 752 //num_assoc_data_elements 3 bits, 753 //num_valid_cc_elements 4 bits 754 755 // check mono_mixdown_present 756 if ((pBuffer[20] & 0x2) != 0) //mono mixdown is presented 757 { 758 ADIFHeaderLen += 5; //mono_mixdown_present 1 bit 759 //mono_mixdown_element_number 4 bits 760 761 //check stereo_mixdown_present 762 if ((pBuffer[21] & 0x10) != 0) //stereo mixdown is presented 763 { 764 ADIFHeaderLen += 5; //stereo_mixdown_present 1 bit 765 //stereo_mixdown_element_number 4 bits 766 767 //check matrix_mixdown_idx_present 768 if ((pBuffer[22] & 0x80) != 0) //matrix mixdown is presented 769 { 770 ADIFHeaderLen += 4; //matrix_mixdown_idx_present 1 bit 771 //matrix_mixdown_idx 2 bits 772 //pseudo_surround_enable 1 bit 773 } 774 else //matrix mixdown is not presented 775 { 776 ADIFHeaderLen += 1; //matrix_mixdown_idx_present 1 bit 777 } 778 } 779 else //stereo mixdown is not presented 780 { 781 ADIFHeaderLen += 1; //stereo_mixdown_present 1 bit 782 783 //check matrix_mixdown_idx_present 784 if ((pBuffer[21] & 0x8) != 0) //matrix mixdown is presented 785 { 786 ADIFHeaderLen += 4; //matrix_mixdown_idx_present 1 bit 787 //matrix_mixdown_idx 2 bits 788 //pseudo_surround_enable 1 bit 789 } 790 else //matrix mixdown is not presented 791 { 792 ADIFHeaderLen += 1; //matrix_mixdown_idx_present 1 bit 793 } 794 }//if ((pBuffer[21] & 0x10) != 0) 795 } 796 else //mono mixdown is not presented 797 { 798 ADIFHeaderLen += 1; //mono_mixdown_present 1 bit 799 800 //check stereo_mixdown_present 801 if ((pBuffer[20] & 0x1) != 0) //stereo mixdown is presented 802 { 803 ADIFHeaderLen += 5; //stereo_mixdown_present 1 bit 804 //stereo_mixdown_element_number 4 bits 805 806 //check matrix_mixdown_idx_present 807 if ((pBuffer[21] & 0x8) != 0) //matrix mixdown is presented 808 { 809 ADIFHeaderLen += 4; //matrix_mixdown_idx_present 1 bit 810 //matrix_mixdown_idx 2 bits 811 //pseudo_surround_enable 1 bit 812 } 813 else //matrix mixdown is not presented 814 { 815 ADIFHeaderLen += 1; //matrix_mixdown_idx_present 1 bit 816 } 817 } 818 else //stereo mixdown is not presented 819 { 820 ADIFHeaderLen += 1; //stereo_mixdown_present 1 bit 821 822 //check matrix_mixdown_idx_present 823 if ((pBuffer[21] & 0x80) != 0) //matrix mixdown is presented 824 { 825 ADIFHeaderLen += 4; //matrix_mixdown_idx_present 1 bit 826 //matrix_mixdown_idx 2 bits 827 //pseudo_surround_enable 1 bit 828 } 829 else //matrix mixdown is not presented 830 { 831 ADIFHeaderLen += 1; //matrix_mixdown_idx_present 1 bit 832 } 833 }//if ((pBuffer[20] & 0x1) != 0) 834 835 }//if ((pBuffer[20] & 0x2) != 0) 836 837 }// if (bitstreamType == 0) 838 839 for (i = 0; i < (int32)numFrontChanElem; i++) 840 { 841 //calculate channel configuration 842 offset = ADIFHeaderLen >> 3; 843 bitIndex = ADIFHeaderLen & 0x7; 844 tmp = (uint8)((pBuffer[offset] << bitIndex) | (pBuffer[offset+1] >> (8 - bitIndex))); 845 tmp >>= (8 - 1); //front channel element takes 1 bit 846 iChannelConfig += tmp; 847 848 //update ADIF variable header length 849 ADIFHeaderLen += 5; //front_element_is_cpe[i] 1 bit, 850 //front_element_tag_select[i] 4 bits 851 } 852 853 for (i = 0; i < (int32)numSideChanElem; i++) 854 { 855 //calculate channel configuration 856 offset = ADIFHeaderLen >> 3; 857 bitIndex = ADIFHeaderLen & 0x7; 858 tmp = (uint8)((pBuffer[offset] << bitIndex) | (pBuffer[offset+1] >> (8 - bitIndex))); 859 tmp >>= (8 - 1); //side channel element takes 1 bit 860 iChannelConfig += (tmp + 1); 861 862 //update ADIF variable header length 863 ADIFHeaderLen += 5; //side_element_is_cpe[i] 1 bit, 864 //side_element_tag_select[i] 4 bits 865 } 866 867 for (i = 0; i < (int32)numBackChanElem; i++) 868 { 869 //calculate channel configuration 870 offset = ADIFHeaderLen >> 3; 871 bitIndex = ADIFHeaderLen & 0x7; 872 tmp = (uint8)((pBuffer[offset] << bitIndex) | (pBuffer[offset+1] >> (8 - bitIndex))); 873 tmp >>= (8 - 1); //back channel element takes 1 bit 874 iChannelConfig += (tmp + 1); 875 876 //update ADIF variable header length 877 ADIFHeaderLen += 5; //back_element_is_cpe[i] 1 bit, 878 //back_element_tag_select[i] 4 bits 879 } 880 881 if (numLfeChanElem != 0) 882 { 883 iChannelConfig++; //1 front low frequency effects speaker 884 } 885 886 for (i = 0; i < (int32)numLfeChanElem; i++) 887 { 888 ADIFHeaderLen += 4; //lfe_element_tag_select[i] 4 bits 889 } 890 891 for (i = 0; i < (int32)numAssocDataElem; i++) 892 { 893 ADIFHeaderLen += 4; //assoc_data_element_tag_select[i] 4 bits 894 } 895 896 for (i = 0; i < (int32)numValidCCElem; i++) 897 { 898 ADIFHeaderLen += 5; //cc_element_is_ind_sw[i] 1 bit, 899 //valid_cc_element_tag_select[i] 4 bits 900 } 901 902 // byte_allignment 903 ADIFHeaderLen += 7; 904 ADIFHeaderLen &= 0xF8; 905 906 // comment_field_bytes (8 bits) 907 offset = ADIFHeaderLen >> 3; 908 bitIndex = ADIFHeaderLen & 0x7; 909 commentFieldBytes = (pBuffer[offset] << bitIndex) | (pBuffer[offset+1] >> (8 - bitIndex)); 910 911 ADIFHeaderLen += 8; //comment_field_bytes 8 bits 912 913 for (i = 0; i < (int32)commentFieldBytes; i++) 914 { 915 ADIFHeaderLen += 8; //comment_field_data 8 bits 916 } 917 918 }// for (i = 0; i < (int32)numProgConfigElem + 1; i++) 919 920 } 921 else //copyright ID is not presented 922 { 923 ADIFHeaderLen += 3; // copyright_id_present 1 bit 924 // original_copy 1 bit, 925 // home 1 bit, 926 927 // check bitstream type 928 bitstreamType = pBuffer[4] & 0x10; 929 930 // get number of program config. element 931 numProgConfigElem = (pBuffer[7] & 0x1E) >> 1; 932 933 // get bitrate (max for variable rate bitstream) 934 iBitrate = bitRate = ((pBuffer[4] & 0xF0) << 15) | 935 (pBuffer[5] << 11) | 936 (pBuffer[6] << 3) | 937 ((pBuffer[7] & 0xE0) >> 5); 938 939 if (iBitrate == 0) //bitrate is not known 940 { 941 PVMF_AACPARSER_LOGERROR((0, "AACBitstreamObject::getFileInfo- Misc Error")); 942 return AACBitstreamObject::MISC_ERROR; 943 } 944 945 ADIFHeaderLen += 28; // bitstream_type 1 bit, 946 // bitrate 23 bits 947 // num_program_config_elements 4 bits 948 949 for (i = 0; i < (int32)numProgConfigElem + 1; i++) 950 { 951 if (bitstreamType == 0) //bistream type is constant rate bitstream 952 { 953 ADIFHeaderLen += 20; //adif_buffer_fullness 20 bits 954 955 // get audio object type 956 iAudioObjectType = (uint8)(((pBuffer[10] & 0x1) << 1) | ((pBuffer[11] & 0x80) >> 7)); 957 958 // get sampling rate index 959 iSampleFreqIndex = sampleFreqIndex = (uint8)((pBuffer[11] & 0x78) >> 3); 960 961 // get number of front channel elements 962 numFrontChanElem = (uint32)(((pBuffer[11] & 0x7) << 1) | ((pBuffer[12] & 0x80) >> 7)); 963 964 // get number of side channel elements 965 numSideChanElem = (uint32)((pBuffer[12] & 0x78) >> 3); 966 967 // get number of back channel elements 968 numBackChanElem = (uint32)(((pBuffer[12] & 0x7) << 1) | ((pBuffer[13] & 0x80) >> 7)); 969 970 // get number of LFE channel elements 971 numLfeChanElem = (uint32)((pBuffer[13] & 0x60) >> 5); 972 973 // get number of assoc data elements 974 numAssocDataElem = (uint32)((pBuffer[13] & 0x1C) >> 2); 975 976 // get number of valid CC elements 977 numValidCCElem = (uint32)(((pBuffer[13] & 0x3) << 2) | ((pBuffer[14] & 0xC0) >> 6)); 978 979 ADIFHeaderLen += 31; //element_instance_tag 4 bits, 980 //object_type 2 bits, 981 //sampling_frequency_index 4 bits, 982 //num_front_channel_elements 4 bits, 983 //num_side_channel_elements 4 bits, 984 //num_back_channel_elements 4 bits, 985 //num_lfe_channel_elements 2 bits, 986 //num_assoc_data_elements 3 bits, 987 //num_valid_cc_elements 4 bits 988 989 // check mono_mixdown_present 990 if ((pBuffer[14] & 0x20) != 0) //mono mixdown is presented 991 { 992 ADIFHeaderLen += 5; //mono_mixdown_present 1 bit 993 //mono_mixdown_element_number 4 bits 994 995 //check stereo_mixdown_present 996 if ((pBuffer[14] & 0x1) != 0) //stereo mixdown is presented 997 { 998 ADIFHeaderLen += 5; //stereo_mixdown_present 1 bit 999 //stereo_mixdown_element_number 4 bits 1000 1001 //check matrix_mixdown_idx_present 1002 if ((pBuffer[15] & 0x8) != 0) //matrix mixdown is presented 1003 { 1004 ADIFHeaderLen += 4; //matrix_mixdown_idx_present 1 bit 1005 //matrix_mixdown_idx 2 bits 1006 //pseudo_surround_enable 1 bit 1007 } 1008 else //matrix mixdown is not presented 1009 { 1010 ADIFHeaderLen += 1; //matrix_mixdown_idx_present 1 bit 1011 } 1012 } 1013 else //stereo mixdown is not presented 1014 { 1015 ADIFHeaderLen += 1; //stereo_mixdown_present 1 bit 1016 1017 //check matrix_mixdown_idx_present 1018 if ((pBuffer[15] & 0x80) != 0) //matrix mixdown is presented 1019 { 1020 ADIFHeaderLen += 4; //matrix_mixdown_idx_present 1 bit 1021 //matrix_mixdown_idx 2 bits 1022 //pseudo_surround_enable 1 bit 1023 } 1024 else //matrix mixdown is not presented 1025 { 1026 ADIFHeaderLen += 1; //matrix_mixdown_idx_present 1 bit 1027 } 1028 }//if ((pBuffer[14] & 0x1) != 0) 1029 } 1030 else //mono mixdown is not presented 1031 { 1032 ADIFHeaderLen += 1; //mono_mixdown_present 1 bit 1033 1034 //check stereo_mixdown_present 1035 if ((pBuffer[14] & 0x10) != 0) //stereo mixdown is presented 1036 { 1037 ADIFHeaderLen += 5; //stereo_mixdown_present 1 bit 1038 //stereo_mixdown_element_number 4 bits 1039 1040 //check matrix_mixdown_idx_present 1041 if ((pBuffer[15] & 0x80) != 0) //matrix mixdown is presented 1042 { 1043 ADIFHeaderLen += 4; //matrix_mixdown_idx_present 1 bit 1044 //matrix_mixdown_idx 2 bits 1045 //pseudo_surround_enable 1 bit 1046 } 1047 else //matrix mixdown is not presented 1048 { 1049 ADIFHeaderLen += 1; //matrix_mixdown_idx_present 1 bit 1050 } 1051 } 1052 else //stereo mixdown is not presented 1053 { 1054 ADIFHeaderLen += 1; //stereo_mixdown_present 1 bit 1055 1056 //check matrix_mixdown_idx_present 1057 if ((pBuffer[14] & 0x8) != 0) //matrix mixdown is presented 1058 { 1059 ADIFHeaderLen += 4; //matrix_mixdown_idx_present 1 bit 1060 //matrix_mixdown_idx 2 bits 1061 //pseudo_surround_enable 1 bit 1062 } 1063 else //matrix mixdown is not presented 1064 { 1065 ADIFHeaderLen += 1; //matrix_mixdown_idx_present 1 bit 1066 } 1067 }//if ((pBuffer[14] & 0x10) != 0) 1068 1069 }//if ((pBuffer[14] & 0x20) != 0) 1070 1071 } 1072 else //bistream type is variable rate bitstream 1073 { 1074 // get audio object type 1075 iAudioObjectType = (uint8)((pBuffer[8] & 0x18) >> 3); 1076 1077 // get sampling rate index 1078 iSampleFreqIndex = sampleFreqIndex = (uint8)(((pBuffer[8] & 0x7) << 1) | ((pBuffer[9] & 0x80) >> 7)); 1079 1080 // get number of front channel elements 1081 numFrontChanElem = (uint32)((pBuffer[9] & 0x78) >> 3); 1082 1083 // get number of side channel elements 1084 numSideChanElem = (uint32)(((pBuffer[9] & 0x7) << 1) | ((pBuffer[10] & 0x80) >> 7)); 1085 1086 // get number of back channel elements 1087 numBackChanElem = (uint32)((pBuffer[10] & 0x78) >> 3); 1088 1089 // get number of LFE channel elements 1090 numLfeChanElem = (uint32)((pBuffer[10] & 0x6) >> 1); 1091 1092 // get number of assoc data elements 1093 numAssocDataElem = (uint32)(((pBuffer[10] & 0x1) << 2) | ((pBuffer[11] & 0xC0) >> 6)); 1094 1095 // get number of valid CC elements 1096 numValidCCElem = (uint32)((pBuffer[11] & 0x3C) >> 2); 1097 1098 ADIFHeaderLen += 31; //element_instance_tag 4 bits, 1099 //object_type 2 bits, 1100 //sampling_frequency_index 4 bits, 1101 //num_front_channel_elements 4 bits, 1102 //num_side_channel_elements 4 bits, 1103 //num_back_channel_elements 4 bits, 1104 //num_lfe_channel_elements 2 bits, 1105 //num_assoc_data_elements 3 bits, 1106 //num_valid_cc_elements 4 bits 1107 1108 // check mono_mixdown_present 1109 if ((pBuffer[11] & 0x2) != 0) //mono mixdown is presented 1110 { 1111 ADIFHeaderLen += 5; //mono_mixdown_present 1 bit 1112 //mono_mixdown_element_number 4 bits 1113 1114 //check stereo_mixdown_present 1115 if ((pBuffer[12] & 0x10) != 0) //stereo mixdown is presented 1116 { 1117 ADIFHeaderLen += 5; //stereo_mixdown_present 1 bit 1118 //stereo_mixdown_element_number 4 bits 1119 1120 //check matrix_mixdown_idx_present 1121 if ((pBuffer[13] & 0x80) != 0) //matrix mixdown is presented 1122 { 1123 ADIFHeaderLen += 4; //matrix_mixdown_idx_present 1 bit 1124 //matrix_mixdown_idx 2 bits 1125 //pseudo_surround_enable 1 bit 1126 } 1127 else //matrix mixdown is not presented 1128 { 1129 ADIFHeaderLen += 1; //matrix_mixdown_idx_present 1 bit 1130 } 1131 } 1132 else //stereo mixdown is not presented 1133 { 1134 ADIFHeaderLen += 1; //stereo_mixdown_present 1 bit 1135 1136 //check matrix_mixdown_idx_present 1137 if ((pBuffer[12] & 0x8) != 0) //matrix mixdown is presented 1138 { 1139 ADIFHeaderLen += 4; //matrix_mixdown_idx_present 1 bit 1140 //matrix_mixdown_idx 2 bits 1141 //pseudo_surround_enable 1 bit 1142 } 1143 else //matrix mixdown is not presented 1144 { 1145 ADIFHeaderLen += 1; //matrix_mixdown_idx_present 1 bit 1146 } 1147 }//if ((pBuffer[12] & 0x10) != 0) 1148 } 1149 else //mono mixdown is not presented 1150 { 1151 ADIFHeaderLen += 1; //mono_mixdown_present 1 bit 1152 1153 //check stereo_mixdown_present 1154 if ((pBuffer[11] & 0x1) != 0) //stereo mixdown is presented 1155 { 1156 ADIFHeaderLen += 5; //stereo_mixdown_present 1 bit 1157 //stereo_mixdown_element_number 4 bits 1158 1159 //check matrix_mixdown_idx_present 1160 if ((pBuffer[12] & 0x8) != 0) //matrix mixdown is presented 1161 { 1162 ADIFHeaderLen += 4; //matrix_mixdown_idx_present 1 bit 1163 //matrix_mixdown_idx 2 bits 1164 //pseudo_surround_enable 1 bit 1165 } 1166 else //matrix mixdown is not presented 1167 { 1168 ADIFHeaderLen += 1; //matrix_mixdown_idx_present 1 bit 1169 } 1170 } 1171 else //stereo mixdown is not presented 1172 { 1173 ADIFHeaderLen += 1; //stereo_mixdown_present 1 bit 1174 1175 //check matrix_mixdown_idx_present 1176 if ((pBuffer[12] & 0x80) != 0) //matrix mixdown is presented 1177 { 1178 ADIFHeaderLen += 4; //matrix_mixdown_idx_present 1 bit 1179 //matrix_mixdown_idx 2 bits 1180 //pseudo_surround_enable 1 bit 1181 } 1182 else //matrix mixdown is not presented 1183 { 1184 ADIFHeaderLen += 1; //matrix_mixdown_idx_present 1 bit 1185 } 1186 }//if ((pBuffer[11] & 0x1) != 0) 1187 1188 }//if ((pBuffer[11] & 0x2) != 0) 1189 1190 }// if (bitstreamType == 0) 1191 1192 for (i = 0; i < (int32)numFrontChanElem; i++) 1193 { 1194 //calculate channel configuration 1195 offset = ADIFHeaderLen >> 3; 1196 bitIndex = ADIFHeaderLen & 0x7; 1197 tmp = (uint8)((pBuffer[offset] << bitIndex) | (pBuffer[offset+1] >> (8 - bitIndex))); 1198 tmp >>= (8 - 1); //front channel element takes 1 bit 1199 iChannelConfig += tmp; 1200 1201 //update ADIF variable header length 1202 ADIFHeaderLen += 5; //front_element_is_cpe[i] 1 bit, 1203 //front_element_tag_select[i] 4 bits 1204 } 1205 1206 for (i = 0; i < (int32)numSideChanElem; i++) 1207 { 1208 //calculate channel configuration 1209 offset = ADIFHeaderLen >> 3; 1210 bitIndex = ADIFHeaderLen & 0x7; 1211 tmp = (uint8)((pBuffer[offset] << bitIndex) | (pBuffer[offset+1] >> (8 - bitIndex))); 1212 tmp >>= (8 - 1); //side channel element takes 1 bit 1213 iChannelConfig += (tmp + 1); 1214 1215 //update ADIF variable header length 1216 ADIFHeaderLen += 5; //side_element_is_cpe[i] 1 bit, 1217 //side_element_tag_select[i] 4 bits 1218 } 1219 1220 for (i = 0; i < (int32)numBackChanElem; i++) 1221 { 1222 //calculate channel configuration 1223 offset = ADIFHeaderLen >> 3; 1224 bitIndex = ADIFHeaderLen & 0x7; 1225 tmp = (uint8)((pBuffer[offset] << bitIndex) | (pBuffer[offset+1] >> (8 - bitIndex))); 1226 tmp >>= (8 - 1); //back channel element takes 1 bit 1227 iChannelConfig += (tmp + 1); 1228 1229 //update ADIF variable header length 1230 ADIFHeaderLen += 5; //side_element_is_cpe[i] 1 bit, 1231 //side_element_tag_select[i] 4 bits 1232 } 1233 1234 if (numLfeChanElem != 0) 1235 { 1236 iChannelConfig++; //1 front low frequency effects speaker 1237 } 1238 1239 for (i = 0; i < (int32)numLfeChanElem; i++) 1240 { 1241 ADIFHeaderLen += 4; //lfe_element_tag_select[i] 4 bits 1242 } 1243 1244 for (i = 0; i < (int32)numAssocDataElem; i++) 1245 { 1246 ADIFHeaderLen += 4; //assoc_data_element_tag_select[i] 4 bits 1247 } 1248 1249 for (i = 0; i < (int32)numValidCCElem; i++) 1250 { 1251 ADIFHeaderLen += 5; //cc_element_is_ind_sw[i] 1 bit, 1252 //valid_cc_element_tag_select[i] 4 bits 1253 } 1254 1255 // byte_allignment 1256 ADIFHeaderLen += 7; 1257 ADIFHeaderLen &= 0xF8; 1258 1259 // comment_field_bytes (8 bits) 1260 offset = ADIFHeaderLen >> 3; 1261 bitIndex = ADIFHeaderLen & 0x7; 1262 commentFieldBytes = (pBuffer[offset] << bitIndex) | (pBuffer[offset+1] >> (8 - bitIndex)); 1263 1264 ADIFHeaderLen += 8; //comment_field_bytes 8 bits 1265 1266 for (i = 0; i < (int32)commentFieldBytes; i++) 1267 { 1268 ADIFHeaderLen += 8; //comment_field_data 8 bits 1269 } 1270 1271 }// for (i = 0; i < (int32)numProgConfigElem + 1; i++) 1272 1273 } // if(id!=0) 1274 1275 // ADIF header length in bits 1276 iADIFHeaderLen = HeaderLen = ADIFHeaderLen; 1277 1278 // get ADIF id header part to iAACHeaderBuffer (4 bytes) 1279 oscl_memcpy(iAACHeaderBuffer, pBuffer, PACKET_INDICATOR_LENGTH); 1280 } 1281 else // Check if it is AAC raw bitstream file 1282 { 1283 1284 int32 config_header_size = iActual_size; 1285 int32 status = GetActualAacConfig(pBuffer, 1286 &iAudioObjectType, &config_header_size, &sampleFreqIndex, &iChannelConfig); 1287 if (status != SUCCESS) return AACBitstreamObject::MISC_ERROR; 1288 1289 // Retrieve the audio object type 1290 if (iAudioObjectType != 2 && 1291 iAudioObjectType != 4 && 1292 iAudioObjectType != 5 && 1293 iAudioObjectType != 29) 1294 { 1295 // Unsupported object type 1296 PVMF_AACPARSER_LOGERROR((0, "AACBitstreamObject::getFileInfo- Misc Error")); 1297 return AACBitstreamObject::MISC_ERROR; 1298 } 1299 1300 iSampleFreqIndex = sampleFreqIndex; 1301 oscl_memcpy(iAACHeaderBuffer, pBuffer, config_header_size); 1302 iRawAACHeaderLen = (uint32)config_header_size; 1303 HeaderLen = (uint32)config_header_size << 3; 1304 1305 // Raw AAC format 1306 iAACFormat = format = EAACRaw; 1307 } 1308 } 1309 } 1310 else 1311 { 1312 fileSize = iFileSize; 1313 format = iAACFormat; 1314 sampleFreqIndex = iSampleFreqIndex; 1315 } 1316 return ret_value; 1317 } 1318 1319 1320 //! extended search to get clip information only for adts format 1321 int32 AACBitstreamObject::extendedAdtsSearchForFileInfo(TAACFormat& format, 1322 uint8& sampleFreqIndex) 1323 { 1324 sampleFreqIndex = 0; 1325 int32 ret_value = AACBitstreamObject::EVERYTHING_OK; 1326 1327 iPos = iPosSyncAdtsFound; /* overlap only needed data */ 1328 ret_value = refill(); 1329 if (ret_value == AACBitstreamObject::EVERYTHING_OK) 1330 { 1331 1332 uint8 *pBuffer = &iBuffer[iPos]; 1333 1334 // Check for possible adts sync word 1335 int32 index = find_adts_syncword(pBuffer); 1336 if (index != -1) 1337 { 1338 //ADTS format 1339 iAACFormat = format = EAACADTS; 1340 // get sample frequency index 1341 iSampleFreqIndex = sampleFreqIndex = (uint8)((pBuffer[2 + index] & 0x3c) >> 2); 1342 1343 // check the crc_check field 1344 ibCRC_Check = ((pBuffer[1 + index] & 0x01) ? false : true); 1345 1346 // get ADTS fixed header part to iAACHeaderBuffer 1347 oscl_memcpy(iAACHeaderBuffer, &pBuffer[index], PACKET_INDICATOR_LENGTH); 1348 1349 } 1350 else 1351 { 1352 if (iBytesRead > ADTS_SYNC_SEARCH_LENGTH(iFileSize, 5)) // search over 3.13 % of the file 1353 { 1354 return AACBitstreamObject::MISC_ERROR; // break the loop 1355 } 1356 //otherwise keep looking 1357 } 1358 1359 } 1360 return ret_value; 1361 } 1362 1363 int32 AACBitstreamObject::getDecoderConfigHeader(uint8* headerBuffer) 1364 { 1365 if (iAACFormat == EAACADTS) //ADTS 1366 { 1367 if (!headerBuffer || 1368 !(iAACHeaderBuffer[0] == 0xff && 1369 (iAACHeaderBuffer[1] & 0xf0) == 0xf0)) 1370 { 1371 PVMF_AACPARSER_LOGERROR((0, "AACBitstreamObject::getFileInfo- Misc Error")); 1372 return AACBitstreamObject::MISC_ERROR; 1373 } 1374 1375 // parse the ADTS header of the first frame: iAACHeaderReferenceBuffer[] (got from the bitstream in InitAACFile() 1376 headerBuffer[0] = headerBuffer[1] = 0; 1377 1378 // 1. construct auditoObjectType(bit1-5, 5 bits, MPEG-4) from profile(bit17-18, 2 bits, ADTS) 1379 uint8 profile = (uint8)(iAACHeaderBuffer[2] >> 6); // 2 bits long 1380 headerBuffer[0] |= ++profile << 3; // put it into the highest 5 bits 1381 1382 // 2. construct samplingFrequencyIndex(bit6-9, 4 bits, MPEG-4) from sampling_frequency_index(bit19-22, 4 bits, ADTS) 1383 uint8 sampling_frequency_index = (uint8)((iAACHeaderBuffer[2] >> 2) & 0x0f); // 4 bits long 1384 headerBuffer[0] |= (sampling_frequency_index >> 1); // put 3 bits 1385 headerBuffer[1] |= ((sampling_frequency_index & 0x1) << 7); // put 1 bit 1386 1387 // 3. construct channelConfiguration(bit10-13, 4 bits, MPEG-4) from channel_configuration(bit22-24, 3 bits, ADTS) 1388 uint8 channel_config = (uint8)(((iAACHeaderBuffer[2] & 0x01) << 2) | 1389 (iAACHeaderBuffer[3] >> 6)); // 3 bits long in ADTS => 4 valid bits in MPEG-4 1390 headerBuffer[1] |= (channel_config << 3); 1391 } 1392 else if (iAACFormat == EAACADIF) //ADIF 1393 { 1394 if (!headerBuffer || 1395 !((iAACHeaderBuffer[0] == 0x41) && // 'A' 1396 (iAACHeaderBuffer[1] == 0x44) && // 'D' 1397 (iAACHeaderBuffer[2] == 0x49) && // 'I' 1398 (iAACHeaderBuffer[3] == 0x46))) // 'F' 1399 { 1400 PVMF_AACPARSER_LOGERROR((0, "AACBitstreamObject::getFileInfo- Misc Error")); 1401 return AACBitstreamObject::MISC_ERROR; 1402 } 1403 1404 // parse the ADIF header 1405 headerBuffer[0] = headerBuffer[1] = 0; 1406 1407 // 1. construct audio object type (2 bits) 1408 headerBuffer[0] |= ((iAudioObjectType + 1) << 3); 1409 1410 // 2. construct sampling frequency index (4 bits) 1411 headerBuffer[0] |= (iSampleFreqIndex >> 1); //put 3 bits in headerBuffer[0] 1412 headerBuffer[1] |= ((iSampleFreqIndex & 0x1) << 7); //put 1 bit in headerBuffer[1] 1413 1414 // 3. construct channel configuration (4 bits) 1415 headerBuffer[1] |= ((iChannelConfig + 1) << 3); 1416 } 1417 else if (iAACFormat == EAACRaw) 1418 { 1419 // Just copy the audio specific config 1420 oscl_memcpy(headerBuffer, iAACHeaderBuffer, iRawAACHeaderLen); 1421 } 1422 1423 return AACBitstreamObject::EVERYTHING_OK; 1424 } 1425 1426 template <class PtrType> 1427 class AutoPtrArrayContainer 1428 { 1429 private: 1430 bool _Ownership; 1431 PtrType *_Ptr; 1432 1433 public: 1434 // default constructors 1435 explicit AutoPtrArrayContainer(PtrType *inPtr = 0) : 1436 _Ownership(inPtr != 0), _Ptr(inPtr) {}; 1437 1438 ~AutoPtrArrayContainer() 1439 { 1440 if (_Ownership && _Ptr) 1441 { 1442 OSCL_ARRAY_DELETE(_Ptr); 1443 _Ptr = NULL; 1444 } 1445 _Ownership = false; 1446 } 1447 }; 1448 1449 1450 //---------------------------------------------------------------------------- 1451 // FUNCTION NAME: CAACFileParser::CAACFileParser 1452 //---------------------------------------------------------------------------- 1453 // INPUT AND OUTPUT DEFINITIONS 1454 // 1455 // Inputs: 1456 // None 1457 // 1458 // Outputs: 1459 // None 1460 // 1461 // Returns: 1462 // None 1463 // 1464 // Global Variables Used: 1465 // None 1466 // 1467 //---------------------------------------------------------------------------- 1468 // FUNCTION DESCRIPTION 1469 // 1470 // Constructor for CAACFileParser class 1471 // 1472 //---------------------------------------------------------------------------- 1473 // REQUIREMENTS 1474 // 1475 //---------------------------------------------------------------------------- 1476 // REFERENCES 1477 // 1478 //------------------------------------------------------------------------------ 1479 // CAUTION 1480 // 1481 //------------------------------------------------------------------------------ 1482 OSCL_EXPORT_REF CAACFileParser::CAACFileParser(void) : 1483 iAACDuration(0), 1484 iAACSampleFrequency(0), 1485 iAACBitRate(0), 1486 iAACHeaderLen(0), 1487 iFirstTime(false), 1488 iAACFileSize(0), 1489 iTotalNumFramesRead(0), 1490 iAACFormat(EAACUnrecognized), 1491 iEndOfFileReached(false), 1492 iLogger(PVLogger::GetLoggerObject("pvaacparser")), 1493 iDiagnosticLogger(PVLogger::GetLoggerObject("playerdiagnostics.pvaac_parser")), 1494 ipBSO(NULL) 1495 { 1496 } 1497 1498 //---------------------------------------------------------------------------- 1499 // FUNCTION NAME: CAACFileParser::~CAACFileParser 1500 //---------------------------------------------------------------------------- 1501 // INPUT AND OUTPUT DEFINITIONS 1502 // 1503 // Inputs: 1504 // None 1505 // 1506 // Outputs: 1507 // None 1508 // 1509 // Returns: 1510 // None 1511 // 1512 // Global Variables Used: 1513 // None 1514 // 1515 //---------------------------------------------------------------------------- 1516 // FUNCTION DESCRIPTION 1517 // 1518 // Destructor for CAACFileParser class 1519 // 1520 //---------------------------------------------------------------------------- 1521 // REQUIREMENTS 1522 // 1523 //---------------------------------------------------------------------------- 1524 // REFERENCES 1525 // 1526 //------------------------------------------------------------------------------ 1527 // CAUTION 1528 // 1529 //------------------------------------------------------------------------------ 1530 OSCL_EXPORT_REF CAACFileParser::~CAACFileParser(void) 1531 { 1532 1533 if (iAACFile.IsOpen()) 1534 { 1535 iAACFile.Close(); 1536 } 1537 if (ipBSO != NULL) 1538 { 1539 PV_AAC_FF_DELETE(NULL, AACBitstreamObject, ipBSO); 1540 ipBSO = NULL; 1541 1542 } 1543 1544 } 1545 1546 //---------------------------------------------------------------------------- 1547 // FUNCTION NAME: CAACFileParser::InitAACFile 1548 //---------------------------------------------------------------------------- 1549 // INPUT AND OUTPUT DEFINITIONS 1550 // 1551 // Inputs: 1552 // aClip = pointer to the AAC file name to be played of type TPtrC 1553 // 1554 // Outputs: 1555 // None 1556 // 1557 // Returns: 1558 // returnValue = true if the init succeeds, else false. 1559 // 1560 // Global Variables Used: 1561 // None 1562 // 1563 //---------------------------------------------------------------------------- 1564 // FUNCTION DESCRIPTION 1565 // 1566 // This function opens the AAC file, checks for AAC format type, calculates 1567 // the track duration, and sets the AAC bitrate value. 1568 // 1569 //---------------------------------------------------------------------------- 1570 // REQUIREMENTS 1571 // 1572 //---------------------------------------------------------------------------- 1573 // REFERENCES 1574 // 1575 //------------------------------------------------------------------------------ 1576 // CAUTION 1577 // 1578 //------------------------------------------------------------------------------ 1579 OSCL_EXPORT_REF bool CAACFileParser::InitAACFile(OSCL_wString& aClip, bool aInitParsingEnable, Oscl_FileServer* iFileSession, PVMFCPMPluginAccessInterfaceFactory* aCPMAccess, OsclFileHandle*aHandle) 1580 { 1581 uint32 bitRateValue; 1582 uint32 HeaderLenValue; 1583 1584 iAACFile.SetCPM(aCPMAccess); 1585 iAACFile.SetFileHandle(aHandle); 1586 1587 //For aac overwritte pvfile default settings in order to prevent 1588 //audio artifacts when playing files from MMC 1589 //use native cache (if supported by the platform) size 32KB. 1590 PVFileCacheParams cacheParams; 1591 cacheParams.iCacheSize = 32768; //32K 1592 cacheParams.iNativeAccessMode = 1; 1593 1594 iAACFile.SetFileCacheParams(cacheParams); 1595 1596 // Open the file (aClip) 1597 if (iAACFile.Open(aClip.get_cstr(), (Oscl_File::MODE_READ | Oscl_File::MODE_BINARY), *iFileSession) != 0) 1598 { 1599 return false; 1600 } 1601 1602 // create ipBSO 1603 PV_AAC_FF_NEW(NULL, AACBitstreamObject, (&iAACFile), ipBSO); 1604 1605 if (!ipBSO) 1606 { 1607 return false; 1608 } 1609 if (ipBSO->get()) 1610 { 1611 return false; 1612 } 1613 1614 // get file info: file size, format, sampling rate 1615 uint8 sampleFreqTableValue; 1616 TAACFormat format; 1617 if (ipBSO->getFileInfo(iAACFileSize, format, sampleFreqTableValue, bitRateValue, HeaderLenValue, aClip)) 1618 { 1619 return false; 1620 } 1621 1622 if (format == EAACADTS) 1623 { 1624 // ADTS format 1625 iAACFormat = EAACADTS; 1626 if (sampleFreqTableValue >= 16) 1627 return false; 1628 iAACSampleFrequency = ADTSSampleFreqTable[(uint16)sampleFreqTableValue]; 1629 if (iAACSampleFrequency == -1) 1630 return false; 1631 } 1632 else if (format == EAACADIF) 1633 { 1634 // ADIF format 1635 iAACFormat = EAACADIF; 1636 //ADIF and ADTS uses the same sampling frequency lookup table 1637 if (sampleFreqTableValue >= 16) 1638 return false; 1639 iAACSampleFrequency = ADTSSampleFreqTable[(uint16)sampleFreqTableValue]; 1640 if (iAACSampleFrequency == -1) 1641 return false; 1642 //bitrate and variable header length for ADIF only 1643 iAACBitRate = (int32)bitRateValue; 1644 iAACHeaderLen = (int32)HeaderLenValue; 1645 iFirstTime = true; 1646 } 1647 else if (format == EAACRaw) 1648 { 1649 // AAC raw format 1650 iAACFormat = EAACRaw; 1651 // Use the same sampling frequency lookup table 1652 if (sampleFreqTableValue >= 16) 1653 return false; 1654 iAACSampleFrequency = ADTSSampleFreqTable[(uint16)sampleFreqTableValue]; 1655 if (iAACSampleFrequency == -1) 1656 return false; 1657 //variable header length for raw only 1658 iAACHeaderLen = (int32)HeaderLenValue; 1659 iFirstTime = true; 1660 } 1661 else 1662 { 1663 iAACFormat = EAACUnrecognized; 1664 return false; 1665 } 1666 1667 // Determine file duration and set up random positioning table if needed 1668 if (aInitParsingEnable) 1669 { 1670 if (iAACFormat == EAACADTS) 1671 { 1672 // fully go through each frame to calculate duration 1673 int32 status = AACBitstreamObject::EVERYTHING_OK; 1674 int32 frame_size = 0; 1675 int32 numBlocks; 1676 1677 1678 uint8 *maxAACFrameBuffer = OSCL_ARRAY_NEW(uint8, MAX_AAC_FRAME_SIZE); // MAX_AAC_FRAME_SIZE=8192 1679 if (!maxAACFrameBuffer) 1680 { 1681 return false; 1682 } 1683 AutoPtrArrayContainer<uint8> autoPtr(maxAACFrameBuffer); 1684 1685 iAACDuration = 0; 1686 int32 filePos = 0; 1687 iRPTable.push_back(filePos); 1688 1689 while (status == AACBitstreamObject::EVERYTHING_OK) 1690 { 1691 // get the next frame 1692 status = ipBSO->getNextFrameInfo(frame_size, numBlocks); 1693 if (status == AACBitstreamObject::END_OF_FILE) 1694 { 1695 break; 1696 } 1697 else if (status == AACBitstreamObject::EVERYTHING_OK && frame_size > 0) 1698 { 1699 int32 hdrSize = 0; 1700 status = ipBSO->getNextFrame(maxAACFrameBuffer, frame_size, hdrSize); 1701 1702 if (status == AACBitstreamObject::EVERYTHING_OK) 1703 { 1704 // calulate the number of frames 1705 iAACDuration ++; 1706 1707 // set up the table for randow positioning 1708 int32 frame_length = frame_size + ADTS_HEADER_LENGTH + (ipBSO->isCRCEnabled() ? 2 : 0); 1709 filePos += frame_length; 1710 iRPTable.push_back(filePos); 1711 } 1712 else if (status == AACBitstreamObject::END_OF_FILE) 1713 { 1714 break; 1715 } 1716 else 1717 { 1718 // error happens! 1719 PVMF_AACPARSER_LOGERROR((0, "Error InitAacfile")); 1720 return false; 1721 1722 } 1723 } 1724 else 1725 { 1726 // error happens! 1727 PVMF_AACPARSER_LOGERROR((0, "CAACFileParser::InitAACFile:Error in getting next frame ")); 1728 return false; 1729 } 1730 } 1731 1732 // get the duration in millisec 1733 MediaClockConverter mcc; 1734 mcc.set_timescale(iAACSampleFrequency); 1735 mcc.set_clock(iAACDuration*1024, 0); 1736 iAACDuration = mcc.get_converted_ts(1000); 1737 1738 if (ipBSO->reset(0)) 1739 return false; 1740 } 1741 else if (iAACFormat == EAACADIF) 1742 { 1743 int32 raw_data_bits; 1744 1745 iAACDuration = 0; 1746 iRPTable.push_back(iAACDuration); 1747 1748 raw_data_bits = iAACFileSize * 8 - iAACHeaderLen; 1749 1750 // rough duration calculation based on max bitrate for variable rate bitstream 1751 MediaClockConverter mcc; 1752 mcc.set_timescale(iAACBitRate); 1753 mcc.set_clock(raw_data_bits, 0); 1754 iAACDuration = mcc.get_converted_ts(1000); 1755 1756 if (ipBSO->reset(ipBSO->GetByteOffsetToStartOfAudioFrames() + (iAACHeaderLen >> 3))) 1757 return false; 1758 } 1759 else if (iAACFormat == EAACRaw) 1760 { 1761 iAACDuration = 0; 1762 iRPTable.push_back(iAACDuration); 1763 1764 // Duration cannot be calculated 1765 int32 hdrsize = iAACHeaderLen >> 3; 1766 if (iAACHeaderLen&0x7) 1767 { 1768 ++hdrsize; 1769 } 1770 if (ipBSO->reset(ipBSO->GetByteOffsetToStartOfAudioFrames() + hdrsize)) 1771 { 1772 PVMF_AACPARSER_LOGERROR((0, "CAACFileParser::InitAACFile:Error Bitstream object failed to reset")); 1773 return false; 1774 } 1775 } 1776 1777 } // end of: if(aInitParsingEnable) 1778 1779 1780 return true; 1781 } 1782 1783 //---------------------------------------------------------------------------- 1784 // FUNCTION NAME: CAACFileParser::RetrieveFileInfo 1785 //---------------------------------------------------------------------------- 1786 // INPUT AND OUTPUT DEFINITIONS 1787 // 1788 // Inputs: 1789 // 1790 // Outputs: 1791 // None 1792 // 1793 // Returns: 1794 // false if an error happens, else true 1795 // 1796 // Global Variables Used: 1797 // None 1798 // 1799 //---------------------------------------------------------------------------- 1800 // FUNCTION DESCRIPTION 1801 // 1802 // This function opens the AAC file, checks for AAC format type, calculates 1803 // the track duration, and sets the AAC bitrate value. 1804 // 1805 //---------------------------------------------------------------------------- 1806 // REQUIREMENTS 1807 // 1808 //---------------------------------------------------------------------------- 1809 // REFERENCES 1810 // 1811 //------------------------------------------------------------------------------ 1812 // CAUTION 1813 // 1814 //------------------------------------------------------------------------------ 1815 OSCL_EXPORT_REF bool CAACFileParser::RetrieveFileInfo(TPVAacFileInfo& aInfo) 1816 { 1817 if (iAACFormat == EAACUnrecognized) 1818 { 1819 // File is not open and parsed 1820 return false; 1821 } 1822 1823 aInfo.iTimescale = 1000; 1824 aInfo.iDuration = iAACDuration; 1825 aInfo.iSampleFrequency = iAACSampleFrequency; 1826 aInfo.iBitrate = iAACBitRate; 1827 aInfo.iFormat = iAACFormat; 1828 aInfo.iFileSize = iAACFileSize; 1829 PVMF_AACPARSER_LOGDIAGNOSTICS((0, "CAACFileParser::RetrieveFileInfo- duration = %d, bitrate = %d, filesize = %d", iAACDuration, iAACBitRate, iAACFileSize)); 1830 1831 return true; 1832 } 1833 1834 //---------------------------------------------------------------------------- 1835 // FUNCTION NAME: CAACFileParser::RetrieveID3Info 1836 //---------------------------------------------------------------------------- 1837 // INPUT AND OUTPUT DEFINITIONS 1838 // 1839 // Inputs: 1840 // aID3MetaData: pointer to data structure for the output. 1841 // 1842 // Outputs: 1843 // None 1844 // 1845 // Returns: 1846 // false if an error happens, else true 1847 // 1848 // Global Variables Used: 1849 // None 1850 // 1851 //---------------------------------------------------------------------------- 1852 // FUNCTION DESCRIPTION 1853 // 1854 // This function retrieves the ID3 data if any was found in the file. 1855 // 1856 //---------------------------------------------------------------------------- 1857 // REQUIREMENTS 1858 // 1859 //---------------------------------------------------------------------------- 1860 // REFERENCES 1861 // 1862 //------------------------------------------------------------------------------ 1863 // CAUTION 1864 // 1865 //------------------------------------------------------------------------------ 1866 OSCL_EXPORT_REF bool CAACFileParser::RetrieveID3Info(PvmiKvpSharedPtrVector& aID3MetaData) 1867 { 1868 if (ipBSO) 1869 { 1870 ipBSO->ID3MetaData(aID3MetaData); 1871 if (aID3MetaData.size() > 0) 1872 return true; 1873 else 1874 return false; 1875 } 1876 else 1877 { 1878 return false; 1879 } 1880 } 1881 1882 OSCL_EXPORT_REF bool CAACFileParser::IsID3Frame(const OSCL_String &frameType) 1883 { 1884 return ipBSO->IsID3Frame(frameType); 1885 } 1886 1887 OSCL_EXPORT_REF void CAACFileParser::GetID3Frame(const OSCL_String& aFrameType, PvmiKvpSharedPtrVector& aFrame) 1888 { 1889 ipBSO->GetID3Frame(aFrameType, aFrame); 1890 } 1891 1892 //---------------------------------------------------------------------------- 1893 // FUNCTION NAME: CAACFileParser::ResetPlayback 1894 //---------------------------------------------------------------------------- 1895 // INPUT AND OUTPUT DEFINITIONS 1896 // 1897 // Inputs: 1898 // aStartTime = integer value as where to move the playback positioning to. 1899 // 1900 // Outputs: 1901 // None 1902 // 1903 // Returns: 1904 // 0 if success, -1 if failure 1905 // 1906 // Global Variables Used: 1907 // None 1908 // 1909 //---------------------------------------------------------------------------- 1910 // FUNCTION DESCRIPTION 1911 // 1912 // This function sets the file pointer to the location that aStartTime would 1913 // point to in the file. 1914 // 1915 //---------------------------------------------------------------------------- 1916 // REQUIREMENTS 1917 // 1918 //---------------------------------------------------------------------------- 1919 // REFERENCES 1920 // 1921 //------------------------------------------------------------------------------ 1922 // CAUTION 1923 // 1924 //------------------------------------------------------------------------------ 1925 1926 OSCL_EXPORT_REF int32 CAACFileParser::ResetPlayback(uint32 aStartTime, uint32& aActualStartTime) 1927 { 1928 // Check if the file is opened 1929 int32 result; 1930 if (!iAACFile.IsOpen()) 1931 { 1932 PVMF_AACPARSER_LOGERROR((0, "CAACFileParser::ResetPlayback- Misc error-")); 1933 return AACBitstreamObject::MISC_ERROR; 1934 } 1935 1936 // initialize "iTotalNumFramesRead" 1937 // +1 means we choose the next frame(ts>=aStartTime) 1938 //iTotalNumFramesRead = aStartTime/(1024000/iAACSampleFrequency); 1939 iTotalNumFramesRead = (int32)((OsclFloat)aStartTime * iAACSampleFrequency / 1024000.0) + (aStartTime > 0) * 1; 1940 PVMF_AACPARSER_LOGDIAGNOSTICS((0, "CAACFileParser::resetplayback - TotalNumFramesRead=%d", iTotalNumFramesRead)); 1941 1942 if (iAACFormat == EAACADTS) 1943 { 1944 // set new file position 1945 int32 newPosition = 0; 1946 if (iAACDuration != 0 && iRPTable.size() <= 0) 1947 { 1948 newPosition = (iAACFileSize * aStartTime) / iAACDuration; 1949 PVMF_AACPARSER_LOGDIAGNOSTICS((0, "CAACFileParser::resetplayback - newPosition=%d", newPosition)); 1950 if (newPosition < 0) 1951 { 1952 newPosition = 0; // if we have no duration information, reset the file position at 0. 1953 } 1954 } 1955 else if (iRPTable.size() > 0) 1956 { 1957 // use the randow positioning table to determine the file position 1958 if (iTotalNumFramesRead > (int32)iRPTable.size()) 1959 { 1960 iTotalNumFramesRead = ((int32)iRPTable.size()) - 2; 1961 } 1962 newPosition = iRPTable[iTotalNumFramesRead]; 1963 } 1964 result = ipBSO->reset(ipBSO->GetByteOffsetToStartOfAudioFrames() + newPosition); 1965 if (newPosition >= 0 && result) 1966 { 1967 PVMF_AACPARSER_LOGERROR((0, "CAACFileParser::ResetPlayback- Misc error-")); 1968 return result; 1969 } 1970 iEndOfFileReached = false; 1971 } 1972 else if (iAACFormat == EAACADIF) 1973 { 1974 int32 newPosition = (iAACHeaderLen >> 3); 1975 1976 if (newPosition >= 0 && ipBSO->reset(ipBSO->GetByteOffsetToStartOfAudioFrames() + newPosition)) 1977 { 1978 PVMF_AACPARSER_LOGERROR((0, "CAACFileParser::ResetPlayback- Misc error-")); 1979 return AACBitstreamObject::MISC_ERROR; 1980 } 1981 iEndOfFileReached = false; 1982 iFirstTime = true; 1983 iTotalNumFramesRead = 0; // For ADIF reposition to time 0 always 1984 } 1985 else if (iAACFormat == EAACRaw) 1986 { 1987 int32 newPosition = (iAACHeaderLen >> 3); 1988 if (iAACHeaderLen&0x7) 1989 { 1990 ++newPosition; 1991 } 1992 1993 if (newPosition >= 0 && ipBSO->reset(ipBSO->GetByteOffsetToStartOfAudioFrames() + newPosition)) 1994 { 1995 PVMF_AACPARSER_LOGERROR((0, "CAACFileParser::ResetPlayback- Misc error-")); 1996 return AACBitstreamObject::MISC_ERROR; 1997 } 1998 iEndOfFileReached = false; 1999 iFirstTime = true; 2000 iTotalNumFramesRead = 0; // For AAC raw bitstream reposition to time 0 always 2001 } 2002 2003 MediaClockConverter mcc; 2004 mcc.set_timescale(iAACSampleFrequency); 2005 mcc.set_clock(iTotalNumFramesRead*1024, 0); 2006 aActualStartTime = mcc.get_converted_ts(1000); 2007 2008 PVMF_AACPARSER_LOGDIAGNOSTICS((0, "CAACFileParser::resetplayback - aActualStartTime=%d", aActualStartTime)); 2009 return AACBitstreamObject::EVERYTHING_OK; 2010 } 2011 2012 //---------------------------------------------------------------------------- 2013 // FUNCTION NAME: CAACFileParser::SeekPointFromTimestamp 2014 //---------------------------------------------------------------------------- 2015 // INPUT AND OUTPUT DEFINITIONS 2016 // 2017 // Inputs: 2018 // aStartTime = integer value as for the specified start time 2019 // 2020 // Outputs: 2021 // None 2022 // 2023 // Returns: 2024 // Timestamp in milliseconds of the actual position 2025 // 2026 // Global Variables Used: 2027 // None 2028 // 2029 //---------------------------------------------------------------------------- 2030 // FUNCTION DESCRIPTION 2031 // 2032 // This function returns the timestamp for an actual position corresponding 2033 // to the specified start time 2034 // 2035 //---------------------------------------------------------------------------- 2036 // REQUIREMENTS 2037 // 2038 //---------------------------------------------------------------------------- 2039 // REFERENCES 2040 // 2041 //------------------------------------------------------------------------------ 2042 // CAUTION 2043 // 2044 //------------------------------------------------------------------------------ 2045 OSCL_EXPORT_REF uint32 CAACFileParser::SeekPointFromTimestamp(uint32 aStartTime) 2046 { 2047 // Check if the file is opened 2048 if (!iAACFile.IsOpen()) 2049 { 2050 return 0; 2051 } 2052 2053 // Determine the frame number corresponding to timestamp 2054 // note: +1 means we choose the next frame(ts>=aStartTime) 2055 uint32 startframenum = (int32)((OsclFloat)aStartTime * iAACSampleFrequency / 1024000.0) + (aStartTime > 0) * 1; 2056 2057 // Correct the frame number if necessary 2058 if (iAACFormat == EAACADTS) 2059 { 2060 // set new file position 2061 if (iAACDuration != 0 && iRPTable.size() <= 0) 2062 { 2063 // Duration not known and reposition table not available so go to first frame 2064 startframenum = 0; 2065 } 2066 else if (iRPTable.size() > 0) 2067 { 2068 if (startframenum >= iRPTable.size()) 2069 { 2070 // Requesting past the end of table so set to (end of table-1) 2071 // to be at the last sample 2072 startframenum = ((int32)iRPTable.size()) - 2; 2073 } 2074 } 2075 } 2076 else if (iAACFormat == EAACADIF || iAACFormat == EAACRaw) 2077 { 2078 // Not enough info in file to reposition so go to time 0 2079 return 0; 2080 } 2081 2082 return (int32)((OsclFloat)startframenum*1024000.0 / iAACSampleFrequency); 2083 } 2084 2085 //---------------------------------------------------------------------------- 2086 // FUNCTION NAME: CAACFileParser::GetNextBundledAccessUnits 2087 //---------------------------------------------------------------------------- 2088 // INPUT AND OUTPUT DEFINITIONS 2089 // 2090 // Inputs: 2091 // aNumSamples = requested number of frames to be read from file 2092 // aGau = frame information structure of type GAU 2093 // 2094 // Outputs: 2095 // None 2096 // 2097 // Returns: 2098 // 0 if success, -1 if failure 2099 // Global Variables Used: 2100 // None 2101 // 2102 //---------------------------------------------------------------------------- 2103 // FUNCTION DESCRIPTION 2104 // 2105 // This function attempts to read in the number of AAC frames specified by 2106 // aNumSamples. It formats the read data to WMF bit order and stores it in 2107 // the GAU structure. 2108 // 2109 //---------------------------------------------------------------------------- 2110 // REQUIREMENTS 2111 // 2112 //---------------------------------------------------------------------------- 2113 // REFERENCES 2114 // 2115 //------------------------------------------------------------------------------ 2116 // CAUTION 2117 // 2118 //------------------------------------------------------------------------------ 2119 OSCL_EXPORT_REF int32 2120 CAACFileParser::GetNextBundledAccessUnits(uint32 *aNumSamples, 2121 GAU *aGau, 2122 bool bADTSHeaderIncluded) 2123 { 2124 // AMR format has already been identified in InitAMRFile function. 2125 // Check if AMR format is valid as the safeguard 2126 if (iAACFormat == EAACUnrecognized) 2127 { 2128 PVMF_AACPARSER_LOGERROR((0, "CAACFileParser::GetNextBundledAccessUnits- Misc error-")); 2129 return AACBitstreamObject::MISC_ERROR; 2130 } 2131 2132 int32 returnValue = AACBitstreamObject::EVERYTHING_OK; 2133 2134 if (iAACFormat == EAACADTS) 2135 { 2136 if (iEndOfFileReached) 2137 { 2138 *aNumSamples = 0; 2139 return AACBitstreamObject::END_OF_FILE; 2140 } 2141 2142 uint8* pTempGau = (uint8 *)aGau->buf.fragments[0].ptr; 2143 uint32 gauBufferSize = aGau->buf.fragments[0].len; 2144 uint32 i, bytesReadInGau = 0, numSamplesRead = 0; 2145 int32 frame_size = 0, numBlocks; 2146 int32 prev_iTotalNumFramesRead = iTotalNumFramesRead; // BX 2147 2148 for (i = 0; i < *aNumSamples && !iEndOfFileReached; i++) 2149 { 2150 // get the frame size and number of data blocks 2151 returnValue = ipBSO->getNextFrameInfo(frame_size, numBlocks); 2152 PVMF_AACPARSER_LOGDIAGNOSTICS((0, "CAACFileParser::GetNextBundledAccessUnits - frame_size=%d", frame_size)); 2153 if (returnValue == AACBitstreamObject::END_OF_FILE) 2154 { 2155 iEndOfFileReached = true; 2156 break; 2157 } 2158 2159 else if (returnValue == AACBitstreamObject::EVERYTHING_OK && frame_size > 0) 2160 { 2161 // Check whether the gau buffer will be overflow or the requested number 2162 // of samples will be met 2163 if (bytesReadInGau + frame_size >= gauBufferSize || 2164 numSamplesRead + numBlocks > *aNumSamples) 2165 break; 2166 2167 // At this point, we can get the next frame 2168 int32 hdrSize = 0; 2169 returnValue = ipBSO->getNextFrame(pTempGau, frame_size, hdrSize, bADTSHeaderIncluded); 2170 if (returnValue == AACBitstreamObject::END_OF_FILE) 2171 { 2172 iEndOfFileReached = true; 2173 break; 2174 } 2175 else if (returnValue == AACBitstreamObject::EVERYTHING_OK) 2176 { 2177 // update infomation 2178 pTempGau += frame_size; 2179 bytesReadInGau += frame_size; 2180 aGau->info[i].len = frame_size + hdrSize; 2181 aGau->info[i].ts = (int32)(((OsclFloat)(iTotalNumFramesRead++) * 1024000.0) / (OsclFloat)iAACSampleFrequency); // BX 2182 numSamplesRead += numBlocks; 2183 } 2184 else 2185 { // error happens!! 2186 PVMF_AACPARSER_LOGERROR((0, "CAACFileParser::GetNextBundledAccessUnits- Read error-")); 2187 *aNumSamples = 0; 2188 return AACBitstreamObject::READ_ERROR; 2189 } 2190 } 2191 else 2192 { 2193 // error happens!! 2194 PVMF_AACPARSER_LOGERROR((0, "CAACFileParser::GetNextBundledAccessUnits- Read error-")); 2195 *aNumSamples = 0; 2196 return AACBitstreamObject::READ_ERROR; 2197 } 2198 } // end of: for(i = 0; i < *aNumSamples && !iEndOfFileReached; i++) 2199 2200 aGau->info[0].ts = (int32)(((OsclFloat)prev_iTotalNumFramesRead * 1024000.0) / (OsclFloat)iAACSampleFrequency); // BX 2201 *aNumSamples = numSamplesRead; 2202 } 2203 2204 else if (iAACFormat == EAACADIF || iAACFormat == EAACRaw) 2205 { 2206 *aNumSamples = 0; 2207 2208 uint8* pTempGau = (uint8 *)aGau->buf.fragments[0].ptr; //point to the current data location in StreamingBuffer 2209 uint32 gauBufferSize = aGau->buf.fragments[0].len; 2210 uint32 bytesReadInGau = 0; 2211 uint32 bytestoread = 0; 2212 uint32 i; 2213 2214 if (iFirstTime == true) 2215 { 2216 // read from file to get two guranteed AAC decoder frames in streaming buffer 2217 for (i = 0; i < 2; i++) //AAC Streaming Buffer Max Data Size is 15359 (9*1536 + 1535) 2218 { 2219 // At this point, we can get the next frame 2220 if (bytesReadInGau >= gauBufferSize) 2221 { 2222 // No more buffer space to read 2223 break; 2224 } 2225 bytestoread = gauBufferSize - bytesReadInGau; 2226 if (bytestoread > AAC_DECODER_INPUT_BUFF_SIZE) 2227 { 2228 bytestoread = AAC_DECODER_INPUT_BUFF_SIZE; 2229 } 2230 int32 hdrSize = 0; 2231 returnValue = ipBSO->getNextFrame(pTempGau, (int32 &)bytestoread, hdrSize, bADTSHeaderIncluded); 2232 2233 if (returnValue == AACBitstreamObject::END_OF_FILE) 2234 { 2235 iEndOfFileReached = true; 2236 break; 2237 } 2238 else if (returnValue == AACBitstreamObject::EVERYTHING_OK) 2239 { 2240 // update infomation 2241 pTempGau += bytestoread; 2242 aGau->info[i].len = bytestoread; 2243 aGau->info[i].ts = 0; // First block of AAC data read has timestamp 0 2244 bytesReadInGau += bytestoread; 2245 *aNumSamples += 1; 2246 } 2247 else 2248 { 2249 // error happens!! 2250 PVMF_AACPARSER_LOGERROR((0, "CAACFileParser::GetNextBundledAccessUnits- Read error-")); 2251 return AACBitstreamObject::READ_ERROR; 2252 } 2253 } 2254 iFirstTime = false; 2255 } 2256 else // read from file to get one guranteed AAC decoder frame in streaming buffer 2257 { 2258 // At this point, we can get the next frame 2259 bytestoread = gauBufferSize; 2260 if (bytestoread > AAC_DECODER_INPUT_BUFF_SIZE) 2261 { 2262 bytestoread = AAC_DECODER_INPUT_BUFF_SIZE; 2263 } 2264 2265 int32 hdrSize = 0; 2266 returnValue = ipBSO->getNextFrame(pTempGau, (int32 &)bytestoread, hdrSize, bADTSHeaderIncluded); 2267 2268 if (returnValue == AACBitstreamObject::END_OF_FILE) 2269 { 2270 iEndOfFileReached = true; 2271 } 2272 else if (returnValue == AACBitstreamObject::EVERYTHING_OK) 2273 { 2274 // update infomation 2275 aGau->info[0].len = bytestoread; 2276 aGau->info[0].ts = 0xFFFFFFFF; // Unknown timestamp 2277 // aGau->info[0].ts=(int32)(((OsclFloat)(iTotalNumFramesRead++) * 1024000.0) / (OsclFloat)iAACSampleFrequency); // BX 2278 bytesReadInGau += bytestoread; 2279 *aNumSamples += 1; 2280 } 2281 else 2282 { 2283 // error happens!! 2284 PVMF_AACPARSER_LOGERROR((0, "CAACFileParser::GetNextBundledAccessUnits- Read error-")); 2285 return AACBitstreamObject::READ_ERROR; 2286 } 2287 } 2288 } 2289 2290 //We may have reached EOF but also found some samples. 2291 //don't return EOF until there are no samples left. 2292 if (returnValue == AACBitstreamObject::END_OF_FILE 2293 && *aNumSamples > 0) 2294 { 2295 return AACBitstreamObject::EVERYTHING_OK; 2296 } 2297 2298 return returnValue; 2299 } 2300 2301 //---------------------------------------------------------------------------- 2302 // FUNCTION NAME: CAACFileParser::PeekNextTimestamp 2303 //---------------------------------------------------------------------------- 2304 // INPUT AND OUTPUT DEFINITIONS 2305 // 2306 // Inputs: 2307 // None 2308 // 2309 // Outputs: 2310 // None 2311 // 2312 // Returns: 2313 // return = status EVERYTHING_OK. 2314 // 2315 // Global Variables Used: 2316 // None 2317 // 2318 //---------------------------------------------------------------------------- 2319 // FUNCTION DESCRIPTION 2320 // 2321 // This function returns the next timestamp without processing any data. 2322 // 2323 //---------------------------------------------------------------------------- 2324 // REQUIREMENTS 2325 // 2326 //---------------------------------------------------------------------------- 2327 // REFERENCES 2328 // 2329 //------------------------------------------------------------------------------ 2330 // CAUTION 2331 // 2332 //------------------------------------------------------------------------------ 2333 OSCL_EXPORT_REF int32 CAACFileParser::PeekNextTimestamp(uint32& ts) 2334 { 2335 MediaClockConverter mcc; 2336 mcc.set_timescale(iAACSampleFrequency); 2337 mcc.set_clock((iTotalNumFramesRead + 1)*1024, 0); 2338 ts = mcc.get_converted_ts(1000); 2339 2340 return AACBitstreamObject::EVERYTHING_OK; 2341 } 2342 2343 //---------------------------------------------------------------------------- 2344 // FUNCTION NAME: CAACFileParser::GetTrackDecoderSpecificInfoSize 2345 //---------------------------------------------------------------------------- 2346 // INPUT AND OUTPUT DEFINITIONS 2347 // 2348 // Inputs: 2349 // None 2350 // 2351 // Outputs: 2352 // None 2353 // 2354 // Returns: 2355 // return = AAC_DECODER_SPECIFIC_INFO_SIZE 2356 // 2357 // Global Variables Used: 2358 // None 2359 // 2360 //---------------------------------------------------------------------------- 2361 // FUNCTION DESCRIPTION 2362 // 2363 // This function returns the value defined by AAC_DECODER_SPECIFIC_INFO_SIZE. 2364 // 2365 //---------------------------------------------------------------------------- 2366 // REQUIREMENTS 2367 // 2368 //---------------------------------------------------------------------------- 2369 // REFERENCES 2370 // 2371 //------------------------------------------------------------------------------ 2372 // CAUTION 2373 // 2374 //------------------------------------------------------------------------------ 2375 OSCL_EXPORT_REF int32 CAACFileParser::GetTrackDecoderSpecificInfoSize(void) 2376 { 2377 if (iAACFormat == EAACRaw) 2378 { 2379 int32 infosize = iAACHeaderLen >> 3; 2380 if (iAACHeaderLen&0x7) 2381 { 2382 ++infosize; 2383 } 2384 return infosize; 2385 } 2386 else 2387 { 2388 return AAC_DECODER_SPECIFIC_INFO_SIZE; 2389 } 2390 } 2391 2392 //---------------------------------------------------------------------------- 2393 // FUNCTION NAME: CAACFileParser::GetTrackDecoderSpecificInfoContent 2394 //---------------------------------------------------------------------------- 2395 // INPUT AND OUTPUT DEFINITIONS 2396 // 2397 // Inputs: 2398 // None 2399 // 2400 // Outputs: 2401 // None 2402 // 2403 // Returns: 2404 // return = address to location of iAACFrameBuffer[PACKET_INDICATOR_LENGTH] 2405 // 2406 // Global Variables Used: 2407 // None 2408 // 2409 //---------------------------------------------------------------------------- 2410 // FUNCTION DESCRIPTION 2411 // 2412 // This function populates iAACFrameBuffer with the two byte of decoder 2413 // specific info and returns the address to the values. 2414 // 2415 //---------------------------------------------------------------------------- 2416 // REQUIREMENTS 2417 // 2418 //---------------------------------------------------------------------------- 2419 // REFERENCES 2420 // 2421 //------------------------------------------------------------------------------ 2422 // CAUTION 2423 // 2424 //------------------------------------------------------------------------------ 2425 OSCL_EXPORT_REF uint8* CAACFileParser::GetTrackDecoderSpecificInfoContent(void) 2426 { 2427 iAACFrameBuffer[PACKET_INDICATOR_LENGTH] = 0x12; 2428 iAACFrameBuffer[PACKET_INDICATOR_LENGTH + 1] = 0x10; 2429 2430 ipBSO->getDecoderConfigHeader(&iAACFrameBuffer[PACKET_INDICATOR_LENGTH]); 2431 return &iAACFrameBuffer[PACKET_INDICATOR_LENGTH]; 2432 } 2433 2434 //---------------------------------------------------------------------------- 2435 // FUNCTION NAME: CAACFileParser::GetAACFormat 2436 //---------------------------------------------------------------------------- 2437 // INPUT AND OUTPUT DEFINITIONS 2438 // 2439 // Inputs: 2440 // None 2441 // 2442 // Outputs: 2443 // None 2444 // 2445 // Returns: 2446 // return = iAACFormat 2447 // 2448 // Global Variables Used: 2449 // None 2450 // 2451 //---------------------------------------------------------------------------- 2452 // FUNCTION DESCRIPTION 2453 // 2454 // This function returns iAACFormat value. 2455 // 2456 //---------------------------------------------------------------------------- 2457 // REQUIREMENTS 2458 // 2459 //---------------------------------------------------------------------------- 2460 // REFERENCES 2461 // 2462 //------------------------------------------------------------------------------ 2463 // CAUTION 2464 // 2465 //------------------------------------------------------------------------------ 2466 OSCL_EXPORT_REF TAACFormat CAACFileParser::GetAACFormat(void) 2467 { 2468 return iAACFormat; 2469 } 2470 2471 OSCL_EXPORT_REF PVID3Version CAACFileParser::GetID3Version() const 2472 { 2473 return ipBSO->GetID3Version(); 2474 } 2475 2476 OSCL_EXPORT_REF ParserErrorCode CAACFileParser::getAACHeaderLen(OSCL_wString& aClip, 2477 bool aInitParsingEnable, 2478 Oscl_FileServer* iFileSession, 2479 PVMFCPMPluginAccessInterfaceFactory* aCPMAccess, 2480 OsclFileHandle* aHandle, 2481 uint32* HeaderLenValue) 2482 { 2483 PVFile iAACFileTemp; 2484 OSCL_UNUSED_ARG(aInitParsingEnable); 2485 2486 iAACFileTemp.SetCPM(aCPMAccess); 2487 iAACFileTemp.SetFileHandle(aHandle); 2488 2489 // Open the file (aClip) 2490 if (iAACFileTemp.Open(aClip.get_cstr(), (Oscl_File::MODE_READ | Oscl_File::MODE_BINARY), *iFileSession) != 0) 2491 { 2492 PVMF_AACPARSER_LOGERROR((0, "CAACFileParser::getAACHeaderLen- File open error-")); 2493 return FILE_OPEN_ERROR; 2494 } 2495 AACBitstreamObject *ipBSOTemp; 2496 PV_AAC_FF_NEW(NULL, AACBitstreamObject, (&iAACFileTemp), ipBSOTemp); 2497 2498 2499 if (!ipBSOTemp || ipBSOTemp->get()) 2500 { 2501 PVMF_AACPARSER_LOGERROR((0, "CAACFileParser::getAACHeaderLen- Memory allocation failed-")); 2502 // release temp storage, file control block.. 2503 iAACFileTemp.Close(); 2504 PV_AAC_FF_DELETE(NULL, AACBitstreamObject, ipBSOTemp); 2505 return MEMORY_ERROR; 2506 } 2507 2508 uint32 bitRateValueTemp; 2509 uint32 tempHeaderLenValue = 0; 2510 2511 int32 iAACFileSizeTemp; 2512 uint8 sampleFreqTableValueTemp; 2513 TAACFormat formatTemp; 2514 if (ipBSOTemp->getFileInfo(iAACFileSizeTemp, formatTemp, sampleFreqTableValueTemp, bitRateValueTemp, tempHeaderLenValue, aClip)) 2515 { 2516 return FILE_OPEN_ERROR; 2517 } 2518 if (formatTemp == EAACADTS) 2519 { 2520 tempHeaderLenValue = ADTS_HEADER_LENGTH; 2521 } 2522 iAACFileTemp.Close(); 2523 PV_AAC_FF_DELETE(NULL, AACBitstreamObject, ipBSOTemp); 2524 ipBSOTemp = NULL; 2525 *HeaderLenValue = tempHeaderLenValue; 2526 return OK; 2527 } 2528 2529 OSCL_EXPORT_REF ParserErrorCode CAACFileParser::IsAACFile(OSCL_wString& aClip, Oscl_FileServer* aFileSession, PVMFCPMPluginAccessInterfaceFactory* aCPMAccess, OsclFileHandle* aHandle) 2530 { 2531 PVFile iAACFileTemp; 2532 iAACFileTemp.SetCPM(aCPMAccess); 2533 iAACFileTemp.SetFileHandle(aHandle); 2534 2535 // Open the file (aClip) 2536 if (iAACFileTemp.Open(aClip.get_cstr(), (Oscl_File::MODE_READ | Oscl_File::MODE_BINARY), *aFileSession) != 0) 2537 { 2538 PVMF_AACPARSER_LOGERROR((0, "CAACFileParser::IsAACFile- File open error-")); 2539 return FILE_OPEN_ERROR; 2540 } 2541 2542 AACBitstreamObject *ipBSOTemp; 2543 PV_AAC_FF_NEW(NULL, AACBitstreamObject, (&iAACFileTemp), ipBSOTemp); 2544 2545 if (!ipBSOTemp || ipBSOTemp->get()) 2546 { 2547 PVMF_AACPARSER_LOGERROR((0, "CAACFileParser::IsAACFile- Memory allocation failed-")); 2548 // release temp storage, file control block.. 2549 iAACFileTemp.Close(); 2550 PV_AAC_FF_DELETE(NULL, AACBitstreamObject, ipBSOTemp); 2551 return MEMORY_ERROR; 2552 } 2553 2554 int32 result = ipBSOTemp->isAACFile(); 2555 2556 // release temp storage, file control block and the file 2557 iAACFileTemp.Close(); 2558 PV_AAC_FF_DELETE(NULL, AACBitstreamObject, ipBSOTemp); 2559 ipBSOTemp = NULL; 2560 2561 if (AACBitstreamObject::EVERYTHING_OK == result) 2562 { 2563 return OK; 2564 } 2565 else if (AACBitstreamObject::INSUFFICIENT_DATA == result) 2566 { 2567 return INSUFFICIENT_DATA; 2568 } 2569 return GENERIC_ERROR; 2570 } 2571 2572