PlaylistFetcher.cpp revision dcb89b3b505522efde173c105a851c412f947178
1/* 2 * Copyright (C) 2012 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 "PlaylistFetcher" 19#include <utils/Log.h> 20 21#include "PlaylistFetcher.h" 22 23#include "LiveDataSource.h" 24#include "LiveSession.h" 25#include "M3UParser.h" 26 27#include "include/avc_utils.h" 28#include "include/HTTPBase.h" 29#include "include/ID3.h" 30#include "mpeg2ts/AnotherPacketSource.h" 31 32#include <media/IStreamSource.h> 33#include <media/stagefright/foundation/ABitReader.h> 34#include <media/stagefright/foundation/ABuffer.h> 35#include <media/stagefright/foundation/ADebug.h> 36#include <media/stagefright/foundation/hexdump.h> 37#include <media/stagefright/FileSource.h> 38#include <media/stagefright/MediaDefs.h> 39#include <media/stagefright/MetaData.h> 40#include <media/stagefright/Utils.h> 41 42#include <ctype.h> 43#include <openssl/aes.h> 44#include <openssl/md5.h> 45 46namespace android { 47 48// static 49const int64_t PlaylistFetcher::kMinBufferedDurationUs = 10000000ll; 50 51PlaylistFetcher::PlaylistFetcher( 52 const sp<AMessage> ¬ify, 53 const sp<LiveSession> &session, 54 const char *uri) 55 : mNotify(notify), 56 mSession(session), 57 mURI(uri), 58 mStreamTypeMask(0), 59 mStartTimeUs(-1ll), 60 mLastPlaylistFetchTimeUs(-1ll), 61 mSeqNumber(-1), 62 mNumRetries(0), 63 mStartup(true), 64 mNextPTSTimeUs(-1ll), 65 mMonitorQueueGeneration(0), 66 mRefreshState(INITIAL_MINIMUM_RELOAD_DELAY), 67 mFirstPTSValid(false), 68 mAbsoluteTimeAnchorUs(0ll) { 69 memset(mPlaylistHash, 0, sizeof(mPlaylistHash)); 70} 71 72PlaylistFetcher::~PlaylistFetcher() { 73} 74 75int64_t PlaylistFetcher::getSegmentStartTimeUs(int32_t seqNumber) const { 76 CHECK(mPlaylist != NULL); 77 78 int32_t firstSeqNumberInPlaylist; 79 if (mPlaylist->meta() == NULL || !mPlaylist->meta()->findInt32( 80 "media-sequence", &firstSeqNumberInPlaylist)) { 81 firstSeqNumberInPlaylist = 0; 82 } 83 84 int32_t lastSeqNumberInPlaylist = 85 firstSeqNumberInPlaylist + (int32_t)mPlaylist->size() - 1; 86 87 CHECK_GE(seqNumber, firstSeqNumberInPlaylist); 88 CHECK_LE(seqNumber, lastSeqNumberInPlaylist); 89 90 int64_t segmentStartUs = 0ll; 91 for (int32_t index = 0; 92 index < seqNumber - firstSeqNumberInPlaylist; ++index) { 93 sp<AMessage> itemMeta; 94 CHECK(mPlaylist->itemAt( 95 index, NULL /* uri */, &itemMeta)); 96 97 int64_t itemDurationUs; 98 CHECK(itemMeta->findInt64("durationUs", &itemDurationUs)); 99 100 segmentStartUs += itemDurationUs; 101 } 102 103 return segmentStartUs; 104} 105 106bool PlaylistFetcher::timeToRefreshPlaylist(int64_t nowUs) const { 107 if (mPlaylist == NULL) { 108 CHECK_EQ((int)mRefreshState, (int)INITIAL_MINIMUM_RELOAD_DELAY); 109 return true; 110 } 111 112 int32_t targetDurationSecs; 113 CHECK(mPlaylist->meta()->findInt32("target-duration", &targetDurationSecs)); 114 115 int64_t targetDurationUs = targetDurationSecs * 1000000ll; 116 117 int64_t minPlaylistAgeUs; 118 119 switch (mRefreshState) { 120 case INITIAL_MINIMUM_RELOAD_DELAY: 121 { 122 size_t n = mPlaylist->size(); 123 if (n > 0) { 124 sp<AMessage> itemMeta; 125 CHECK(mPlaylist->itemAt(n - 1, NULL /* uri */, &itemMeta)); 126 127 int64_t itemDurationUs; 128 CHECK(itemMeta->findInt64("durationUs", &itemDurationUs)); 129 130 minPlaylistAgeUs = itemDurationUs; 131 break; 132 } 133 134 // fall through 135 } 136 137 case FIRST_UNCHANGED_RELOAD_ATTEMPT: 138 { 139 minPlaylistAgeUs = targetDurationUs / 2; 140 break; 141 } 142 143 case SECOND_UNCHANGED_RELOAD_ATTEMPT: 144 { 145 minPlaylistAgeUs = (targetDurationUs * 3) / 2; 146 break; 147 } 148 149 case THIRD_UNCHANGED_RELOAD_ATTEMPT: 150 { 151 minPlaylistAgeUs = targetDurationUs * 3; 152 break; 153 } 154 155 default: 156 TRESPASS(); 157 break; 158 } 159 160 return mLastPlaylistFetchTimeUs + minPlaylistAgeUs <= nowUs; 161} 162 163status_t PlaylistFetcher::decryptBuffer( 164 size_t playlistIndex, const sp<ABuffer> &buffer) { 165 sp<AMessage> itemMeta; 166 bool found = false; 167 AString method; 168 169 for (ssize_t i = playlistIndex; i >= 0; --i) { 170 AString uri; 171 CHECK(mPlaylist->itemAt(i, &uri, &itemMeta)); 172 173 if (itemMeta->findString("cipher-method", &method)) { 174 found = true; 175 break; 176 } 177 } 178 179 if (!found) { 180 method = "NONE"; 181 } 182 183 if (method == "NONE") { 184 return OK; 185 } else if (!(method == "AES-128")) { 186 ALOGE("Unsupported cipher method '%s'", method.c_str()); 187 return ERROR_UNSUPPORTED; 188 } 189 190 AString keyURI; 191 if (!itemMeta->findString("cipher-uri", &keyURI)) { 192 ALOGE("Missing key uri"); 193 return ERROR_MALFORMED; 194 } 195 196 ssize_t index = mAESKeyForURI.indexOfKey(keyURI); 197 198 sp<ABuffer> key; 199 if (index >= 0) { 200 key = mAESKeyForURI.valueAt(index); 201 } else { 202 status_t err = mSession->fetchFile(keyURI.c_str(), &key); 203 204 if (err != OK) { 205 ALOGE("failed to fetch cipher key from '%s'.", keyURI.c_str()); 206 return ERROR_IO; 207 } else if (key->size() != 16) { 208 ALOGE("key file '%s' wasn't 16 bytes in size.", keyURI.c_str()); 209 return ERROR_MALFORMED; 210 } 211 212 mAESKeyForURI.add(keyURI, key); 213 } 214 215 AES_KEY aes_key; 216 if (AES_set_decrypt_key(key->data(), 128, &aes_key) != 0) { 217 ALOGE("failed to set AES decryption key."); 218 return UNKNOWN_ERROR; 219 } 220 221 unsigned char aes_ivec[16]; 222 223 AString iv; 224 if (itemMeta->findString("cipher-iv", &iv)) { 225 if ((!iv.startsWith("0x") && !iv.startsWith("0X")) 226 || iv.size() != 16 * 2 + 2) { 227 ALOGE("malformed cipher IV '%s'.", iv.c_str()); 228 return ERROR_MALFORMED; 229 } 230 231 memset(aes_ivec, 0, sizeof(aes_ivec)); 232 for (size_t i = 0; i < 16; ++i) { 233 char c1 = tolower(iv.c_str()[2 + 2 * i]); 234 char c2 = tolower(iv.c_str()[3 + 2 * i]); 235 if (!isxdigit(c1) || !isxdigit(c2)) { 236 ALOGE("malformed cipher IV '%s'.", iv.c_str()); 237 return ERROR_MALFORMED; 238 } 239 uint8_t nibble1 = isdigit(c1) ? c1 - '0' : c1 - 'a' + 10; 240 uint8_t nibble2 = isdigit(c2) ? c2 - '0' : c2 - 'a' + 10; 241 242 aes_ivec[i] = nibble1 << 4 | nibble2; 243 } 244 } else { 245 memset(aes_ivec, 0, sizeof(aes_ivec)); 246 aes_ivec[15] = mSeqNumber & 0xff; 247 aes_ivec[14] = (mSeqNumber >> 8) & 0xff; 248 aes_ivec[13] = (mSeqNumber >> 16) & 0xff; 249 aes_ivec[12] = (mSeqNumber >> 24) & 0xff; 250 } 251 252 AES_cbc_encrypt( 253 buffer->data(), buffer->data(), buffer->size(), 254 &aes_key, aes_ivec, AES_DECRYPT); 255 256 // hexdump(buffer->data(), buffer->size()); 257 258 size_t n = buffer->size(); 259 CHECK_GT(n, 0u); 260 261 size_t pad = buffer->data()[n - 1]; 262 263 CHECK_GT(pad, 0u); 264 CHECK_LE(pad, 16u); 265 CHECK_GE((size_t)n, pad); 266 for (size_t i = 0; i < pad; ++i) { 267 CHECK_EQ((unsigned)buffer->data()[n - 1 - i], pad); 268 } 269 270 n -= pad; 271 272 buffer->setRange(buffer->offset(), n); 273 274 return OK; 275} 276 277void PlaylistFetcher::postMonitorQueue(int64_t delayUs) { 278 sp<AMessage> msg = new AMessage(kWhatMonitorQueue, id()); 279 msg->setInt32("generation", mMonitorQueueGeneration); 280 msg->post(delayUs); 281} 282 283void PlaylistFetcher::cancelMonitorQueue() { 284 ++mMonitorQueueGeneration; 285} 286 287void PlaylistFetcher::startAsync( 288 const sp<AnotherPacketSource> &audioSource, 289 const sp<AnotherPacketSource> &videoSource, 290 const sp<AnotherPacketSource> &subtitleSource, 291 int64_t startTimeUs) { 292 sp<AMessage> msg = new AMessage(kWhatStart, id()); 293 294 uint32_t streamTypeMask = 0ul; 295 296 if (audioSource != NULL) { 297 msg->setPointer("audioSource", audioSource.get()); 298 streamTypeMask |= LiveSession::STREAMTYPE_AUDIO; 299 } 300 301 if (videoSource != NULL) { 302 msg->setPointer("videoSource", videoSource.get()); 303 streamTypeMask |= LiveSession::STREAMTYPE_VIDEO; 304 } 305 306 if (subtitleSource != NULL) { 307 msg->setPointer("subtitleSource", subtitleSource.get()); 308 streamTypeMask |= LiveSession::STREAMTYPE_SUBTITLES; 309 } 310 311 msg->setInt32("streamTypeMask", streamTypeMask); 312 msg->setInt64("startTimeUs", startTimeUs); 313 msg->post(); 314} 315 316void PlaylistFetcher::pauseAsync() { 317 (new AMessage(kWhatPause, id()))->post(); 318} 319 320void PlaylistFetcher::stopAsync() { 321 (new AMessage(kWhatStop, id()))->post(); 322} 323 324void PlaylistFetcher::onMessageReceived(const sp<AMessage> &msg) { 325 switch (msg->what()) { 326 case kWhatStart: 327 { 328 status_t err = onStart(msg); 329 330 sp<AMessage> notify = mNotify->dup(); 331 notify->setInt32("what", kWhatStarted); 332 notify->setInt32("err", err); 333 notify->post(); 334 break; 335 } 336 337 case kWhatPause: 338 { 339 onPause(); 340 341 sp<AMessage> notify = mNotify->dup(); 342 notify->setInt32("what", kWhatPaused); 343 notify->post(); 344 break; 345 } 346 347 case kWhatStop: 348 { 349 onStop(); 350 351 sp<AMessage> notify = mNotify->dup(); 352 notify->setInt32("what", kWhatStopped); 353 notify->post(); 354 break; 355 } 356 357 case kWhatMonitorQueue: 358 { 359 int32_t generation; 360 CHECK(msg->findInt32("generation", &generation)); 361 362 if (generation != mMonitorQueueGeneration) { 363 // Stale event 364 break; 365 } 366 367 onMonitorQueue(); 368 break; 369 } 370 371 default: 372 TRESPASS(); 373 } 374} 375 376status_t PlaylistFetcher::onStart(const sp<AMessage> &msg) { 377 mPacketSources.clear(); 378 379 uint32_t streamTypeMask; 380 CHECK(msg->findInt32("streamTypeMask", (int32_t *)&streamTypeMask)); 381 382 int64_t startTimeUs; 383 CHECK(msg->findInt64("startTimeUs", &startTimeUs)); 384 385 if (streamTypeMask & LiveSession::STREAMTYPE_AUDIO) { 386 void *ptr; 387 CHECK(msg->findPointer("audioSource", &ptr)); 388 389 mPacketSources.add( 390 LiveSession::STREAMTYPE_AUDIO, 391 static_cast<AnotherPacketSource *>(ptr)); 392 } 393 394 if (streamTypeMask & LiveSession::STREAMTYPE_VIDEO) { 395 void *ptr; 396 CHECK(msg->findPointer("videoSource", &ptr)); 397 398 mPacketSources.add( 399 LiveSession::STREAMTYPE_VIDEO, 400 static_cast<AnotherPacketSource *>(ptr)); 401 } 402 403 if (streamTypeMask & LiveSession::STREAMTYPE_SUBTITLES) { 404 void *ptr; 405 CHECK(msg->findPointer("subtitleSource", &ptr)); 406 407 mPacketSources.add( 408 LiveSession::STREAMTYPE_SUBTITLES, 409 static_cast<AnotherPacketSource *>(ptr)); 410 } 411 412 mStreamTypeMask = streamTypeMask; 413 mStartTimeUs = startTimeUs; 414 415 if (mStartTimeUs >= 0ll) { 416 mSeqNumber = -1; 417 mStartup = true; 418 } 419 420 postMonitorQueue(); 421 422 return OK; 423} 424 425void PlaylistFetcher::onPause() { 426 cancelMonitorQueue(); 427 428 mPacketSources.clear(); 429 mStreamTypeMask = 0; 430} 431 432void PlaylistFetcher::onStop() { 433 cancelMonitorQueue(); 434 435 for (size_t i = 0; i < mPacketSources.size(); ++i) { 436 mPacketSources.valueAt(i)->clear(); 437 } 438 439 mPacketSources.clear(); 440 mStreamTypeMask = 0; 441} 442 443void PlaylistFetcher::notifyError(status_t err) { 444 sp<AMessage> notify = mNotify->dup(); 445 notify->setInt32("what", kWhatError); 446 notify->setInt32("err", err); 447 notify->post(); 448} 449 450void PlaylistFetcher::queueDiscontinuity( 451 ATSParser::DiscontinuityType type, const sp<AMessage> &extra) { 452 for (size_t i = 0; i < mPacketSources.size(); ++i) { 453 mPacketSources.valueAt(i)->queueDiscontinuity(type, extra); 454 } 455} 456 457void PlaylistFetcher::onMonitorQueue() { 458 bool downloadMore = false; 459 460 status_t finalResult; 461 if (mStreamTypeMask == LiveSession::STREAMTYPE_SUBTITLES) { 462 sp<AnotherPacketSource> packetSource = 463 mPacketSources.valueFor(LiveSession::STREAMTYPE_SUBTITLES); 464 465 int64_t bufferedDurationUs = 466 packetSource->getBufferedDurationUs(&finalResult); 467 468 downloadMore = (bufferedDurationUs < kMinBufferedDurationUs); 469 finalResult = OK; 470 } else { 471 bool first = true; 472 int64_t minBufferedDurationUs = 0ll; 473 474 for (size_t i = 0; i < mPacketSources.size(); ++i) { 475 if ((mStreamTypeMask & mPacketSources.keyAt(i)) == 0) { 476 continue; 477 } 478 479 int64_t bufferedDurationUs = 480 mPacketSources.valueAt(i)->getBufferedDurationUs(&finalResult); 481 482 if (first || bufferedDurationUs < minBufferedDurationUs) { 483 minBufferedDurationUs = bufferedDurationUs; 484 first = false; 485 } 486 } 487 488 downloadMore = 489 !first && (minBufferedDurationUs < kMinBufferedDurationUs); 490 } 491 492 if (finalResult == OK && downloadMore) { 493 onDownloadNext(); 494 } else { 495 // Nothing to do yet, try again in a second. 496 497 sp<AMessage> msg = mNotify->dup(); 498 msg->setInt32("what", kWhatTemporarilyDoneFetching); 499 msg->post(); 500 501 postMonitorQueue(1000000ll); 502 } 503} 504 505void PlaylistFetcher::onDownloadNext() { 506 int64_t nowUs = ALooper::GetNowUs(); 507 508 if (mLastPlaylistFetchTimeUs < 0ll 509 || (!mPlaylist->isComplete() && timeToRefreshPlaylist(nowUs))) { 510 bool unchanged; 511 sp<M3UParser> playlist = mSession->fetchPlaylist( 512 mURI.c_str(), mPlaylistHash, &unchanged); 513 514 if (playlist == NULL) { 515 if (unchanged) { 516 // We succeeded in fetching the playlist, but it was 517 // unchanged from the last time we tried. 518 519 if (mRefreshState != THIRD_UNCHANGED_RELOAD_ATTEMPT) { 520 mRefreshState = (RefreshState)(mRefreshState + 1); 521 } 522 } else { 523 ALOGE("failed to load playlist at url '%s'", mURI.c_str()); 524 notifyError(ERROR_IO); 525 return; 526 } 527 } else { 528 mRefreshState = INITIAL_MINIMUM_RELOAD_DELAY; 529 mPlaylist = playlist; 530 531 if (mPlaylist->isComplete() || mPlaylist->isEvent()) { 532 updateDuration(); 533 } 534 } 535 536 mLastPlaylistFetchTimeUs = ALooper::GetNowUs(); 537 } 538 539 int32_t firstSeqNumberInPlaylist; 540 if (mPlaylist->meta() == NULL || !mPlaylist->meta()->findInt32( 541 "media-sequence", &firstSeqNumberInPlaylist)) { 542 firstSeqNumberInPlaylist = 0; 543 } 544 545 bool seekDiscontinuity = false; 546 bool explicitDiscontinuity = false; 547 548 const int32_t lastSeqNumberInPlaylist = 549 firstSeqNumberInPlaylist + (int32_t)mPlaylist->size() - 1; 550 551 if (mSeqNumber < 0) { 552 CHECK_GE(mStartTimeUs, 0ll); 553 554 if (mPlaylist->isComplete() || mPlaylist->isEvent()) { 555 mSeqNumber = getSeqNumberForTime(mStartTimeUs); 556 } else { 557 // If this is a live session, start 3 segments from the end. 558 mSeqNumber = lastSeqNumberInPlaylist - 3; 559 if (mSeqNumber < firstSeqNumberInPlaylist) { 560 mSeqNumber = firstSeqNumberInPlaylist; 561 } 562 } 563 564 mStartTimeUs = -1ll; 565 } 566 567 if (mSeqNumber < firstSeqNumberInPlaylist 568 || mSeqNumber > lastSeqNumberInPlaylist) { 569 if (!mPlaylist->isComplete() && mNumRetries < kMaxNumRetries) { 570 ++mNumRetries; 571 572 if (mSeqNumber > lastSeqNumberInPlaylist) { 573 mLastPlaylistFetchTimeUs = -1; 574 postMonitorQueue(3000000ll); 575 return; 576 } 577 578 // we've missed the boat, let's start from the lowest sequence 579 // number available and signal a discontinuity. 580 581 ALOGI("We've missed the boat, restarting playback."); 582 mSeqNumber = lastSeqNumberInPlaylist; 583 explicitDiscontinuity = true; 584 585 // fall through 586 } else { 587 ALOGE("Cannot find sequence number %d in playlist " 588 "(contains %d - %d)", 589 mSeqNumber, firstSeqNumberInPlaylist, 590 firstSeqNumberInPlaylist + mPlaylist->size() - 1); 591 592 notifyError(ERROR_END_OF_STREAM); 593 return; 594 } 595 } 596 597 mNumRetries = 0; 598 599 AString uri; 600 sp<AMessage> itemMeta; 601 CHECK(mPlaylist->itemAt( 602 mSeqNumber - firstSeqNumberInPlaylist, 603 &uri, 604 &itemMeta)); 605 606 int32_t val; 607 if (itemMeta->findInt32("discontinuity", &val) && val != 0) { 608 explicitDiscontinuity = true; 609 } 610 611 int64_t range_offset, range_length; 612 if (!itemMeta->findInt64("range-offset", &range_offset) 613 || !itemMeta->findInt64("range-length", &range_length)) { 614 range_offset = 0; 615 range_length = -1; 616 } 617 618 ALOGV("fetching segment %d from (%d .. %d)", 619 mSeqNumber, firstSeqNumberInPlaylist, lastSeqNumberInPlaylist); 620 621 ALOGV("fetching '%s'", uri.c_str()); 622 623 sp<ABuffer> buffer; 624 status_t err = mSession->fetchFile( 625 uri.c_str(), &buffer, range_offset, range_length); 626 627 if (err != OK) { 628 ALOGE("failed to fetch .ts segment at url '%s'", uri.c_str()); 629 notifyError(err); 630 return; 631 } 632 633 CHECK(buffer != NULL); 634 635 err = decryptBuffer(mSeqNumber - firstSeqNumberInPlaylist, buffer); 636 637 if (err != OK) { 638 ALOGE("decryptBuffer failed w/ error %d", err); 639 640 notifyError(err); 641 return; 642 } 643 644 if (mStartup || seekDiscontinuity || explicitDiscontinuity) { 645 // Signal discontinuity. 646 647 if (mPlaylist->isComplete() || mPlaylist->isEvent()) { 648 // If this was a live event this made no sense since 649 // we don't have access to all the segment before the current 650 // one. 651 mNextPTSTimeUs = getSegmentStartTimeUs(mSeqNumber); 652 } 653 654 if (seekDiscontinuity || explicitDiscontinuity) { 655 ALOGI("queueing discontinuity (seek=%d, explicit=%d)", 656 seekDiscontinuity, explicitDiscontinuity); 657 658 queueDiscontinuity( 659 explicitDiscontinuity 660 ? ATSParser::DISCONTINUITY_FORMATCHANGE 661 : ATSParser::DISCONTINUITY_SEEK, 662 NULL /* extra */); 663 } 664 } 665 666 err = extractAndQueueAccessUnits(buffer, itemMeta); 667 668 if (err != OK) { 669 notifyError(err); 670 return; 671 } 672 673 ++mSeqNumber; 674 675 postMonitorQueue(); 676 677 mStartup = false; 678} 679 680int32_t PlaylistFetcher::getSeqNumberForTime(int64_t timeUs) const { 681 int32_t firstSeqNumberInPlaylist; 682 if (mPlaylist->meta() == NULL || !mPlaylist->meta()->findInt32( 683 "media-sequence", &firstSeqNumberInPlaylist)) { 684 firstSeqNumberInPlaylist = 0; 685 } 686 687 size_t index = 0; 688 int64_t segmentStartUs = 0; 689 while (index < mPlaylist->size()) { 690 sp<AMessage> itemMeta; 691 CHECK(mPlaylist->itemAt( 692 index, NULL /* uri */, &itemMeta)); 693 694 int64_t itemDurationUs; 695 CHECK(itemMeta->findInt64("durationUs", &itemDurationUs)); 696 697 if (timeUs < segmentStartUs + itemDurationUs) { 698 break; 699 } 700 701 segmentStartUs += itemDurationUs; 702 ++index; 703 } 704 705 if (index >= mPlaylist->size()) { 706 index = mPlaylist->size() - 1; 707 } 708 709 return firstSeqNumberInPlaylist + index; 710} 711 712status_t PlaylistFetcher::extractAndQueueAccessUnits( 713 const sp<ABuffer> &buffer, const sp<AMessage> &itemMeta) { 714 if (buffer->size() > 0 && buffer->data()[0] == 0x47) { 715 // Let's assume this is an MPEG2 transport stream. 716 717 if ((buffer->size() % 188) != 0) { 718 ALOGE("MPEG2 transport stream is not an even multiple of 188 " 719 "bytes in length."); 720 return ERROR_MALFORMED; 721 } 722 723 if (mTSParser == NULL) { 724 mTSParser = new ATSParser; 725 } 726 727 if (mNextPTSTimeUs >= 0ll) { 728 sp<AMessage> extra = new AMessage; 729 extra->setInt64(IStreamListener::kKeyMediaTimeUs, mNextPTSTimeUs); 730 731 mTSParser->signalDiscontinuity( 732 ATSParser::DISCONTINUITY_SEEK, extra); 733 734 mNextPTSTimeUs = -1ll; 735 } 736 737 size_t offset = 0; 738 while (offset < buffer->size()) { 739 status_t err = mTSParser->feedTSPacket(buffer->data() + offset, 188); 740 741 if (err != OK) { 742 return err; 743 } 744 745 offset += 188; 746 } 747 748 for (size_t i = mPacketSources.size(); i-- > 0;) { 749 sp<AnotherPacketSource> packetSource = mPacketSources.valueAt(i); 750 751 ATSParser::SourceType type; 752 switch (mPacketSources.keyAt(i)) { 753 case LiveSession::STREAMTYPE_VIDEO: 754 type = ATSParser::VIDEO; 755 break; 756 757 case LiveSession::STREAMTYPE_AUDIO: 758 type = ATSParser::AUDIO; 759 break; 760 761 case LiveSession::STREAMTYPE_SUBTITLES: 762 { 763 ALOGE("MPEG2 Transport streams do not contain subtitles."); 764 return ERROR_MALFORMED; 765 break; 766 } 767 768 default: 769 TRESPASS(); 770 } 771 772 sp<AnotherPacketSource> source = 773 static_cast<AnotherPacketSource *>( 774 mTSParser->getSource(type).get()); 775 776 if (source == NULL) { 777 ALOGW("MPEG2 Transport stream does not contain %s data.", 778 type == ATSParser::VIDEO ? "video" : "audio"); 779 780 mStreamTypeMask &= ~mPacketSources.keyAt(i); 781 mPacketSources.removeItemsAt(i); 782 continue; 783 } 784 785 sp<ABuffer> accessUnit; 786 status_t finalResult; 787 while (source->hasBufferAvailable(&finalResult) 788 && source->dequeueAccessUnit(&accessUnit) == OK) { 789 // Note that we do NOT dequeue any discontinuities. 790 791 packetSource->queueAccessUnit(accessUnit); 792 } 793 794 if (packetSource->getFormat() == NULL) { 795 packetSource->setFormat(source->getFormat()); 796 } 797 } 798 799 return OK; 800 } else if (buffer->size() >= 7 && !memcmp("WEBVTT\n", buffer->data(), 7)) { 801 if (mStreamTypeMask != LiveSession::STREAMTYPE_SUBTITLES) { 802 ALOGE("This stream only contains subtitles."); 803 return ERROR_MALFORMED; 804 } 805 806 const sp<AnotherPacketSource> packetSource = 807 mPacketSources.valueFor(LiveSession::STREAMTYPE_SUBTITLES); 808 809 int64_t durationUs; 810 CHECK(itemMeta->findInt64("durationUs", &durationUs)); 811 buffer->meta()->setInt64("timeUs", getSegmentStartTimeUs(mSeqNumber)); 812 buffer->meta()->setInt64("durationUs", durationUs); 813 814 packetSource->queueAccessUnit(buffer); 815 return OK; 816 } 817 818 if (mNextPTSTimeUs >= 0ll) { 819 mFirstPTSValid = false; 820 mAbsoluteTimeAnchorUs = mNextPTSTimeUs; 821 mNextPTSTimeUs = -1ll; 822 } 823 824 // This better be an ISO 13818-7 (AAC) or ISO 13818-1 (MPEG) audio 825 // stream prefixed by an ID3 tag. 826 827 bool firstID3Tag = true; 828 uint64_t PTS = 0; 829 830 for (;;) { 831 // Make sure to skip all ID3 tags preceding the audio data. 832 // At least one must be present to provide the PTS timestamp. 833 834 ID3 id3(buffer->data(), buffer->size(), true /* ignoreV1 */); 835 if (!id3.isValid()) { 836 if (firstID3Tag) { 837 ALOGE("Unable to parse ID3 tag."); 838 return ERROR_MALFORMED; 839 } else { 840 break; 841 } 842 } 843 844 if (firstID3Tag) { 845 bool found = false; 846 847 ID3::Iterator it(id3, "PRIV"); 848 while (!it.done()) { 849 size_t length; 850 const uint8_t *data = it.getData(&length); 851 852 static const char *kMatchName = 853 "com.apple.streaming.transportStreamTimestamp"; 854 static const size_t kMatchNameLen = strlen(kMatchName); 855 856 if (length == kMatchNameLen + 1 + 8 857 && !strncmp((const char *)data, kMatchName, kMatchNameLen)) { 858 found = true; 859 PTS = U64_AT(&data[kMatchNameLen + 1]); 860 } 861 862 it.next(); 863 } 864 865 if (!found) { 866 ALOGE("Unable to extract transportStreamTimestamp from ID3 tag."); 867 return ERROR_MALFORMED; 868 } 869 } 870 871 // skip the ID3 tag 872 buffer->setRange( 873 buffer->offset() + id3.rawSize(), buffer->size() - id3.rawSize()); 874 875 firstID3Tag = false; 876 } 877 878 if (!mFirstPTSValid) { 879 mFirstPTSValid = true; 880 mFirstPTS = PTS; 881 } 882 PTS -= mFirstPTS; 883 884 int64_t timeUs = (PTS * 100ll) / 9ll + mAbsoluteTimeAnchorUs; 885 886 if (mStreamTypeMask != LiveSession::STREAMTYPE_AUDIO) { 887 ALOGW("This stream only contains audio data!"); 888 889 mStreamTypeMask &= LiveSession::STREAMTYPE_AUDIO; 890 891 if (mStreamTypeMask == 0) { 892 return OK; 893 } 894 } 895 896 sp<AnotherPacketSource> packetSource = 897 mPacketSources.valueFor(LiveSession::STREAMTYPE_AUDIO); 898 899 if (packetSource->getFormat() == NULL && buffer->size() >= 7) { 900 ABitReader bits(buffer->data(), buffer->size()); 901 902 // adts_fixed_header 903 904 CHECK_EQ(bits.getBits(12), 0xfffu); 905 bits.skipBits(3); // ID, layer 906 bool protection_absent = bits.getBits(1) != 0; 907 908 unsigned profile = bits.getBits(2); 909 CHECK_NE(profile, 3u); 910 unsigned sampling_freq_index = bits.getBits(4); 911 bits.getBits(1); // private_bit 912 unsigned channel_configuration = bits.getBits(3); 913 CHECK_NE(channel_configuration, 0u); 914 bits.skipBits(2); // original_copy, home 915 916 sp<MetaData> meta = MakeAACCodecSpecificData( 917 profile, sampling_freq_index, channel_configuration); 918 919 meta->setInt32(kKeyIsADTS, true); 920 921 packetSource->setFormat(meta); 922 } 923 924 int64_t numSamples = 0ll; 925 int32_t sampleRate; 926 CHECK(packetSource->getFormat()->findInt32(kKeySampleRate, &sampleRate)); 927 928 size_t offset = 0; 929 while (offset < buffer->size()) { 930 const uint8_t *adtsHeader = buffer->data() + offset; 931 CHECK_LT(offset + 5, buffer->size()); 932 933 unsigned aac_frame_length = 934 ((adtsHeader[3] & 3) << 11) 935 | (adtsHeader[4] << 3) 936 | (adtsHeader[5] >> 5); 937 938 CHECK_LE(offset + aac_frame_length, buffer->size()); 939 940 sp<ABuffer> unit = new ABuffer(aac_frame_length); 941 memcpy(unit->data(), adtsHeader, aac_frame_length); 942 943 int64_t unitTimeUs = timeUs + numSamples * 1000000ll / sampleRate; 944 unit->meta()->setInt64("timeUs", unitTimeUs); 945 946 // Each AAC frame encodes 1024 samples. 947 numSamples += 1024; 948 949 packetSource->queueAccessUnit(unit); 950 951 offset += aac_frame_length; 952 } 953 954 return OK; 955} 956 957void PlaylistFetcher::updateDuration() { 958 int64_t durationUs = 0ll; 959 for (size_t index = 0; index < mPlaylist->size(); ++index) { 960 sp<AMessage> itemMeta; 961 CHECK(mPlaylist->itemAt( 962 index, NULL /* uri */, &itemMeta)); 963 964 int64_t itemDurationUs; 965 CHECK(itemMeta->findInt64("durationUs", &itemDurationUs)); 966 967 durationUs += itemDurationUs; 968 } 969 970 sp<AMessage> msg = mNotify->dup(); 971 msg->setInt32("what", kWhatDurationUpdate); 972 msg->setInt64("durationUs", durationUs); 973 msg->post(); 974} 975 976} // namespace android 977