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