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