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