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 46 namespace android { 47 48 // static 49 const int64_t PlaylistFetcher::kMinBufferedDurationUs = 10000000ll; 50 const int64_t PlaylistFetcher::kMaxMonitorDelayUs = 3000000ll; 51 const int32_t PlaylistFetcher::kDownloadBlockSize = 192; 52 const int32_t PlaylistFetcher::kNumSkipFrames = 10; 53 54 PlaylistFetcher::PlaylistFetcher( 55 const sp<AMessage> ¬ify, 56 const sp<LiveSession> &session, 57 const char *uri) 58 : mNotify(notify), 59 mStartTimeUsNotify(notify->dup()), 60 mSession(session), 61 mURI(uri), 62 mStreamTypeMask(0), 63 mStartTimeUs(-1ll), 64 mMinStartTimeUs(0ll), 65 mStopParams(NULL), 66 mLastPlaylistFetchTimeUs(-1ll), 67 mSeqNumber(-1), 68 mNumRetries(0), 69 mStartup(true), 70 mPrepared(false), 71 mNextPTSTimeUs(-1ll), 72 mMonitorQueueGeneration(0), 73 mRefreshState(INITIAL_MINIMUM_RELOAD_DELAY), 74 mFirstPTSValid(false), 75 mAbsoluteTimeAnchorUs(0ll) { 76 memset(mPlaylistHash, 0, sizeof(mPlaylistHash)); 77 mStartTimeUsNotify->setInt32("what", kWhatStartedAt); 78 mStartTimeUsNotify->setInt32("streamMask", 0); 79 } 80 81 PlaylistFetcher::~PlaylistFetcher() { 82 } 83 84 int64_t PlaylistFetcher::getSegmentStartTimeUs(int32_t seqNumber) const { 85 CHECK(mPlaylist != NULL); 86 87 int32_t firstSeqNumberInPlaylist; 88 if (mPlaylist->meta() == NULL || !mPlaylist->meta()->findInt32( 89 "media-sequence", &firstSeqNumberInPlaylist)) { 90 firstSeqNumberInPlaylist = 0; 91 } 92 93 int32_t lastSeqNumberInPlaylist = 94 firstSeqNumberInPlaylist + (int32_t)mPlaylist->size() - 1; 95 96 CHECK_GE(seqNumber, firstSeqNumberInPlaylist); 97 CHECK_LE(seqNumber, lastSeqNumberInPlaylist); 98 99 int64_t segmentStartUs = 0ll; 100 for (int32_t index = 0; 101 index < seqNumber - firstSeqNumberInPlaylist; ++index) { 102 sp<AMessage> itemMeta; 103 CHECK(mPlaylist->itemAt( 104 index, NULL /* uri */, &itemMeta)); 105 106 int64_t itemDurationUs; 107 CHECK(itemMeta->findInt64("durationUs", &itemDurationUs)); 108 109 segmentStartUs += itemDurationUs; 110 } 111 112 return segmentStartUs; 113 } 114 115 int64_t PlaylistFetcher::delayUsToRefreshPlaylist() const { 116 int64_t nowUs = ALooper::GetNowUs(); 117 118 if (mPlaylist == NULL || mLastPlaylistFetchTimeUs < 0ll) { 119 CHECK_EQ((int)mRefreshState, (int)INITIAL_MINIMUM_RELOAD_DELAY); 120 return 0ll; 121 } 122 123 if (mPlaylist->isComplete()) { 124 return (~0llu >> 1); 125 } 126 127 int32_t targetDurationSecs; 128 CHECK(mPlaylist->meta()->findInt32("target-duration", &targetDurationSecs)); 129 130 int64_t targetDurationUs = targetDurationSecs * 1000000ll; 131 132 int64_t minPlaylistAgeUs; 133 134 switch (mRefreshState) { 135 case INITIAL_MINIMUM_RELOAD_DELAY: 136 { 137 size_t n = mPlaylist->size(); 138 if (n > 0) { 139 sp<AMessage> itemMeta; 140 CHECK(mPlaylist->itemAt(n - 1, NULL /* uri */, &itemMeta)); 141 142 int64_t itemDurationUs; 143 CHECK(itemMeta->findInt64("durationUs", &itemDurationUs)); 144 145 minPlaylistAgeUs = itemDurationUs; 146 break; 147 } 148 149 // fall through 150 } 151 152 case FIRST_UNCHANGED_RELOAD_ATTEMPT: 153 { 154 minPlaylistAgeUs = targetDurationUs / 2; 155 break; 156 } 157 158 case SECOND_UNCHANGED_RELOAD_ATTEMPT: 159 { 160 minPlaylistAgeUs = (targetDurationUs * 3) / 2; 161 break; 162 } 163 164 case THIRD_UNCHANGED_RELOAD_ATTEMPT: 165 { 166 minPlaylistAgeUs = targetDurationUs * 3; 167 break; 168 } 169 170 default: 171 TRESPASS(); 172 break; 173 } 174 175 int64_t delayUs = mLastPlaylistFetchTimeUs + minPlaylistAgeUs - nowUs; 176 return delayUs > 0ll ? delayUs : 0ll; 177 } 178 179 status_t PlaylistFetcher::decryptBuffer( 180 size_t playlistIndex, const sp<ABuffer> &buffer, 181 bool first) { 182 sp<AMessage> itemMeta; 183 bool found = false; 184 AString method; 185 186 for (ssize_t i = playlistIndex; i >= 0; --i) { 187 AString uri; 188 CHECK(mPlaylist->itemAt(i, &uri, &itemMeta)); 189 190 if (itemMeta->findString("cipher-method", &method)) { 191 found = true; 192 break; 193 } 194 } 195 196 if (!found) { 197 method = "NONE"; 198 } 199 buffer->meta()->setString("cipher-method", method.c_str()); 200 201 if (method == "NONE") { 202 return OK; 203 } else if (!(method == "AES-128")) { 204 ALOGE("Unsupported cipher method '%s'", method.c_str()); 205 return ERROR_UNSUPPORTED; 206 } 207 208 AString keyURI; 209 if (!itemMeta->findString("cipher-uri", &keyURI)) { 210 ALOGE("Missing key uri"); 211 return ERROR_MALFORMED; 212 } 213 214 ssize_t index = mAESKeyForURI.indexOfKey(keyURI); 215 216 sp<ABuffer> key; 217 if (index >= 0) { 218 key = mAESKeyForURI.valueAt(index); 219 } else { 220 ssize_t err = mSession->fetchFile(keyURI.c_str(), &key); 221 222 if (err < 0) { 223 ALOGE("failed to fetch cipher key from '%s'.", keyURI.c_str()); 224 return ERROR_IO; 225 } else if (key->size() != 16) { 226 ALOGE("key file '%s' wasn't 16 bytes in size.", keyURI.c_str()); 227 return ERROR_MALFORMED; 228 } 229 230 mAESKeyForURI.add(keyURI, key); 231 } 232 233 AES_KEY aes_key; 234 if (AES_set_decrypt_key(key->data(), 128, &aes_key) != 0) { 235 ALOGE("failed to set AES decryption key."); 236 return UNKNOWN_ERROR; 237 } 238 239 size_t n = buffer->size(); 240 if (!n) { 241 return OK; 242 } 243 CHECK(n % 16 == 0); 244 245 if (first) { 246 // If decrypting the first block in a file, read the iv from the manifest 247 // or derive the iv from the file's sequence number. 248 249 AString iv; 250 if (itemMeta->findString("cipher-iv", &iv)) { 251 if ((!iv.startsWith("0x") && !iv.startsWith("0X")) 252 || iv.size() != 16 * 2 + 2) { 253 ALOGE("malformed cipher IV '%s'.", iv.c_str()); 254 return ERROR_MALFORMED; 255 } 256 257 memset(mAESInitVec, 0, sizeof(mAESInitVec)); 258 for (size_t i = 0; i < 16; ++i) { 259 char c1 = tolower(iv.c_str()[2 + 2 * i]); 260 char c2 = tolower(iv.c_str()[3 + 2 * i]); 261 if (!isxdigit(c1) || !isxdigit(c2)) { 262 ALOGE("malformed cipher IV '%s'.", iv.c_str()); 263 return ERROR_MALFORMED; 264 } 265 uint8_t nibble1 = isdigit(c1) ? c1 - '0' : c1 - 'a' + 10; 266 uint8_t nibble2 = isdigit(c2) ? c2 - '0' : c2 - 'a' + 10; 267 268 mAESInitVec[i] = nibble1 << 4 | nibble2; 269 } 270 } else { 271 memset(mAESInitVec, 0, sizeof(mAESInitVec)); 272 mAESInitVec[15] = mSeqNumber & 0xff; 273 mAESInitVec[14] = (mSeqNumber >> 8) & 0xff; 274 mAESInitVec[13] = (mSeqNumber >> 16) & 0xff; 275 mAESInitVec[12] = (mSeqNumber >> 24) & 0xff; 276 } 277 } 278 279 AES_cbc_encrypt( 280 buffer->data(), buffer->data(), buffer->size(), 281 &aes_key, mAESInitVec, AES_DECRYPT); 282 283 return OK; 284 } 285 286 status_t PlaylistFetcher::checkDecryptPadding(const sp<ABuffer> &buffer) { 287 status_t err; 288 AString method; 289 CHECK(buffer->meta()->findString("cipher-method", &method)); 290 if (method == "NONE") { 291 return OK; 292 } 293 294 uint8_t padding = 0; 295 if (buffer->size() > 0) { 296 padding = buffer->data()[buffer->size() - 1]; 297 } 298 299 if (padding > 16) { 300 return ERROR_MALFORMED; 301 } 302 303 for (size_t i = buffer->size() - padding; i < padding; i++) { 304 if (buffer->data()[i] != padding) { 305 return ERROR_MALFORMED; 306 } 307 } 308 309 buffer->setRange(buffer->offset(), buffer->size() - padding); 310 return OK; 311 } 312 313 void PlaylistFetcher::postMonitorQueue(int64_t delayUs, int64_t minDelayUs) { 314 int64_t maxDelayUs = delayUsToRefreshPlaylist(); 315 if (maxDelayUs < minDelayUs) { 316 maxDelayUs = minDelayUs; 317 } 318 if (delayUs > maxDelayUs) { 319 ALOGV("Need to refresh playlist in %lld", maxDelayUs); 320 delayUs = maxDelayUs; 321 } 322 sp<AMessage> msg = new AMessage(kWhatMonitorQueue, id()); 323 msg->setInt32("generation", mMonitorQueueGeneration); 324 msg->post(delayUs); 325 } 326 327 void PlaylistFetcher::cancelMonitorQueue() { 328 ++mMonitorQueueGeneration; 329 } 330 331 void PlaylistFetcher::startAsync( 332 const sp<AnotherPacketSource> &audioSource, 333 const sp<AnotherPacketSource> &videoSource, 334 const sp<AnotherPacketSource> &subtitleSource, 335 int64_t startTimeUs, 336 int64_t minStartTimeUs, 337 int32_t startSeqNumberHint) { 338 sp<AMessage> msg = new AMessage(kWhatStart, id()); 339 340 uint32_t streamTypeMask = 0ul; 341 342 if (audioSource != NULL) { 343 msg->setPointer("audioSource", audioSource.get()); 344 streamTypeMask |= LiveSession::STREAMTYPE_AUDIO; 345 } 346 347 if (videoSource != NULL) { 348 msg->setPointer("videoSource", videoSource.get()); 349 streamTypeMask |= LiveSession::STREAMTYPE_VIDEO; 350 } 351 352 if (subtitleSource != NULL) { 353 msg->setPointer("subtitleSource", subtitleSource.get()); 354 streamTypeMask |= LiveSession::STREAMTYPE_SUBTITLES; 355 } 356 357 msg->setInt32("streamTypeMask", streamTypeMask); 358 msg->setInt64("startTimeUs", startTimeUs); 359 msg->setInt64("minStartTimeUs", minStartTimeUs); 360 msg->setInt32("startSeqNumberHint", startSeqNumberHint); 361 msg->post(); 362 } 363 364 void PlaylistFetcher::pauseAsync() { 365 (new AMessage(kWhatPause, id()))->post(); 366 } 367 368 void PlaylistFetcher::stopAsync(bool selfTriggered) { 369 sp<AMessage> msg = new AMessage(kWhatStop, id()); 370 msg->setInt32("selfTriggered", selfTriggered); 371 msg->post(); 372 } 373 374 void PlaylistFetcher::resumeUntilAsync(const sp<AMessage> ¶ms) { 375 AMessage* msg = new AMessage(kWhatResumeUntil, id()); 376 msg->setMessage("params", params); 377 msg->post(); 378 } 379 380 void PlaylistFetcher::onMessageReceived(const sp<AMessage> &msg) { 381 switch (msg->what()) { 382 case kWhatStart: 383 { 384 status_t err = onStart(msg); 385 386 sp<AMessage> notify = mNotify->dup(); 387 notify->setInt32("what", kWhatStarted); 388 notify->setInt32("err", err); 389 notify->post(); 390 break; 391 } 392 393 case kWhatPause: 394 { 395 onPause(); 396 397 sp<AMessage> notify = mNotify->dup(); 398 notify->setInt32("what", kWhatPaused); 399 notify->post(); 400 break; 401 } 402 403 case kWhatStop: 404 { 405 onStop(msg); 406 407 sp<AMessage> notify = mNotify->dup(); 408 notify->setInt32("what", kWhatStopped); 409 notify->post(); 410 break; 411 } 412 413 case kWhatMonitorQueue: 414 case kWhatDownloadNext: 415 { 416 int32_t generation; 417 CHECK(msg->findInt32("generation", &generation)); 418 419 if (generation != mMonitorQueueGeneration) { 420 // Stale event 421 break; 422 } 423 424 if (msg->what() == kWhatMonitorQueue) { 425 onMonitorQueue(); 426 } else { 427 onDownloadNext(); 428 } 429 break; 430 } 431 432 case kWhatResumeUntil: 433 { 434 onResumeUntil(msg); 435 break; 436 } 437 438 default: 439 TRESPASS(); 440 } 441 } 442 443 status_t PlaylistFetcher::onStart(const sp<AMessage> &msg) { 444 mPacketSources.clear(); 445 446 uint32_t streamTypeMask; 447 CHECK(msg->findInt32("streamTypeMask", (int32_t *)&streamTypeMask)); 448 449 int64_t startTimeUs; 450 int32_t startSeqNumberHint; 451 CHECK(msg->findInt64("startTimeUs", &startTimeUs)); 452 CHECK(msg->findInt64("minStartTimeUs", (int64_t *) &mMinStartTimeUs)); 453 CHECK(msg->findInt32("startSeqNumberHint", &startSeqNumberHint)); 454 455 if (streamTypeMask & LiveSession::STREAMTYPE_AUDIO) { 456 void *ptr; 457 CHECK(msg->findPointer("audioSource", &ptr)); 458 459 mPacketSources.add( 460 LiveSession::STREAMTYPE_AUDIO, 461 static_cast<AnotherPacketSource *>(ptr)); 462 } 463 464 if (streamTypeMask & LiveSession::STREAMTYPE_VIDEO) { 465 void *ptr; 466 CHECK(msg->findPointer("videoSource", &ptr)); 467 468 mPacketSources.add( 469 LiveSession::STREAMTYPE_VIDEO, 470 static_cast<AnotherPacketSource *>(ptr)); 471 } 472 473 if (streamTypeMask & LiveSession::STREAMTYPE_SUBTITLES) { 474 void *ptr; 475 CHECK(msg->findPointer("subtitleSource", &ptr)); 476 477 mPacketSources.add( 478 LiveSession::STREAMTYPE_SUBTITLES, 479 static_cast<AnotherPacketSource *>(ptr)); 480 } 481 482 mStreamTypeMask = streamTypeMask; 483 mStartTimeUs = startTimeUs; 484 485 if (mStartTimeUs >= 0ll) { 486 mSeqNumber = -1; 487 mStartup = true; 488 mPrepared = false; 489 } 490 491 if (startSeqNumberHint >= 0) { 492 mSeqNumber = startSeqNumberHint; 493 } 494 495 postMonitorQueue(); 496 497 return OK; 498 } 499 500 void PlaylistFetcher::onPause() { 501 cancelMonitorQueue(); 502 } 503 504 void PlaylistFetcher::onStop(const sp<AMessage> &msg) { 505 cancelMonitorQueue(); 506 507 int32_t selfTriggered; 508 CHECK(msg->findInt32("selfTriggered", &selfTriggered)); 509 if (!selfTriggered) { 510 // Self triggered stops only happen during switching, in which case we do not want 511 // to clear the discontinuities queued at the end of packet sources. 512 for (size_t i = 0; i < mPacketSources.size(); i++) { 513 sp<AnotherPacketSource> packetSource = mPacketSources.valueAt(i); 514 packetSource->clear(); 515 } 516 } 517 518 mPacketSources.clear(); 519 mStreamTypeMask = 0; 520 } 521 522 // Resume until we have reached the boundary timestamps listed in `msg`; when 523 // the remaining time is too short (within a resume threshold) stop immediately 524 // instead. 525 status_t PlaylistFetcher::onResumeUntil(const sp<AMessage> &msg) { 526 sp<AMessage> params; 527 CHECK(msg->findMessage("params", ¶ms)); 528 529 bool stop = false; 530 for (size_t i = 0; i < mPacketSources.size(); i++) { 531 sp<AnotherPacketSource> packetSource = mPacketSources.valueAt(i); 532 533 const char *stopKey; 534 int streamType = mPacketSources.keyAt(i); 535 switch (streamType) { 536 case LiveSession::STREAMTYPE_VIDEO: 537 stopKey = "timeUsVideo"; 538 break; 539 540 case LiveSession::STREAMTYPE_AUDIO: 541 stopKey = "timeUsAudio"; 542 break; 543 544 case LiveSession::STREAMTYPE_SUBTITLES: 545 stopKey = "timeUsSubtitle"; 546 break; 547 548 default: 549 TRESPASS(); 550 } 551 552 // Don't resume if we would stop within a resume threshold. 553 int64_t latestTimeUs = 0, stopTimeUs = 0; 554 sp<AMessage> latestMeta = packetSource->getLatestMeta(); 555 if (latestMeta != NULL 556 && (latestMeta->findInt64("timeUs", &latestTimeUs) 557 && params->findInt64(stopKey, &stopTimeUs))) { 558 int64_t diffUs = stopTimeUs - latestTimeUs; 559 if (diffUs < resumeThreshold(latestMeta)) { 560 stop = true; 561 } 562 } 563 } 564 565 if (stop) { 566 for (size_t i = 0; i < mPacketSources.size(); i++) { 567 mPacketSources.valueAt(i)->queueAccessUnit(mSession->createFormatChangeBuffer()); 568 } 569 stopAsync(/* selfTriggered = */ true); 570 return OK; 571 } 572 573 mStopParams = params; 574 postMonitorQueue(); 575 576 return OK; 577 } 578 579 void PlaylistFetcher::notifyError(status_t err) { 580 sp<AMessage> notify = mNotify->dup(); 581 notify->setInt32("what", kWhatError); 582 notify->setInt32("err", err); 583 notify->post(); 584 } 585 586 void PlaylistFetcher::queueDiscontinuity( 587 ATSParser::DiscontinuityType type, const sp<AMessage> &extra) { 588 for (size_t i = 0; i < mPacketSources.size(); ++i) { 589 mPacketSources.valueAt(i)->queueDiscontinuity(type, extra); 590 } 591 } 592 593 void PlaylistFetcher::onMonitorQueue() { 594 bool downloadMore = false; 595 refreshPlaylist(); 596 597 int32_t targetDurationSecs; 598 int64_t targetDurationUs = kMinBufferedDurationUs; 599 if (mPlaylist != NULL) { 600 CHECK(mPlaylist->meta()->findInt32("target-duration", &targetDurationSecs)); 601 targetDurationUs = targetDurationSecs * 1000000ll; 602 } 603 604 // buffer at least 3 times the target duration, or up to 10 seconds 605 int64_t durationToBufferUs = targetDurationUs * 3; 606 if (durationToBufferUs > kMinBufferedDurationUs) { 607 durationToBufferUs = kMinBufferedDurationUs; 608 } 609 610 int64_t bufferedDurationUs = 0ll; 611 status_t finalResult = NOT_ENOUGH_DATA; 612 if (mStreamTypeMask == LiveSession::STREAMTYPE_SUBTITLES) { 613 sp<AnotherPacketSource> packetSource = 614 mPacketSources.valueFor(LiveSession::STREAMTYPE_SUBTITLES); 615 616 bufferedDurationUs = 617 packetSource->getBufferedDurationUs(&finalResult); 618 finalResult = OK; 619 } else { 620 // Use max stream duration to prevent us from waiting on a non-existent stream; 621 // when we cannot make out from the manifest what streams are included in a playlist 622 // we might assume extra streams. 623 for (size_t i = 0; i < mPacketSources.size(); ++i) { 624 if ((mStreamTypeMask & mPacketSources.keyAt(i)) == 0) { 625 continue; 626 } 627 628 int64_t bufferedStreamDurationUs = 629 mPacketSources.valueAt(i)->getBufferedDurationUs(&finalResult); 630 ALOGV("buffered %lld for stream %d", 631 bufferedStreamDurationUs, mPacketSources.keyAt(i)); 632 if (bufferedStreamDurationUs > bufferedDurationUs) { 633 bufferedDurationUs = bufferedStreamDurationUs; 634 } 635 } 636 } 637 downloadMore = (bufferedDurationUs < durationToBufferUs); 638 639 // signal start if buffered up at least the target size 640 if (!mPrepared && bufferedDurationUs > targetDurationUs && downloadMore) { 641 mPrepared = true; 642 643 ALOGV("prepared, buffered=%lld > %lld", 644 bufferedDurationUs, targetDurationUs); 645 sp<AMessage> msg = mNotify->dup(); 646 msg->setInt32("what", kWhatTemporarilyDoneFetching); 647 msg->post(); 648 } 649 650 if (finalResult == OK && downloadMore) { 651 ALOGV("monitoring, buffered=%lld < %lld", 652 bufferedDurationUs, durationToBufferUs); 653 // delay the next download slightly; hopefully this gives other concurrent fetchers 654 // a better chance to run. 655 // onDownloadNext(); 656 sp<AMessage> msg = new AMessage(kWhatDownloadNext, id()); 657 msg->setInt32("generation", mMonitorQueueGeneration); 658 msg->post(1000l); 659 } else { 660 // Nothing to do yet, try again in a second. 661 662 sp<AMessage> msg = mNotify->dup(); 663 msg->setInt32("what", kWhatTemporarilyDoneFetching); 664 msg->post(); 665 666 int64_t delayUs = mPrepared ? kMaxMonitorDelayUs : targetDurationUs / 2; 667 ALOGV("pausing for %lld, buffered=%lld > %lld", 668 delayUs, bufferedDurationUs, durationToBufferUs); 669 // :TRICKY: need to enforce minimum delay because the delay to 670 // refresh the playlist will become 0 671 postMonitorQueue(delayUs, mPrepared ? targetDurationUs * 2 : 0); 672 } 673 } 674 675 status_t PlaylistFetcher::refreshPlaylist() { 676 if (delayUsToRefreshPlaylist() <= 0) { 677 bool unchanged; 678 sp<M3UParser> playlist = mSession->fetchPlaylist( 679 mURI.c_str(), mPlaylistHash, &unchanged); 680 681 if (playlist == NULL) { 682 if (unchanged) { 683 // We succeeded in fetching the playlist, but it was 684 // unchanged from the last time we tried. 685 686 if (mRefreshState != THIRD_UNCHANGED_RELOAD_ATTEMPT) { 687 mRefreshState = (RefreshState)(mRefreshState + 1); 688 } 689 } else { 690 ALOGE("failed to load playlist at url '%s'", mURI.c_str()); 691 notifyError(ERROR_IO); 692 return ERROR_IO; 693 } 694 } else { 695 mRefreshState = INITIAL_MINIMUM_RELOAD_DELAY; 696 mPlaylist = playlist; 697 698 if (mPlaylist->isComplete() || mPlaylist->isEvent()) { 699 updateDuration(); 700 } 701 } 702 703 mLastPlaylistFetchTimeUs = ALooper::GetNowUs(); 704 } 705 return OK; 706 } 707 708 // static 709 bool PlaylistFetcher::bufferStartsWithTsSyncByte(const sp<ABuffer>& buffer) { 710 return buffer->size() > 0 && buffer->data()[0] == 0x47; 711 } 712 713 void PlaylistFetcher::onDownloadNext() { 714 if (refreshPlaylist() != OK) { 715 return; 716 } 717 718 int32_t firstSeqNumberInPlaylist; 719 if (mPlaylist->meta() == NULL || !mPlaylist->meta()->findInt32( 720 "media-sequence", &firstSeqNumberInPlaylist)) { 721 firstSeqNumberInPlaylist = 0; 722 } 723 724 bool seekDiscontinuity = false; 725 bool explicitDiscontinuity = false; 726 727 const int32_t lastSeqNumberInPlaylist = 728 firstSeqNumberInPlaylist + (int32_t)mPlaylist->size() - 1; 729 730 if (mStartup && mSeqNumber >= 0 731 && (mSeqNumber < firstSeqNumberInPlaylist || mSeqNumber > lastSeqNumberInPlaylist)) { 732 // in case we guessed wrong during reconfiguration, try fetching the latest content. 733 mSeqNumber = lastSeqNumberInPlaylist; 734 } 735 736 if (mSeqNumber < 0) { 737 CHECK_GE(mStartTimeUs, 0ll); 738 739 if (mPlaylist->isComplete() || mPlaylist->isEvent()) { 740 mSeqNumber = getSeqNumberForTime(mStartTimeUs); 741 ALOGV("Initial sequence number for time %lld is %ld from (%ld .. %ld)", 742 mStartTimeUs, mSeqNumber, firstSeqNumberInPlaylist, 743 lastSeqNumberInPlaylist); 744 } else { 745 // If this is a live session, start 3 segments from the end. 746 mSeqNumber = lastSeqNumberInPlaylist - 3; 747 if (mSeqNumber < firstSeqNumberInPlaylist) { 748 mSeqNumber = firstSeqNumberInPlaylist; 749 } 750 ALOGV("Initial sequence number for live event %ld from (%ld .. %ld)", 751 mSeqNumber, firstSeqNumberInPlaylist, 752 lastSeqNumberInPlaylist); 753 } 754 755 mStartTimeUs = -1ll; 756 } 757 758 if (mSeqNumber < firstSeqNumberInPlaylist 759 || mSeqNumber > lastSeqNumberInPlaylist) { 760 if (!mPlaylist->isComplete() && mNumRetries < kMaxNumRetries) { 761 ++mNumRetries; 762 763 if (mSeqNumber > lastSeqNumberInPlaylist) { 764 // refresh in increasing fraction (1/2, 1/3, ...) of the 765 // playlist's target duration or 3 seconds, whichever is less 766 int32_t targetDurationSecs; 767 CHECK(mPlaylist->meta()->findInt32( 768 "target-duration", &targetDurationSecs)); 769 int64_t delayUs = mPlaylist->size() * targetDurationSecs * 770 1000000ll / (1 + mNumRetries); 771 if (delayUs > kMaxMonitorDelayUs) { 772 delayUs = kMaxMonitorDelayUs; 773 } 774 ALOGV("sequence number high: %ld from (%ld .. %ld), monitor in %lld (retry=%d)", 775 mSeqNumber, firstSeqNumberInPlaylist, 776 lastSeqNumberInPlaylist, delayUs, mNumRetries); 777 postMonitorQueue(delayUs); 778 return; 779 } 780 781 // we've missed the boat, let's start from the lowest sequence 782 // number available and signal a discontinuity. 783 784 ALOGI("We've missed the boat, restarting playback." 785 " mStartup=%d, was looking for %d in %d-%d", 786 mStartup, mSeqNumber, firstSeqNumberInPlaylist, 787 lastSeqNumberInPlaylist); 788 mSeqNumber = lastSeqNumberInPlaylist - 3; 789 if (mSeqNumber < firstSeqNumberInPlaylist) { 790 mSeqNumber = firstSeqNumberInPlaylist; 791 } 792 explicitDiscontinuity = true; 793 794 // fall through 795 } else { 796 ALOGE("Cannot find sequence number %d in playlist " 797 "(contains %d - %d)", 798 mSeqNumber, firstSeqNumberInPlaylist, 799 firstSeqNumberInPlaylist + mPlaylist->size() - 1); 800 801 notifyError(ERROR_END_OF_STREAM); 802 return; 803 } 804 } 805 806 mNumRetries = 0; 807 808 AString uri; 809 sp<AMessage> itemMeta; 810 CHECK(mPlaylist->itemAt( 811 mSeqNumber - firstSeqNumberInPlaylist, 812 &uri, 813 &itemMeta)); 814 815 int32_t val; 816 if (itemMeta->findInt32("discontinuity", &val) && val != 0) { 817 explicitDiscontinuity = true; 818 } 819 820 int64_t range_offset, range_length; 821 if (!itemMeta->findInt64("range-offset", &range_offset) 822 || !itemMeta->findInt64("range-length", &range_length)) { 823 range_offset = 0; 824 range_length = -1; 825 } 826 827 ALOGV("fetching segment %d from (%d .. %d)", 828 mSeqNumber, firstSeqNumberInPlaylist, lastSeqNumberInPlaylist); 829 830 ALOGV("fetching '%s'", uri.c_str()); 831 832 sp<DataSource> source; 833 sp<ABuffer> buffer, tsBuffer; 834 // decrypt a junk buffer to prefetch key; since a session uses only one http connection, 835 // this avoids interleaved connections to the key and segment file. 836 { 837 sp<ABuffer> junk = new ABuffer(16); 838 junk->setRange(0, 16); 839 status_t err = decryptBuffer(mSeqNumber - firstSeqNumberInPlaylist, junk, 840 true /* first */); 841 if (err != OK) { 842 notifyError(err); 843 return; 844 } 845 } 846 847 // block-wise download 848 ssize_t bytesRead; 849 do { 850 bytesRead = mSession->fetchFile( 851 uri.c_str(), &buffer, range_offset, range_length, kDownloadBlockSize, &source); 852 853 if (bytesRead < 0) { 854 status_t err = bytesRead; 855 ALOGE("failed to fetch .ts segment at url '%s'", uri.c_str()); 856 notifyError(err); 857 return; 858 } 859 860 CHECK(buffer != NULL); 861 862 size_t size = buffer->size(); 863 // Set decryption range. 864 buffer->setRange(size - bytesRead, bytesRead); 865 status_t err = decryptBuffer(mSeqNumber - firstSeqNumberInPlaylist, buffer, 866 buffer->offset() == 0 /* first */); 867 // Unset decryption range. 868 buffer->setRange(0, size); 869 870 if (err != OK) { 871 ALOGE("decryptBuffer failed w/ error %d", err); 872 873 notifyError(err); 874 return; 875 } 876 877 if (mStartup || seekDiscontinuity || explicitDiscontinuity) { 878 // Signal discontinuity. 879 880 if (mPlaylist->isComplete() || mPlaylist->isEvent()) { 881 // If this was a live event this made no sense since 882 // we don't have access to all the segment before the current 883 // one. 884 mNextPTSTimeUs = getSegmentStartTimeUs(mSeqNumber); 885 } 886 887 if (seekDiscontinuity || explicitDiscontinuity) { 888 ALOGI("queueing discontinuity (seek=%d, explicit=%d)", 889 seekDiscontinuity, explicitDiscontinuity); 890 891 queueDiscontinuity( 892 explicitDiscontinuity 893 ? ATSParser::DISCONTINUITY_FORMATCHANGE 894 : ATSParser::DISCONTINUITY_SEEK, 895 NULL /* extra */); 896 } 897 } 898 899 err = OK; 900 if (bufferStartsWithTsSyncByte(buffer)) { 901 // Incremental extraction is only supported for MPEG2 transport streams. 902 if (tsBuffer == NULL) { 903 tsBuffer = new ABuffer(buffer->data(), buffer->capacity()); 904 tsBuffer->setRange(0, 0); 905 } else if (tsBuffer->capacity() != buffer->capacity()) { 906 size_t tsOff = tsBuffer->offset(), tsSize = tsBuffer->size(); 907 tsBuffer = new ABuffer(buffer->data(), buffer->capacity()); 908 tsBuffer->setRange(tsOff, tsSize); 909 } 910 tsBuffer->setRange(tsBuffer->offset(), tsBuffer->size() + bytesRead); 911 912 err = extractAndQueueAccessUnitsFromTs(tsBuffer); 913 } 914 915 if (err == -EAGAIN) { 916 // bad starting sequence number hint 917 postMonitorQueue(); 918 return; 919 } 920 921 if (err == ERROR_OUT_OF_RANGE) { 922 // reached stopping point 923 stopAsync(/* selfTriggered = */ true); 924 return; 925 } 926 927 if (err != OK) { 928 notifyError(err); 929 return; 930 } 931 932 mStartup = false; 933 } while (bytesRead != 0); 934 935 if (bufferStartsWithTsSyncByte(buffer)) { 936 // If we still don't see a stream after fetching a full ts segment mark it as 937 // nonexistent. 938 const size_t kNumTypes = ATSParser::NUM_SOURCE_TYPES; 939 ATSParser::SourceType srcTypes[kNumTypes] = 940 { ATSParser::VIDEO, ATSParser::AUDIO }; 941 LiveSession::StreamType streamTypes[kNumTypes] = 942 { LiveSession::STREAMTYPE_VIDEO, LiveSession::STREAMTYPE_AUDIO }; 943 944 for (size_t i = 0; i < kNumTypes; i++) { 945 ATSParser::SourceType srcType = srcTypes[i]; 946 LiveSession::StreamType streamType = streamTypes[i]; 947 948 sp<AnotherPacketSource> source = 949 static_cast<AnotherPacketSource *>( 950 mTSParser->getSource(srcType).get()); 951 952 if (source == NULL) { 953 ALOGW("MPEG2 Transport stream does not contain %s data.", 954 srcType == ATSParser::VIDEO ? "video" : "audio"); 955 956 mStreamTypeMask &= ~streamType; 957 mPacketSources.removeItem(streamType); 958 } 959 } 960 961 } 962 963 if (checkDecryptPadding(buffer) != OK) { 964 ALOGE("Incorrect padding bytes after decryption."); 965 notifyError(ERROR_MALFORMED); 966 return; 967 } 968 969 status_t err = OK; 970 if (tsBuffer != NULL) { 971 AString method; 972 CHECK(buffer->meta()->findString("cipher-method", &method)); 973 if ((tsBuffer->size() > 0 && method == "NONE") 974 || tsBuffer->size() > 16) { 975 ALOGE("MPEG2 transport stream is not an even multiple of 188 " 976 "bytes in length."); 977 notifyError(ERROR_MALFORMED); 978 return; 979 } 980 } 981 982 // bulk extract non-ts files 983 if (tsBuffer == NULL) { 984 err = extractAndQueueAccessUnits(buffer, itemMeta); 985 } 986 987 if (err != OK) { 988 notifyError(err); 989 return; 990 } 991 992 ++mSeqNumber; 993 994 postMonitorQueue(); 995 } 996 997 int32_t PlaylistFetcher::getSeqNumberForTime(int64_t timeUs) const { 998 int32_t firstSeqNumberInPlaylist; 999 if (mPlaylist->meta() == NULL || !mPlaylist->meta()->findInt32( 1000 "media-sequence", &firstSeqNumberInPlaylist)) { 1001 firstSeqNumberInPlaylist = 0; 1002 } 1003 1004 size_t index = 0; 1005 int64_t segmentStartUs = 0; 1006 while (index < mPlaylist->size()) { 1007 sp<AMessage> itemMeta; 1008 CHECK(mPlaylist->itemAt( 1009 index, NULL /* uri */, &itemMeta)); 1010 1011 int64_t itemDurationUs; 1012 CHECK(itemMeta->findInt64("durationUs", &itemDurationUs)); 1013 1014 if (timeUs < segmentStartUs + itemDurationUs) { 1015 break; 1016 } 1017 1018 segmentStartUs += itemDurationUs; 1019 ++index; 1020 } 1021 1022 if (index >= mPlaylist->size()) { 1023 index = mPlaylist->size() - 1; 1024 } 1025 1026 return firstSeqNumberInPlaylist + index; 1027 } 1028 1029 status_t PlaylistFetcher::extractAndQueueAccessUnitsFromTs(const sp<ABuffer> &buffer) { 1030 if (mTSParser == NULL) { 1031 // Use TS_TIMESTAMPS_ARE_ABSOLUTE so pts carry over between fetchers. 1032 mTSParser = new ATSParser(ATSParser::TS_TIMESTAMPS_ARE_ABSOLUTE); 1033 } 1034 1035 if (mNextPTSTimeUs >= 0ll) { 1036 sp<AMessage> extra = new AMessage; 1037 // Since we are using absolute timestamps, signal an offset of 0 to prevent 1038 // ATSParser from skewing the timestamps of access units. 1039 extra->setInt64(IStreamListener::kKeyMediaTimeUs, 0); 1040 1041 mTSParser->signalDiscontinuity( 1042 ATSParser::DISCONTINUITY_SEEK, extra); 1043 1044 mNextPTSTimeUs = -1ll; 1045 } 1046 1047 size_t offset = 0; 1048 while (offset + 188 <= buffer->size()) { 1049 status_t err = mTSParser->feedTSPacket(buffer->data() + offset, 188); 1050 1051 if (err != OK) { 1052 return err; 1053 } 1054 1055 offset += 188; 1056 } 1057 // setRange to indicate consumed bytes. 1058 buffer->setRange(buffer->offset() + offset, buffer->size() - offset); 1059 1060 status_t err = OK; 1061 for (size_t i = mPacketSources.size(); i-- > 0;) { 1062 sp<AnotherPacketSource> packetSource = mPacketSources.valueAt(i); 1063 1064 const char *key; 1065 ATSParser::SourceType type; 1066 const LiveSession::StreamType stream = mPacketSources.keyAt(i); 1067 switch (stream) { 1068 case LiveSession::STREAMTYPE_VIDEO: 1069 type = ATSParser::VIDEO; 1070 key = "timeUsVideo"; 1071 break; 1072 1073 case LiveSession::STREAMTYPE_AUDIO: 1074 type = ATSParser::AUDIO; 1075 key = "timeUsAudio"; 1076 break; 1077 1078 case LiveSession::STREAMTYPE_SUBTITLES: 1079 { 1080 ALOGE("MPEG2 Transport streams do not contain subtitles."); 1081 return ERROR_MALFORMED; 1082 break; 1083 } 1084 1085 default: 1086 TRESPASS(); 1087 } 1088 1089 sp<AnotherPacketSource> source = 1090 static_cast<AnotherPacketSource *>( 1091 mTSParser->getSource(type).get()); 1092 1093 if (source == NULL) { 1094 continue; 1095 } 1096 1097 int64_t timeUs; 1098 sp<ABuffer> accessUnit; 1099 status_t finalResult; 1100 while (source->hasBufferAvailable(&finalResult) 1101 && source->dequeueAccessUnit(&accessUnit) == OK) { 1102 1103 CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs)); 1104 if (mMinStartTimeUs > 0) { 1105 if (timeUs < mMinStartTimeUs) { 1106 // TODO untested path 1107 // try a later ts 1108 int32_t targetDuration; 1109 mPlaylist->meta()->findInt32("target-duration", &targetDuration); 1110 int32_t incr = (mMinStartTimeUs - timeUs) / 1000000 / targetDuration; 1111 if (incr == 0) { 1112 // increment mSeqNumber by at least one 1113 incr = 1; 1114 } 1115 mSeqNumber += incr; 1116 err = -EAGAIN; 1117 break; 1118 } else { 1119 int64_t startTimeUs; 1120 if (mStartTimeUsNotify != NULL 1121 && !mStartTimeUsNotify->findInt64(key, &startTimeUs)) { 1122 mStartTimeUsNotify->setInt64(key, timeUs); 1123 1124 uint32_t streamMask = 0; 1125 mStartTimeUsNotify->findInt32("streamMask", (int32_t *) &streamMask); 1126 streamMask |= mPacketSources.keyAt(i); 1127 mStartTimeUsNotify->setInt32("streamMask", streamMask); 1128 1129 if (streamMask == mStreamTypeMask) { 1130 mStartTimeUsNotify->post(); 1131 mStartTimeUsNotify.clear(); 1132 } 1133 } 1134 } 1135 } 1136 1137 if (mStopParams != NULL) { 1138 // Queue discontinuity in original stream. 1139 int64_t stopTimeUs; 1140 if (!mStopParams->findInt64(key, &stopTimeUs) || timeUs >= stopTimeUs) { 1141 packetSource->queueAccessUnit(mSession->createFormatChangeBuffer()); 1142 mStreamTypeMask &= ~stream; 1143 mPacketSources.removeItemsAt(i); 1144 break; 1145 } 1146 } 1147 1148 // Note that we do NOT dequeue any discontinuities except for format change. 1149 1150 // for simplicity, store a reference to the format in each unit 1151 sp<MetaData> format = source->getFormat(); 1152 if (format != NULL) { 1153 accessUnit->meta()->setObject("format", format); 1154 } 1155 1156 // Stash the sequence number so we can hint future playlist where to start at. 1157 accessUnit->meta()->setInt32("seq", mSeqNumber); 1158 packetSource->queueAccessUnit(accessUnit); 1159 } 1160 1161 if (err != OK) { 1162 break; 1163 } 1164 } 1165 1166 if (err != OK) { 1167 for (size_t i = mPacketSources.size(); i-- > 0;) { 1168 sp<AnotherPacketSource> packetSource = mPacketSources.valueAt(i); 1169 packetSource->clear(); 1170 } 1171 return err; 1172 } 1173 1174 if (!mStreamTypeMask) { 1175 // Signal gap is filled between original and new stream. 1176 ALOGV("ERROR OUT OF RANGE"); 1177 return ERROR_OUT_OF_RANGE; 1178 } 1179 1180 return OK; 1181 } 1182 1183 status_t PlaylistFetcher::extractAndQueueAccessUnits( 1184 const sp<ABuffer> &buffer, const sp<AMessage> &itemMeta) { 1185 if (buffer->size() >= 7 && !memcmp("WEBVTT\n", buffer->data(), 7)) { 1186 if (mStreamTypeMask != LiveSession::STREAMTYPE_SUBTITLES) { 1187 ALOGE("This stream only contains subtitles."); 1188 return ERROR_MALFORMED; 1189 } 1190 1191 const sp<AnotherPacketSource> packetSource = 1192 mPacketSources.valueFor(LiveSession::STREAMTYPE_SUBTITLES); 1193 1194 int64_t durationUs; 1195 CHECK(itemMeta->findInt64("durationUs", &durationUs)); 1196 buffer->meta()->setInt64("timeUs", getSegmentStartTimeUs(mSeqNumber)); 1197 buffer->meta()->setInt64("durationUs", durationUs); 1198 buffer->meta()->setInt32("seq", mSeqNumber); 1199 1200 packetSource->queueAccessUnit(buffer); 1201 return OK; 1202 } 1203 1204 if (mNextPTSTimeUs >= 0ll) { 1205 mFirstPTSValid = false; 1206 mAbsoluteTimeAnchorUs = mNextPTSTimeUs; 1207 mNextPTSTimeUs = -1ll; 1208 } 1209 1210 // This better be an ISO 13818-7 (AAC) or ISO 13818-1 (MPEG) audio 1211 // stream prefixed by an ID3 tag. 1212 1213 bool firstID3Tag = true; 1214 uint64_t PTS = 0; 1215 1216 for (;;) { 1217 // Make sure to skip all ID3 tags preceding the audio data. 1218 // At least one must be present to provide the PTS timestamp. 1219 1220 ID3 id3(buffer->data(), buffer->size(), true /* ignoreV1 */); 1221 if (!id3.isValid()) { 1222 if (firstID3Tag) { 1223 ALOGE("Unable to parse ID3 tag."); 1224 return ERROR_MALFORMED; 1225 } else { 1226 break; 1227 } 1228 } 1229 1230 if (firstID3Tag) { 1231 bool found = false; 1232 1233 ID3::Iterator it(id3, "PRIV"); 1234 while (!it.done()) { 1235 size_t length; 1236 const uint8_t *data = it.getData(&length); 1237 1238 static const char *kMatchName = 1239 "com.apple.streaming.transportStreamTimestamp"; 1240 static const size_t kMatchNameLen = strlen(kMatchName); 1241 1242 if (length == kMatchNameLen + 1 + 8 1243 && !strncmp((const char *)data, kMatchName, kMatchNameLen)) { 1244 found = true; 1245 PTS = U64_AT(&data[kMatchNameLen + 1]); 1246 } 1247 1248 it.next(); 1249 } 1250 1251 if (!found) { 1252 ALOGE("Unable to extract transportStreamTimestamp from ID3 tag."); 1253 return ERROR_MALFORMED; 1254 } 1255 } 1256 1257 // skip the ID3 tag 1258 buffer->setRange( 1259 buffer->offset() + id3.rawSize(), buffer->size() - id3.rawSize()); 1260 1261 firstID3Tag = false; 1262 } 1263 1264 if (!mFirstPTSValid) { 1265 mFirstPTSValid = true; 1266 mFirstPTS = PTS; 1267 } 1268 PTS -= mFirstPTS; 1269 1270 int64_t timeUs = (PTS * 100ll) / 9ll + mAbsoluteTimeAnchorUs; 1271 1272 if (mStreamTypeMask != LiveSession::STREAMTYPE_AUDIO) { 1273 ALOGW("This stream only contains audio data!"); 1274 1275 mStreamTypeMask &= LiveSession::STREAMTYPE_AUDIO; 1276 1277 if (mStreamTypeMask == 0) { 1278 return OK; 1279 } 1280 } 1281 1282 sp<AnotherPacketSource> packetSource = 1283 mPacketSources.valueFor(LiveSession::STREAMTYPE_AUDIO); 1284 1285 if (packetSource->getFormat() == NULL && buffer->size() >= 7) { 1286 ABitReader bits(buffer->data(), buffer->size()); 1287 1288 // adts_fixed_header 1289 1290 CHECK_EQ(bits.getBits(12), 0xfffu); 1291 bits.skipBits(3); // ID, layer 1292 bool protection_absent = bits.getBits(1) != 0; 1293 1294 unsigned profile = bits.getBits(2); 1295 CHECK_NE(profile, 3u); 1296 unsigned sampling_freq_index = bits.getBits(4); 1297 bits.getBits(1); // private_bit 1298 unsigned channel_configuration = bits.getBits(3); 1299 CHECK_NE(channel_configuration, 0u); 1300 bits.skipBits(2); // original_copy, home 1301 1302 sp<MetaData> meta = MakeAACCodecSpecificData( 1303 profile, sampling_freq_index, channel_configuration); 1304 1305 meta->setInt32(kKeyIsADTS, true); 1306 1307 packetSource->setFormat(meta); 1308 } 1309 1310 int64_t numSamples = 0ll; 1311 int32_t sampleRate; 1312 CHECK(packetSource->getFormat()->findInt32(kKeySampleRate, &sampleRate)); 1313 1314 size_t offset = 0; 1315 while (offset < buffer->size()) { 1316 const uint8_t *adtsHeader = buffer->data() + offset; 1317 CHECK_LT(offset + 5, buffer->size()); 1318 1319 unsigned aac_frame_length = 1320 ((adtsHeader[3] & 3) << 11) 1321 | (adtsHeader[4] << 3) 1322 | (adtsHeader[5] >> 5); 1323 1324 if (aac_frame_length == 0) { 1325 const uint8_t *id3Header = adtsHeader; 1326 if (!memcmp(id3Header, "ID3", 3)) { 1327 ID3 id3(id3Header, buffer->size() - offset, true); 1328 if (id3.isValid()) { 1329 offset += id3.rawSize(); 1330 continue; 1331 }; 1332 } 1333 return ERROR_MALFORMED; 1334 } 1335 1336 CHECK_LE(offset + aac_frame_length, buffer->size()); 1337 1338 sp<ABuffer> unit = new ABuffer(aac_frame_length); 1339 memcpy(unit->data(), adtsHeader, aac_frame_length); 1340 1341 int64_t unitTimeUs = timeUs + numSamples * 1000000ll / sampleRate; 1342 unit->meta()->setInt64("timeUs", unitTimeUs); 1343 1344 // Each AAC frame encodes 1024 samples. 1345 numSamples += 1024; 1346 1347 unit->meta()->setInt32("seq", mSeqNumber); 1348 packetSource->queueAccessUnit(unit); 1349 1350 offset += aac_frame_length; 1351 } 1352 1353 return OK; 1354 } 1355 1356 void PlaylistFetcher::updateDuration() { 1357 int64_t durationUs = 0ll; 1358 for (size_t index = 0; index < mPlaylist->size(); ++index) { 1359 sp<AMessage> itemMeta; 1360 CHECK(mPlaylist->itemAt( 1361 index, NULL /* uri */, &itemMeta)); 1362 1363 int64_t itemDurationUs; 1364 CHECK(itemMeta->findInt64("durationUs", &itemDurationUs)); 1365 1366 durationUs += itemDurationUs; 1367 } 1368 1369 sp<AMessage> msg = mNotify->dup(); 1370 msg->setInt32("what", kWhatDurationUpdate); 1371 msg->setInt64("durationUs", durationUs); 1372 msg->post(); 1373 } 1374 1375 int64_t PlaylistFetcher::resumeThreshold(const sp<AMessage> &msg) { 1376 int64_t durationUs, threshold; 1377 if (msg->findInt64("durationUs", &durationUs)) { 1378 return kNumSkipFrames * durationUs; 1379 } 1380 1381 sp<RefBase> obj; 1382 msg->findObject("format", &obj); 1383 MetaData *format = static_cast<MetaData *>(obj.get()); 1384 1385 const char *mime; 1386 CHECK(format->findCString(kKeyMIMEType, &mime)); 1387 bool audio = !strncasecmp(mime, "audio/", 6); 1388 if (audio) { 1389 // Assumes 1000 samples per frame. 1390 int32_t sampleRate; 1391 CHECK(format->findInt32(kKeySampleRate, &sampleRate)); 1392 return kNumSkipFrames /* frames */ * 1000 /* samples */ 1393 * (1000000 / sampleRate) /* sample duration (us) */; 1394 } else { 1395 int32_t frameRate; 1396 if (format->findInt32(kKeyFrameRate, &frameRate) && frameRate > 0) { 1397 return kNumSkipFrames * (1000000 / frameRate); 1398 } 1399 } 1400 1401 return 500000ll; 1402 } 1403 1404 } // namespace android 1405