PlaylistFetcher.cpp revision 632740c58119a132ce19f6d498e39c5c3773971a
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 // do not discard buffer upon #EXT-X-DISCONTINUITY tag 592 // (seek will discard buffer by abandoning old fetchers) 593 mPacketSources.valueAt(i)->queueDiscontinuity( 594 type, extra, false /* discard */); 595 } 596} 597 598void PlaylistFetcher::onMonitorQueue() { 599 bool downloadMore = false; 600 refreshPlaylist(); 601 602 int32_t targetDurationSecs; 603 int64_t targetDurationUs = kMinBufferedDurationUs; 604 if (mPlaylist != NULL) { 605 CHECK(mPlaylist->meta()->findInt32("target-duration", &targetDurationSecs)); 606 targetDurationUs = targetDurationSecs * 1000000ll; 607 } 608 609 // buffer at least 3 times the target duration, or up to 10 seconds 610 int64_t durationToBufferUs = targetDurationUs * 3; 611 if (durationToBufferUs > kMinBufferedDurationUs) { 612 durationToBufferUs = kMinBufferedDurationUs; 613 } 614 615 int64_t bufferedDurationUs = 0ll; 616 status_t finalResult = NOT_ENOUGH_DATA; 617 if (mStreamTypeMask == LiveSession::STREAMTYPE_SUBTITLES) { 618 sp<AnotherPacketSource> packetSource = 619 mPacketSources.valueFor(LiveSession::STREAMTYPE_SUBTITLES); 620 621 bufferedDurationUs = 622 packetSource->getBufferedDurationUs(&finalResult); 623 finalResult = OK; 624 } else { 625 // Use max stream duration to prevent us from waiting on a non-existent stream; 626 // when we cannot make out from the manifest what streams are included in a playlist 627 // we might assume extra streams. 628 for (size_t i = 0; i < mPacketSources.size(); ++i) { 629 if ((mStreamTypeMask & mPacketSources.keyAt(i)) == 0) { 630 continue; 631 } 632 633 int64_t bufferedStreamDurationUs = 634 mPacketSources.valueAt(i)->getBufferedDurationUs(&finalResult); 635 ALOGV("buffered %" PRId64 " for stream %d", 636 bufferedStreamDurationUs, mPacketSources.keyAt(i)); 637 if (bufferedStreamDurationUs > bufferedDurationUs) { 638 bufferedDurationUs = bufferedStreamDurationUs; 639 } 640 } 641 } 642 downloadMore = (bufferedDurationUs < durationToBufferUs); 643 644 // signal start if buffered up at least the target size 645 if (!mPrepared && bufferedDurationUs > targetDurationUs && downloadMore) { 646 mPrepared = true; 647 648 ALOGV("prepared, buffered=%" PRId64 " > %" PRId64 "", 649 bufferedDurationUs, targetDurationUs); 650 sp<AMessage> msg = mNotify->dup(); 651 msg->setInt32("what", kWhatTemporarilyDoneFetching); 652 msg->post(); 653 } 654 655 if (finalResult == OK && downloadMore) { 656 ALOGV("monitoring, buffered=%" PRId64 " < %" PRId64 "", 657 bufferedDurationUs, durationToBufferUs); 658 // delay the next download slightly; hopefully this gives other concurrent fetchers 659 // a better chance to run. 660 // onDownloadNext(); 661 sp<AMessage> msg = new AMessage(kWhatDownloadNext, id()); 662 msg->setInt32("generation", mMonitorQueueGeneration); 663 msg->post(1000l); 664 } else { 665 // Nothing to do yet, try again in a second. 666 667 sp<AMessage> msg = mNotify->dup(); 668 msg->setInt32("what", kWhatTemporarilyDoneFetching); 669 msg->post(); 670 671 int64_t delayUs = mPrepared ? kMaxMonitorDelayUs : targetDurationUs / 2; 672 ALOGV("pausing for %" PRId64 ", buffered=%" PRId64 " > %" PRId64 "", 673 delayUs, bufferedDurationUs, durationToBufferUs); 674 // :TRICKY: need to enforce minimum delay because the delay to 675 // refresh the playlist will become 0 676 postMonitorQueue(delayUs, mPrepared ? targetDurationUs * 2 : 0); 677 } 678} 679 680status_t PlaylistFetcher::refreshPlaylist() { 681 if (delayUsToRefreshPlaylist() <= 0) { 682 bool unchanged; 683 sp<M3UParser> playlist = mSession->fetchPlaylist( 684 mURI.c_str(), mPlaylistHash, &unchanged); 685 686 if (playlist == NULL) { 687 if (unchanged) { 688 // We succeeded in fetching the playlist, but it was 689 // unchanged from the last time we tried. 690 691 if (mRefreshState != THIRD_UNCHANGED_RELOAD_ATTEMPT) { 692 mRefreshState = (RefreshState)(mRefreshState + 1); 693 } 694 } else { 695 ALOGE("failed to load playlist at url '%s'", mURI.c_str()); 696 notifyError(ERROR_IO); 697 return ERROR_IO; 698 } 699 } else { 700 mRefreshState = INITIAL_MINIMUM_RELOAD_DELAY; 701 mPlaylist = playlist; 702 703 if (mPlaylist->isComplete() || mPlaylist->isEvent()) { 704 updateDuration(); 705 } 706 } 707 708 mLastPlaylistFetchTimeUs = ALooper::GetNowUs(); 709 } 710 return OK; 711} 712 713// static 714bool PlaylistFetcher::bufferStartsWithTsSyncByte(const sp<ABuffer>& buffer) { 715 return buffer->size() > 0 && buffer->data()[0] == 0x47; 716} 717 718void PlaylistFetcher::onDownloadNext() { 719 if (refreshPlaylist() != OK) { 720 return; 721 } 722 723 int32_t firstSeqNumberInPlaylist; 724 if (mPlaylist->meta() == NULL || !mPlaylist->meta()->findInt32( 725 "media-sequence", &firstSeqNumberInPlaylist)) { 726 firstSeqNumberInPlaylist = 0; 727 } 728 729 bool discontinuity = false; 730 731 const int32_t lastSeqNumberInPlaylist = 732 firstSeqNumberInPlaylist + (int32_t)mPlaylist->size() - 1; 733 734 if (mStartup && mSeqNumber >= 0 735 && (mSeqNumber < firstSeqNumberInPlaylist || mSeqNumber > lastSeqNumberInPlaylist)) { 736 // in case we guessed wrong during reconfiguration, try fetching the latest content. 737 mSeqNumber = lastSeqNumberInPlaylist; 738 } 739 740 if (mSeqNumber < 0) { 741 CHECK_GE(mStartTimeUs, 0ll); 742 743 if (mPlaylist->isComplete() || mPlaylist->isEvent()) { 744 mSeqNumber = getSeqNumberForTime(mStartTimeUs); 745 ALOGV("Initial sequence number for time %" PRId64 " is %d from (%d .. %d)", 746 mStartTimeUs, mSeqNumber, firstSeqNumberInPlaylist, 747 lastSeqNumberInPlaylist); 748 } else { 749 // If this is a live session, start 3 segments from the end. 750 mSeqNumber = lastSeqNumberInPlaylist - 3; 751 if (mSeqNumber < firstSeqNumberInPlaylist) { 752 mSeqNumber = firstSeqNumberInPlaylist; 753 } 754 ALOGV("Initial sequence number for live event %d from (%d .. %d)", 755 mSeqNumber, firstSeqNumberInPlaylist, 756 lastSeqNumberInPlaylist); 757 } 758 759 mStartTimeUs = -1ll; 760 } 761 762 if (mSeqNumber < firstSeqNumberInPlaylist 763 || mSeqNumber > lastSeqNumberInPlaylist) { 764 if (!mPlaylist->isComplete() && mNumRetries < kMaxNumRetries) { 765 ++mNumRetries; 766 767 if (mSeqNumber > lastSeqNumberInPlaylist) { 768 // refresh in increasing fraction (1/2, 1/3, ...) of the 769 // playlist's target duration or 3 seconds, whichever is less 770 int32_t targetDurationSecs; 771 CHECK(mPlaylist->meta()->findInt32( 772 "target-duration", &targetDurationSecs)); 773 int64_t delayUs = mPlaylist->size() * targetDurationSecs * 774 1000000ll / (1 + mNumRetries); 775 if (delayUs > kMaxMonitorDelayUs) { 776 delayUs = kMaxMonitorDelayUs; 777 } 778 ALOGV("sequence number high: %d from (%d .. %d), " 779 "monitor in %" PRId64 " (retry=%d)", 780 mSeqNumber, firstSeqNumberInPlaylist, 781 lastSeqNumberInPlaylist, delayUs, mNumRetries); 782 postMonitorQueue(delayUs); 783 return; 784 } 785 786 // we've missed the boat, let's start from the lowest sequence 787 // number available and signal a discontinuity. 788 789 ALOGI("We've missed the boat, restarting playback." 790 " mStartup=%d, was looking for %d in %d-%d", 791 mStartup, mSeqNumber, firstSeqNumberInPlaylist, 792 lastSeqNumberInPlaylist); 793 mSeqNumber = lastSeqNumberInPlaylist - 3; 794 if (mSeqNumber < firstSeqNumberInPlaylist) { 795 mSeqNumber = firstSeqNumberInPlaylist; 796 } 797 discontinuity = true; 798 799 // fall through 800 } else { 801 ALOGE("Cannot find sequence number %d in playlist " 802 "(contains %d - %d)", 803 mSeqNumber, firstSeqNumberInPlaylist, 804 firstSeqNumberInPlaylist + (int32_t)mPlaylist->size() - 1); 805 806 notifyError(ERROR_END_OF_STREAM); 807 return; 808 } 809 } 810 811 mNumRetries = 0; 812 813 AString uri; 814 sp<AMessage> itemMeta; 815 CHECK(mPlaylist->itemAt( 816 mSeqNumber - firstSeqNumberInPlaylist, 817 &uri, 818 &itemMeta)); 819 820 int32_t val; 821 if (itemMeta->findInt32("discontinuity", &val) && val != 0) { 822 discontinuity = true; 823 } 824 825 int64_t range_offset, range_length; 826 if (!itemMeta->findInt64("range-offset", &range_offset) 827 || !itemMeta->findInt64("range-length", &range_length)) { 828 range_offset = 0; 829 range_length = -1; 830 } 831 832 ALOGV("fetching segment %d from (%d .. %d)", 833 mSeqNumber, firstSeqNumberInPlaylist, lastSeqNumberInPlaylist); 834 835 ALOGV("fetching '%s'", uri.c_str()); 836 837 sp<DataSource> source; 838 sp<ABuffer> buffer, tsBuffer; 839 // decrypt a junk buffer to prefetch key; since a session uses only one http connection, 840 // this avoids interleaved connections to the key and segment file. 841 { 842 sp<ABuffer> junk = new ABuffer(16); 843 junk->setRange(0, 16); 844 status_t err = decryptBuffer(mSeqNumber - firstSeqNumberInPlaylist, junk, 845 true /* first */); 846 if (err != OK) { 847 notifyError(err); 848 return; 849 } 850 } 851 852 // block-wise download 853 ssize_t bytesRead; 854 do { 855 bytesRead = mSession->fetchFile( 856 uri.c_str(), &buffer, range_offset, range_length, kDownloadBlockSize, &source); 857 858 if (bytesRead < 0) { 859 status_t err = bytesRead; 860 ALOGE("failed to fetch .ts segment at url '%s'", uri.c_str()); 861 notifyError(err); 862 return; 863 } 864 865 CHECK(buffer != NULL); 866 867 size_t size = buffer->size(); 868 // Set decryption range. 869 buffer->setRange(size - bytesRead, bytesRead); 870 status_t err = decryptBuffer(mSeqNumber - firstSeqNumberInPlaylist, buffer, 871 buffer->offset() == 0 /* first */); 872 // Unset decryption range. 873 buffer->setRange(0, size); 874 875 if (err != OK) { 876 ALOGE("decryptBuffer failed w/ error %d", err); 877 878 notifyError(err); 879 return; 880 } 881 882 if (mStartup || discontinuity) { 883 // Signal discontinuity. 884 885 if (mPlaylist->isComplete() || mPlaylist->isEvent()) { 886 // If this was a live event this made no sense since 887 // we don't have access to all the segment before the current 888 // one. 889 mNextPTSTimeUs = getSegmentStartTimeUs(mSeqNumber); 890 } 891 892 if (discontinuity) { 893 ALOGI("queueing discontinuity (explicit=%d)", discontinuity); 894 895 queueDiscontinuity( 896 ATSParser::DISCONTINUITY_FORMATCHANGE, 897 NULL /* extra */); 898 899 discontinuity = false; 900 } 901 } 902 903 err = OK; 904 if (bufferStartsWithTsSyncByte(buffer)) { 905 // Incremental extraction is only supported for MPEG2 transport streams. 906 if (tsBuffer == NULL) { 907 tsBuffer = new ABuffer(buffer->data(), buffer->capacity()); 908 tsBuffer->setRange(0, 0); 909 } else if (tsBuffer->capacity() != buffer->capacity()) { 910 size_t tsOff = tsBuffer->offset(), tsSize = tsBuffer->size(); 911 tsBuffer = new ABuffer(buffer->data(), buffer->capacity()); 912 tsBuffer->setRange(tsOff, tsSize); 913 } 914 tsBuffer->setRange(tsBuffer->offset(), tsBuffer->size() + bytesRead); 915 916 err = extractAndQueueAccessUnitsFromTs(tsBuffer); 917 } 918 919 if (err == -EAGAIN) { 920 // bad starting sequence number hint 921 mTSParser.clear(); 922 postMonitorQueue(); 923 return; 924 } 925 926 if (err == ERROR_OUT_OF_RANGE) { 927 // reached stopping point 928 stopAsync(/* selfTriggered = */ true); 929 return; 930 } 931 932 if (err != OK) { 933 notifyError(err); 934 return; 935 } 936 937 mStartup = false; 938 } while (bytesRead != 0); 939 940 if (bufferStartsWithTsSyncByte(buffer)) { 941 // If we still don't see a stream after fetching a full ts segment mark it as 942 // nonexistent. 943 const size_t kNumTypes = ATSParser::NUM_SOURCE_TYPES; 944 ATSParser::SourceType srcTypes[kNumTypes] = 945 { ATSParser::VIDEO, ATSParser::AUDIO }; 946 LiveSession::StreamType streamTypes[kNumTypes] = 947 { LiveSession::STREAMTYPE_VIDEO, LiveSession::STREAMTYPE_AUDIO }; 948 949 for (size_t i = 0; i < kNumTypes; i++) { 950 ATSParser::SourceType srcType = srcTypes[i]; 951 LiveSession::StreamType streamType = streamTypes[i]; 952 953 sp<AnotherPacketSource> source = 954 static_cast<AnotherPacketSource *>( 955 mTSParser->getSource(srcType).get()); 956 957 if (source == NULL) { 958 ALOGW("MPEG2 Transport stream does not contain %s data.", 959 srcType == ATSParser::VIDEO ? "video" : "audio"); 960 961 mStreamTypeMask &= ~streamType; 962 mPacketSources.removeItem(streamType); 963 } 964 } 965 966 } 967 968 if (checkDecryptPadding(buffer) != OK) { 969 ALOGE("Incorrect padding bytes after decryption."); 970 notifyError(ERROR_MALFORMED); 971 return; 972 } 973 974 status_t err = OK; 975 if (tsBuffer != NULL) { 976 AString method; 977 CHECK(buffer->meta()->findString("cipher-method", &method)); 978 if ((tsBuffer->size() > 0 && method == "NONE") 979 || tsBuffer->size() > 16) { 980 ALOGE("MPEG2 transport stream is not an even multiple of 188 " 981 "bytes in length."); 982 notifyError(ERROR_MALFORMED); 983 return; 984 } 985 } 986 987 // bulk extract non-ts files 988 if (tsBuffer == NULL) { 989 err = extractAndQueueAccessUnits(buffer, itemMeta); 990 } 991 992 if (err != OK) { 993 notifyError(err); 994 return; 995 } 996 997 ++mSeqNumber; 998 999 postMonitorQueue(); 1000} 1001 1002int32_t PlaylistFetcher::getSeqNumberForTime(int64_t timeUs) const { 1003 int32_t firstSeqNumberInPlaylist; 1004 if (mPlaylist->meta() == NULL || !mPlaylist->meta()->findInt32( 1005 "media-sequence", &firstSeqNumberInPlaylist)) { 1006 firstSeqNumberInPlaylist = 0; 1007 } 1008 1009 size_t index = 0; 1010 int64_t segmentStartUs = 0; 1011 while (index < mPlaylist->size()) { 1012 sp<AMessage> itemMeta; 1013 CHECK(mPlaylist->itemAt( 1014 index, NULL /* uri */, &itemMeta)); 1015 1016 int64_t itemDurationUs; 1017 CHECK(itemMeta->findInt64("durationUs", &itemDurationUs)); 1018 1019 if (timeUs < segmentStartUs + itemDurationUs) { 1020 break; 1021 } 1022 1023 segmentStartUs += itemDurationUs; 1024 ++index; 1025 } 1026 1027 if (index >= mPlaylist->size()) { 1028 index = mPlaylist->size() - 1; 1029 } 1030 1031 return firstSeqNumberInPlaylist + index; 1032} 1033 1034status_t PlaylistFetcher::extractAndQueueAccessUnitsFromTs(const sp<ABuffer> &buffer) { 1035 if (mTSParser == NULL) { 1036 // Use TS_TIMESTAMPS_ARE_ABSOLUTE so pts carry over between fetchers. 1037 mTSParser = new ATSParser(ATSParser::TS_TIMESTAMPS_ARE_ABSOLUTE); 1038 } 1039 1040 if (mNextPTSTimeUs >= 0ll) { 1041 sp<AMessage> extra = new AMessage; 1042 // Since we are using absolute timestamps, signal an offset of 0 to prevent 1043 // ATSParser from skewing the timestamps of access units. 1044 extra->setInt64(IStreamListener::kKeyMediaTimeUs, 0); 1045 1046 mTSParser->signalDiscontinuity( 1047 ATSParser::DISCONTINUITY_SEEK, extra); 1048 1049 mNextPTSTimeUs = -1ll; 1050 } 1051 1052 size_t offset = 0; 1053 while (offset + 188 <= buffer->size()) { 1054 status_t err = mTSParser->feedTSPacket(buffer->data() + offset, 188); 1055 1056 if (err != OK) { 1057 return err; 1058 } 1059 1060 offset += 188; 1061 } 1062 // setRange to indicate consumed bytes. 1063 buffer->setRange(buffer->offset() + offset, buffer->size() - offset); 1064 1065 status_t err = OK; 1066 for (size_t i = mPacketSources.size(); i-- > 0;) { 1067 sp<AnotherPacketSource> packetSource = mPacketSources.valueAt(i); 1068 1069 const char *key; 1070 ATSParser::SourceType type; 1071 const LiveSession::StreamType stream = mPacketSources.keyAt(i); 1072 switch (stream) { 1073 case LiveSession::STREAMTYPE_VIDEO: 1074 type = ATSParser::VIDEO; 1075 key = "timeUsVideo"; 1076 break; 1077 1078 case LiveSession::STREAMTYPE_AUDIO: 1079 type = ATSParser::AUDIO; 1080 key = "timeUsAudio"; 1081 break; 1082 1083 case LiveSession::STREAMTYPE_SUBTITLES: 1084 { 1085 ALOGE("MPEG2 Transport streams do not contain subtitles."); 1086 return ERROR_MALFORMED; 1087 break; 1088 } 1089 1090 default: 1091 TRESPASS(); 1092 } 1093 1094 sp<AnotherPacketSource> source = 1095 static_cast<AnotherPacketSource *>( 1096 mTSParser->getSource(type).get()); 1097 1098 if (source == NULL) { 1099 continue; 1100 } 1101 1102 if (stream == LiveSession::STREAMTYPE_VIDEO && mVideoMime.empty()) { 1103 const char *mime; 1104 if (source->getFormat()->findCString(kKeyMIMEType, &mime)) { 1105 mVideoMime.setTo(mime); 1106 if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 1107 mSkipToFirstIDRAfterConnect = true; 1108 } 1109 } 1110 } 1111 1112 int64_t timeUs; 1113 sp<ABuffer> accessUnit; 1114 status_t finalResult; 1115 while (source->hasBufferAvailable(&finalResult) 1116 && source->dequeueAccessUnit(&accessUnit) == OK) { 1117 1118 if (stream == LiveSession::STREAMTYPE_VIDEO && mSkipToFirstIDRAfterConnect) { 1119 if (!IsIDR(accessUnit)) { 1120 continue; 1121 } else { 1122 mSkipToFirstIDRAfterConnect = false; 1123 } 1124 } 1125 1126 CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs)); 1127 if (mMinStartTimeUs > 0) { 1128 if (timeUs < mMinStartTimeUs) { 1129 // TODO untested path 1130 // try a later ts 1131 int32_t targetDuration; 1132 mPlaylist->meta()->findInt32("target-duration", &targetDuration); 1133 int32_t incr = (mMinStartTimeUs - timeUs) / 1000000 / targetDuration; 1134 if (incr == 0) { 1135 // increment mSeqNumber by at least one 1136 incr = 1; 1137 } 1138 mSeqNumber += incr; 1139 err = -EAGAIN; 1140 break; 1141 } else { 1142 int64_t startTimeUs; 1143 if (mStartTimeUsNotify != NULL 1144 && !mStartTimeUsNotify->findInt64(key, &startTimeUs)) { 1145 mStartTimeUsNotify->setInt64(key, timeUs); 1146 1147 uint32_t streamMask = 0; 1148 mStartTimeUsNotify->findInt32("streamMask", (int32_t *) &streamMask); 1149 streamMask |= mPacketSources.keyAt(i); 1150 mStartTimeUsNotify->setInt32("streamMask", streamMask); 1151 1152 if (streamMask == mStreamTypeMask) { 1153 mStartTimeUsNotify->post(); 1154 mStartTimeUsNotify.clear(); 1155 } 1156 } 1157 } 1158 } 1159 1160 if (mStopParams != NULL) { 1161 // Queue discontinuity in original stream. 1162 int64_t stopTimeUs; 1163 if (!mStopParams->findInt64(key, &stopTimeUs) || timeUs >= stopTimeUs) { 1164 packetSource->queueAccessUnit(mSession->createFormatChangeBuffer()); 1165 mStreamTypeMask &= ~stream; 1166 mPacketSources.removeItemsAt(i); 1167 break; 1168 } 1169 } 1170 1171 // Note that we do NOT dequeue any discontinuities except for format change. 1172 1173 // for simplicity, store a reference to the format in each unit 1174 sp<MetaData> format = source->getFormat(); 1175 if (format != NULL) { 1176 accessUnit->meta()->setObject("format", format); 1177 } 1178 1179 // Stash the sequence number so we can hint future playlist where to start at. 1180 accessUnit->meta()->setInt32("seq", mSeqNumber); 1181 packetSource->queueAccessUnit(accessUnit); 1182 } 1183 1184 if (err != OK) { 1185 break; 1186 } 1187 } 1188 1189 if (err != OK) { 1190 for (size_t i = mPacketSources.size(); i-- > 0;) { 1191 sp<AnotherPacketSource> packetSource = mPacketSources.valueAt(i); 1192 packetSource->clear(); 1193 } 1194 return err; 1195 } 1196 1197 if (!mStreamTypeMask) { 1198 // Signal gap is filled between original and new stream. 1199 ALOGV("ERROR OUT OF RANGE"); 1200 return ERROR_OUT_OF_RANGE; 1201 } 1202 1203 return OK; 1204} 1205 1206/* static */ 1207bool PlaylistFetcher::bufferStartsWithWebVTTMagicSequence( 1208 const sp<ABuffer> &buffer) { 1209 size_t pos = 0; 1210 1211 // skip possible BOM 1212 if (buffer->size() >= pos + 3 && 1213 !memcmp("\xef\xbb\xbf", buffer->data() + pos, 3)) { 1214 pos += 3; 1215 } 1216 1217 // accept WEBVTT followed by SPACE, TAB or (CR) LF 1218 if (buffer->size() < pos + 6 || 1219 memcmp("WEBVTT", buffer->data() + pos, 6)) { 1220 return false; 1221 } 1222 pos += 6; 1223 1224 if (buffer->size() == pos) { 1225 return true; 1226 } 1227 1228 uint8_t sep = buffer->data()[pos]; 1229 return sep == ' ' || sep == '\t' || sep == '\n' || sep == '\r'; 1230} 1231 1232status_t PlaylistFetcher::extractAndQueueAccessUnits( 1233 const sp<ABuffer> &buffer, const sp<AMessage> &itemMeta) { 1234 if (bufferStartsWithWebVTTMagicSequence(buffer)) { 1235 if (mStreamTypeMask != LiveSession::STREAMTYPE_SUBTITLES) { 1236 ALOGE("This stream only contains subtitles."); 1237 return ERROR_MALFORMED; 1238 } 1239 1240 const sp<AnotherPacketSource> packetSource = 1241 mPacketSources.valueFor(LiveSession::STREAMTYPE_SUBTITLES); 1242 1243 int64_t durationUs; 1244 CHECK(itemMeta->findInt64("durationUs", &durationUs)); 1245 buffer->meta()->setInt64("timeUs", getSegmentStartTimeUs(mSeqNumber)); 1246 buffer->meta()->setInt64("durationUs", durationUs); 1247 buffer->meta()->setInt32("seq", mSeqNumber); 1248 1249 packetSource->queueAccessUnit(buffer); 1250 return OK; 1251 } 1252 1253 if (mNextPTSTimeUs >= 0ll) { 1254 mFirstPTSValid = false; 1255 mAbsoluteTimeAnchorUs = mNextPTSTimeUs; 1256 mNextPTSTimeUs = -1ll; 1257 } 1258 1259 // This better be an ISO 13818-7 (AAC) or ISO 13818-1 (MPEG) audio 1260 // stream prefixed by an ID3 tag. 1261 1262 bool firstID3Tag = true; 1263 uint64_t PTS = 0; 1264 1265 for (;;) { 1266 // Make sure to skip all ID3 tags preceding the audio data. 1267 // At least one must be present to provide the PTS timestamp. 1268 1269 ID3 id3(buffer->data(), buffer->size(), true /* ignoreV1 */); 1270 if (!id3.isValid()) { 1271 if (firstID3Tag) { 1272 ALOGE("Unable to parse ID3 tag."); 1273 return ERROR_MALFORMED; 1274 } else { 1275 break; 1276 } 1277 } 1278 1279 if (firstID3Tag) { 1280 bool found = false; 1281 1282 ID3::Iterator it(id3, "PRIV"); 1283 while (!it.done()) { 1284 size_t length; 1285 const uint8_t *data = it.getData(&length); 1286 1287 static const char *kMatchName = 1288 "com.apple.streaming.transportStreamTimestamp"; 1289 static const size_t kMatchNameLen = strlen(kMatchName); 1290 1291 if (length == kMatchNameLen + 1 + 8 1292 && !strncmp((const char *)data, kMatchName, kMatchNameLen)) { 1293 found = true; 1294 PTS = U64_AT(&data[kMatchNameLen + 1]); 1295 } 1296 1297 it.next(); 1298 } 1299 1300 if (!found) { 1301 ALOGE("Unable to extract transportStreamTimestamp from ID3 tag."); 1302 return ERROR_MALFORMED; 1303 } 1304 } 1305 1306 // skip the ID3 tag 1307 buffer->setRange( 1308 buffer->offset() + id3.rawSize(), buffer->size() - id3.rawSize()); 1309 1310 firstID3Tag = false; 1311 } 1312 1313 if (!mFirstPTSValid) { 1314 mFirstPTSValid = true; 1315 mFirstPTS = PTS; 1316 } 1317 PTS -= mFirstPTS; 1318 1319 int64_t timeUs = (PTS * 100ll) / 9ll + mAbsoluteTimeAnchorUs; 1320 1321 if (mStreamTypeMask != LiveSession::STREAMTYPE_AUDIO) { 1322 ALOGW("This stream only contains audio data!"); 1323 1324 mStreamTypeMask &= LiveSession::STREAMTYPE_AUDIO; 1325 1326 if (mStreamTypeMask == 0) { 1327 return OK; 1328 } 1329 } 1330 1331 sp<AnotherPacketSource> packetSource = 1332 mPacketSources.valueFor(LiveSession::STREAMTYPE_AUDIO); 1333 1334 if (packetSource->getFormat() == NULL && buffer->size() >= 7) { 1335 ABitReader bits(buffer->data(), buffer->size()); 1336 1337 // adts_fixed_header 1338 1339 CHECK_EQ(bits.getBits(12), 0xfffu); 1340 bits.skipBits(3); // ID, layer 1341 bool protection_absent = bits.getBits(1) != 0; 1342 1343 unsigned profile = bits.getBits(2); 1344 CHECK_NE(profile, 3u); 1345 unsigned sampling_freq_index = bits.getBits(4); 1346 bits.getBits(1); // private_bit 1347 unsigned channel_configuration = bits.getBits(3); 1348 CHECK_NE(channel_configuration, 0u); 1349 bits.skipBits(2); // original_copy, home 1350 1351 sp<MetaData> meta = MakeAACCodecSpecificData( 1352 profile, sampling_freq_index, channel_configuration); 1353 1354 meta->setInt32(kKeyIsADTS, true); 1355 1356 packetSource->setFormat(meta); 1357 } 1358 1359 int64_t numSamples = 0ll; 1360 int32_t sampleRate; 1361 CHECK(packetSource->getFormat()->findInt32(kKeySampleRate, &sampleRate)); 1362 1363 size_t offset = 0; 1364 while (offset < buffer->size()) { 1365 const uint8_t *adtsHeader = buffer->data() + offset; 1366 CHECK_LT(offset + 5, buffer->size()); 1367 1368 unsigned aac_frame_length = 1369 ((adtsHeader[3] & 3) << 11) 1370 | (adtsHeader[4] << 3) 1371 | (adtsHeader[5] >> 5); 1372 1373 if (aac_frame_length == 0) { 1374 const uint8_t *id3Header = adtsHeader; 1375 if (!memcmp(id3Header, "ID3", 3)) { 1376 ID3 id3(id3Header, buffer->size() - offset, true); 1377 if (id3.isValid()) { 1378 offset += id3.rawSize(); 1379 continue; 1380 }; 1381 } 1382 return ERROR_MALFORMED; 1383 } 1384 1385 CHECK_LE(offset + aac_frame_length, buffer->size()); 1386 1387 sp<ABuffer> unit = new ABuffer(aac_frame_length); 1388 memcpy(unit->data(), adtsHeader, aac_frame_length); 1389 1390 int64_t unitTimeUs = timeUs + numSamples * 1000000ll / sampleRate; 1391 unit->meta()->setInt64("timeUs", unitTimeUs); 1392 1393 // Each AAC frame encodes 1024 samples. 1394 numSamples += 1024; 1395 1396 unit->meta()->setInt32("seq", mSeqNumber); 1397 packetSource->queueAccessUnit(unit); 1398 1399 offset += aac_frame_length; 1400 } 1401 1402 return OK; 1403} 1404 1405void PlaylistFetcher::updateDuration() { 1406 int64_t durationUs = 0ll; 1407 for (size_t index = 0; index < mPlaylist->size(); ++index) { 1408 sp<AMessage> itemMeta; 1409 CHECK(mPlaylist->itemAt( 1410 index, NULL /* uri */, &itemMeta)); 1411 1412 int64_t itemDurationUs; 1413 CHECK(itemMeta->findInt64("durationUs", &itemDurationUs)); 1414 1415 durationUs += itemDurationUs; 1416 } 1417 1418 sp<AMessage> msg = mNotify->dup(); 1419 msg->setInt32("what", kWhatDurationUpdate); 1420 msg->setInt64("durationUs", durationUs); 1421 msg->post(); 1422} 1423 1424int64_t PlaylistFetcher::resumeThreshold(const sp<AMessage> &msg) { 1425 int64_t durationUs, threshold; 1426 if (msg->findInt64("durationUs", &durationUs)) { 1427 return kNumSkipFrames * durationUs; 1428 } 1429 1430 sp<RefBase> obj; 1431 msg->findObject("format", &obj); 1432 MetaData *format = static_cast<MetaData *>(obj.get()); 1433 1434 const char *mime; 1435 CHECK(format->findCString(kKeyMIMEType, &mime)); 1436 bool audio = !strncasecmp(mime, "audio/", 6); 1437 if (audio) { 1438 // Assumes 1000 samples per frame. 1439 int32_t sampleRate; 1440 CHECK(format->findInt32(kKeySampleRate, &sampleRate)); 1441 return kNumSkipFrames /* frames */ * 1000 /* samples */ 1442 * (1000000 / sampleRate) /* sample duration (us) */; 1443 } else { 1444 int32_t frameRate; 1445 if (format->findInt32(kKeyFrameRate, &frameRate) && frameRate > 0) { 1446 return kNumSkipFrames * (1000000 / frameRate); 1447 } 1448 } 1449 1450 return 500000ll; 1451} 1452 1453} // namespace android 1454