android_GenericPlayer.cpp revision fa2bd93c3a9852a1f879663eeff598d13cf8fa81
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 21#include <media/stagefright/foundation/ADebug.h> 22#include <sys/stat.h> 23 24namespace android { 25 26//-------------------------------------------------------------------------------------------------- 27GenericPlayer::GenericPlayer(const AudioPlayback_Parameters* params) : 28 mDataLocatorType(kDataLocatorNone), 29 mNotifyClient(NULL), 30 mNotifyUser(NULL), 31 mStateFlags(0), 32 mLooperPriority(PRIORITY_DEFAULT), 33 mPlaybackParams(*params), 34 mChannelCount(UNKNOWN_NUMCHANNELS), 35 mDurationMsec(ANDROID_UNKNOWN_TIME), 36 mPositionMsec(ANDROID_UNKNOWN_TIME), 37 mSampleRateHz(UNKNOWN_SAMPLERATE), 38 mCacheStatus(kStatusEmpty), 39 mCacheFill(0), 40 mLastNotifiedCacheFill(0), 41 mCacheFillNotifThreshold(100) 42{ 43 SL_LOGD("GenericPlayer::GenericPlayer()"); 44 45 mLooper = new android::ALooper(); 46 47 mAndroidAudioLevels.mFinalVolume[0] = 1.0f; 48 mAndroidAudioLevels.mFinalVolume[1] = 1.0f; 49} 50 51 52GenericPlayer::~GenericPlayer() { 53 SL_LOGV("GenericPlayer::~GenericPlayer()"); 54 55} 56 57 58void GenericPlayer::init(const notif_cbf_t cbf, void* notifUser) { 59 SL_LOGD("GenericPlayer::init()"); 60 61 { 62 android::Mutex::Autolock autoLock(mNotifyClientLock); 63 mNotifyClient = cbf; 64 mNotifyUser = notifUser; 65 } 66 67 mLooper->registerHandler(this); 68 mLooper->start(false /*runOnCallingThread*/, false /*canCallJava*/, mLooperPriority); 69} 70 71 72void GenericPlayer::preDestroy() { 73 SL_LOGD("GenericPlayer::preDestroy()"); 74 { 75 android::Mutex::Autolock autoLock(mNotifyClientLock); 76 mNotifyClient = NULL; 77 mNotifyUser = NULL; 78 } 79 80 mLooper->stop(); 81 mLooper->unregisterHandler(id()); 82} 83 84 85void GenericPlayer::setDataSource(const char *uri) { 86 SL_LOGV("GenericPlayer::setDataSource(uri=%s)", uri); 87 resetDataLocator(); 88 89 mDataLocator.uriRef = uri; 90 91 mDataLocatorType = kDataLocatorUri; 92} 93 94 95void GenericPlayer::setDataSource(int fd, int64_t offset, int64_t length) { 96 SL_LOGV("GenericPlayer::setDataSource(fd=%d, offset=%lld, length=%lld)", fd, offset, length); 97 resetDataLocator(); 98 99 mDataLocator.fdi.fd = fd; 100 101 struct stat sb; 102 int ret = fstat(fd, &sb); 103 if (ret != 0) { 104 SL_LOGE("GenericPlayer::setDataSource: fstat(%d) failed: %d, %s", fd, ret, strerror(errno)); 105 return; 106 } 107 108 if (offset >= sb.st_size) { 109 SL_LOGE("SfPlayer::setDataSource: invalid offset"); 110 return; 111 } 112 mDataLocator.fdi.offset = offset; 113 114 if (PLAYER_FD_FIND_FILE_SIZE == length) { 115 mDataLocator.fdi.length = sb.st_size; 116 } else if (offset + length > sb.st_size) { 117 mDataLocator.fdi.length = sb.st_size - offset; 118 } else { 119 mDataLocator.fdi.length = length; 120 } 121 122 mDataLocatorType = kDataLocatorFd; 123} 124 125 126void GenericPlayer::prepare() { 127 SL_LOGD("GenericPlayer::prepare()"); 128 sp<AMessage> msg = new AMessage(kWhatPrepare, id()); 129 msg->post(); 130} 131 132 133void GenericPlayer::play() { 134 SL_LOGD("GenericPlayer::play()"); 135 sp<AMessage> msg = new AMessage(kWhatPlay, id()); 136 msg->post(); 137} 138 139 140void GenericPlayer::pause() { 141 SL_LOGD("GenericPlayer::pause()"); 142 sp<AMessage> msg = new AMessage(kWhatPause, id()); 143 msg->post(); 144} 145 146 147void GenericPlayer::stop() { 148 SL_LOGD("GenericPlayer::stop()"); 149 (new AMessage(kWhatPause, id()))->post(); 150 151 // after a stop, playback should resume from the start. 152 seek(0); 153} 154 155 156void GenericPlayer::seek(int64_t timeMsec) { 157 SL_LOGV("GenericPlayer::seek %lld", timeMsec); 158 if (timeMsec < 0) { 159 SL_LOGE("GenericPlayer::seek error, can't seek to negative time %lldms", timeMsec); 160 return; 161 } 162 sp<AMessage> msg = new AMessage(kWhatSeek, id()); 163 msg->setInt64(WHATPARAM_SEEK_SEEKTIME_MS, timeMsec); 164 msg->post(); 165} 166 167 168void GenericPlayer::loop(bool loop) { 169 SL_LOGV("GenericPlayer::loop %s", loop ? "true" : "false"); 170 sp<AMessage> msg = new AMessage(kWhatLoop, id()); 171 msg->setInt32(WHATPARAM_LOOP_LOOPING, (int32_t)loop); 172 msg->post(); 173} 174 175 176void GenericPlayer::setBufferingUpdateThreshold(int16_t thresholdPercent) { 177 SL_LOGV("GenericPlayer::setBufferingUpdateThreshold %d", thresholdPercent); 178 sp<AMessage> msg = new AMessage(kWhatBuffUpdateThres, id()); 179 msg->setInt32(WHATPARAM_BUFFERING_UPDATETHRESHOLD_PERCENT, (int32_t)thresholdPercent); 180 msg->post(); 181} 182 183 184//-------------------------------------------------- 185void GenericPlayer::getDurationMsec(int* msec) { 186 *msec = mDurationMsec; 187} 188 189void GenericPlayer::getPositionMsec(int* msec) { 190 *msec = mPositionMsec; 191} 192 193void GenericPlayer::getSampleRate(uint* hz) { 194 *hz = mSampleRateHz; 195} 196 197//-------------------------------------------------- 198void GenericPlayer::setVolume(float leftVol, float rightVol) 199{ 200 { 201 Mutex::Autolock _l(mSettingsLock); 202 mAndroidAudioLevels.mFinalVolume[0] = leftVol; 203 mAndroidAudioLevels.mFinalVolume[1] = rightVol; 204 } 205 // send a message for the volume to be updated by the object which implements the volume 206 (new AMessage(kWhatVolumeUpdate, id()))->post(); 207} 208 209 210//-------------------------------------------------- 211void GenericPlayer::attachAuxEffect(int32_t effectId) 212{ 213 SL_LOGV("GenericPlayer::attachAuxEffect(id=%d)", effectId); 214 sp<AMessage> msg = new AMessage(kWhatAttachAuxEffect, id()); 215 msg->setInt32(WHATPARAM_ATTACHAUXEFFECT, effectId); 216 msg->post(); 217} 218 219 220//-------------------------------------------------- 221void GenericPlayer::setAuxEffectSendLevel(float level) 222{ 223 SL_LOGV("GenericPlayer::setAuxEffectSendLevel(level=%g)", level); 224 sp<AMessage> msg = new AMessage(kWhatSetAuxEffectSendLevel, id()); 225 msg->setFloat(WHATPARAM_SETAUXEFFECTSENDLEVEL, level); 226 msg->post(); 227} 228 229 230//-------------------------------------------------- 231/* 232 * post-condition: mDataLocatorType == kDataLocatorNone 233 * 234 */ 235void GenericPlayer::resetDataLocator() { 236 SL_LOGV("GenericPlayer::resetDataLocator()"); 237 mDataLocatorType = kDataLocatorNone; 238} 239 240 241void GenericPlayer::notify(const char* event, int data, bool async) { 242 SL_LOGV("GenericPlayer::notify(event=%s, data=%d, async=%s)", event, data, 243 async ? "true" : "false"); 244 sp<AMessage> msg = new AMessage(kWhatNotif, id()); 245 msg->setInt32(event, (int32_t)data); 246 if (async) { 247 msg->post(); 248 } else { 249 this->onNotify(msg); 250 } 251} 252 253 254void GenericPlayer::notify(const char* event, int data1, int data2, bool async) { 255 SL_LOGV("GenericPlayer::notify(event=%s, data1=%d, data2=%d, async=%s)", event, data1, data2, 256 async ? "true" : "false"); 257 sp<AMessage> msg = new AMessage(kWhatNotif, id()); 258 msg->setRect(event, 0, 0, (int32_t)data1, (int32_t)data2); 259 if (async) { 260 msg->post(); 261 } else { 262 this->onNotify(msg); 263 } 264} 265 266 267//-------------------------------------------------- 268// AHandler implementation 269void GenericPlayer::onMessageReceived(const sp<AMessage> &msg) { 270 SL_LOGV("GenericPlayer::onMessageReceived()"); 271 switch (msg->what()) { 272 case kWhatPrepare: 273 SL_LOGV("kWhatPrepare"); 274 onPrepare(); 275 break; 276 277 case kWhatNotif: 278 SL_LOGV("kWhatNotif"); 279 onNotify(msg); 280 break; 281 282 case kWhatPlay: 283 SL_LOGV("kWhatPlay"); 284 onPlay(); 285 break; 286 287 case kWhatPause: 288 SL_LOGV("kWhatPause"); 289 onPause(); 290 break; 291 292 case kWhatSeek: 293 SL_LOGV("kWhatSeek"); 294 onSeek(msg); 295 break; 296 297 case kWhatLoop: 298 SL_LOGV("kWhatLoop"); 299 onLoop(msg); 300 break; 301 302 case kWhatVolumeUpdate: 303 SL_LOGV("kWhatVolumeUpdate"); 304 onVolumeUpdate(); 305 break; 306 307 case kWhatSeekComplete: 308 SL_LOGV("kWhatSeekComplete"); 309 onSeekComplete(); 310 break; 311 312 case kWhatBufferingUpdate: 313 SL_LOGV("kWhatBufferingUpdate"); 314 onBufferingUpdate(msg); 315 break; 316 317 case kWhatBuffUpdateThres: 318 SL_LOGV("kWhatBuffUpdateThres"); 319 onSetBufferingUpdateThreshold(msg); 320 break; 321 322 case kWhatAttachAuxEffect: 323 SL_LOGV("kWhatAttachAuxEffect"); 324 onAttachAuxEffect(msg); 325 break; 326 327 case kWhatSetAuxEffectSendLevel: 328 SL_LOGV("kWhatSetAuxEffectSendLevel"); 329 onSetAuxEffectSendLevel(msg); 330 break; 331 332 default: 333 SL_LOGV("kWhatPlay"); 334 TRESPASS(); 335 } 336} 337 338 339//-------------------------------------------------- 340// Event handlers 341// it is strictly verboten to call those methods outside of the event loop 342 343void GenericPlayer::onPrepare() { 344 SL_LOGV("GenericPlayer::onPrepare()"); 345 // Subclass is responsible for indicating whether prepare was successful or unsuccessful 346 // by updating mStateFlags accordingly. It must set exactly one of these two flags. 347 assert(!(mStateFlags & kFlagPrepared) != !(mStateFlags & kFlagPreparedUnsuccessfully)); 348 notify(PLAYEREVENT_PREPARED, mStateFlags & kFlagPrepared ? PLAYER_SUCCESS : PLAYER_FAILURE, 349 false /*async*/); 350 SL_LOGD("GenericPlayer::onPrepare() done, mStateFlags=0x%x", mStateFlags); 351} 352 353 354void GenericPlayer::onNotify(const sp<AMessage> &msg) { 355 SL_LOGV("GenericPlayer::onNotify()"); 356 notif_cbf_t notifClient; 357 void* notifUser; 358 { 359 android::Mutex::Autolock autoLock(mNotifyClientLock); 360 if (NULL == mNotifyClient) { 361 return; 362 } else { 363 notifClient = mNotifyClient; 364 notifUser = mNotifyUser; 365 } 366 } 367 368 int32_t val1, val2; 369 if (msg->findInt32(PLAYEREVENT_PREFETCHSTATUSCHANGE, &val1)) { 370 SL_LOGV("GenericPlayer notifying %s = %d", PLAYEREVENT_PREFETCHSTATUSCHANGE, val1); 371 notifClient(kEventPrefetchStatusChange, val1, 0, notifUser); 372 } else if (msg->findInt32(PLAYEREVENT_PREFETCHFILLLEVELUPDATE, &val1)) { 373 SL_LOGV("GenericPlayer notifying %s = %d", PLAYEREVENT_PREFETCHFILLLEVELUPDATE, val1); 374 notifClient(kEventPrefetchFillLevelUpdate, val1, 0, notifUser); 375 } else if (msg->findInt32(PLAYEREVENT_ENDOFSTREAM, &val1)) { 376 SL_LOGV("GenericPlayer notifying %s = %d", PLAYEREVENT_ENDOFSTREAM, val1); 377 notifClient(kEventEndOfStream, val1, 0, notifUser); 378 } else if (msg->findInt32(PLAYEREVENT_PREPARED, &val1)) { 379 SL_LOGV("GenericPlayer notifying %s = %d", PLAYEREVENT_PREPARED, val1); 380 notifClient(kEventPrepared, val1, 0, notifUser); 381 } else if (msg->findInt32(PLAYEREVENT_CHANNEL_COUNT, &val1)) { 382 SL_LOGV("GenericPlayer notifying %s = %d", PLAYEREVENT_CHANNEL_COUNT, val1); 383 notifClient(kEventChannelCount, val1, 0, notifUser); 384 } else if (msg->findRect(PLAYEREVENT_VIDEO_SIZE_UPDATE, &val1, &val2, &val1, &val2)) { 385 SL_LOGV("GenericPlayer notifying %s = %d, %d", PLAYEREVENT_VIDEO_SIZE_UPDATE, val1, val2); 386 notifClient(kEventHasVideoSize, val1, val2, notifUser); 387 } else { 388 SL_LOGV("GenericPlayer notifying unknown"); 389 } 390} 391 392 393void GenericPlayer::onPlay() { 394 SL_LOGD("GenericPlayer::onPlay()"); 395 if ((mStateFlags & kFlagPrepared)) { 396 SL_LOGD("starting player"); 397 mStateFlags |= kFlagPlaying; 398 } else { 399 SL_LOGV("NOT starting player mStateFlags=0x%x", mStateFlags); 400 } 401} 402 403 404void GenericPlayer::onPause() { 405 SL_LOGD("GenericPlayer::onPause()"); 406 if ((mStateFlags & kFlagPrepared)) { 407 mStateFlags &= ~kFlagPlaying; 408 } 409} 410 411 412void GenericPlayer::onSeek(const sp<AMessage> &msg) { 413 SL_LOGV("GenericPlayer::onSeek"); 414} 415 416 417void GenericPlayer::onLoop(const sp<AMessage> &msg) { 418 SL_LOGV("GenericPlayer::onLoop"); 419} 420 421 422void GenericPlayer::onVolumeUpdate() { 423 SL_LOGV("GenericPlayer::onVolumeUpdate"); 424} 425 426 427void GenericPlayer::onSeekComplete() { 428 SL_LOGD("GenericPlayer::onSeekComplete()"); 429 mStateFlags &= ~kFlagSeeking; 430} 431 432 433void GenericPlayer::onBufferingUpdate(const sp<AMessage> &msg) { 434 SL_LOGV("GenericPlayer::onBufferingUpdate"); 435} 436 437 438void GenericPlayer::onSetBufferingUpdateThreshold(const sp<AMessage> &msg) { 439 SL_LOGV("GenericPlayer::onSetBufferingUpdateThreshold"); 440 int32_t thresholdPercent = 0; 441 if (msg->findInt32(WHATPARAM_BUFFERING_UPDATETHRESHOLD_PERCENT, &thresholdPercent)) { 442 Mutex::Autolock _l(mSettingsLock); 443 mCacheFillNotifThreshold = (int16_t)thresholdPercent; 444 } 445} 446 447 448void GenericPlayer::onAttachAuxEffect(const sp<AMessage> &msg) { 449 SL_LOGV("GenericPlayer::onAttachAuxEffect()"); 450} 451 452 453void GenericPlayer::onSetAuxEffectSendLevel(const sp<AMessage> &msg) { 454 SL_LOGV("GenericPlayer::onSetAuxEffectSendLevel()"); 455} 456 457 458//------------------------------------------------- 459void GenericPlayer::notifyStatus() { 460 SL_LOGV("GenericPlayer::notifyStatus"); 461 notify(PLAYEREVENT_PREFETCHSTATUSCHANGE, (int32_t)mCacheStatus, true /*async*/); 462} 463 464 465void GenericPlayer::notifyCacheFill() { 466 SL_LOGV("GenericPlayer::notifyCacheFill"); 467 mLastNotifiedCacheFill = mCacheFill; 468 notify(PLAYEREVENT_PREFETCHFILLLEVELUPDATE, (int32_t)mLastNotifiedCacheFill, true/*async*/); 469} 470 471 472void GenericPlayer::seekComplete() { 473 SL_LOGV("GenericPlayer::seekComplete"); 474 sp<AMessage> msg = new AMessage(kWhatSeekComplete, id()); 475 msg->post(); 476} 477 478 479void GenericPlayer::bufferingUpdate(int16_t fillLevelPerMille) { 480 SL_LOGV("GenericPlayer::bufferingUpdate"); 481 sp<AMessage> msg = new AMessage(kWhatBufferingUpdate, id()); 482 msg->setInt32(WHATPARAM_BUFFERING_UPDATE, fillLevelPerMille); 483 msg->post(); 484} 485 486} // namespace android 487