ATSParser.cpp revision 9bcf3ae6c9a413afc7accb5b48db3e5c3c829785
1/* 2 * Copyright (C) 2010 The Android Open Source Project 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 express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17//#define LOG_NDEBUG 0 18#define LOG_TAG "ATSParser" 19#include <utils/Log.h> 20 21#include "ATSParser.h" 22 23#include "AnotherPacketSource.h" 24#include "ESQueue.h" 25#include "include/avc_utils.h" 26 27#include <media/stagefright/foundation/ABitReader.h> 28#include <media/stagefright/foundation/ABuffer.h> 29#include <media/stagefright/foundation/ADebug.h> 30#include <media/stagefright/foundation/AMessage.h> 31#include <media/stagefright/foundation/hexdump.h> 32#include <media/stagefright/MediaDefs.h> 33#include <media/stagefright/MediaErrors.h> 34#include <media/stagefright/MetaData.h> 35#include <media/stagefright/Utils.h> 36#include <media/IStreamSource.h> 37#include <utils/KeyedVector.h> 38#include <utils/Vector.h> 39 40#include <inttypes.h> 41 42namespace android { 43 44// I want the expression "y" evaluated even if verbose logging is off. 45#define MY_LOGV(x, y) \ 46 do { unsigned tmp = y; ALOGV(x, tmp); } while (0) 47 48static const size_t kTSPacketSize = 188; 49 50struct ATSParser::Program : public RefBase { 51 Program(ATSParser *parser, unsigned programNumber, unsigned programMapPID); 52 53 bool parsePSISection( 54 unsigned pid, ABitReader *br, status_t *err); 55 56 bool parsePID( 57 unsigned pid, unsigned continuity_counter, 58 unsigned payload_unit_start_indicator, 59 ABitReader *br, status_t *err); 60 61 void signalDiscontinuity( 62 DiscontinuityType type, const sp<AMessage> &extra); 63 64 void signalEOS(status_t finalResult); 65 66 sp<MediaSource> getSource(SourceType type); 67 bool hasSource(SourceType type) const; 68 69 int64_t convertPTSToTimestamp(uint64_t PTS); 70 71 bool PTSTimeDeltaEstablished() const { 72 return mFirstPTSValid; 73 } 74 75 unsigned number() const { return mProgramNumber; } 76 77 void updateProgramMapPID(unsigned programMapPID) { 78 mProgramMapPID = programMapPID; 79 } 80 81 unsigned programMapPID() const { 82 return mProgramMapPID; 83 } 84 85 uint32_t parserFlags() const { 86 return mParser->mFlags; 87 } 88 89private: 90 struct StreamInfo { 91 unsigned mType; 92 unsigned mPID; 93 }; 94 95 ATSParser *mParser; 96 unsigned mProgramNumber; 97 unsigned mProgramMapPID; 98 KeyedVector<unsigned, sp<Stream> > mStreams; 99 bool mFirstPTSValid; 100 uint64_t mFirstPTS; 101 int64_t mLastRecoveredPTS; 102 103 status_t parseProgramMap(ABitReader *br); 104 int64_t recoverPTS(uint64_t PTS_33bit); 105 bool switchPIDs(const Vector<StreamInfo> &infos); 106 107 DISALLOW_EVIL_CONSTRUCTORS(Program); 108}; 109 110struct ATSParser::Stream : public RefBase { 111 Stream(Program *program, 112 unsigned elementaryPID, 113 unsigned streamType, 114 unsigned PCR_PID); 115 116 unsigned type() const { return mStreamType; } 117 unsigned pid() const { return mElementaryPID; } 118 void setPID(unsigned pid) { mElementaryPID = pid; } 119 120 status_t parse( 121 unsigned continuity_counter, 122 unsigned payload_unit_start_indicator, 123 ABitReader *br); 124 125 void signalDiscontinuity( 126 DiscontinuityType type, const sp<AMessage> &extra); 127 128 void signalEOS(status_t finalResult); 129 130 sp<MediaSource> getSource(SourceType type); 131 132 bool isAudio() const; 133 bool isVideo() const; 134 135protected: 136 virtual ~Stream(); 137 138private: 139 Program *mProgram; 140 unsigned mElementaryPID; 141 unsigned mStreamType; 142 unsigned mPCR_PID; 143 int32_t mExpectedContinuityCounter; 144 145 sp<ABuffer> mBuffer; 146 sp<AnotherPacketSource> mSource; 147 bool mPayloadStarted; 148 149 uint64_t mPrevPTS; 150 151 ElementaryStreamQueue *mQueue; 152 153 status_t flush(); 154 status_t parsePES(ABitReader *br); 155 156 void onPayloadData( 157 unsigned PTS_DTS_flags, uint64_t PTS, uint64_t DTS, 158 const uint8_t *data, size_t size); 159 160 void extractAACFrames(const sp<ABuffer> &buffer); 161 162 DISALLOW_EVIL_CONSTRUCTORS(Stream); 163}; 164 165struct ATSParser::PSISection : public RefBase { 166 PSISection(); 167 168 status_t append(const void *data, size_t size); 169 void clear(); 170 171 bool isComplete() const; 172 bool isEmpty() const; 173 174 const uint8_t *data() const; 175 size_t size() const; 176 177protected: 178 virtual ~PSISection(); 179 180private: 181 sp<ABuffer> mBuffer; 182 183 DISALLOW_EVIL_CONSTRUCTORS(PSISection); 184}; 185 186//////////////////////////////////////////////////////////////////////////////// 187 188ATSParser::Program::Program( 189 ATSParser *parser, unsigned programNumber, unsigned programMapPID) 190 : mParser(parser), 191 mProgramNumber(programNumber), 192 mProgramMapPID(programMapPID), 193 mFirstPTSValid(false), 194 mFirstPTS(0), 195 mLastRecoveredPTS(-1ll) { 196 ALOGV("new program number %u", programNumber); 197} 198 199bool ATSParser::Program::parsePSISection( 200 unsigned pid, ABitReader *br, status_t *err) { 201 *err = OK; 202 203 if (pid != mProgramMapPID) { 204 return false; 205 } 206 207 *err = parseProgramMap(br); 208 209 return true; 210} 211 212bool ATSParser::Program::parsePID( 213 unsigned pid, unsigned continuity_counter, 214 unsigned payload_unit_start_indicator, 215 ABitReader *br, status_t *err) { 216 *err = OK; 217 218 ssize_t index = mStreams.indexOfKey(pid); 219 if (index < 0) { 220 return false; 221 } 222 223 *err = mStreams.editValueAt(index)->parse( 224 continuity_counter, payload_unit_start_indicator, br); 225 226 return true; 227} 228 229void ATSParser::Program::signalDiscontinuity( 230 DiscontinuityType type, const sp<AMessage> &extra) { 231 int64_t mediaTimeUs; 232 if ((type & DISCONTINUITY_TIME) 233 && extra != NULL 234 && extra->findInt64( 235 IStreamListener::kKeyMediaTimeUs, &mediaTimeUs)) { 236 mFirstPTSValid = false; 237 } 238 239 for (size_t i = 0; i < mStreams.size(); ++i) { 240 mStreams.editValueAt(i)->signalDiscontinuity(type, extra); 241 } 242} 243 244void ATSParser::Program::signalEOS(status_t finalResult) { 245 for (size_t i = 0; i < mStreams.size(); ++i) { 246 mStreams.editValueAt(i)->signalEOS(finalResult); 247 } 248} 249 250bool ATSParser::Program::switchPIDs(const Vector<StreamInfo> &infos) { 251 bool success = false; 252 253 if (mStreams.size() == infos.size()) { 254 // build type->PIDs map for old and new mapping 255 size_t i; 256 KeyedVector<int32_t, Vector<int32_t> > oldType2PIDs, newType2PIDs; 257 for (i = 0; i < mStreams.size(); ++i) { 258 ssize_t index = oldType2PIDs.indexOfKey(mStreams[i]->type()); 259 if (index < 0) { 260 oldType2PIDs.add(mStreams[i]->type(), Vector<int32_t>()); 261 } 262 oldType2PIDs.editValueFor(mStreams[i]->type()).push_back(mStreams[i]->pid()); 263 } 264 for (i = 0; i < infos.size(); ++i) { 265 ssize_t index = newType2PIDs.indexOfKey(infos[i].mType); 266 if (index < 0) { 267 newType2PIDs.add(infos[i].mType, Vector<int32_t>()); 268 } 269 newType2PIDs.editValueFor(infos[i].mType).push_back(infos[i].mPID); 270 } 271 272 // we can recover if the number of streams for each type hasn't changed 273 if (oldType2PIDs.size() == newType2PIDs.size()) { 274 success = true; 275 for (i = 0; i < oldType2PIDs.size(); ++i) { 276 // KeyedVector is sorted, we just compare key and size of each index 277 if (oldType2PIDs.keyAt(i) != newType2PIDs.keyAt(i) 278 || oldType2PIDs[i].size() != newType2PIDs[i].size()) { 279 success = false; 280 break; 281 } 282 } 283 } 284 285 if (success) { 286 // save current streams to temp 287 KeyedVector<int32_t, sp<Stream> > temp; 288 for (i = 0; i < mStreams.size(); ++i) { 289 temp.add(mStreams.keyAt(i), mStreams.editValueAt(i)); 290 } 291 292 mStreams.clear(); 293 for (i = 0; i < temp.size(); ++i) { 294 // The two checks below shouldn't happen, 295 // we already checked above the stream count matches 296 ssize_t index = newType2PIDs.indexOfKey(temp[i]->type()); 297 CHECK(index >= 0); 298 Vector<int32_t> &newPIDs = newType2PIDs.editValueAt(index); 299 CHECK(newPIDs.size() > 0); 300 301 // get the next PID for temp[i]->type() in the new PID map 302 Vector<int32_t>::iterator it = newPIDs.begin(); 303 304 // change the PID of the stream, and add it back 305 temp.editValueAt(i)->setPID(*it); 306 mStreams.add(temp[i]->pid(), temp.editValueAt(i)); 307 308 // removed the used PID 309 newPIDs.erase(it); 310 } 311 } 312 } 313 return success; 314} 315 316status_t ATSParser::Program::parseProgramMap(ABitReader *br) { 317 unsigned table_id = br->getBits(8); 318 ALOGV(" table_id = %u", table_id); 319 if (table_id != 0x02u) { 320 ALOGE("PMT data error!"); 321 return ERROR_MALFORMED; 322 } 323 unsigned section_syntax_indicator = br->getBits(1); 324 ALOGV(" section_syntax_indicator = %u", section_syntax_indicator); 325 if (section_syntax_indicator != 1u) { 326 ALOGE("PMT data error!"); 327 return ERROR_MALFORMED; 328 } 329 330 CHECK_EQ(br->getBits(1), 0u); 331 MY_LOGV(" reserved = %u", br->getBits(2)); 332 333 unsigned section_length = br->getBits(12); 334 ALOGV(" section_length = %u", section_length); 335 CHECK_EQ(section_length & 0xc00, 0u); 336 CHECK_LE(section_length, 1021u); 337 338 MY_LOGV(" program_number = %u", br->getBits(16)); 339 MY_LOGV(" reserved = %u", br->getBits(2)); 340 MY_LOGV(" version_number = %u", br->getBits(5)); 341 MY_LOGV(" current_next_indicator = %u", br->getBits(1)); 342 MY_LOGV(" section_number = %u", br->getBits(8)); 343 MY_LOGV(" last_section_number = %u", br->getBits(8)); 344 MY_LOGV(" reserved = %u", br->getBits(3)); 345 346 unsigned PCR_PID = br->getBits(13); 347 ALOGV(" PCR_PID = 0x%04x", PCR_PID); 348 349 MY_LOGV(" reserved = %u", br->getBits(4)); 350 351 unsigned program_info_length = br->getBits(12); 352 ALOGV(" program_info_length = %u", program_info_length); 353 CHECK_EQ(program_info_length & 0xc00, 0u); 354 355 br->skipBits(program_info_length * 8); // skip descriptors 356 357 Vector<StreamInfo> infos; 358 359 // infoBytesRemaining is the number of bytes that make up the 360 // variable length section of ES_infos. It does not include the 361 // final CRC. 362 size_t infoBytesRemaining = section_length - 9 - program_info_length - 4; 363 364 while (infoBytesRemaining > 0) { 365 CHECK_GE(infoBytesRemaining, 5u); 366 367 unsigned streamType = br->getBits(8); 368 ALOGV(" stream_type = 0x%02x", streamType); 369 370 MY_LOGV(" reserved = %u", br->getBits(3)); 371 372 unsigned elementaryPID = br->getBits(13); 373 ALOGV(" elementary_PID = 0x%04x", elementaryPID); 374 375 MY_LOGV(" reserved = %u", br->getBits(4)); 376 377 unsigned ES_info_length = br->getBits(12); 378 ALOGV(" ES_info_length = %u", ES_info_length); 379 CHECK_EQ(ES_info_length & 0xc00, 0u); 380 381 CHECK_GE(infoBytesRemaining - 5, ES_info_length); 382 383#if 0 384 br->skipBits(ES_info_length * 8); // skip descriptors 385#else 386 unsigned info_bytes_remaining = ES_info_length; 387 while (info_bytes_remaining >= 2) { 388 MY_LOGV(" tag = 0x%02x", br->getBits(8)); 389 390 unsigned descLength = br->getBits(8); 391 ALOGV(" len = %u", descLength); 392 393 CHECK_GE(info_bytes_remaining, 2 + descLength); 394 395 br->skipBits(descLength * 8); 396 397 info_bytes_remaining -= descLength + 2; 398 } 399 CHECK_EQ(info_bytes_remaining, 0u); 400#endif 401 402 StreamInfo info; 403 info.mType = streamType; 404 info.mPID = elementaryPID; 405 infos.push(info); 406 407 infoBytesRemaining -= 5 + ES_info_length; 408 } 409 410 CHECK_EQ(infoBytesRemaining, 0u); 411 MY_LOGV(" CRC = 0x%08x", br->getBits(32)); 412 413 bool PIDsChanged = false; 414 for (size_t i = 0; i < infos.size(); ++i) { 415 StreamInfo &info = infos.editItemAt(i); 416 417 ssize_t index = mStreams.indexOfKey(info.mPID); 418 419 if (index >= 0 && mStreams.editValueAt(index)->type() != info.mType) { 420 ALOGI("uh oh. stream PIDs have changed."); 421 PIDsChanged = true; 422 break; 423 } 424 } 425 426 if (PIDsChanged) { 427#if 0 428 ALOGI("before:"); 429 for (size_t i = 0; i < mStreams.size(); ++i) { 430 sp<Stream> stream = mStreams.editValueAt(i); 431 432 ALOGI("PID 0x%08x => type 0x%02x", stream->pid(), stream->type()); 433 } 434 435 ALOGI("after:"); 436 for (size_t i = 0; i < infos.size(); ++i) { 437 StreamInfo &info = infos.editItemAt(i); 438 439 ALOGI("PID 0x%08x => type 0x%02x", info.mPID, info.mType); 440 } 441#endif 442 443 // we can recover if number of streams for each type remain the same 444 bool success = switchPIDs(infos); 445 446 if (!success) { 447 ALOGI("Stream PIDs changed and we cannot recover."); 448 return ERROR_MALFORMED; 449 } 450 } 451 452 for (size_t i = 0; i < infos.size(); ++i) { 453 StreamInfo &info = infos.editItemAt(i); 454 455 ssize_t index = mStreams.indexOfKey(info.mPID); 456 457 if (index < 0) { 458 sp<Stream> stream = new Stream( 459 this, info.mPID, info.mType, PCR_PID); 460 461 mStreams.add(info.mPID, stream); 462 } 463 } 464 465 return OK; 466} 467 468int64_t ATSParser::Program::recoverPTS(uint64_t PTS_33bit) { 469 // We only have the lower 33-bit of the PTS. It could overflow within a 470 // reasonable amount of time. To handle the wrap-around, use fancy math 471 // to get an extended PTS that is within [-0xffffffff, 0xffffffff] 472 // of the latest recovered PTS. 473 if (mLastRecoveredPTS < 0ll) { 474 // Use the original 33bit number for 1st frame, the reason is that 475 // if 1st frame wraps to negative that's far away from 0, we could 476 // never start. Only start wrapping around from 2nd frame. 477 mLastRecoveredPTS = static_cast<int64_t>(PTS_33bit); 478 } else { 479 mLastRecoveredPTS = static_cast<int64_t>( 480 ((mLastRecoveredPTS - PTS_33bit + 0x100000000ll) 481 & 0xfffffffe00000000ull) | PTS_33bit); 482 // We start from 0, but recovered PTS could be slightly below 0. 483 // Clamp it to 0 as rest of the pipeline doesn't take negative pts. 484 // (eg. video is read first and starts at 0, but audio starts at 0xfffffff0) 485 if (mLastRecoveredPTS < 0ll) { 486 ALOGI("Clamping negative recovered PTS (%lld) to 0", mLastRecoveredPTS); 487 mLastRecoveredPTS = 0ll; 488 } 489 } 490 491 return mLastRecoveredPTS; 492} 493 494sp<MediaSource> ATSParser::Program::getSource(SourceType type) { 495 size_t index = (type == AUDIO) ? 0 : 0; 496 497 for (size_t i = 0; i < mStreams.size(); ++i) { 498 sp<MediaSource> source = mStreams.editValueAt(i)->getSource(type); 499 if (source != NULL) { 500 if (index == 0) { 501 return source; 502 } 503 --index; 504 } 505 } 506 507 return NULL; 508} 509 510bool ATSParser::Program::hasSource(SourceType type) const { 511 for (size_t i = 0; i < mStreams.size(); ++i) { 512 const sp<Stream> &stream = mStreams.valueAt(i); 513 if (type == AUDIO && stream->isAudio()) { 514 return true; 515 } else if (type == VIDEO && stream->isVideo()) { 516 return true; 517 } 518 } 519 520 return false; 521} 522 523int64_t ATSParser::Program::convertPTSToTimestamp(uint64_t PTS) { 524 PTS = recoverPTS(PTS); 525 526 if (!(mParser->mFlags & TS_TIMESTAMPS_ARE_ABSOLUTE)) { 527 if (!mFirstPTSValid) { 528 mFirstPTSValid = true; 529 mFirstPTS = PTS; 530 PTS = 0; 531 } else if (PTS < mFirstPTS) { 532 PTS = 0; 533 } else { 534 PTS -= mFirstPTS; 535 } 536 } 537 538 int64_t timeUs = (PTS * 100) / 9; 539 540 if (mParser->mAbsoluteTimeAnchorUs >= 0ll) { 541 timeUs += mParser->mAbsoluteTimeAnchorUs; 542 } 543 544 if (mParser->mTimeOffsetValid) { 545 timeUs += mParser->mTimeOffsetUs; 546 } 547 548 return timeUs; 549} 550 551//////////////////////////////////////////////////////////////////////////////// 552 553ATSParser::Stream::Stream( 554 Program *program, 555 unsigned elementaryPID, 556 unsigned streamType, 557 unsigned PCR_PID) 558 : mProgram(program), 559 mElementaryPID(elementaryPID), 560 mStreamType(streamType), 561 mPCR_PID(PCR_PID), 562 mExpectedContinuityCounter(-1), 563 mPayloadStarted(false), 564 mPrevPTS(0), 565 mQueue(NULL) { 566 switch (mStreamType) { 567 case STREAMTYPE_H264: 568 mQueue = new ElementaryStreamQueue( 569 ElementaryStreamQueue::H264, 570 (mProgram->parserFlags() & ALIGNED_VIDEO_DATA) 571 ? ElementaryStreamQueue::kFlag_AlignedData : 0); 572 break; 573 case STREAMTYPE_MPEG2_AUDIO_ADTS: 574 mQueue = new ElementaryStreamQueue(ElementaryStreamQueue::AAC); 575 break; 576 case STREAMTYPE_MPEG1_AUDIO: 577 case STREAMTYPE_MPEG2_AUDIO: 578 mQueue = new ElementaryStreamQueue( 579 ElementaryStreamQueue::MPEG_AUDIO); 580 break; 581 582 case STREAMTYPE_MPEG1_VIDEO: 583 case STREAMTYPE_MPEG2_VIDEO: 584 mQueue = new ElementaryStreamQueue( 585 ElementaryStreamQueue::MPEG_VIDEO); 586 break; 587 588 case STREAMTYPE_MPEG4_VIDEO: 589 mQueue = new ElementaryStreamQueue( 590 ElementaryStreamQueue::MPEG4_VIDEO); 591 break; 592 593 case STREAMTYPE_LPCM_AC3: 594 case STREAMTYPE_AC3: 595 mQueue = new ElementaryStreamQueue( 596 ElementaryStreamQueue::AC3); 597 break; 598 599 default: 600 break; 601 } 602 603 ALOGV("new stream PID 0x%02x, type 0x%02x", elementaryPID, streamType); 604 605 if (mQueue != NULL) { 606 mBuffer = new ABuffer(192 * 1024); 607 mBuffer->setRange(0, 0); 608 } 609} 610 611ATSParser::Stream::~Stream() { 612 delete mQueue; 613 mQueue = NULL; 614} 615 616status_t ATSParser::Stream::parse( 617 unsigned continuity_counter, 618 unsigned payload_unit_start_indicator, ABitReader *br) { 619 if (mQueue == NULL) { 620 return OK; 621 } 622 623 if (mExpectedContinuityCounter >= 0 624 && (unsigned)mExpectedContinuityCounter != continuity_counter) { 625 ALOGI("discontinuity on stream pid 0x%04x", mElementaryPID); 626 627 mPayloadStarted = false; 628 mBuffer->setRange(0, 0); 629 mExpectedContinuityCounter = -1; 630 631#if 0 632 // Uncomment this if you'd rather see no corruption whatsoever on 633 // screen and suspend updates until we come across another IDR frame. 634 635 if (mStreamType == STREAMTYPE_H264) { 636 ALOGI("clearing video queue"); 637 mQueue->clear(true /* clearFormat */); 638 } 639#endif 640 641 if (!payload_unit_start_indicator) { 642 return OK; 643 } 644 } 645 646 mExpectedContinuityCounter = (continuity_counter + 1) & 0x0f; 647 648 if (payload_unit_start_indicator) { 649 if (mPayloadStarted) { 650 // Otherwise we run the danger of receiving the trailing bytes 651 // of a PES packet that we never saw the start of and assuming 652 // we have a a complete PES packet. 653 654 status_t err = flush(); 655 656 if (err != OK) { 657 return err; 658 } 659 } 660 661 mPayloadStarted = true; 662 } 663 664 if (!mPayloadStarted) { 665 return OK; 666 } 667 668 size_t payloadSizeBits = br->numBitsLeft(); 669 CHECK_EQ(payloadSizeBits % 8, 0u); 670 671 size_t neededSize = mBuffer->size() + payloadSizeBits / 8; 672 if (mBuffer->capacity() < neededSize) { 673 // Increment in multiples of 64K. 674 neededSize = (neededSize + 65535) & ~65535; 675 676 ALOGI("resizing buffer to %zu bytes", neededSize); 677 678 sp<ABuffer> newBuffer = new ABuffer(neededSize); 679 memcpy(newBuffer->data(), mBuffer->data(), mBuffer->size()); 680 newBuffer->setRange(0, mBuffer->size()); 681 mBuffer = newBuffer; 682 } 683 684 memcpy(mBuffer->data() + mBuffer->size(), br->data(), payloadSizeBits / 8); 685 mBuffer->setRange(0, mBuffer->size() + payloadSizeBits / 8); 686 687 return OK; 688} 689 690bool ATSParser::Stream::isVideo() const { 691 switch (mStreamType) { 692 case STREAMTYPE_H264: 693 case STREAMTYPE_MPEG1_VIDEO: 694 case STREAMTYPE_MPEG2_VIDEO: 695 case STREAMTYPE_MPEG4_VIDEO: 696 return true; 697 698 default: 699 return false; 700 } 701} 702 703bool ATSParser::Stream::isAudio() const { 704 switch (mStreamType) { 705 case STREAMTYPE_MPEG1_AUDIO: 706 case STREAMTYPE_MPEG2_AUDIO: 707 case STREAMTYPE_MPEG2_AUDIO_ADTS: 708 case STREAMTYPE_LPCM_AC3: 709 case STREAMTYPE_AC3: 710 return true; 711 712 default: 713 return false; 714 } 715} 716 717void ATSParser::Stream::signalDiscontinuity( 718 DiscontinuityType type, const sp<AMessage> &extra) { 719 mExpectedContinuityCounter = -1; 720 721 if (mQueue == NULL) { 722 return; 723 } 724 725 mPayloadStarted = false; 726 mBuffer->setRange(0, 0); 727 728 bool clearFormat = false; 729 if (isAudio()) { 730 if (type & DISCONTINUITY_AUDIO_FORMAT) { 731 clearFormat = true; 732 } 733 } else { 734 if (type & DISCONTINUITY_VIDEO_FORMAT) { 735 clearFormat = true; 736 } 737 } 738 739 mQueue->clear(clearFormat); 740 741 if (type & DISCONTINUITY_TIME) { 742 uint64_t resumeAtPTS; 743 if (extra != NULL 744 && extra->findInt64( 745 IStreamListener::kKeyResumeAtPTS, 746 (int64_t *)&resumeAtPTS)) { 747 int64_t resumeAtMediaTimeUs = 748 mProgram->convertPTSToTimestamp(resumeAtPTS); 749 750 extra->setInt64("resume-at-mediaTimeUs", resumeAtMediaTimeUs); 751 } 752 } 753 754 if (mSource != NULL) { 755 mSource->queueDiscontinuity(type, extra, true); 756 } 757} 758 759void ATSParser::Stream::signalEOS(status_t finalResult) { 760 if (mSource != NULL) { 761 mSource->signalEOS(finalResult); 762 } 763} 764 765status_t ATSParser::Stream::parsePES(ABitReader *br) { 766 unsigned packet_startcode_prefix = br->getBits(24); 767 768 ALOGV("packet_startcode_prefix = 0x%08x", packet_startcode_prefix); 769 770 if (packet_startcode_prefix != 1) { 771 ALOGV("Supposedly payload_unit_start=1 unit does not start " 772 "with startcode."); 773 774 return ERROR_MALFORMED; 775 } 776 777 CHECK_EQ(packet_startcode_prefix, 0x000001u); 778 779 unsigned stream_id = br->getBits(8); 780 ALOGV("stream_id = 0x%02x", stream_id); 781 782 unsigned PES_packet_length = br->getBits(16); 783 ALOGV("PES_packet_length = %u", PES_packet_length); 784 785 if (stream_id != 0xbc // program_stream_map 786 && stream_id != 0xbe // padding_stream 787 && stream_id != 0xbf // private_stream_2 788 && stream_id != 0xf0 // ECM 789 && stream_id != 0xf1 // EMM 790 && stream_id != 0xff // program_stream_directory 791 && stream_id != 0xf2 // DSMCC 792 && stream_id != 0xf8) { // H.222.1 type E 793 CHECK_EQ(br->getBits(2), 2u); 794 795 MY_LOGV("PES_scrambling_control = %u", br->getBits(2)); 796 MY_LOGV("PES_priority = %u", br->getBits(1)); 797 MY_LOGV("data_alignment_indicator = %u", br->getBits(1)); 798 MY_LOGV("copyright = %u", br->getBits(1)); 799 MY_LOGV("original_or_copy = %u", br->getBits(1)); 800 801 unsigned PTS_DTS_flags = br->getBits(2); 802 ALOGV("PTS_DTS_flags = %u", PTS_DTS_flags); 803 804 unsigned ESCR_flag = br->getBits(1); 805 ALOGV("ESCR_flag = %u", ESCR_flag); 806 807 unsigned ES_rate_flag = br->getBits(1); 808 ALOGV("ES_rate_flag = %u", ES_rate_flag); 809 810 unsigned DSM_trick_mode_flag = br->getBits(1); 811 ALOGV("DSM_trick_mode_flag = %u", DSM_trick_mode_flag); 812 813 unsigned additional_copy_info_flag = br->getBits(1); 814 ALOGV("additional_copy_info_flag = %u", additional_copy_info_flag); 815 816 MY_LOGV("PES_CRC_flag = %u", br->getBits(1)); 817 MY_LOGV("PES_extension_flag = %u", br->getBits(1)); 818 819 unsigned PES_header_data_length = br->getBits(8); 820 ALOGV("PES_header_data_length = %u", PES_header_data_length); 821 822 unsigned optional_bytes_remaining = PES_header_data_length; 823 824 uint64_t PTS = 0, DTS = 0; 825 826 if (PTS_DTS_flags == 2 || PTS_DTS_flags == 3) { 827 CHECK_GE(optional_bytes_remaining, 5u); 828 829 if (br->getBits(4) != PTS_DTS_flags) { 830 ALOGE("PES data Error!"); 831 return ERROR_MALFORMED; 832 } 833 PTS = ((uint64_t)br->getBits(3)) << 30; 834 CHECK_EQ(br->getBits(1), 1u); 835 PTS |= ((uint64_t)br->getBits(15)) << 15; 836 CHECK_EQ(br->getBits(1), 1u); 837 PTS |= br->getBits(15); 838 CHECK_EQ(br->getBits(1), 1u); 839 840 ALOGV("PTS = 0x%016" PRIx64 " (%.2f)", PTS, PTS / 90000.0); 841 842 optional_bytes_remaining -= 5; 843 844 if (PTS_DTS_flags == 3) { 845 CHECK_GE(optional_bytes_remaining, 5u); 846 847 CHECK_EQ(br->getBits(4), 1u); 848 849 DTS = ((uint64_t)br->getBits(3)) << 30; 850 CHECK_EQ(br->getBits(1), 1u); 851 DTS |= ((uint64_t)br->getBits(15)) << 15; 852 CHECK_EQ(br->getBits(1), 1u); 853 DTS |= br->getBits(15); 854 CHECK_EQ(br->getBits(1), 1u); 855 856 ALOGV("DTS = %" PRIu64, DTS); 857 858 optional_bytes_remaining -= 5; 859 } 860 } 861 862 if (ESCR_flag) { 863 CHECK_GE(optional_bytes_remaining, 6u); 864 865 br->getBits(2); 866 867 uint64_t ESCR = ((uint64_t)br->getBits(3)) << 30; 868 CHECK_EQ(br->getBits(1), 1u); 869 ESCR |= ((uint64_t)br->getBits(15)) << 15; 870 CHECK_EQ(br->getBits(1), 1u); 871 ESCR |= br->getBits(15); 872 CHECK_EQ(br->getBits(1), 1u); 873 874 ALOGV("ESCR = %" PRIu64, ESCR); 875 MY_LOGV("ESCR_extension = %u", br->getBits(9)); 876 877 CHECK_EQ(br->getBits(1), 1u); 878 879 optional_bytes_remaining -= 6; 880 } 881 882 if (ES_rate_flag) { 883 CHECK_GE(optional_bytes_remaining, 3u); 884 885 CHECK_EQ(br->getBits(1), 1u); 886 MY_LOGV("ES_rate = %u", br->getBits(22)); 887 CHECK_EQ(br->getBits(1), 1u); 888 889 optional_bytes_remaining -= 3; 890 } 891 892 br->skipBits(optional_bytes_remaining * 8); 893 894 // ES data follows. 895 896 if (PES_packet_length != 0) { 897 CHECK_GE(PES_packet_length, PES_header_data_length + 3); 898 899 unsigned dataLength = 900 PES_packet_length - 3 - PES_header_data_length; 901 902 if (br->numBitsLeft() < dataLength * 8) { 903 ALOGE("PES packet does not carry enough data to contain " 904 "payload. (numBitsLeft = %zu, required = %u)", 905 br->numBitsLeft(), dataLength * 8); 906 907 return ERROR_MALFORMED; 908 } 909 910 CHECK_GE(br->numBitsLeft(), dataLength * 8); 911 912 onPayloadData( 913 PTS_DTS_flags, PTS, DTS, br->data(), dataLength); 914 915 br->skipBits(dataLength * 8); 916 } else { 917 onPayloadData( 918 PTS_DTS_flags, PTS, DTS, 919 br->data(), br->numBitsLeft() / 8); 920 921 size_t payloadSizeBits = br->numBitsLeft(); 922 CHECK_EQ(payloadSizeBits % 8, 0u); 923 924 ALOGV("There's %zu bytes of payload.", payloadSizeBits / 8); 925 } 926 } else if (stream_id == 0xbe) { // padding_stream 927 CHECK_NE(PES_packet_length, 0u); 928 br->skipBits(PES_packet_length * 8); 929 } else { 930 CHECK_NE(PES_packet_length, 0u); 931 br->skipBits(PES_packet_length * 8); 932 } 933 934 return OK; 935} 936 937status_t ATSParser::Stream::flush() { 938 if (mBuffer->size() == 0) { 939 return OK; 940 } 941 942 ALOGV("flushing stream 0x%04x size = %zu", mElementaryPID, mBuffer->size()); 943 944 ABitReader br(mBuffer->data(), mBuffer->size()); 945 946 status_t err = parsePES(&br); 947 948 mBuffer->setRange(0, 0); 949 950 return err; 951} 952 953void ATSParser::Stream::onPayloadData( 954 unsigned PTS_DTS_flags, uint64_t PTS, uint64_t /* DTS */, 955 const uint8_t *data, size_t size) { 956#if 0 957 ALOGI("payload streamType 0x%02x, PTS = 0x%016llx, dPTS = %lld", 958 mStreamType, 959 PTS, 960 (int64_t)PTS - mPrevPTS); 961 mPrevPTS = PTS; 962#endif 963 964 ALOGV("onPayloadData mStreamType=0x%02x", mStreamType); 965 966 int64_t timeUs = 0ll; // no presentation timestamp available. 967 if (PTS_DTS_flags == 2 || PTS_DTS_flags == 3) { 968 timeUs = mProgram->convertPTSToTimestamp(PTS); 969 } 970 971 status_t err = mQueue->appendData(data, size, timeUs); 972 973 if (err != OK) { 974 return; 975 } 976 977 sp<ABuffer> accessUnit; 978 while ((accessUnit = mQueue->dequeueAccessUnit()) != NULL) { 979 if (mSource == NULL) { 980 sp<MetaData> meta = mQueue->getFormat(); 981 982 if (meta != NULL) { 983 ALOGV("Stream PID 0x%08x of type 0x%02x now has data.", 984 mElementaryPID, mStreamType); 985 986 const char *mime; 987 if (meta->findCString(kKeyMIMEType, &mime) 988 && !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC) 989 && !IsIDR(accessUnit)) { 990 continue; 991 } 992 mSource = new AnotherPacketSource(meta); 993 mSource->queueAccessUnit(accessUnit); 994 } 995 } else if (mQueue->getFormat() != NULL) { 996 // After a discontinuity we invalidate the queue's format 997 // and won't enqueue any access units to the source until 998 // the queue has reestablished the new format. 999 1000 if (mSource->getFormat() == NULL) { 1001 mSource->setFormat(mQueue->getFormat()); 1002 } 1003 mSource->queueAccessUnit(accessUnit); 1004 } 1005 } 1006} 1007 1008sp<MediaSource> ATSParser::Stream::getSource(SourceType type) { 1009 switch (type) { 1010 case VIDEO: 1011 { 1012 if (isVideo()) { 1013 return mSource; 1014 } 1015 break; 1016 } 1017 1018 case AUDIO: 1019 { 1020 if (isAudio()) { 1021 return mSource; 1022 } 1023 break; 1024 } 1025 1026 default: 1027 break; 1028 } 1029 1030 return NULL; 1031} 1032 1033//////////////////////////////////////////////////////////////////////////////// 1034 1035ATSParser::ATSParser(uint32_t flags) 1036 : mFlags(flags), 1037 mAbsoluteTimeAnchorUs(-1ll), 1038 mTimeOffsetValid(false), 1039 mTimeOffsetUs(0ll), 1040 mNumTSPacketsParsed(0), 1041 mNumPCRs(0) { 1042 mPSISections.add(0 /* PID */, new PSISection); 1043} 1044 1045ATSParser::~ATSParser() { 1046} 1047 1048status_t ATSParser::feedTSPacket(const void *data, size_t size) { 1049 CHECK_EQ(size, kTSPacketSize); 1050 1051 ABitReader br((const uint8_t *)data, kTSPacketSize); 1052 return parseTS(&br); 1053} 1054 1055void ATSParser::signalDiscontinuity( 1056 DiscontinuityType type, const sp<AMessage> &extra) { 1057 int64_t mediaTimeUs; 1058 if ((type & DISCONTINUITY_TIME) 1059 && extra != NULL 1060 && extra->findInt64( 1061 IStreamListener::kKeyMediaTimeUs, &mediaTimeUs)) { 1062 mAbsoluteTimeAnchorUs = mediaTimeUs; 1063 } else if (type == DISCONTINUITY_ABSOLUTE_TIME) { 1064 int64_t timeUs; 1065 CHECK(extra->findInt64("timeUs", &timeUs)); 1066 1067 CHECK(mPrograms.empty()); 1068 mAbsoluteTimeAnchorUs = timeUs; 1069 return; 1070 } else if (type == DISCONTINUITY_TIME_OFFSET) { 1071 int64_t offset; 1072 CHECK(extra->findInt64("offset", &offset)); 1073 1074 mTimeOffsetValid = true; 1075 mTimeOffsetUs = offset; 1076 return; 1077 } 1078 1079 for (size_t i = 0; i < mPrograms.size(); ++i) { 1080 mPrograms.editItemAt(i)->signalDiscontinuity(type, extra); 1081 } 1082} 1083 1084void ATSParser::signalEOS(status_t finalResult) { 1085 CHECK_NE(finalResult, (status_t)OK); 1086 1087 for (size_t i = 0; i < mPrograms.size(); ++i) { 1088 mPrograms.editItemAt(i)->signalEOS(finalResult); 1089 } 1090} 1091 1092void ATSParser::parseProgramAssociationTable(ABitReader *br) { 1093 unsigned table_id = br->getBits(8); 1094 ALOGV(" table_id = %u", table_id); 1095 if (table_id != 0x00u) { 1096 ALOGE("PAT data error!"); 1097 return ; 1098 } 1099 unsigned section_syntax_indictor = br->getBits(1); 1100 ALOGV(" section_syntax_indictor = %u", section_syntax_indictor); 1101 CHECK_EQ(section_syntax_indictor, 1u); 1102 1103 CHECK_EQ(br->getBits(1), 0u); 1104 MY_LOGV(" reserved = %u", br->getBits(2)); 1105 1106 unsigned section_length = br->getBits(12); 1107 ALOGV(" section_length = %u", section_length); 1108 CHECK_EQ(section_length & 0xc00, 0u); 1109 1110 MY_LOGV(" transport_stream_id = %u", br->getBits(16)); 1111 MY_LOGV(" reserved = %u", br->getBits(2)); 1112 MY_LOGV(" version_number = %u", br->getBits(5)); 1113 MY_LOGV(" current_next_indicator = %u", br->getBits(1)); 1114 MY_LOGV(" section_number = %u", br->getBits(8)); 1115 MY_LOGV(" last_section_number = %u", br->getBits(8)); 1116 1117 size_t numProgramBytes = (section_length - 5 /* header */ - 4 /* crc */); 1118 CHECK_EQ((numProgramBytes % 4), 0u); 1119 1120 for (size_t i = 0; i < numProgramBytes / 4; ++i) { 1121 unsigned program_number = br->getBits(16); 1122 ALOGV(" program_number = %u", program_number); 1123 1124 MY_LOGV(" reserved = %u", br->getBits(3)); 1125 1126 if (program_number == 0) { 1127 MY_LOGV(" network_PID = 0x%04x", br->getBits(13)); 1128 } else { 1129 unsigned programMapPID = br->getBits(13); 1130 1131 ALOGV(" program_map_PID = 0x%04x", programMapPID); 1132 1133 bool found = false; 1134 for (size_t index = 0; index < mPrograms.size(); ++index) { 1135 const sp<Program> &program = mPrograms.itemAt(index); 1136 1137 if (program->number() == program_number) { 1138 program->updateProgramMapPID(programMapPID); 1139 found = true; 1140 break; 1141 } 1142 } 1143 1144 if (!found) { 1145 mPrograms.push( 1146 new Program(this, program_number, programMapPID)); 1147 } 1148 1149 if (mPSISections.indexOfKey(programMapPID) < 0) { 1150 mPSISections.add(programMapPID, new PSISection); 1151 } 1152 } 1153 } 1154 1155 MY_LOGV(" CRC = 0x%08x", br->getBits(32)); 1156} 1157 1158status_t ATSParser::parsePID( 1159 ABitReader *br, unsigned PID, 1160 unsigned continuity_counter, 1161 unsigned payload_unit_start_indicator) { 1162 ssize_t sectionIndex = mPSISections.indexOfKey(PID); 1163 1164 if (sectionIndex >= 0) { 1165 sp<PSISection> section = mPSISections.valueAt(sectionIndex); 1166 1167 if (payload_unit_start_indicator) { 1168 if (!section->isEmpty()) { 1169 ALOGW("parsePID encounters payload_unit_start_indicator when section is not empty"); 1170 section->clear(); 1171 } 1172 1173 unsigned skip = br->getBits(8); 1174 br->skipBits(skip * 8); 1175 } 1176 1177 CHECK((br->numBitsLeft() % 8) == 0); 1178 status_t err = section->append(br->data(), br->numBitsLeft() / 8); 1179 1180 if (err != OK) { 1181 return err; 1182 } 1183 1184 if (!section->isComplete()) { 1185 return OK; 1186 } 1187 1188 ABitReader sectionBits(section->data(), section->size()); 1189 1190 if (PID == 0) { 1191 parseProgramAssociationTable(§ionBits); 1192 } else { 1193 bool handled = false; 1194 for (size_t i = 0; i < mPrograms.size(); ++i) { 1195 status_t err; 1196 if (!mPrograms.editItemAt(i)->parsePSISection( 1197 PID, §ionBits, &err)) { 1198 continue; 1199 } 1200 1201 if (err != OK) { 1202 return err; 1203 } 1204 1205 handled = true; 1206 break; 1207 } 1208 1209 if (!handled) { 1210 mPSISections.removeItem(PID); 1211 section.clear(); 1212 } 1213 } 1214 1215 if (section != NULL) { 1216 section->clear(); 1217 } 1218 1219 return OK; 1220 } 1221 1222 bool handled = false; 1223 for (size_t i = 0; i < mPrograms.size(); ++i) { 1224 status_t err; 1225 if (mPrograms.editItemAt(i)->parsePID( 1226 PID, continuity_counter, payload_unit_start_indicator, 1227 br, &err)) { 1228 if (err != OK) { 1229 return err; 1230 } 1231 1232 handled = true; 1233 break; 1234 } 1235 } 1236 1237 if (!handled) { 1238 ALOGV("PID 0x%04x not handled.", PID); 1239 } 1240 1241 return OK; 1242} 1243 1244void ATSParser::parseAdaptationField(ABitReader *br, unsigned PID) { 1245 unsigned adaptation_field_length = br->getBits(8); 1246 1247 if (adaptation_field_length > 0) { 1248 unsigned discontinuity_indicator = br->getBits(1); 1249 1250 if (discontinuity_indicator) { 1251 ALOGV("PID 0x%04x: discontinuity_indicator = 1 (!!!)", PID); 1252 } 1253 1254 br->skipBits(2); 1255 unsigned PCR_flag = br->getBits(1); 1256 1257 size_t numBitsRead = 4; 1258 1259 if (PCR_flag) { 1260 br->skipBits(4); 1261 uint64_t PCR_base = br->getBits(32); 1262 PCR_base = (PCR_base << 1) | br->getBits(1); 1263 1264 br->skipBits(6); 1265 unsigned PCR_ext = br->getBits(9); 1266 1267 // The number of bytes from the start of the current 1268 // MPEG2 transport stream packet up and including 1269 // the final byte of this PCR_ext field. 1270 size_t byteOffsetFromStartOfTSPacket = 1271 (188 - br->numBitsLeft() / 8); 1272 1273 uint64_t PCR = PCR_base * 300 + PCR_ext; 1274 1275 ALOGV("PID 0x%04x: PCR = 0x%016" PRIx64 " (%.2f)", 1276 PID, PCR, PCR / 27E6); 1277 1278 // The number of bytes received by this parser up to and 1279 // including the final byte of this PCR_ext field. 1280 size_t byteOffsetFromStart = 1281 mNumTSPacketsParsed * 188 + byteOffsetFromStartOfTSPacket; 1282 1283 for (size_t i = 0; i < mPrograms.size(); ++i) { 1284 updatePCR(PID, PCR, byteOffsetFromStart); 1285 } 1286 1287 numBitsRead += 52; 1288 } 1289 1290 CHECK_GE(adaptation_field_length * 8, numBitsRead); 1291 1292 br->skipBits(adaptation_field_length * 8 - numBitsRead); 1293 } 1294} 1295 1296status_t ATSParser::parseTS(ABitReader *br) { 1297 ALOGV("---"); 1298 1299 unsigned sync_byte = br->getBits(8); 1300 if (sync_byte != 0x47u) { 1301 ALOGE("[error] parseTS: return error as sync_byte=0x%x", sync_byte); 1302 return BAD_VALUE; 1303 } 1304 1305 if (br->getBits(1)) { // transport_error_indicator 1306 // silently ignore. 1307 return OK; 1308 } 1309 1310 unsigned payload_unit_start_indicator = br->getBits(1); 1311 ALOGV("payload_unit_start_indicator = %u", payload_unit_start_indicator); 1312 1313 MY_LOGV("transport_priority = %u", br->getBits(1)); 1314 1315 unsigned PID = br->getBits(13); 1316 ALOGV("PID = 0x%04x", PID); 1317 1318 MY_LOGV("transport_scrambling_control = %u", br->getBits(2)); 1319 1320 unsigned adaptation_field_control = br->getBits(2); 1321 ALOGV("adaptation_field_control = %u", adaptation_field_control); 1322 1323 unsigned continuity_counter = br->getBits(4); 1324 ALOGV("PID = 0x%04x, continuity_counter = %u", PID, continuity_counter); 1325 1326 // ALOGI("PID = 0x%04x, continuity_counter = %u", PID, continuity_counter); 1327 1328 if (adaptation_field_control == 2 || adaptation_field_control == 3) { 1329 parseAdaptationField(br, PID); 1330 } 1331 1332 status_t err = OK; 1333 1334 if (adaptation_field_control == 1 || adaptation_field_control == 3) { 1335 err = parsePID( 1336 br, PID, continuity_counter, payload_unit_start_indicator); 1337 } 1338 1339 ++mNumTSPacketsParsed; 1340 1341 return err; 1342} 1343 1344sp<MediaSource> ATSParser::getSource(SourceType type) { 1345 int which = -1; // any 1346 1347 for (size_t i = 0; i < mPrograms.size(); ++i) { 1348 const sp<Program> &program = mPrograms.editItemAt(i); 1349 1350 if (which >= 0 && (int)program->number() != which) { 1351 continue; 1352 } 1353 1354 sp<MediaSource> source = program->getSource(type); 1355 1356 if (source != NULL) { 1357 return source; 1358 } 1359 } 1360 1361 return NULL; 1362} 1363 1364bool ATSParser::hasSource(SourceType type) const { 1365 for (size_t i = 0; i < mPrograms.size(); ++i) { 1366 const sp<Program> &program = mPrograms.itemAt(i); 1367 if (program->hasSource(type)) { 1368 return true; 1369 } 1370 } 1371 1372 return false; 1373} 1374 1375bool ATSParser::PTSTimeDeltaEstablished() { 1376 if (mPrograms.isEmpty()) { 1377 return false; 1378 } 1379 1380 return mPrograms.editItemAt(0)->PTSTimeDeltaEstablished(); 1381} 1382 1383void ATSParser::updatePCR( 1384 unsigned /* PID */, uint64_t PCR, size_t byteOffsetFromStart) { 1385 ALOGV("PCR 0x%016" PRIx64 " @ %zu", PCR, byteOffsetFromStart); 1386 1387 if (mNumPCRs == 2) { 1388 mPCR[0] = mPCR[1]; 1389 mPCRBytes[0] = mPCRBytes[1]; 1390 mSystemTimeUs[0] = mSystemTimeUs[1]; 1391 mNumPCRs = 1; 1392 } 1393 1394 mPCR[mNumPCRs] = PCR; 1395 mPCRBytes[mNumPCRs] = byteOffsetFromStart; 1396 mSystemTimeUs[mNumPCRs] = ALooper::GetNowUs(); 1397 1398 ++mNumPCRs; 1399 1400 if (mNumPCRs == 2) { 1401 double transportRate = 1402 (mPCRBytes[1] - mPCRBytes[0]) * 27E6 / (mPCR[1] - mPCR[0]); 1403 1404 ALOGV("transportRate = %.2f bytes/sec", transportRate); 1405 } 1406} 1407 1408//////////////////////////////////////////////////////////////////////////////// 1409 1410ATSParser::PSISection::PSISection() { 1411} 1412 1413ATSParser::PSISection::~PSISection() { 1414} 1415 1416status_t ATSParser::PSISection::append(const void *data, size_t size) { 1417 if (mBuffer == NULL || mBuffer->size() + size > mBuffer->capacity()) { 1418 size_t newCapacity = 1419 (mBuffer == NULL) ? size : mBuffer->capacity() + size; 1420 1421 newCapacity = (newCapacity + 1023) & ~1023; 1422 1423 sp<ABuffer> newBuffer = new ABuffer(newCapacity); 1424 1425 if (mBuffer != NULL) { 1426 memcpy(newBuffer->data(), mBuffer->data(), mBuffer->size()); 1427 newBuffer->setRange(0, mBuffer->size()); 1428 } else { 1429 newBuffer->setRange(0, 0); 1430 } 1431 1432 mBuffer = newBuffer; 1433 } 1434 1435 memcpy(mBuffer->data() + mBuffer->size(), data, size); 1436 mBuffer->setRange(0, mBuffer->size() + size); 1437 1438 return OK; 1439} 1440 1441void ATSParser::PSISection::clear() { 1442 if (mBuffer != NULL) { 1443 mBuffer->setRange(0, 0); 1444 } 1445} 1446 1447bool ATSParser::PSISection::isComplete() const { 1448 if (mBuffer == NULL || mBuffer->size() < 3) { 1449 return false; 1450 } 1451 1452 unsigned sectionLength = U16_AT(mBuffer->data() + 1) & 0xfff; 1453 return mBuffer->size() >= sectionLength + 3; 1454} 1455 1456bool ATSParser::PSISection::isEmpty() const { 1457 return mBuffer == NULL || mBuffer->size() == 0; 1458} 1459 1460const uint8_t *ATSParser::PSISection::data() const { 1461 return mBuffer == NULL ? NULL : mBuffer->data(); 1462} 1463 1464size_t ATSParser::PSISection::size() const { 1465 return mBuffer == NULL ? 0 : mBuffer->size(); 1466} 1467 1468} // namespace android 1469