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#include "latmpayloadparser.h" 19 20#include "e_tmp4audioobjecttype.h" 21#include "e_mp4ff_const.h" 22#include "e_progconfigconst.h" 23#include "e_rawbitstreamconst.h" 24#ifndef OSCL_EXCLUSIVE_PTR_H_INCLUDED 25#include "oscl_exclusive_ptr.h" 26#endif 27 28#define MAX_NUM_COMPOSITE_FRAMES 32 29/* Mempool size of latm parser should be at least 1 more than OMX component 30 mempool size, which is 10 */ 31#define PVLATMPARSER_MEDIADATA_POOLNUM 12 32#define PVLATMPARSER_LATMDATA_CHUNKSIZE 1536*10 // 10 maximum aac frames 33#define PVLATMPARSER_MEDIADATA_CHUNKSIZE 128 34 35static uint32 BufferShowBits(uint8 *inbuf, uint32 pos1, uint32 pos2); 36static uint32 BufferReadBits(uint8 *inbuf, uint32 *pos1, int32 len); 37 38 39#ifndef OSCL_DLL_H_INCLUDED 40#include "oscl_dll.h" 41#endif 42 43// Define entry point for this DLL 44OSCL_DLL_ENTRY_POINT_DEFAULT() 45 46 47OSCL_EXPORT_REF PV_LATM_Parser::PV_LATM_Parser() : 48 last_timestamp(0), 49 last_mbit(0), 50 offset(0), 51 framestart(false), 52 framesize(0), 53 currLen(0), 54 firstBlock(true), 55 bytesRead(0), 56 myBool(false), 57 frameNum(0), 58 compositenumframes(0), 59 iMediaDataSimpleAlloc(&iLATMDataMemPool), 60 iLATMDataMemPool(PVLATMPARSER_MEDIADATA_POOLNUM, PVLATMPARSER_LATMDATA_CHUNKSIZE), 61 iMediaDataMemPool(PVLATMPARSER_MEDIADATA_POOLNUM, PVLATMPARSER_MEDIADATA_CHUNKSIZE), 62 sMC(NULL), 63 // used only for composemultipleframe, allow at least 4 AAC frames 64 currSize(PVLATMPARSER_LATMDATA_CHUNKSIZE), 65 firstPacket(true), 66 dropFrames(false), 67 firstSMC(true), 68 startedParsing(false), 69 framePos(NULL), 70 frameCount(0) 71{ 72 multiFrameBuf = (uint8 *) oscl_calloc(currSize, sizeof(uint8)); 73 74 // calculate a max frame size to check if the latm parser gets out of sync 75 maxFrameSize = currSize; // currently allows 4 max length case AAC frames 76 77 iOsclErrorTrapImp = OsclErrorTrap::GetErrorTrapImp(); 78} 79 80 81OSCL_EXPORT_REF PV_LATM_Parser::~PV_LATM_Parser() 82{ 83 if (sMC != NULL) 84 { 85 if (sMC->audioSpecificConfigPtr != NULL) 86 { 87 oscl_free(sMC->audioSpecificConfigPtr); 88 sMC->audioSpecificConfigPtr = NULL; 89 } 90 oscl_free(sMC); 91 sMC = NULL; 92 } 93 if (multiFrameBuf != NULL) 94 { 95 oscl_free(multiFrameBuf); 96 multiFrameBuf = NULL; 97 } 98 99 mediaDataOut.Unbind(); 100} 101 102 103/* ======================================================================== */ 104/* Function : compose() */ 105/* Purpose : parse AAC LATM payload */ 106/* In/out : */ 107/* Return : */ 108/* Note : */ 109/* Modified : */ 110/* ======================================================================== */ 111 112OSCL_EXPORT_REF uint8 PV_LATM_Parser::compose(PVMFSharedMediaDataPtr& mediaDataIn) 113{ 114 uint8 retVal = 0; 115 116 OsclRefCounterMemFrag memFragIn; 117 mediaDataIn->getMediaFragment(0, memFragIn); 118 119 // Don't need the ref to iMediaData so unbind it 120 mediaDataOut.Unbind(); 121 122 int errcode = 0; 123 OsclSharedPtr<PVMFMediaDataImpl> mediaDataImpl; 124 OSCL_TRY_NO_TLS(iOsclErrorTrapImp, errcode, mediaDataImpl = iMediaDataSimpleAlloc.allocate((uint32)memFragIn.getMemFrag().len)); 125 OSCL_FIRST_CATCH_ANY(errcode, return FRAME_OUTPUTNOTAVAILABLE); 126 127 errcode = 0; 128 OSCL_TRY_NO_TLS(iOsclErrorTrapImp, errcode, mediaDataOut = PVMFMediaData::createMediaData(mediaDataImpl, &iMediaDataMemPool)); 129 OSCL_FIRST_CATCH_ANY(errcode, return FRAME_OUTPUTNOTAVAILABLE); 130 131 OsclRefCounterMemFrag memFragOut; 132 mediaDataOut->getMediaFragment(0, memFragOut); 133 134 /* 135 * Latch for very first packet, sequence number is not established yet. 136 */ 137 int32 seqNum = mediaDataIn->getSeqNum(); 138 139 if (!firstPacket) 140 { 141 if ((seqNum - last_sequence_num) > 1) /* detect any gap in sequence */ 142 { 143 // means we missed an RTP packet. 144 dropFrames = true; 145 } 146 } 147 else 148 { 149 firstPacket = false; 150 } 151 152 last_timestamp = mediaDataIn->getTimestamp(); 153 last_sequence_num = seqNum; 154 last_mbit = mediaDataIn->getMarkerInfo(); 155 156 if (dropFrames) 157 { 158 if (mediaDataIn->getMarkerInfo()) 159 { 160 /* 161 * try to recover packet as sequencing was broken, new packet could be valid 162 * it is possible that the received packet contains a complete audioMuxElement() 163 * so try to retrieve it. 164 */ 165 166 dropFrames = false; 167 } 168 else 169 { 170 171 /* 172 * we are in the middle of a spread audioMuxElement(), or faulty rtp header 173 * return error 174 */ 175 176 framesize = 0; 177 frameNum = 0; 178 bytesRead = 0; 179 compositenumframes = 0; 180 181 /* 182 * Drop frame as we are not certain if it is a valid frame 183 */ 184 memFragOut.getMemFrag().len = 0; 185 mediaDataOut->setMediaFragFilledLen(0, 0); 186 187 firstBlock = true; // set for next call 188 return FRAME_ERROR; 189 } 190 } 191 192 193 if (sMC->numSubFrames > 0 || (sMC->cpresent == 1 && ((*(uint8*)(memFragIn.getMemFrag().ptr)) &(0x80)))) 194 { 195 // this is a less efficient version that must be used when you know an AudioMuxElement has 196 // more than one subFrame -- I also added the case where the StreamMuxConfig is inline 197 // The reason for this is that the StreamMuxConfig can be possibly large and there is no 198 // way to know its size without parsing it. (the problem is it can straddle an RTP boundary) 199 // it is less efficient because it composes the AudioMuxElement in a separate buffer (one 200 // oscl_memcpy() per rtp packet) then parses it (one oscl_memcpy() per audio frame to the output 201 // buffer (newpkt->outptr)) when it gets a whole AudioMuxElement. 202 // The function below does a oscl_memcpy() directly into the output buffer 203 // note, composeMultipleFrame will also work for the simple case in case there is another reason 204 // to have to use it.. 205 206 retVal = composeMultipleFrame(mediaDataIn); 207 } 208 else 209 { 210 // this is an efficient version that can be used when you know an AudioMuxElement has 211 // only one subFrame 212 retVal = composeSingleFrame(mediaDataIn); 213 } 214 215 // set this to drop frames in the future -- till we find another marker bit 216 if (retVal == FRAME_ERROR) 217 { 218 dropFrames = true; 219 220 framesize = 0; 221 frameNum = 0; 222 bytesRead = 0; 223 compositenumframes = 0; 224 225 //changed 226 memFragOut.getMemFrag().len = 0; 227 mediaDataOut->setMediaFragFilledLen(0, 0); 228 229 firstBlock = true; // set for next call 230 231 } 232 return retVal; 233} 234 235OSCL_EXPORT_REF uint8 PV_LATM_Parser::compose(uint8* aData, uint32 aDataLen, uint32 aTimestamp, uint32 aSeqNum, uint32 aMbit) 236{ 237 uint8 retVal = 0; 238 239 // Don't need the ref to iMediaData so unbind it 240 mediaDataOut.Unbind(); 241 242 int errcode = 0; 243 OsclSharedPtr<PVMFMediaDataImpl> mediaDataImpl; 244 OSCL_TRY_NO_TLS(iOsclErrorTrapImp, errcode, mediaDataImpl = iMediaDataSimpleAlloc.allocate(aDataLen)); 245 OSCL_FIRST_CATCH_ANY(errcode, return FRAME_OUTPUTNOTAVAILABLE); 246 247 errcode = 0; 248 OSCL_TRY_NO_TLS(iOsclErrorTrapImp, errcode, mediaDataOut = PVMFMediaData::createMediaData(mediaDataImpl, &iMediaDataMemPool)); 249 OSCL_FIRST_CATCH_ANY(errcode, return FRAME_OUTPUTNOTAVAILABLE); 250 251 OsclRefCounterMemFrag memFragOut; 252 mediaDataOut->getMediaFragment(0, memFragOut); 253 254 /* 255 * Latch for very first packet, sequence number is not established yet. 256 */ 257 258 if (!firstPacket) 259 { 260 if ((aSeqNum - last_sequence_num) > 1) /* detect any gap in sequence */ 261 { 262 // means we missed an RTP packet. 263 dropFrames = true; 264 } 265 } 266 else 267 { 268 firstPacket = false; 269 } 270 271 last_timestamp = aTimestamp; 272 last_sequence_num = aSeqNum; 273 last_mbit = aMbit; 274 275 if (dropFrames) 276 { 277 if (last_mbit) 278 { 279 /* 280 * try to recover packet as sequencing was broken, new packet could be valid 281 * it is possible that the received packet contains a complete audioMuxElement() 282 * so try to retrieve it. 283 */ 284 285 dropFrames = false; 286 } 287 else 288 { 289 290 /* 291 * we are in the middle of a spread audioMuxElement(), or faulty rtp header 292 * return error 293 */ 294 295 framesize = 0; 296 frameNum = 0; 297 bytesRead = 0; 298 compositenumframes = 0; 299 300 /* 301 * Drop frame as we are not certain if it is a valid frame 302 */ 303 memFragOut.getMemFrag().len = 0; 304 mediaDataOut->setMediaFragFilledLen(0, 0); 305 306 firstBlock = true; // set for next call 307 return FRAME_ERROR; 308 } 309 } 310 311 312 if (sMC->numSubFrames > 0 || (sMC->cpresent == 1 && ((*aData) & (0x80)))) 313 { 314 // this is a less efficient version that must be used when you know an AudioMuxElement has 315 // more than one subFrame -- I also added the case where the StreamMuxConfig is inline 316 // The reason for this is that the StreamMuxConfig can be possibly large and there is no 317 // way to know its size without parsing it. (the problem is it can straddle an RTP boundary) 318 // it is less efficient because it composes the AudioMuxElement in a separate buffer (one 319 // oscl_memcpy() per rtp packet) then parses it (one oscl_memcpy() per audio frame to the output 320 // buffer (newpkt->outptr)) when it gets a whole AudioMuxElement. 321 // The function below does a oscl_memcpy() directly into the output buffer 322 // note, composeMultipleFrame will also work for the simple case in case there is another reason 323 // to have to use it.. 324 325 retVal = composeMultipleFrame(aData, aDataLen, aTimestamp, aSeqNum, aMbit); 326 } 327 else 328 { 329 // this is an efficient version that can be used when you know an AudioMuxElement has 330 // only one subFrame 331 retVal = composeSingleFrame(aData, aDataLen, aTimestamp, aSeqNum, aMbit); 332 } 333 334 // set this to drop frames in the future -- till we find another marker bit 335 if (retVal == FRAME_ERROR) 336 { 337 dropFrames = true; 338 339 framesize = 0; 340 frameNum = 0; 341 bytesRead = 0; 342 compositenumframes = 0; 343 344 //changed 345 memFragOut.getMemFrag().len = 0; 346 mediaDataOut->setMediaFragFilledLen(0, 0); 347 348 firstBlock = true; // set for next call 349 350 } 351 return retVal; 352} 353/* ======================================================================== */ 354/* Function : composeSingleFrame() */ 355/* Purpose : parse AAC LATM payload */ 356/* In/out : */ 357/* Return : */ 358/* Note : */ 359/* Modified : */ 360/* ======================================================================== */ 361 362uint8 PV_LATM_Parser::composeSingleFrame(PVMFSharedMediaDataPtr& mediaDataIn) 363{ 364 int32 tmp = 0; 365 366 //changed 367 OsclRefCounterMemFrag memFragIn; 368 mediaDataIn->getMediaFragment(0, memFragIn); 369 370 // pool made for output data 371 OsclRefCounterMemFrag memFragOut; 372 mediaDataOut->getMediaFragment(0, memFragOut); 373 374 //uint8 * myData = newpkt->data; 375 uint8 * myData = (uint8*)memFragIn.getMemFrag().ptr; 376 377 /* 378 * Total Payload length, in bytes, includes 379 * length of the AudioMuxElement() 380 * AudioMuxElement() 381 * Other data (for RF3016 not supported) 382 */ 383 int32 pktsize = memFragIn.getMemFrag().len; 384 385 int32 m_bit = mediaDataIn->getMarkerInfo(); 386 387 /* 388 * All streams have same time framing (there is only one stream anyway) 389 */ 390 if (firstBlock) 391 { 392 /* 393 * AudioMuxElement() fits in a single rtp packet or this is the first 394 * block of an AudioMuxElement() spread accross more than one rtp packet 395 */ 396 397 398 int32 bUsed = 0; 399 400 /* 401 * PayLoadlenghtInfo( ) 402 */ 403 404 do 405 { 406 tmp = *(myData++); /* get payload lenght 8-bit in bytes */ 407 framesize += tmp; 408 bUsed++; 409 } 410 while (tmp == 0xff); /* 0xff is the escape sequence for values bigger than 255 */ 411 412 413 /* 414 * PayLoadMux( ) 415 */ 416 417 bytesRead = (pktsize - bUsed); 418 419 // framesize must be equal to the bytesRead if mbit is 1 420 // or greater than bytesRead if mbit is 0 421 if ((m_bit && framesize != bytesRead && !sMC->otherDataPresent) || 422 (!m_bit && framesize < bytesRead && !sMC->otherDataPresent)) 423 { 424 // to update number of bytes copied 425 memFragOut.getMemFrag().len = 0; 426 mediaDataOut->setMediaFragFilledLen(0, 0); 427 bytesRead = 0; 428 429 return FRAME_ERROR; 430 } 431 432 oscl_memcpy((uint8*)memFragOut.getMemFrag().ptr, myData, bytesRead); //ptr +1 changed 433 434 if (sMC->otherDataPresent) 435 { 436 ; /* dont' care at this point, no MUX other than aac supported */ 437 } 438 439 } 440 else 441 { 442 /* 443 * We have an AudioMuxElement() spread accross more than one rtp packet 444 */ 445 if ((m_bit && framesize != pktsize + (bytesRead - 1) && !sMC->otherDataPresent) /* last block */ || 446 (!m_bit && framesize < pktsize + (bytesRead - 1) && !sMC->otherDataPresent) /* intermediate block */) 447 { 448 449 // to update number of bytes copied 450 memFragOut.getMemFrag().len = 0; 451 mediaDataOut->setMediaFragFilledLen(0, 0); 452 453 return FRAME_ERROR; 454 } 455 456 /* 457 * Accumulate blocks until the full frame is complete 458 */ 459 oscl_memcpy((uint8*)memFragOut.getMemFrag().ptr + bytesRead, myData, pktsize); 460 bytesRead += pktsize; 461 } 462 463 464 // to update number of bytes copied 465 memFragOut.getMemFrag().len = bytesRead; 466 mediaDataOut->setMediaFragFilledLen(0, bytesRead); 467 mediaDataOut->setSeqNum(mediaDataIn->getSeqNum()); 468 mediaDataOut->setTimestamp(mediaDataIn->getTimestamp()); 469 470 471 firstBlock = false; /* we already processed the first block, so this should be false */ 472 473 if (m_bit) /* check if it is a complete packet (m bit ==1) */ 474 { 475 firstBlock = true; /* if m-bit is "1", then the farme fits in a block or this was the last 476 block of the frame, set for next call */ 477 framesize = 0; 478 frameNum = 0; 479 bytesRead = 0; 480 compositenumframes = 0; 481 } 482 else 483 { 484 /* 485 * We have an AudioMuxElement() spread accross more than one rtp packet 486 */ 487 compositenumframes++; 488 489 if (compositenumframes < MAX_NUM_COMPOSITE_FRAMES) 490 { 491 // this is not yet a finished packet 492 return FRAME_INCOMPLETE; 493 } 494 else 495 { 496 return FRAME_ERROR; 497 } 498 499 } 500 return FRAME_COMPLETE; 501} 502 503 504// this below is to choose between a version that returns blocks of frames 505// to the cadi, or buffers those frames and returns one at a time 506// set to 1 for original version that returns blocks of frames 507// set to 0 for new version that buffers and returns only one frame per call 508 509 510/* ======================================================================== */ 511/* Function : composeMulitpleFrame() */ 512/* Purpose : parse AAC LATM payload */ 513/* In/out : */ 514/* Return : */ 515/* Note : */ 516/* Modified : */ 517/* ======================================================================== */ 518uint8 PV_LATM_Parser::composeMultipleFrame(PVMFSharedMediaDataPtr& mediaDataIn) 519{ 520 521 uint32 tmp; 522 uint8 * myData; 523 uint32 i; 524 525 526 OsclRefCounterMemFrag memFragIn; 527 mediaDataIn->getMediaFragment(0, memFragIn); 528 529 // pool made for output data 530 OsclRefCounterMemFrag memFragOut; 531 mediaDataOut->getMediaFragment(0, memFragOut); 532 533 int32 pktsize = memFragIn.getMemFrag().len; 534 535 // make sure we have enough memory to hold the data 536 if (bytesRead + pktsize > currSize) 537 { 538 uint8 * tempPtr = (uint8*) oscl_calloc(bytesRead + pktsize, sizeof(uint8)); 539 if (tempPtr == NULL) 540 { 541 // memory problem? 542 return FRAME_ERROR; 543 } 544 currSize = bytesRead + pktsize; 545 oscl_memcpy(tempPtr, multiFrameBuf, bytesRead); 546 oscl_free(multiFrameBuf); 547 multiFrameBuf = tempPtr; 548 } 549 550 oscl_memcpy(multiFrameBuf + bytesRead, memFragIn.getMemFrag().ptr, pktsize); 551 552 bytesRead += pktsize; 553 //newpkt->frame_size = bytesRead; 554 555 // to update number of bytes copied 556 memFragOut.getMemFrag().len = bytesRead; 557 mediaDataOut->setMediaFragFilledLen(0, bytesRead); 558 mediaDataOut->setSeqNum(mediaDataIn->getSeqNum()); 559 mediaDataOut->setTimestamp(mediaDataIn->getTimestamp()); 560 561 if (mediaDataIn->getMarkerInfo()) 562 { 563 // means this is the last packet for this audioMuxElement 564 565 myData = multiFrameBuf; 566 567 uint32 outPtrPos = 0; 568 for (i = 0; i <= sMC->numSubFrames; i++) 569 { 570 framesize = 0; 571 do 572 { 573 tmp = *(myData); 574 framesize += tmp; 575 } 576 while (*(myData++) == 0xff); 577 578 //int32 bUsed = (framesize/255)+1; // 0-254: 1, 255-511: 2 ... 579 // do a check on the last one 580 if (i == sMC->numSubFrames && !sMC->otherDataPresent) 581 { 582 if (framesize != bytesRead - (myData - multiFrameBuf)) 583 { 584 // to update number of bytes copied 585 memFragOut.getMemFrag().len = 0; 586 mediaDataOut->setMediaFragFilledLen(0, 0); 587 588 return FRAME_INCOMPLETE; 589 } 590 } 591 oscl_memcpy((uint8*)memFragOut.getMemFrag().ptr + outPtrPos, myData, framesize); 592 myData += framesize; 593 outPtrPos += framesize; 594 } 595 596 597 598 // to update number of bytes copied 599 memFragOut.getMemFrag().len = outPtrPos; 600 mediaDataOut->setMediaFragFilledLen(0, outPtrPos); 601 602 bytesRead = 0; 603 framesize = 0; 604 compositenumframes = 0; 605 606 } 607 else 608 { 609 compositenumframes++; 610 611 if (compositenumframes < MAX_NUM_COMPOSITE_FRAMES) 612 { 613 return FRAME_INCOMPLETE; 614 } 615 else 616 { 617 return FRAME_ERROR; 618 } 619 620 } 621 622 return FRAME_COMPLETE; 623} 624 625///////////////////////////////////Create a function to decode the StreamMuxConfig 626// note this function should ideally also get a reference to an object that holds the values 627// for the streammuxconfig... these are alse needed in the mediaInfo class (to pass to 628// the parser constructor) and can be gotten here. for now just get the audiospecificconfig 629OSCL_EXPORT_REF uint8 * PV_LATM_Parser::ParseStreamMuxConfig(uint8* decoderSpecificConfig, int32 * size) 630{ 631 uint32 SMC_SUCCESS = 0; 632 uint32 SMC_INVALID_MUX_VERSION = 1; 633 uint32 SMC_INVALID_NUM_PROGRAM = 2; 634 uint32 SMC_INVALID_NUM_LAYER = 4; 635 uint32 SMC_INVALID_OBJECT_TYPE = 8; 636 uint32 SMC_USED_RESERVED_SAMPLING_FREQ = 16; 637 638 uint32 samplingFreqTable[] = 639 { 640 96000, 88200, 64000, 48000, 44100, 641 32000, 24000, 22050, 16000, 12000, 642 11025, 8000, 7350 643 }; 644 645 if (*size == 0) 646 { 647 // means there is nothing to parse 648 return NULL; 649 } 650 651 652 // size should be the length of the decoderSpecificConfig.. the AudioSpecificConfing cant 653 // be larger than that, so just allocate that number of bytes 654 // we wont know until we've parsed it how big it is. 655 OsclMemAllocator alloc; 656 uint8* ASCPtr = (uint8*)(alloc.allocate(sizeof(uint8) * (*size))); 657 if (ASCPtr == NULL) 658 { 659 // memory allocation problem? 660 *size = 0; 661 return NULL; 662 } 663 oscl_memset(ASCPtr, 0, *size); 664 665 OsclExclusivePtrA<uint8, OsclMemAllocator> ascAutoPtr; 666 ascAutoPtr.set(ASCPtr); 667 668 //streamMuxConfig * sMC; 669 sMC = (streamMuxConfig *) oscl_calloc(1, sizeof(streamMuxConfig)); 670 if (sMC == NULL) 671 { // unlikely: calloc failure 672 return NULL; 673 } 674 675 676 sMC->parseResult = SMC_SUCCESS; // set default result 677 678 uint32 bitPos = 0; 679 uint32 ASCPos = 0; 680 681 int32 temp; 682 int32 numProgram = 0; 683 int32 prog, lay; 684 int32 numLayer; 685 int32 count; 686 int32 dependsOnCoreCoder; 687 688 // audio mux version 689 sMC->audioMuxVersion = BufferReadBits(decoderSpecificConfig, &bitPos, 1); 690 if (sMC->audioMuxVersion == 0) 691 { 692 // should not be anything other than 0!! 693 694 // all streams same time framing 695 sMC->allStreamsSameTimeFraming = BufferReadBits(decoderSpecificConfig, &bitPos, 1); 696 697 /* 698 * numSubFrames -- how many payloadmux() are multiplexed 699 */ 700 sMC->numSubFrames = BufferReadBits(decoderSpecificConfig, &bitPos, 6); 701 702 /* 703 * numPrograms -- how many programs are multiplexed 704 */ 705 numProgram = BufferReadBits(decoderSpecificConfig, &bitPos, 4); 706 707 if (numProgram != 0) 708 { 709 sMC->parseResult |= SMC_INVALID_NUM_PROGRAM; 710 //numProgram = 0; 711 // really should exit 712 *size = 0; 713 return NULL; 714 } 715 716 // loop through programs -- happens only once now 717 for (prog = 0; prog <= numProgram; prog++) 718 { 719 // can only be one numProgram (RFC3016) 720 numLayer = BufferReadBits(decoderSpecificConfig, &bitPos, 3); 721 /* 722 * Number of scalable layers, only one is indicated in rfc3016 723 */ 724 if (numLayer != 0) 725 { 726 sMC->parseResult |= SMC_INVALID_NUM_LAYER; 727 //numLayer = 0; 728 // really should exit 729 *size = 0; 730 return NULL; 731 } 732 733 for (lay = 0; lay <= numLayer; lay++) 734 { 735 // can only be one numLayer (RFC3016) 736 if (prog == 0 && lay == 0) 737 { 738 /* 739 * audioSpecificConfig 740 * 741 * it starts at byte 1's last (lsb) bit 742 * basically copy all the rest of the bytes into the ASCPtr 743 * then shift these over to be byte aligned 744 */ 745 ASCPos = bitPos; 746 747 sMC->audioObjectType = BufferReadBits(decoderSpecificConfig, &bitPos, LEN_OBJ_TYPE); 748 749 if (sMC->audioObjectType != MP4AUDIO_AAC_LC && 750 sMC->audioObjectType != MP4AUDIO_LTP && 751 sMC->audioObjectType != MP4AUDIO_PS && 752 sMC->audioObjectType != MP4AUDIO_SBR) 753 { 754 sMC->parseResult |= SMC_INVALID_OBJECT_TYPE; 755 *size = 0; 756 return NULL; 757 } 758 759 760 // SamplingFrequencyIndex -- see audio spec for meanings 761 temp = BufferReadBits(decoderSpecificConfig, &bitPos, LEN_SAMP_RATE_IDX); 762 763 if (temp == 13 || temp == 14) 764 { 765 sMC->parseResult |= SMC_USED_RESERVED_SAMPLING_FREQ; 766 } 767 768 769 if (temp <= 12) 770 { 771 sMC->samplingFrequency = samplingFreqTable[temp]; 772 } 773 774 if (temp == 0xf) 775 { 776 // means the sampling frequency is specified directly in the next 24 bits 777 temp = BufferReadBits(decoderSpecificConfig, &bitPos, LEN_SAMP_RATE); 778 } 779 780 // ChannelConfiguration 781 sMC->channelConfiguration = BufferReadBits(decoderSpecificConfig, &bitPos, LEN_CHAN_CONFIG); 782 783 sMC->sbrPresentFlag = -1; 784 785 if (sMC->audioObjectType == MP4AUDIO_SBR || 786 sMC->audioObjectType == MP4AUDIO_PS) 787 { 788 /* to disable explicit backward compatiblity check */ 789 sMC->extensionAudioObjectType = sMC->audioObjectType; 790 791 sMC->sbrPresentFlag = 1; 792 793 sMC->extensionSamplingFrequencyIndex = /* extensionSamplingFrequencyIndex */ 794 BufferReadBits(decoderSpecificConfig, &bitPos, LEN_SAMP_RATE_IDX); 795 796 if (sMC->extensionSamplingFrequencyIndex == 0x0f) 797 { 798 /* 799 * sampling rate not listed in Table 1.6.2, 800 * this release does not support this 801 */ 802 sMC->extensionSamplingFrequency = /* extensionSamplingFrequency */ 803 BufferReadBits(decoderSpecificConfig, &bitPos, LEN_SAMP_RATE); 804 } 805 806 807 sMC->audioObjectType = BufferReadBits(decoderSpecificConfig, &bitPos, LEN_OBJ_TYPE); 808 } 809 810 811 if (sMC->audioObjectType == MP4AUDIO_AAC_LC || sMC->audioObjectType == MP4AUDIO_LTP) 812 { 813 // GASpecificConfig 814 815 // frameLengthFlag 816 temp = BufferReadBits(decoderSpecificConfig, &bitPos, LEN_FRAME_LEN_FLAG); 817 818 // dependsOnCoreCoder 819 dependsOnCoreCoder = BufferReadBits(decoderSpecificConfig, &bitPos, LEN_DEPEND_ON_CORE); 820 821 822 if (dependsOnCoreCoder == 1) 823 { 824 // means there are 14 more bits of coreCoderDelay 825 temp = BufferReadBits(decoderSpecificConfig, &bitPos, LEN_CORE_DELAY); 826 } 827 // ExtensionFlag 828 int extensionFlag = BufferReadBits(decoderSpecificConfig, &bitPos, LEN_EXT_FLAG); 829 830 if (sMC->channelConfiguration == 0) 831 { 832 // there should be a program_config_element 833 // defined in 4.4.1.1 of 3995 sp4 834 // note, since we are only parsing this to get the size of the 835 // audioSpecificConfig, we dont care about the values except to know 836 // how many loops to do in the parsing process... save these loop 837 // variables in an array 838 uint32 loopVars[6] = {0, 0, 0, 0, 0, 0}; 839 840 // dont actually need these values, just increment bit pointer 841 bitPos += LEN_TAG; //temp = BufferReadBits(ASCPtr, &bitPos, 4); // element_instance_tag 842 bitPos += LEN_PROFILE; //temp = BufferReadBits(ASCPtr, &bitPos, 2); // object_type 843 bitPos += LEN_SAMP_IDX; //temp = BufferReadBits(ASCPtr, &bitPos, 4); // sampling frequency index 844 loopVars[0] = BufferReadBits(decoderSpecificConfig, &bitPos, LEN_NUM_ELE); // num front channel elems 845 loopVars[1] = BufferReadBits(decoderSpecificConfig, &bitPos, LEN_NUM_ELE); // num side channel elems 846 loopVars[2] = BufferReadBits(decoderSpecificConfig, &bitPos, LEN_NUM_ELE); // num back channel elems 847 loopVars[3] = BufferReadBits(decoderSpecificConfig, &bitPos, LEN_NUM_LFE); // num lfe channel elems 848 loopVars[3] = BufferReadBits(decoderSpecificConfig, &bitPos, LEN_NUM_DAT); // num assoc data elems 849 loopVars[3] = BufferReadBits(decoderSpecificConfig, &bitPos, LEN_NUM_CCE); // num valid cc elems 850 851 temp = BufferReadBits(decoderSpecificConfig, &bitPos, LEN_MIX_PRES); // mono mixdown present 852 if (temp) 853 { 854 bitPos += LEN_NUM_ELE; 855 } 856 temp = BufferReadBits(decoderSpecificConfig, &bitPos, LEN_MIX_PRES); // stereo mixdown present 857 if (temp) 858 { 859 bitPos += LEN_NUM_ELE; 860 } 861 temp = BufferReadBits(decoderSpecificConfig, &bitPos, LEN_MIX_PRES); // matrix mixdown present 862 if (temp) 863 { 864 bitPos += LEN_NUM_DAT; 865 } 866 867 bitPos += (loopVars[0] * 5); // front channel info 868 bitPos += (loopVars[1] * 5); // side channel info 869 bitPos += (loopVars[2] * 5); // back channel info 870 bitPos += (loopVars[3] * 4); // lfe channel info 871 bitPos += (loopVars[4] * 4); // assoc data info 872 bitPos += (loopVars[5] * 5); // valid cc info 873 874 // then the spec says byte_alignement() .. need to add bits to byte align 875 // divide by 8, add 1, multiply by 8. wont work if already byte aligned 876 // check with a mod 8 877 if (bitPos % 8 != 0) 878 { 879 bitPos = ((bitPos >> 3) + 1) << 3; 880 } 881 882 temp = BufferReadBits(decoderSpecificConfig, &bitPos, LEN_COMMENT_BYTES); // comment field bytes 883 bitPos += (temp << 3); 884 885 } 886 887 // this below obviously cant happen at this point, but show it for clarity's sake 888 if (sMC->audioObjectType == MP4AUDIO_AAC_SCALABLE || 889 sMC->audioObjectType == MP4AUDIO_ER_AAC_SCALABLE) 890 { 891 } 892 893 if (extensionFlag) 894 { 895 if (sMC->audioObjectType == MP4AUDIO_ER_BSAC) 896 { 897 // cant ever happen here 898 } 899 if (sMC->audioObjectType == MP4AUDIO_ER_AAC_LC || 900 sMC->audioObjectType == 18 || 901 sMC->audioObjectType == MP4AUDIO_ER_AAC_LTP || 902 sMC->audioObjectType == MP4AUDIO_ER_AAC_SCALABLE || 903 sMC->audioObjectType == MP4AUDIO_ER_TWINVQ || 904 sMC->audioObjectType == MP4AUDIO_ER_AAC_LD) 905 { 906 // cant ever happen here 907 } 908 // extensionFlag3 -- theoretically possible -- but should only see in future, if ever 909 temp = BufferReadBits(decoderSpecificConfig, &bitPos, 1); 910 if (temp) 911 { 912 // tbd in version 3 913 } 914 } 915 } 916 else 917 { 918 sMC->parseResult |= SMC_INVALID_OBJECT_TYPE; 919 *size = 0; 920 return NULL; 921 } 922 923 924 925 /* 926 * SBR tool explicit signaling ( backward compatible ) 927 */ 928 929 if (sMC->extensionAudioObjectType != MP4AUDIO_SBR) 930 { 931 int32 syncExtensionType = /* syncExtensionType */ 932 BufferReadBits(decoderSpecificConfig, &bitPos, LEN_SYNC_EXTENSION_TYPE); 933 934 if (syncExtensionType == 0x2b7) 935 { 936 sMC->extensionAudioObjectType = /* extensionAudioObjectType */ 937 BufferReadBits(decoderSpecificConfig, &bitPos, LEN_OBJ_TYPE); 938 939 if (sMC->extensionAudioObjectType == MP4AUDIO_SBR) 940 { 941 /* sbrPresentFlag */ 942 sMC->sbrPresentFlag = BufferReadBits(decoderSpecificConfig, &bitPos, 1); 943 944 if (sMC->sbrPresentFlag == 1) 945 { 946 sMC->extensionSamplingFrequencyIndex = /* extensionSamplingFrequencyIndex */ 947 BufferReadBits(decoderSpecificConfig, &bitPos, LEN_SAMP_RATE_IDX); 948 949 if (sMC->extensionSamplingFrequencyIndex == 0x0f) 950 { 951 /* 952 * sampling rate not listed in Table 1.6.2, 953 * this release does not support this 954 */ 955 int32 sampling_rate = 0; 956 sampling_rate = BufferReadBits(decoderSpecificConfig, &bitPos, LEN_SAMP_RATE); 957 958 } 959 } 960 } 961 } 962 else 963 { 964 /* 965 * Rewind bitstream pointer so that the syncExtensionType reading has no 966 * effect when decoding raw bitstream 967 */ 968 bitPos -= LEN_SYNC_EXTENSION_TYPE; 969 970 } 971 } 972 973 // this is the end of the audioSpecificConfig 974 975 976 977 /* 978 * Byte Align 979 */ 980 int32 ASCLen = bitPos - ASCPos; // length in bits -- will need to be byte aligned 981 // change length in bytes 982 if (ASCLen % 8 == 0) 983 { 984 ASCLen >>= 3; 985 } 986 else 987 { 988 ASCLen = (ASCLen >> 3) + 1; 989 } 990 int ASCOffset = ASCPos % 8; // use for masking -- do i need this? 991 992 if (ASCOffset == 0) 993 { 994 oscl_memcpy(ASCPtr, decoderSpecificConfig + ASCPos, ASCLen); 995 } 996 else 997 { 998 for (count = 0; count < ASCLen; count++) 999 { 1000 ASCPtr[count] = (uint8)BufferReadBits(decoderSpecificConfig, &ASCPos, 8); 1001 } 1002 } 1003 *size = ASCLen; 1004 1005 1006 // go back to using decoderSpecificInfo 1007 sMC->frameLengthType = BufferReadBits(decoderSpecificConfig, &bitPos, 3); 1008 if (sMC->frameLengthType == 0) 1009 { 1010 sMC->bufferFullness = BufferReadBits(decoderSpecificConfig, &bitPos, 8); 1011 } 1012 1013 sMC->otherDataPresent = BufferReadBits(decoderSpecificConfig, &bitPos, 1) ? 1 : 0; 1014 if (sMC->otherDataPresent) 1015 { 1016 do 1017 { 1018 temp = BufferReadBits(decoderSpecificConfig, &bitPos, 1); // get escape flag 1019 bitPos += 8; // skip over data itself 1020 } 1021 while (temp == 1); 1022 } 1023 1024 sMC->crcCheckPresent = BufferReadBits(decoderSpecificConfig, &bitPos, 1) ? 1 : 0; 1025 if (sMC->crcCheckPresent) 1026 { 1027 bitPos += 8; 1028 } 1029 1030 // that should be the end of the stream mux config 1031 } 1032 } 1033 } 1034 1035 } 1036 else 1037 { 1038 // spec says tbd 1039 sMC->parseResult |= SMC_INVALID_MUX_VERSION; 1040 *size = 0; 1041 return NULL; 1042 } 1043 1044 ascAutoPtr.release(); 1045 return ASCPtr; 1046} 1047uint8 PV_LATM_Parser::composeSingleFrame(uint8* aData, uint32 aDataLen, uint32 aTimestamp, uint32 aSeqNum, uint32 aMbit) 1048{ 1049 int32 tmp = 0; 1050 1051 // pool made for output data 1052 OsclRefCounterMemFrag memFragOut; 1053 mediaDataOut->getMediaFragment(0, memFragOut); 1054 1055 //uint8 * myData = newpkt->data; 1056 uint8 * myData = aData; 1057 1058 /* 1059 * Total Payload length, in bytes, includes 1060 * length of the AudioMuxElement() 1061 * AudioMuxElement() 1062 * Other data (for RF3016 not supported) 1063 */ 1064 int32 pktsize = aDataLen; 1065 1066 int32 m_bit = aMbit; 1067 1068 /* 1069 * All streams have same time framing (there is only one stream anyway) 1070 */ 1071 if (firstBlock) 1072 { 1073 /* 1074 * AudioMuxElement() fits in a single rtp packet or this is the first 1075 * block of an AudioMuxElement() spread accross more than one rtp packet 1076 */ 1077 1078 1079 int32 bUsed = 0; 1080 1081 /* 1082 * PayLoadlenghtInfo( ) 1083 */ 1084 1085 do 1086 { 1087 tmp = *(myData++); /* get payload lenght 8-bit in bytes */ 1088 framesize += tmp; 1089 bUsed++; 1090 } 1091 while (tmp == 0xff); /* 0xff is the escape sequence for values bigger than 255 */ 1092 1093 1094 /* 1095 * PayLoadMux( ) 1096 */ 1097 1098 bytesRead = (pktsize - bUsed); 1099 1100 // framesize must be equal to the bytesRead if mbit is 1 1101 // or greater than bytesRead if mbit is 0 1102 if ((m_bit && framesize != bytesRead && !sMC->otherDataPresent) || 1103 (!m_bit && framesize < bytesRead && !sMC->otherDataPresent)) 1104 { 1105 // to update number of bytes copied 1106 memFragOut.getMemFrag().len = 0; 1107 mediaDataOut->setMediaFragFilledLen(0, 0); 1108 bytesRead = 0; 1109 1110 return FRAME_ERROR; 1111 } 1112 1113 oscl_memcpy((uint8*)memFragOut.getMemFrag().ptr, myData, bytesRead); //ptr +1 changed 1114 1115 if (sMC->otherDataPresent) 1116 { 1117 ; /* dont' care at this point, no MUX other than aac supported */ 1118 } 1119 1120 } 1121 else 1122 { 1123 /* 1124 * We have an AudioMuxElement() spread accross more than one rtp packet 1125 */ 1126 if ((m_bit && framesize != pktsize + (bytesRead - 1) && !sMC->otherDataPresent) /* last block */ || 1127 (!m_bit && framesize < pktsize + (bytesRead - 1) && !sMC->otherDataPresent) /* intermediate block */) 1128 { 1129 1130 // to update number of bytes copied 1131 memFragOut.getMemFrag().len = 0; 1132 mediaDataOut->setMediaFragFilledLen(0, 0); 1133 1134 return FRAME_ERROR; 1135 } 1136 1137 /* 1138 * Accumulate blocks until the full frame is complete 1139 */ 1140 oscl_memcpy((uint8*)memFragOut.getMemFrag().ptr + bytesRead, myData, pktsize); 1141 bytesRead += pktsize; 1142 } 1143 1144 1145 // to update number of bytes copied 1146 memFragOut.getMemFrag().len = bytesRead; 1147 mediaDataOut->setMediaFragFilledLen(0, bytesRead); 1148 mediaDataOut->setSeqNum(aSeqNum); 1149 mediaDataOut->setTimestamp(aTimestamp); 1150 1151 1152 firstBlock = false; /* we already processed the first block, so this should be false */ 1153 1154 if (m_bit) /* check if it is a complete packet (m bit ==1) */ 1155 { 1156 firstBlock = true; /* if m-bit is "1", then the farme fits in a block or this was the last 1157 block of the frame, set for next call */ 1158 framesize = 0; 1159 frameNum = 0; 1160 bytesRead = 0; 1161 compositenumframes = 0; 1162 } 1163 else 1164 { 1165 /* 1166 * We have an AudioMuxElement() spread accross more than one rtp packet 1167 */ 1168 compositenumframes++; 1169 1170 if (compositenumframes < MAX_NUM_COMPOSITE_FRAMES) 1171 { 1172 // this is not yet a finished packet 1173 return FRAME_INCOMPLETE; 1174 } 1175 else 1176 { 1177 return FRAME_ERROR; 1178 } 1179 1180 } 1181 return FRAME_COMPLETE; 1182} 1183 1184 1185 1186uint8 PV_LATM_Parser::composeMultipleFrame(uint8* aData, uint32 aDataLen, uint32 aTimestamp, uint32 aSeqNum, uint32 aMbit) 1187{ 1188 1189 uint32 tmp; 1190 uint8 * myData; 1191 uint32 i; 1192 1193 int32 pktsize = aDataLen; 1194 // pool made for output data 1195 OsclRefCounterMemFrag memFragOut; 1196 mediaDataOut->getMediaFragment(0, memFragOut); 1197 // make sure we have enough memory to hold the data 1198 if (bytesRead + pktsize > currSize) 1199 { 1200 uint8 * tempPtr = (uint8*) oscl_calloc(bytesRead + pktsize, sizeof(uint8)); 1201 if (tempPtr == NULL) 1202 { 1203 // memory problem? 1204 return FRAME_ERROR; 1205 } 1206 currSize = bytesRead + pktsize; 1207 oscl_memcpy(tempPtr, multiFrameBuf, bytesRead); 1208 oscl_free(multiFrameBuf); 1209 multiFrameBuf = tempPtr; 1210 } 1211 1212 oscl_memcpy(multiFrameBuf + bytesRead, aData, pktsize); 1213 1214 bytesRead += pktsize; 1215 //newpkt->frame_size = bytesRead; 1216 1217 // to update number of bytes copied 1218 memFragOut.getMemFrag().len = bytesRead; 1219 mediaDataOut->setMediaFragFilledLen(0, bytesRead); 1220 mediaDataOut->setSeqNum(aSeqNum); 1221 mediaDataOut->setTimestamp(aTimestamp); 1222 1223 if (aMbit) 1224 { 1225 // means this is the last packet for this audioMuxElement 1226 1227 myData = multiFrameBuf; 1228 1229 uint32 outPtrPos = 0; 1230 for (i = 0; i <= sMC->numSubFrames; i++) 1231 { 1232 framesize = 0; 1233 do 1234 { 1235 tmp = *(myData); 1236 framesize += tmp; 1237 } 1238 while (*(myData++) == 0xff); 1239 1240 //int32 bUsed = (framesize/255)+1; // 0-254: 1, 255-511: 2 ... 1241 // do a check on the last one 1242 if (i == sMC->numSubFrames && !sMC->otherDataPresent) 1243 { 1244 if (framesize != bytesRead - (myData - multiFrameBuf)) 1245 { 1246 // to update number of bytes copied 1247 memFragOut.getMemFrag().len = 0; 1248 mediaDataOut->setMediaFragFilledLen(0, 0); 1249 1250 return FRAME_INCOMPLETE; 1251 } 1252 } 1253 oscl_memcpy((uint8*)memFragOut.getMemFrag().ptr + outPtrPos, myData, framesize); 1254 myData += framesize; 1255 outPtrPos += framesize; 1256 } 1257 1258 1259 1260 // to update number of bytes copied 1261 memFragOut.getMemFrag().len = outPtrPos; 1262 mediaDataOut->setMediaFragFilledLen(0, outPtrPos); 1263 1264 bytesRead = 0; 1265 framesize = 0; 1266 compositenumframes = 0; 1267 1268 } 1269 else 1270 { 1271 compositenumframes++; 1272 1273 if (compositenumframes < MAX_NUM_COMPOSITE_FRAMES) 1274 { 1275 return FRAME_INCOMPLETE; 1276 } 1277 else 1278 { 1279 return FRAME_ERROR; 1280 } 1281 1282 } 1283 1284 return FRAME_COMPLETE; 1285} 1286 1287uint32 BufferShowBits(uint8 *inbuf, uint32 pos1, uint32 pos2) 1288{ 1289 uint32 ptr1 = pos1 % 8, ptr2 = pos2 % 8, Ptr1 = pos1 >> 3, Ptr2 = pos2 >> 3; 1290 uint32 tmpvar = 0; 1291 // this really should be static, but not supported in EPOC 1292 uint8 mask[] = {255, 127, 63, 31, 15, 7, 3, 1, 0}; 1293 1294 if (Ptr1 == Ptr2) // When all the bits to copy are in the same byte 1295 { 1296 return ((inbuf[Ptr1] & (mask[ptr1] - mask[ptr2+1])) >> (7 - ptr2)); 1297 } 1298 else // Otherwise 1299 { 1300 tmpvar = inbuf[Ptr1] & mask[ptr1]; 1301 for (Ptr1 ++; Ptr1 < Ptr2; Ptr1 ++) 1302 { 1303 tmpvar <<= 8; 1304 tmpvar += inbuf[Ptr1]; 1305 } 1306 tmpvar <<= (ptr2 + 1); 1307 tmpvar += (inbuf[Ptr2] & (255 - mask[ptr2+1])) >> (7 - ptr2); 1308 } 1309 return tmpvar; 1310} 1311 1312uint32 BufferReadBits(uint8 *inbuf, uint32 *pos1, int32 len) 1313{ 1314 uint32 rval = BufferShowBits(inbuf, *pos1, (*pos1) + len - 1); 1315 *pos1 += len; 1316 return rval; 1317} 1318 1319