android_GenericPlayer.cpp revision b2549c73290f1955f3a7731bf98446a45f295dfa
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//-------------------------------------------------- 248/* 249 * post-condition: mDataLocatorType == kDataLocatorNone 250 * 251 */ 252void GenericPlayer::resetDataLocator() { 253 SL_LOGV("GenericPlayer::resetDataLocator()"); 254 mDataLocatorType = kDataLocatorNone; 255} 256 257 258void GenericPlayer::notify(const char* event, int data, bool async) { 259 SL_LOGV("GenericPlayer::notify(event=%s, data=%d, async=%s)", event, data, 260 async ? "true" : "false"); 261 sp<AMessage> msg = new AMessage(kWhatNotif, id()); 262 msg->setInt32(event, (int32_t)data); 263 if (async) { 264 msg->post(); 265 } else { 266 this->onNotify(msg); 267 } 268} 269 270 271void GenericPlayer::notify(const char* event, int data1, int data2, bool async) { 272 SL_LOGV("GenericPlayer::notify(event=%s, data1=%d, data2=%d, async=%s)", event, data1, data2, 273 async ? "true" : "false"); 274 sp<AMessage> msg = new AMessage(kWhatNotif, id()); 275 msg->setRect(event, 0, 0, (int32_t)data1, (int32_t)data2); 276 if (async) { 277 msg->post(); 278 } else { 279 this->onNotify(msg); 280 } 281} 282 283 284//-------------------------------------------------- 285// AHandler implementation 286void GenericPlayer::onMessageReceived(const sp<AMessage> &msg) { 287 SL_LOGV("GenericPlayer::onMessageReceived()"); 288 switch (msg->what()) { 289 case kWhatPrepare: 290 SL_LOGD("kWhatPrepare"); 291 onPrepare(); 292 break; 293 294 case kWhatNotif: 295 SL_LOGI("kWhatNotif"); 296 onNotify(msg); 297 break; 298 299 case kWhatPlay: 300 SL_LOGV("kWhatPlay"); 301 onPlay(); 302 break; 303 304 case kWhatPause: 305 SL_LOGV("kWhatPause"); 306 onPause(); 307 break; 308 309 case kWhatSeek: 310 SL_LOGV("kWhatSeek"); 311 onSeek(msg); 312 break; 313 314 case kWhatLoop: 315 SL_LOGV("kWhatLoop"); 316 onLoop(msg); 317 break; 318 319 case kWhatVolumeUpdate: 320 SL_LOGV("kWhatVolumeUpdate"); 321 onVolumeUpdate(); 322 break; 323 324 case kWhatSeekComplete: 325 SL_LOGV("kWhatSeekComplete"); 326 onSeekComplete(); 327 break; 328 329 case kWhatBufferingUpdate: 330 SL_LOGV("kWhatBufferingUpdate"); 331 onBufferingUpdate(msg); 332 break; 333 334 case kWhatBuffUpdateThres: 335 SL_LOGV("kWhatBuffUpdateThres"); 336 onSetBufferingUpdateThreshold(msg); 337 break; 338 339 default: 340 SL_LOGV("kWhatPlay"); 341 TRESPASS(); 342 } 343} 344 345 346//-------------------------------------------------- 347// Event handlers 348// it is strictly verboten to call those methods outside of the event loop 349 350void GenericPlayer::onPrepare() { 351 SL_LOGD("GenericPlayer::onPrepare()"); 352 if (!(mStateFlags & kFlagPrepared)) { 353 mStateFlags |= kFlagPrepared; 354 notify(PLAYEREVENT_PREPARED, PLAYER_SUCCESS, false /*async*/); 355 } 356 SL_LOGD("GenericPlayer::onPrepare() done, mStateFlags=0x%x", mStateFlags); 357} 358 359 360void GenericPlayer::onNotify(const sp<AMessage> &msg) { 361 SL_LOGV("GenericPlayer::onNotify()"); 362 notif_cbf_t notifClient; 363 void* notifUser; 364 { 365 android::Mutex::Autolock autoLock(mNotifyClientLock); 366 if (NULL == mNotifyClient) { 367 return; 368 } else { 369 notifClient = mNotifyClient; 370 notifUser = mNotifyUser; 371 } 372 } 373 374 int32_t val1, val2; 375 if (msg->findInt32(PLAYEREVENT_PREFETCHSTATUSCHANGE, &val1)) { 376 SL_LOGV("GenericPlayer notifying %s = %d", PLAYEREVENT_PREFETCHSTATUSCHANGE, val1); 377 notifClient(kEventPrefetchStatusChange, val1, 0, notifUser); 378 } else if (msg->findInt32(PLAYEREVENT_PREFETCHFILLLEVELUPDATE, &val1)) { 379 SL_LOGV("GenericPlayer notifying %s = %d", PLAYEREVENT_PREFETCHFILLLEVELUPDATE, val1); 380 notifClient(kEventPrefetchFillLevelUpdate, val1, 0, notifUser); 381 } else if (msg->findInt32(PLAYEREVENT_ENDOFSTREAM, &val1)) { 382 SL_LOGV("GenericPlayer notifying %s = %d", PLAYEREVENT_ENDOFSTREAM, val1); 383 notifClient(kEventEndOfStream, val1, 0, notifUser); 384 } else if (msg->findInt32(PLAYEREVENT_PREPARED, &val1)) { 385 SL_LOGV("GenericPlayer notifying %s = %d", PLAYEREVENT_PREPARED, val1); 386 notifClient(kEventPrepared, val1, 0, notifUser); 387 } else if (msg->findRect(PLAYEREVENT_VIDEO_SIZE_UPDATE, &val1, &val2, &val1, &val2)) { 388 SL_LOGV("GenericPlayer notifying %s = %d, %d", PLAYEREVENT_VIDEO_SIZE_UPDATE, val1, val2); 389 notifClient(kEventHasVideoSize, val1, val2, notifUser); 390 } else { 391 SL_LOGV("GenericPlayer notifying unknown"); 392 } 393} 394 395 396void GenericPlayer::onPlay() { 397 SL_LOGD("GenericPlayer::onPlay()"); 398 if ((mStateFlags & kFlagPrepared)) { 399 SL_LOGD("starting player"); 400 mStateFlags |= kFlagPlaying; 401 } else { 402 SL_LOGV("NOT starting player mStateFlags=0x%x", mStateFlags); 403 } 404} 405 406 407void GenericPlayer::onPause() { 408 SL_LOGD("GenericPlayer::onPause()"); 409 if ((mStateFlags & kFlagPrepared)) { 410 mStateFlags &= ~kFlagPlaying; 411 } 412} 413 414 415void GenericPlayer::onSeek(const sp<AMessage> &msg) { 416 SL_LOGV("GenericPlayer::onSeek"); 417} 418 419 420void GenericPlayer::onLoop(const sp<AMessage> &msg) { 421 SL_LOGV("GenericPlayer::onLoop"); 422} 423 424 425void GenericPlayer::onVolumeUpdate() { 426 SL_LOGV("GenericPlayer::onVolumeUpdate"); 427} 428 429 430void GenericPlayer::onSeekComplete() { 431 SL_LOGD("GenericPlayer::onSeekComplete()"); 432 mStateFlags &= ~kFlagSeeking; 433} 434 435 436void GenericPlayer::onBufferingUpdate(const sp<AMessage> &msg) { 437 SL_LOGV("GenericPlayer::onBufferingUpdate"); 438} 439 440 441void GenericPlayer::onSetBufferingUpdateThreshold(const sp<AMessage> &msg) { 442 SL_LOGV("GenericPlayer::onSetBufferingUpdateThreshold"); 443 int32_t thresholdPercent = 0; 444 if (msg->findInt32(WHATPARAM_BUFFERING_UPDATETHRESHOLD_PERCENT, &thresholdPercent)) { 445 Mutex::Autolock _l(mSettingsLock); 446 mCacheFillNotifThreshold = (int16_t)thresholdPercent; 447 } 448} 449 450 451//------------------------------------------------- 452void GenericPlayer::notifyStatus() { 453 SL_LOGV("GenericPlayer::notifyStatus"); 454 notify(PLAYEREVENT_PREFETCHSTATUSCHANGE, (int32_t)mCacheStatus, true /*async*/); 455} 456 457 458void GenericPlayer::notifyCacheFill() { 459 SL_LOGV("GenericPlayer::notifyCacheFill"); 460 mLastNotifiedCacheFill = mCacheFill; 461 notify(PLAYEREVENT_PREFETCHFILLLEVELUPDATE, (int32_t)mLastNotifiedCacheFill, true/*async*/); 462} 463 464 465void GenericPlayer::seekComplete() { 466 SL_LOGV("GenericPlayer::seekComplete"); 467 sp<AMessage> msg = new AMessage(kWhatSeekComplete, id()); 468 msg->post(); 469} 470 471 472void GenericPlayer::bufferingUpdate(int16_t fillLevelPerMille) { 473 SL_LOGV("GenericPlayer::bufferingUpdate"); 474 sp<AMessage> msg = new AMessage(kWhatBufferingUpdate, id()); 475 msg->setInt32(WHATPARAM_BUFFERING_UPDATE, fillLevelPerMille); 476 msg->post(); 477} 478 479} // namespace android 480