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