android_AudioSfDecoder.cpp revision 13d02b645fc6e8ffe70a8bf8cc5f69f03558ae40
1/* 2 * Copyright (C) 2011 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 USE_LOG SLAndroidLogLevel_Verbose 18 19#include "sles_allinclusive.h" 20#include "android/android_AudioSfDecoder.h" 21 22#include <media/stagefright/foundation/ADebug.h> 23 24 25#define SIZE_CACHED_HIGH_BYTES 1000000 26#define SIZE_CACHED_MED_BYTES 700000 27#define SIZE_CACHED_LOW_BYTES 400000 28 29namespace android { 30 31// keep in sync with the entries of kPcmDecodeMetadataKeys[] defined in android_AudioSfDecoder.h 32#define ANDROID_KEY_INDEX_PCMFORMAT_NUMCHANNELS 0 33#define ANDROID_KEY_INDEX_PCMFORMAT_SAMPLESPERSEC 1 34#define ANDROID_KEY_INDEX_PCMFORMAT_BITSPERSAMPLE 2 35#define ANDROID_KEY_INDEX_PCMFORMAT_CONTAINERSIZE 3 36#define ANDROID_KEY_INDEX_PCMFORMAT_CHANNELMASK 4 37#define ANDROID_KEY_INDEX_PCMFORMAT_ENDIANNESS 5 38 39//-------------------------------------------------------------------------------------------------- 40AudioSfDecoder::AudioSfDecoder(const AudioPlayback_Parameters* params) : GenericPlayer(params), 41 mDataSource(0), 42 mAudioSource(0), 43 mAudioSourceStarted(false), 44 mBitrate(-1), 45 mChannelMask(ANDROID_UNKNOWN_CHANNELMASK), 46 mDurationUsec(-1), 47 mDecodeBuffer(NULL), 48 mTimeDelta(-1), 49 mSeekTimeMsec(0), 50 mLastDecodedPositionUs(-1), 51 mPcmFormatKeyCount(0), 52 mGetPcmFormatKeyCount(false) 53{ 54 SL_LOGV("AudioSfDecoder::AudioSfDecoder()"); 55} 56 57 58AudioSfDecoder::~AudioSfDecoder() { 59 SL_LOGV("AudioSfDecoder::~AudioSfDecoder()"); 60} 61 62 63void AudioSfDecoder::preDestroy() { 64 GenericPlayer::preDestroy(); 65 SL_LOGD("AudioSfDecoder::preDestroy()"); 66 { 67 Mutex::Autolock _l(mBufferSourceLock); 68 69 if (NULL != mDecodeBuffer) { 70 mDecodeBuffer->release(); 71 mDecodeBuffer = NULL; 72 } 73 74 if ((mAudioSource != 0) && mAudioSourceStarted) { 75 mAudioSource->stop(); 76 mAudioSourceStarted = false; 77 } 78 } 79} 80 81 82//-------------------------------------------------- 83void AudioSfDecoder::play() { 84 SL_LOGV("AudioSfDecoder::play"); 85 86 GenericPlayer::play(); 87 (new AMessage(kWhatDecode, id()))->post(); 88} 89 90 91void AudioSfDecoder::startPrefetch_async() { 92 SL_LOGV("AudioSfDecoder::startPrefetch_async()"); 93 94 if (wantPrefetch()) { 95 SL_LOGV("AudioSfDecoder::startPrefetch_async(): sending check cache msg"); 96 97 mStateFlags |= kFlagPreparing | kFlagBuffering; 98 99 (new AMessage(kWhatCheckCache, id()))->post(); 100 } 101} 102 103 104//-------------------------------------------------- 105uint32_t AudioSfDecoder::getPcmFormatKeyCount() { 106 android::Mutex::Autolock autoLock(mGetPcmFormatLockSingleton); 107 mGetPcmFormatKeyCount = false; 108 (new AMessage(kWhatGetPcmFormat, id()))->post(); 109 { 110 android::Mutex::Autolock autoLock(mGetPcmFormatLock); 111 while (!mGetPcmFormatKeyCount) { 112 mGetPcmFormatCondition.wait(mGetPcmFormatLock); 113 } 114 } 115 mGetPcmFormatKeyCount = false; 116 return mPcmFormatKeyCount; 117} 118 119 120//-------------------------------------------------- 121bool AudioSfDecoder::getPcmFormatKeySize(uint32_t index, uint32_t* pKeySize) { 122 uint32_t keyCount = getPcmFormatKeyCount(); 123 if (index >= keyCount) { 124 return false; 125 } else { 126 *pKeySize = strlen(kPcmDecodeMetadataKeys[index]) +1; 127 return true; 128 } 129} 130 131 132//-------------------------------------------------- 133bool AudioSfDecoder::getPcmFormatKeyName(uint32_t index, uint32_t keySize, char* keyName) { 134 uint32_t actualKeySize; 135 if (!getPcmFormatKeySize(index, &actualKeySize)) { 136 return false; 137 } 138 if (keySize < actualKeySize) { 139 return false; 140 } 141 strncpy(keyName, kPcmDecodeMetadataKeys[index], actualKeySize); 142 return true; 143} 144 145 146//-------------------------------------------------- 147bool AudioSfDecoder::getPcmFormatValueSize(uint32_t index, uint32_t* pValueSize) { 148 uint32_t keyCount = getPcmFormatKeyCount(); 149 if (index >= keyCount) { 150 *pValueSize = 0; 151 return false; 152 } else { 153 *pValueSize = sizeof(uint32_t); 154 return true; 155 } 156} 157 158 159//-------------------------------------------------- 160bool AudioSfDecoder::getPcmFormatKeyValue(uint32_t index, uint32_t size, uint32_t* pValue) { 161 uint32_t valueSize = 0; 162 if (!getPcmFormatValueSize(index, &valueSize)) { 163 return false; 164 } else if (size != valueSize) { 165 // this ensures we are accessing mPcmFormatValues with a valid size for that index 166 SL_LOGE("Error retrieving metadata value at index %d: using size of %d, should be %d", 167 index, size, valueSize); 168 return false; 169 } else { 170 *pValue = mPcmFormatValues[index]; 171 return true; 172 } 173} 174 175 176//-------------------------------------------------- 177// Event handlers 178// it is strictly verboten to call those methods outside of the event loop 179 180// Initializes the data and audio sources, and update the PCM format info 181// post-condition: upon successful initialization based on the player data locator 182// GenericPlayer::onPrepare() was called 183// mDataSource != 0 184// mAudioSource != 0 185// mAudioSourceStarted == true 186void AudioSfDecoder::onPrepare() { 187 SL_LOGD("AudioSfDecoder::onPrepare()"); 188 Mutex::Autolock _l(mBufferSourceLock); 189 190 // Initialize the PCM format info with the known parameters before the start of the decode 191 mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_BITSPERSAMPLE] = SL_PCMSAMPLEFORMAT_FIXED_16; 192 mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_CONTAINERSIZE] = 16; 193 mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_ENDIANNESS] = SL_BYTEORDER_LITTLEENDIAN; 194 // initialization with the default values: they will be replaced by the actual values 195 // once the decoder has figured them out 196 mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_NUMCHANNELS] = mChannelCount; 197 mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_SAMPLESPERSEC] = mSampleRateHz; 198 mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_CHANNELMASK] = mChannelMask; 199 200 //--------------------------------- 201 // Instantiate and initialize the data source for the decoder 202 sp<DataSource> dataSource; 203 204 switch (mDataLocatorType) { 205 206 case kDataLocatorNone: 207 SL_LOGE("AudioSfDecoder::onPrepare: no data locator set"); 208 notifyPrepared(MEDIA_ERROR_BASE); 209 return; 210 211 case kDataLocatorUri: 212 dataSource = DataSource::CreateFromURI(mDataLocator.uriRef); 213 if (dataSource == NULL) { 214 SL_LOGE("AudioSfDecoder::onPrepare(): Error opening %s", mDataLocator.uriRef); 215 notifyPrepared(MEDIA_ERROR_BASE); 216 return; 217 } 218 break; 219 220 case kDataLocatorFd: 221 { 222 dataSource = new FileSource( 223 mDataLocator.fdi.fd, mDataLocator.fdi.offset, mDataLocator.fdi.length); 224 status_t err = dataSource->initCheck(); 225 if (err != OK) { 226 notifyPrepared(err); 227 return; 228 } 229 break; 230 } 231 232 default: 233 TRESPASS(); 234 } 235 236 //--------------------------------- 237 // Instanciate and initialize the decoder attached to the data source 238 sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource); 239 if (extractor == NULL) { 240 SL_LOGE("AudioSfDecoder::onPrepare: Could not instantiate extractor."); 241 notifyPrepared(ERROR_UNSUPPORTED); 242 return; 243 } 244 245 ssize_t audioTrackIndex = -1; 246 bool isRawAudio = false; 247 for (size_t i = 0; i < extractor->countTracks(); ++i) { 248 sp<MetaData> meta = extractor->getTrackMetaData(i); 249 250 const char *mime; 251 CHECK(meta->findCString(kKeyMIMEType, &mime)); 252 253 if (!strncasecmp("audio/", mime, 6)) { 254 audioTrackIndex = i; 255 256 if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_RAW, mime)) { 257 isRawAudio = true; 258 } 259 break; 260 } 261 } 262 263 if (audioTrackIndex < 0) { 264 SL_LOGE("AudioSfDecoder::onPrepare: Could not find a supported audio track."); 265 notifyPrepared(ERROR_UNSUPPORTED); 266 return; 267 } 268 269 sp<MediaSource> source = extractor->getTrack(audioTrackIndex); 270 sp<MetaData> meta = source->getFormat(); 271 272 bool hasChannelCount = meta->findInt32(kKeyChannelCount, &mChannelCount); 273 if (hasChannelCount) { 274 mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_NUMCHANNELS] = mChannelCount; 275 } 276 277 off64_t size; 278 int64_t durationUs; 279 if (dataSource->getSize(&size) == OK 280 && meta->findInt64(kKeyDuration, &durationUs)) { 281 mBitrate = size * 8000000ll / durationUs; // in bits/sec 282 mDurationUsec = durationUs; 283 mDurationMsec = durationUs / 1000; 284 } else { 285 mBitrate = -1; 286 mDurationUsec = -1; 287 } 288 289 // the audio content is not raw PCM, so we need a decoder 290 if (!isRawAudio) { 291 OMXClient client; 292 CHECK_EQ(client.connect(), (status_t)OK); 293 294 source = OMXCodec::Create( 295 client.interface(), meta, false /* createEncoder */, 296 source); 297 298 if (source == NULL) { 299 SL_LOGE("AudioSfDecoder::onPrepare: Could not instantiate decoder."); 300 notifyPrepared(ERROR_UNSUPPORTED); 301 return; 302 } 303 304 meta = source->getFormat(); 305 } 306 307 308 if (source->start() != OK) { 309 SL_LOGE("AudioSfDecoder::onPrepare: Failed to start source/decoder."); 310 notifyPrepared(MEDIA_ERROR_BASE); 311 return; 312 } 313 314 //--------------------------------- 315 // The data source, and audio source (a decoder if required) are ready to be used 316 mDataSource = dataSource; 317 mAudioSource = source; 318 mAudioSourceStarted = true; 319 320 if (!hasChannelCount) { 321 // even though the channel count was already queried above, there are issues with some 322 // OMXCodecs (e.g. MP3 software decoder) not reporting the right count, 323 // we trust the first reported value. 324 CHECK(meta->findInt32(kKeyChannelCount, &mChannelCount)); 325 mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_NUMCHANNELS] = mChannelCount; 326 } 327 int32_t sr; 328 CHECK(meta->findInt32(kKeySampleRate, &sr)); 329 mSampleRateHz = (uint32_t) sr; 330 mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_SAMPLESPERSEC] = mSampleRateHz; 331 // FIXME add code below once channel mask support is in, currently initialized to default 332 // if (meta->findInt32(kKeyChannelMask, &mChannelMask)) { 333 // mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_CHANNELMASK] = mChannelMask; 334 // } 335 336 if (!wantPrefetch()) { 337 SL_LOGV("AudioSfDecoder::onPrepare: no need to prefetch"); 338 // doesn't need prefetching, notify good to go 339 mCacheStatus = kStatusHigh; 340 mCacheFill = 1000; 341 notifyStatus(); 342 notifyCacheFill(); 343 } 344 345 // at this point we have enough information about the source to create the sink that 346 // will consume the data 347 createAudioSink(); 348 349 GenericPlayer::onPrepare(); 350 SL_LOGD("AudioSfDecoder::onPrepare() done, mStateFlags=0x%x", mStateFlags); 351} 352 353 354void AudioSfDecoder::onPause() { 355 SL_LOGD("AudioSfDecoder::onPause()"); 356 GenericPlayer::onPause(); 357 pauseAudioSink(); 358} 359 360 361void AudioSfDecoder::onPlay() { 362 SL_LOGD("AudioSfDecoder::onPlay()"); 363 GenericPlayer::onPlay(); 364 startAudioSink(); 365} 366 367 368void AudioSfDecoder::onSeek(const sp<AMessage> &msg) { 369 SL_LOGV("AudioSfDecoder::onSeek"); 370 int64_t timeMsec; 371 CHECK(msg->findInt64(WHATPARAM_SEEK_SEEKTIME_MS, &timeMsec)); 372 373 Mutex::Autolock _l(mSeekLock); 374 mStateFlags |= kFlagSeeking; 375 mSeekTimeMsec = timeMsec; 376 mTimeDelta = -1; 377 mLastDecodedPositionUs = -1; 378} 379 380 381void AudioSfDecoder::onLoop(const sp<AMessage> &msg) { 382 SL_LOGV("AudioSfDecoder::onLoop"); 383 int32_t loop; 384 CHECK(msg->findInt32(WHATPARAM_LOOP_LOOPING, &loop)); 385 386 if (loop) { 387 //SL_LOGV("AudioSfDecoder::onLoop start looping"); 388 mStateFlags |= kFlagLooping; 389 } else { 390 //SL_LOGV("AudioSfDecoder::onLoop stop looping"); 391 mStateFlags &= ~kFlagLooping; 392 } 393} 394 395 396void AudioSfDecoder::onGetPcmFormatKeyCount() { 397 SL_LOGV("AudioSfDecoder::onGetPcmFormatKeyCount"); 398 { 399 android::Mutex::Autolock autoLock(mGetPcmFormatLock); 400 401 if (!(mStateFlags & kFlagPrepared)) { 402 mPcmFormatKeyCount = 0; 403 } else { 404 mPcmFormatKeyCount = NB_PCMMETADATA_KEYS; 405 } 406 407 mGetPcmFormatKeyCount = true; 408 mGetPcmFormatCondition.signal(); 409 } 410 411} 412 413 414void AudioSfDecoder::onCheckCache(const sp<AMessage> &msg) { 415 //SL_LOGV("AudioSfDecoder::onCheckCache"); 416 bool eos; 417 CacheStatus_t status = getCacheRemaining(&eos); 418 419 if (eos || status == kStatusHigh 420 || ((mStateFlags & kFlagPreparing) && (status >= kStatusEnough))) { 421 if (mStateFlags & kFlagPlaying) { 422 startAudioSink(); 423 } 424 mStateFlags &= ~kFlagBuffering; 425 426 SL_LOGV("AudioSfDecoder::onCheckCache: buffering done."); 427 428 if (mStateFlags & kFlagPreparing) { 429 //SL_LOGV("AudioSfDecoder::onCheckCache: preparation done."); 430 mStateFlags &= ~kFlagPreparing; 431 } 432 433 mTimeDelta = -1; 434 if (mStateFlags & kFlagPlaying) { 435 (new AMessage(kWhatDecode, id()))->post(); 436 } 437 return; 438 } 439 440 msg->post(100000); 441} 442 443 444void AudioSfDecoder::onDecode() { 445 SL_LOGV("AudioSfDecoder::onDecode"); 446 447 //-------------------------------- Need to buffer some more before decoding? 448 bool eos; 449 if (mDataSource == 0) { 450 // application set play state to paused which failed, then set play state to playing 451 return; 452 } 453 454 if (wantPrefetch() 455 && (getCacheRemaining(&eos) == kStatusLow) 456 && !eos) { 457 SL_LOGV("buffering more."); 458 459 if (mStateFlags & kFlagPlaying) { 460 pauseAudioSink(); 461 } 462 mStateFlags |= kFlagBuffering; 463 (new AMessage(kWhatCheckCache, id()))->post(100000); 464 return; 465 } 466 467 if (!(mStateFlags & (kFlagPlaying | kFlagBuffering | kFlagPreparing))) { 468 // don't decode if we're not buffering, prefetching or playing 469 //SL_LOGV("don't decode: not buffering, prefetching or playing"); 470 return; 471 } 472 473 //-------------------------------- Decode 474 status_t err; 475 MediaSource::ReadOptions readOptions; 476 if (mStateFlags & kFlagSeeking) { 477 readOptions.setSeekTo(mSeekTimeMsec * 1000); 478 } 479 480 { 481 Mutex::Autolock _l(mBufferSourceLock); 482 483 if (NULL != mDecodeBuffer) { 484 // the current decoded buffer hasn't been rendered, drop it 485 mDecodeBuffer->release(); 486 mDecodeBuffer = NULL; 487 } 488 if(!mAudioSourceStarted) { 489 return; 490 } 491 err = mAudioSource->read(&mDecodeBuffer, &readOptions); 492 if (err == OK) { 493 CHECK(mDecodeBuffer->meta_data()->findInt64(kKeyTime, &mLastDecodedPositionUs)); 494 } 495 } 496 497 { 498 Mutex::Autolock _l(mSeekLock); 499 if (mStateFlags & kFlagSeeking) { 500 mStateFlags &= ~kFlagSeeking; 501 } 502 } 503 504 //-------------------------------- Handle return of decode 505 if (err != OK) { 506 bool continueDecoding = false; 507 switch(err) { 508 case ERROR_END_OF_STREAM: 509 if (0 < mDurationUsec) { 510 mLastDecodedPositionUs = mDurationUsec; 511 } 512 // handle notification and looping at end of stream 513 if (mStateFlags & kFlagPlaying) { 514 notify(PLAYEREVENT_ENDOFSTREAM, 1, true); 515 } 516 if (mStateFlags & kFlagLooping) { 517 seek(0); 518 // kick-off decoding again 519 continueDecoding = true; 520 } 521 break; 522 case INFO_FORMAT_CHANGED: 523 SL_LOGD("MediaSource::read encountered INFO_FORMAT_CHANGED"); 524 // reconfigure output 525 updateAudioSink(); 526 continueDecoding = true; 527 break; 528 case INFO_DISCONTINUITY: 529 SL_LOGD("MediaSource::read encountered INFO_DISCONTINUITY"); 530 continueDecoding = true; 531 break; 532 default: 533 SL_LOGE("MediaSource::read returned error %d", err); 534 break; 535 } 536 if (continueDecoding) { 537 if (NULL == mDecodeBuffer) { 538 (new AMessage(kWhatDecode, id()))->post(); 539 return; 540 } 541 } else { 542 return; 543 } 544 } 545 546 //-------------------------------- Render 547 sp<AMessage> msg = new AMessage(kWhatRender, id()); 548 msg->post(); 549} 550 551 552void AudioSfDecoder::onRender() { 553 //SL_LOGV("AudioSfDecoder::onRender"); 554 555 Mutex::Autolock _l(mBufferSourceLock); 556 557 if (NULL == mDecodeBuffer) { 558 // nothing to render, move along 559 SL_LOGV("AudioSfDecoder::onRender NULL buffer, exiting"); 560 return; 561 } 562 563 mDecodeBuffer->release(); 564 mDecodeBuffer = NULL; 565 566} 567 568 569void AudioSfDecoder::onMessageReceived(const sp<AMessage> &msg) { 570 switch (msg->what()) { 571 case kWhatPrepare: 572 onPrepare(); 573 break; 574 575 case kWhatDecode: 576 onDecode(); 577 break; 578 579 case kWhatRender: 580 onRender(); 581 break; 582 583 case kWhatCheckCache: 584 onCheckCache(msg); 585 break; 586 587 case kWhatNotif: 588 onNotify(msg); 589 break; 590 591 case kWhatPlay: 592 onPlay(); 593 break; 594 595 case kWhatPause: 596 onPause(); 597 break; 598 599 case kWhatGetPcmFormat: 600 onGetPcmFormatKeyCount(); 601 break; 602/* 603 case kWhatSeek: 604 onSeek(msg); 605 break; 606 607 case kWhatLoop: 608 onLoop(msg); 609 break; 610*/ 611 default: 612 GenericPlayer::onMessageReceived(msg); 613 break; 614 } 615} 616 617//-------------------------------------------------- 618// Prepared state, prefetch status notifications 619void AudioSfDecoder::notifyPrepared(status_t prepareRes) { 620 notify(PLAYEREVENT_PREPARED, (int32_t)prepareRes, true); 621 622} 623 624 625void AudioSfDecoder::onNotify(const sp<AMessage> &msg) { 626 notif_cbf_t notifyClient; 627 void* notifyUser; 628 { 629 android::Mutex::Autolock autoLock(mNotifyClientLock); 630 if (NULL == mNotifyClient) { 631 return; 632 } else { 633 notifyClient = mNotifyClient; 634 notifyUser = mNotifyUser; 635 } 636 } 637 int32_t val; 638 if (msg->findInt32(PLAYEREVENT_PREFETCHSTATUSCHANGE, &val)) { 639 SL_LOGV("\tASfPlayer notifying %s = %d", PLAYEREVENT_PREFETCHSTATUSCHANGE, val); 640 notifyClient(kEventPrefetchStatusChange, val, 0, notifyUser); 641 } 642 else if (msg->findInt32(PLAYEREVENT_PREFETCHFILLLEVELUPDATE, &val)) { 643 SL_LOGV("\tASfPlayer notifying %s = %d", PLAYEREVENT_PREFETCHFILLLEVELUPDATE, val); 644 notifyClient(kEventPrefetchFillLevelUpdate, val, 0, notifyUser); 645 } 646 else if (msg->findInt32(PLAYEREVENT_ENDOFSTREAM, &val)) { 647 SL_LOGV("\tASfPlayer notifying %s = %d", PLAYEREVENT_ENDOFSTREAM, val); 648 notifyClient(kEventEndOfStream, val, 0, notifyUser); 649 } 650 else { 651 GenericPlayer::onNotify(msg); 652 } 653} 654 655 656//-------------------------------------------------- 657// Private utility functions 658 659bool AudioSfDecoder::wantPrefetch() { 660 if (mDataSource != 0) { 661 return (mDataSource->flags() & DataSource::kWantsPrefetching); 662 } else { 663 // happens if an improper data locator was passed, if the media extractor couldn't be 664 // initialized, if there is no audio track in the media, if the OMX decoder couldn't be 665 // instantiated, if the source couldn't be opened, or if the MediaSource 666 // couldn't be started 667 SL_LOGV("AudioSfDecoder::wantPrefetch() tries to access NULL mDataSource"); 668 return false; 669 } 670} 671 672 673int64_t AudioSfDecoder::getPositionUsec() { 674 Mutex::Autolock _l(mSeekLock); 675 if (mStateFlags & kFlagSeeking) { 676 return mSeekTimeMsec * 1000; 677 } else { 678 if (mLastDecodedPositionUs < 0) { 679 return 0; 680 } else { 681 return mLastDecodedPositionUs; 682 } 683 } 684} 685 686 687CacheStatus_t AudioSfDecoder::getCacheRemaining(bool *eos) { 688 sp<NuCachedSource2> cachedSource = 689 static_cast<NuCachedSource2 *>(mDataSource.get()); 690 691 CacheStatus_t oldStatus = mCacheStatus; 692 693 status_t finalStatus; 694 size_t dataRemaining = cachedSource->approxDataRemaining(&finalStatus); 695 *eos = (finalStatus != OK); 696 697 CHECK_GE(mBitrate, 0); 698 699 int64_t dataRemainingUs = dataRemaining * 8000000ll / mBitrate; 700 //SL_LOGV("AudioSfDecoder::getCacheRemaining: approx %.2f secs remaining (eos=%d)", 701 // dataRemainingUs / 1E6, *eos); 702 703 if (*eos) { 704 // data is buffered up to the end of the stream, it can't get any better than this 705 mCacheStatus = kStatusHigh; 706 mCacheFill = 1000; 707 708 } else { 709 if (mDurationUsec > 0) { 710 // known duration: 711 712 // fill level is ratio of how much has been played + how much is 713 // cached, divided by total duration 714 uint32_t currentPositionUsec = getPositionUsec(); 715 mCacheFill = (int16_t) ((1000.0 716 * (double)(currentPositionUsec + dataRemainingUs) / mDurationUsec)); 717 //SL_LOGV("cacheFill = %d", mCacheFill); 718 719 // cache status is evaluated against duration thresholds 720 if (dataRemainingUs > DURATION_CACHED_HIGH_MS*1000) { 721 mCacheStatus = kStatusHigh; 722 //LOGV("high"); 723 } else if (dataRemainingUs > DURATION_CACHED_MED_MS*1000) { 724 //LOGV("enough"); 725 mCacheStatus = kStatusEnough; 726 } else if (dataRemainingUs < DURATION_CACHED_LOW_MS*1000) { 727 //LOGV("low"); 728 mCacheStatus = kStatusLow; 729 } else { 730 mCacheStatus = kStatusIntermediate; 731 } 732 733 } else { 734 // unknown duration: 735 736 // cache status is evaluated against cache amount thresholds 737 // (no duration so we don't have the bitrate either, could be derived from format?) 738 if (dataRemaining > SIZE_CACHED_HIGH_BYTES) { 739 mCacheStatus = kStatusHigh; 740 } else if (dataRemaining > SIZE_CACHED_MED_BYTES) { 741 mCacheStatus = kStatusEnough; 742 } else if (dataRemaining < SIZE_CACHED_LOW_BYTES) { 743 mCacheStatus = kStatusLow; 744 } else { 745 mCacheStatus = kStatusIntermediate; 746 } 747 } 748 749 } 750 751 if (oldStatus != mCacheStatus) { 752 notifyStatus(); 753 } 754 755 if (abs(mCacheFill - mLastNotifiedCacheFill) > mCacheFillNotifThreshold) { 756 notifyCacheFill(); 757 } 758 759 return mCacheStatus; 760} 761 762} // namespace android 763