1 /* ------------------------------------------------------------------ 2 * Copyright (C) 1998-2009 PacketVideo 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 13 * express or implied. 14 * See the License for the specific language governing permissions 15 * and limitations under the License. 16 * ------------------------------------------------------------------- 17 */ 18 /*********************************************************************************/ 19 /* ------------------------------------------------------------------- */ 20 /* MPEG-4 TrackAtom Class */ 21 /* ------------------------------------------------------------------- */ 22 /*********************************************************************************/ 23 /* 24 This TrackAtom Class is the container for a single track in the MPEG-4 25 presentation. 26 */ 27 28 29 #ifndef TRACKATOM_H_INCLUDED 30 #define TRACKATOM_H_INCLUDED 31 32 #ifndef OSCL_FILE_IO_H_INCLUDED 33 #include "oscl_file_io.h" 34 #endif 35 36 #ifndef ATOM_H_INCLUDED 37 #include "atom.h" 38 #endif 39 40 #ifndef TRACKHEADERATOM_H_INCLUDED 41 #include "trackheaderatom.h" 42 #endif 43 44 #ifndef MEDIAATOM_H_INCLUDED 45 #include "mediaatom.h" 46 #endif 47 48 #ifndef TRACKREFERENCEATOM_H_INCLUDED 49 #include "trackreferenceatom.h" 50 #endif 51 52 #ifndef EDITATOM_H_INCLUDED 53 #include "editatom.h" 54 #endif 55 56 #ifndef DECODERSPECIFICINFO_H_INCLUDED 57 #include "decoderspecificinfo.h" 58 #endif 59 60 61 #ifndef USERDATAATOM_H_INCLUDED 62 #include "userdataatom.h" 63 #endif 64 65 #ifndef OSCL_MEDIA_DATA_H_INCLUDED 66 #include "oscl_media_data.h" 67 #endif 68 69 #ifndef PV_GAU_H_INCLUDED 70 #include "pv_gau.h" 71 #endif 72 73 #ifndef OMA2BOXES_H_INCLUDED 74 #include "oma2boxes.h" 75 #endif 76 77 class AVCSampleEntry; 78 79 class TrackAtom : public Atom 80 { 81 82 public: 83 TrackAtom(MP4_FF_FILE *fp, 84 OSCL_wString& filename, 85 uint32 size, 86 uint32 type, 87 bool oPVContent = false, 88 bool oPVContentDownloadable = false, 89 uint32 parsingMode = 0); // Stream-in Constructor 90 91 virtual ~TrackAtom(); 92 93 /* Returns media samples 94 buf: A pointer to the data buffer into which to place the media sample. 95 size: The size of the data buffer 96 index: An output parameter which is the index of the sample entry to which the returned sample refers. If zero, will return based on the index set by the previous call to getNextMediaSample(). 97 return: The size in bytes of the data placed into the provided buffer. If the buffer is not large enough, the return value is the negative of the size that is needed. 98 */ getNextMediaSample(uint8 * buf,int32 & size,uint32 & index,uint32 & SampleOffset)99 int32 getNextMediaSample(uint8 *buf, int32 &size, uint32 &index, uint32 &SampleOffset) 100 { 101 if (_pmediaAtom == NULL) 102 { 103 return READ_MEDIA_ATOM_FAILED; 104 } 105 return _pmediaAtom->getNextSample(buf, size, index, SampleOffset); 106 } 107 getKeyMediaSampleNumAt(uint32 aKeySampleNum,GAU * pgau)108 MP4_ERROR_CODE getKeyMediaSampleNumAt(uint32 aKeySampleNum, 109 GAU *pgau) 110 { 111 if (_pmediaAtom == NULL) 112 { 113 return READ_MEDIA_ATOM_FAILED; 114 } 115 return _pmediaAtom->getKeyMediaSampleNumAt(aKeySampleNum, pgau); 116 } 117 getNumKeyFrames()118 uint32 getNumKeyFrames() 119 { 120 if (_pmediaAtom != NULL) 121 { 122 return (_pmediaAtom->getNumKeyFrames()); 123 } 124 else 125 { 126 return 0; 127 } 128 } 129 getPrevKeyMediaSample(uint32 inputtimestamp,uint32 & aKeySampleNum,uint32 * n,GAU * pgau)130 int32 getPrevKeyMediaSample(uint32 inputtimestamp, 131 uint32 &aKeySampleNum, 132 uint32 *n, 133 GAU *pgau) 134 { 135 if (_pmediaAtom == NULL) 136 { 137 return READ_MEDIA_ATOM_FAILED; 138 } 139 return _pmediaAtom->getPrevKeyMediaSample(inputtimestamp, aKeySampleNum, n, pgau); 140 } 141 getNextKeyMediaSample(uint32 inputtimestamp,uint32 & aKeySampleNum,uint32 * n,GAU * pgau)142 int32 getNextKeyMediaSample(uint32 inputtimestamp, 143 uint32 &aKeySampleNum, 144 uint32 *n, 145 GAU *pgau) 146 { 147 if (_pmediaAtom == NULL) 148 { 149 return READ_MEDIA_ATOM_FAILED; 150 } 151 return _pmediaAtom->getNextKeyMediaSample(inputtimestamp, aKeySampleNum, n, pgau); 152 } 153 154 getMediaSample(uint32 sampleNumber,uint8 * buf,int32 & size,uint32 & index,uint32 & SampleOffset)155 int32 getMediaSample(uint32 sampleNumber, uint8 *buf, int32 &size, uint32 &index, uint32 &SampleOffset) 156 { 157 if (_pmediaAtom == NULL) 158 { 159 return READ_MEDIA_ATOM_FAILED; 160 } 161 return _pmediaAtom->getMediaSample(sampleNumber, buf, size, index, SampleOffset); 162 } 163 updateFileSize(uint32 filesize)164 int32 updateFileSize(uint32 filesize) 165 { 166 if (_pmediaAtom != NULL) 167 { 168 return _pmediaAtom->updateFileSize(filesize); 169 } 170 return DEFAULT_ERROR; 171 } 172 getOffsetByTime(uint32 ts,int32 * sampleFileOffset)173 int32 getOffsetByTime(uint32 ts, int32* sampleFileOffset) 174 { 175 if (_pmediaAtom == NULL) 176 { 177 return DEFAULT_ERROR; 178 } 179 return _pmediaAtom->getOffsetByTime(ts, sampleFileOffset); 180 } 181 getTrackID()182 uint32 getTrackID() const 183 { 184 if (_ptrackHeader != NULL) 185 { 186 return _ptrackHeader->getTrackID(); 187 } 188 else 189 { 190 return 0; 191 } 192 } 193 getTrackDuration()194 uint64 getTrackDuration() const 195 { 196 if (_ptrackHeader != NULL) 197 { 198 return _ptrackHeader->getDuration(); 199 } 200 else 201 { 202 return 0; 203 } 204 } 205 206 // Get the max size buffer needed to retrieve the media samples getMaxBufferSizeDB()207 uint32 getMaxBufferSizeDB() const 208 { 209 if (_pmediaAtom != NULL) 210 { 211 return _pmediaAtom->getMaxBufferSizeDB(); 212 } 213 else 214 { 215 return 0; 216 } 217 } 218 getMediaType()219 uint32 getMediaType() const 220 { 221 return _pMediaType; 222 } 223 resetPlayBack()224 void resetPlayBack() 225 { 226 if (_pmediaAtom != NULL) 227 { 228 _pmediaAtom->resetPlayBack(); 229 } 230 } 231 resetTrackToEOT()232 void resetTrackToEOT() 233 { 234 if (_pmediaAtom != NULL) 235 { 236 _pmediaAtom->resetTrackToEOT(); 237 } 238 } 239 240 int32 resetPlayBack(int32 time, bool oDependsOn = false) 241 { 242 if (_pmediaAtom != NULL) 243 { 244 return _pmediaAtom->resetPlayBack(time, oDependsOn); 245 } 246 else 247 { 248 return 0; 249 } 250 } 251 252 int32 queryRepositionTime(int32 time, bool oDependsOn = false, bool bBeforeRequestedTime = true) 253 { 254 if (_pmediaAtom != NULL) 255 { 256 return _pmediaAtom->queryRepositionTime(time, oDependsOn, bBeforeRequestedTime); 257 } 258 else 259 { 260 return 0; 261 } 262 } 263 IsResetNeeded(int32 time)264 int32 IsResetNeeded(int32 time) 265 { 266 if (_pmediaAtom == NULL) 267 return READ_MEDIA_ATOM_FAILED; 268 return _pmediaAtom->IsResetNeeded((int32)((float)time*(float)_pmediaAtom->getMediaTimescale() / (float)1000)); 269 } 270 getTimestampForSampleNumber(uint32 sampleNumber)271 uint32 getTimestampForSampleNumber(uint32 sampleNumber) 272 { 273 if (_pmediaAtom != NULL) 274 { 275 return _pmediaAtom->getTimestampForSampleNumber(sampleNumber); 276 } 277 else 278 { 279 return 0; 280 } 281 } 282 getSampleSizeAt(int32 sampleNum)283 int32 getSampleSizeAt(int32 sampleNum) 284 { 285 if (_pmediaAtom != NULL) 286 { 287 return _pmediaAtom->getSampleSizeAt(sampleNum); 288 } 289 else 290 { 291 return 0; 292 } 293 } 294 295 296 // Returns the timestamp from the last video sample 297 // This is mainly to be used when seeking in the bitstream - you request a video frame at timestamp 298 // X, but the actual frame you get is Y, this method returns the timestamp for Y so you know which 299 // audio sample to request. getTimestampForCurrentSample()300 int32 getTimestampForCurrentSample() 301 { 302 if (_pmediaAtom != NULL) 303 { 304 return _pmediaAtom->getTimestampForCurrentSample(); 305 } 306 else 307 { 308 return 0; 309 } 310 } 311 312 // Returns the sample number of the last samplle returned 313 // Used when requesting a hint sample for a specific randomly accessed sample getSampleNumberForCurrentSample()314 int32 getSampleNumberForCurrentSample() 315 { 316 if (_pmediaAtom != NULL) 317 { 318 return _pmediaAtom->getSampleNumberForCurrentSample(); 319 } 320 else 321 { 322 return 0; 323 } 324 } 325 326 // Getting and setting the Mpeg4 VOL header getDecoderSpecificInfo()327 DecoderSpecificInfo *getDecoderSpecificInfo() const 328 { 329 if (_pmediaAtom != NULL) 330 { 331 return _pmediaAtom->getDecoderSpecificInfo(); 332 } 333 else 334 { 335 return NULL; 336 } 337 } 338 getDecoderSpecificInfoForSDI(uint32 index)339 DecoderSpecificInfo *getDecoderSpecificInfoForSDI(uint32 index) const 340 { 341 if (_pmediaAtom != NULL) 342 { 343 return _pmediaAtom->getDecoderSpecificInfoForSDI(index); 344 } 345 else 346 { 347 return NULL; 348 } 349 } 350 351 // TS offset value for the start of the media track. The STTS 352 // Atom only holds TS deltas. For a track that does not begin at 0s, we need to hold an 353 // offset timestamp value. 354 int32 NEWsetTrackTSOffset(uint32 ts); 355 356 int32 getTrackTSOffset(uint32& aTSOffset, uint32 aMovieTimeScale); 357 setTrackTSOffset(uint32 ts)358 void setTrackTSOffset(uint32 ts) 359 { 360 _trackStartOffset = ts; 361 362 if (_pmediaAtom != NULL) 363 { 364 _pmediaAtom->setTrackTSOffset(ts); 365 } 366 } 367 368 369 //From TrackHeader getTrackDuration()370 uint64 getTrackDuration() 371 { 372 if (_ptrackHeader != NULL) 373 { 374 return _ptrackHeader->getDuration(); 375 } 376 else 377 { 378 return 0; 379 } 380 } // in terms of the movie timescale 381 382 // From TrackReference dependsOn()383 uint32 dependsOn() 384 { 385 if (_ptrackReference != NULL) 386 { 387 return _ptrackReference->getTrackReference(); 388 } 389 else 390 { 391 return 0; 392 } 393 } 394 395 // From MediaAtom -> MediaHeader getMediaDuration()396 uint64 getMediaDuration() 397 { 398 if (_pmediaAtom != NULL) 399 { 400 return _pmediaAtom->getMediaDuration(); 401 } 402 else 403 { 404 return 0; 405 } 406 } // in terms of the media timescale 407 getMediaTimescale()408 uint32 getMediaTimescale() 409 { 410 if (_pmediaAtom != NULL) 411 { 412 return _pmediaAtom->getMediaTimescale(); 413 } 414 else 415 { 416 //RETURN SOME UNDEFINED VALUE 417 return (0xFFFFFFFF); 418 } 419 } 420 getLanguageCode()421 uint16 getLanguageCode() 422 { 423 if (_pmediaAtom != NULL) 424 { 425 return _pmediaAtom->getLanguageCode(); 426 } 427 else 428 { 429 //RETURN SOME UNDEFINED VALUE 430 return (0xFFFF); 431 } 432 433 } 434 435 436 // From mediaAtom -> Handler getTrackStreamType()437 uint32 getTrackStreamType() 438 { 439 if (_pmediaAtom != NULL) 440 { 441 return _pmediaAtom->getTrackStreamType(); 442 } 443 else 444 { 445 return 0xFFFFFFFF; 446 } 447 } 448 449 // From mediaAtom -> SampleDescription getNumSampleEntries()450 uint32 getNumSampleEntries() 451 { 452 if (_pmediaAtom != NULL) 453 { 454 return _pmediaAtom->getNumSampleEntries(); 455 } 456 else 457 { 458 return 0xFFFFFFFF; 459 } 460 } 461 getMIMEType(OSCL_String & aMimeType)462 void getMIMEType(OSCL_String& aMimeType) 463 { 464 if (_pmediaAtom != NULL) 465 { 466 _pmediaAtom->getMIMEType(aMimeType); 467 } 468 } // Based on OTI value 469 470 OSCL_IMPORT_REF uint8 getObjectTypeIndication(); 471 getMaxBufferSizeDB()472 int getMaxBufferSizeDB() 473 { 474 if (_pmediaAtom != NULL) 475 { 476 return _pmediaAtom->getMaxBufferSizeDB(); 477 } 478 else 479 { 480 return 0; 481 } 482 } 483 getAverageBitrate()484 int getAverageBitrate() 485 { 486 if (_pmediaAtom != NULL) 487 { 488 return _pmediaAtom->getAverageBitrate(); 489 } 490 else 491 { 492 return 0; 493 } 494 } getHeight()495 int32 getHeight() 496 { 497 if (_pmediaAtom != NULL) 498 { 499 return _pmediaAtom->getHeight(); 500 } 501 else 502 { 503 return 0; 504 } 505 506 } 507 getWidth()508 int32 getWidth() 509 { 510 if (_pmediaAtom != NULL) 511 { 512 return _pmediaAtom->getWidth(); 513 } 514 else 515 { 516 return 0; 517 } 518 } 519 520 //PASP box getHspacing()521 uint32 getHspacing() 522 { 523 524 if (_pmediaAtom != NULL) 525 { 526 return _pmediaAtom->getHspacing(); 527 } 528 else 529 { 530 return 0; 531 } 532 } 533 getVspacing()534 uint32 getVspacing() 535 { 536 if (_pmediaAtom != NULL) 537 { 538 return _pmediaAtom->getVspacing(); 539 } 540 else 541 { 542 return 0; 543 } 544 } 545 getNextBundledAccessUnits(uint32 * n,GAU * pgau)546 int32 getNextBundledAccessUnits(uint32 *n, 547 GAU *pgau) 548 { 549 if (_pmediaAtom != NULL) 550 { 551 return _pmediaAtom->getNextBundledAccessUnits(n, pgau); 552 } 553 else 554 { 555 return -1; 556 } 557 } 558 peekNextBundledAccessUnits(uint32 * n,MediaMetaInfo * mInfo)559 int32 peekNextBundledAccessUnits(uint32 *n, 560 MediaMetaInfo *mInfo) 561 { 562 if (_pmediaAtom != NULL) 563 { 564 return _pmediaAtom->peekNextBundledAccessUnits(n, mInfo); 565 } 566 else 567 { 568 return -1; 569 } 570 } 571 getSampleCount()572 uint32 getSampleCount() 573 { 574 if (_pmediaAtom != NULL) 575 { 576 return (_pmediaAtom->getSampleCount()); 577 } 578 else 579 { 580 return 0; 581 } 582 } 583 getLayer()584 int16 getLayer() 585 { 586 if (_ptrackHeader != NULL) 587 { 588 return _ptrackHeader->getLayer(); 589 } 590 else 591 { 592 return (-1); 593 } 594 } getAlternateGroup()595 uint16 getAlternateGroup() 596 { 597 if (_ptrackHeader != NULL) 598 { 599 return _ptrackHeader->getAlternateGroup(); 600 } 601 else 602 { 603 return (0xFFFF); 604 } 605 } getTextTrackWidth()606 int32 getTextTrackWidth() 607 { 608 if (_ptrackHeader != NULL) 609 { 610 return _ptrackHeader->getTextTrackWidth(); 611 } 612 else 613 { 614 return (-1); 615 } 616 } 617 getTextTrackHeight()618 int32 getTextTrackHeight() 619 { 620 if (_ptrackHeader != NULL) 621 { 622 return _ptrackHeader->getTextTrackHeight(); 623 } 624 else 625 { 626 return (-1); 627 } 628 } 629 getTextTrackXOffset()630 int32 getTextTrackXOffset() 631 { 632 if (_ptrackHeader != NULL) 633 { 634 return _ptrackHeader->getTextTrackXOffset(); 635 } 636 else 637 { 638 return (-1); 639 } 640 } 641 getTextTrackYOffset()642 int32 getTextTrackYOffset() 643 { 644 if (_ptrackHeader != NULL) 645 { 646 return _ptrackHeader->getTextTrackYOffset(); 647 } 648 else 649 { 650 return (-1); 651 } 652 } 653 getTextSampleEntryAt(uint32 index)654 SampleEntry *getTextSampleEntryAt(uint32 index) 655 { 656 if (_pmediaAtom != NULL) 657 { 658 return (_pmediaAtom-> getTextSampleEntryAt(index)); 659 } 660 else 661 { 662 return NULL; 663 } 664 } 665 getTimestampForRandomAccessPoints(uint32 * num,uint32 * tsBuf,uint32 * numBuf,uint32 * offsetBuf)666 int32 getTimestampForRandomAccessPoints(uint32 *num, uint32 *tsBuf, uint32* numBuf, uint32* offsetBuf) 667 { 668 if (_pmediaAtom != NULL) 669 { 670 return _pmediaAtom->getTimestampForRandomAccessPoints(num, tsBuf, numBuf, offsetBuf); 671 } 672 else 673 { 674 return 0; 675 } 676 } 677 getTimestampForRandomAccessPointsBeforeAfter(uint32 ts,uint32 * tsBuf,uint32 * numBuf,uint32 & numsamplestoget,uint32 howManyKeySamples)678 int32 getTimestampForRandomAccessPointsBeforeAfter(uint32 ts, uint32 *tsBuf, uint32* numBuf, 679 uint32& numsamplestoget, 680 uint32 howManyKeySamples) 681 { 682 if (_pmediaAtom != NULL) 683 { 684 return _pmediaAtom->getTimestampForRandomAccessPointsBeforeAfter(ts, tsBuf, numBuf, numsamplestoget, howManyKeySamples); 685 } 686 else 687 { 688 return 0; 689 } 690 691 } getNumAMRFramesPerSample()692 int32 getNumAMRFramesPerSample() 693 { 694 if (_pmediaAtom != NULL) 695 { 696 return (_pmediaAtom->getNumAMRFramesPerSample()); 697 } 698 else 699 { 700 return 0; 701 } 702 } 703 getMaxTrackTimeStamp(uint32 fileSize,uint32 & timeStamp)704 MP4_ERROR_CODE getMaxTrackTimeStamp(uint32 fileSize, uint32& timeStamp) 705 { 706 if (_pmediaAtom != NULL) 707 { 708 return (_pmediaAtom->getMaxTrackTimeStamp(fileSize, timeStamp)); 709 } 710 else 711 { 712 return DEFAULT_ERROR; 713 } 714 } 715 716 MP4_ERROR_CODE getSampleNumberClosestToTimeStamp(uint32 &sampleNumber, 717 uint32 timeStamp, 718 uint32 sampleOffset = 0) 719 { 720 if (_pmediaAtom != NULL) 721 { 722 return 723 (_pmediaAtom->getSampleNumberClosestToTimeStamp(sampleNumber, 724 timeStamp, 725 sampleOffset)); 726 } 727 else 728 { 729 return (READ_FAILED); 730 } 731 } 732 getAVCSampleEntry(uint32 index)733 AVCSampleEntry* getAVCSampleEntry(uint32 index) 734 { 735 if (_pmediaAtom != NULL) 736 { 737 return (_pmediaAtom->getAVCSampleEntry(index)); 738 } 739 return (NULL); 740 } 741 getAVCNALLengthSize(uint32 index)742 uint32 getAVCNALLengthSize(uint32 index) 743 { 744 if (_pmediaAtom != NULL) 745 { 746 return (_pmediaAtom->getAVCNALLengthSize(index)); 747 } 748 return 0; 749 } 750 getNumAVCSampleEntries()751 uint32 getNumAVCSampleEntries() 752 { 753 if (_pmediaAtom != NULL) 754 { 755 return (_pmediaAtom->getNumAVCSampleEntries()); 756 } 757 return 0; 758 } 759 getTrackLevelOMA2DRMInfoSize()760 uint32 getTrackLevelOMA2DRMInfoSize() 761 { 762 if (_pmediaAtom != NULL) 763 { 764 return (_pmediaAtom->getTrackLevelOMA2DRMInfoSize()); 765 } 766 return 0; 767 } 768 getTrackLevelOMA2DRMInfo()769 uint8* getTrackLevelOMA2DRMInfo() 770 { 771 if (_pmediaAtom != NULL) 772 { 773 return (_pmediaAtom->getTrackLevelOMA2DRMInfo()); 774 } 775 return NULL; 776 } 777 isMultipleSampleDescriptionAvailable()778 bool isMultipleSampleDescriptionAvailable() 779 { 780 if (_pmediaAtom != NULL) 781 { 782 return (_pmediaAtom->isMultipleSampleDescriptionAvailable()); 783 } 784 return 0; 785 } 786 787 private: 788 UserDataAtom *_puserdataatom; 789 EditAtom *_pEditAtom; 790 TrackHeaderAtom *_ptrackHeader; 791 TrackReferenceAtom *_ptrackReference; 792 MediaAtom *_pmediaAtom; 793 uint32 _trackStartOffset; 794 int32 _pMediaType; 795 796 OMADRMKMSBox* _pOMADRMKMSBox; 797 }; 798 799 #endif // TRACKATOM_H_INCLUDED 800 801 802