android_GenericPlayer.cpp revision 4ee246c55533bdab8ab5fa0f0581744fe58e7c91
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_LOGI("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 sp<AMessage> msg = new AMessage(kWhatSeek, id()); 145 msg->setInt64(WHATPARAM_SEEK_SEEKTIME_MS, timeMsec); 146 msg->post(); 147} 148 149 150void GenericPlayer::loop(bool loop) { 151 sp<AMessage> msg = new AMessage(kWhatLoop, id()); 152 msg->setInt32(WHATPARAM_LOOP_LOOPING, (int32_t)loop); 153 msg->post(); 154} 155 156 157void GenericPlayer::setBufferingUpdateThreshold(int16_t thresholdPercent) { 158 sp<AMessage> msg = new AMessage(kWhatBuffUpdateThres, id()); 159 msg->setInt32(WHATPARAM_BUFFERING_UPDATETHRESHOLD_PERCENT, (int32_t)thresholdPercent); 160 msg->post(); 161} 162 163 164//-------------------------------------------------- 165void GenericPlayer::getDurationMsec(int* msec) { 166 *msec = mDurationMsec; 167} 168 169void GenericPlayer::getPositionMsec(int* msec) { 170 *msec = mPositionMsec; 171} 172 173//-------------------------------------------------- 174void GenericPlayer::setVolume(bool mute, bool useStereoPos, 175 XApermille stereoPos, XAmillibel volume) { 176 177 // compute amplification as the combination of volume level and stereo position 178 float leftVol = 1.0f, rightVol = 1.0f; 179 // amplification from volume level 180 leftVol *= sles_to_android_amplification(volume); 181 rightVol = leftVol; 182 183 // amplification from direct level (changed in SLEffectSendtItf and SLAndroidEffectSendItf) 184 // FIXME use calculation below when supporting effects 185 //leftVol *= mAndroidAudioLevels.mAmplFromDirectLevel; 186 //rightVol *= mAndroidAudioLevels.mAmplFromDirectLevel; 187 188 // amplification from stereo position 189 if (useStereoPos) { 190 // panning law depends on number of channels of content: stereo panning vs 2ch. balance 191 if (1 == mChannelCount) { 192 // stereo panning 193 double theta = (1000 + stereoPos) * M_PI_4 / 1000.0f; // 0 <= theta <= Pi/2 194 leftVol *= cos(theta); 195 rightVol *= sin(theta); 196 } else { 197 // stereo balance 198 if (stereoPos > 0) { 199 leftVol *= (1000 - stereoPos) / 1000.0f; 200 rightVol *= 1.0f; 201 } else { 202 leftVol *= 1.0f; 203 rightVol *= (1000 + stereoPos) / 1000.0f; 204 } 205 } 206 } 207 208 { 209 Mutex::Autolock _l(mSettingsLock); 210 mAndroidAudioLevels.mMute = mute; 211 mAndroidAudioLevels.mFinalVolume[0] = leftVol; 212 mAndroidAudioLevels.mFinalVolume[1] = rightVol; 213 } 214 215 // send a message for the volume to be updated by the object which implements the volume 216 (new AMessage(kWhatVolumeUpdate, id()))->post(); 217} 218 219 220//-------------------------------------------------- 221/* 222 * post-condition: mDataLocatorType == kDataLocatorNone 223 * 224 */ 225void GenericPlayer::resetDataLocator() { 226 mDataLocatorType = kDataLocatorNone; 227} 228 229 230void GenericPlayer::notify(const char* event, int data, bool async) { 231 sp<AMessage> msg = new AMessage(kWhatNotif, id()); 232 msg->setInt32(event, (int32_t)data); 233 if (async) { 234 msg->post(); 235 } else { 236 this->onNotify(msg); 237 } 238} 239 240 241void GenericPlayer::notify(const char* event, int data1, int data2, bool async) { 242 sp<AMessage> msg = new AMessage(kWhatNotif, id()); 243 msg->setRect(event, 0, 0, (int32_t)data1, (int32_t)data2); 244 if (async) { 245 msg->post(); 246 } else { 247 this->onNotify(msg); 248 } 249} 250 251 252//-------------------------------------------------- 253// AHandler implementation 254void GenericPlayer::onMessageReceived(const sp<AMessage> &msg) { 255 switch (msg->what()) { 256 case kWhatPrepare: 257 onPrepare(); 258 break; 259 260 case kWhatNotif: 261 onNotify(msg); 262 break; 263 264 case kWhatPlay: 265 onPlay(); 266 break; 267 268 case kWhatPause: 269 onPause(); 270 break; 271 272 case kWhatSeek: 273 onSeek(msg); 274 break; 275 276 case kWhatLoop: 277 onLoop(msg); 278 break; 279 280 case kWhatVolumeUpdate: 281 onVolumeUpdate(); 282 break; 283 284 case kWhatSeekComplete: 285 onSeekComplete(); 286 break; 287 288 case kWhatBufferingUpdate: 289 onBufferingUpdate(msg); 290 break; 291 292 case kWhatBuffUpdateThres: 293 onSetBufferingUpdateThreshold(msg); 294 break; 295 296 default: 297 TRESPASS(); 298 } 299} 300 301 302//-------------------------------------------------- 303// Event handlers 304// it is strictly verboten to call those methods outside of the event loop 305 306void GenericPlayer::onPrepare() { 307 SL_LOGD("GenericPlayer::onPrepare()"); 308 if (!(mStateFlags & kFlagPrepared)) { 309 mStateFlags |= kFlagPrepared; 310 notify(PLAYEREVENT_PREPARED, PLAYER_SUCCESS, false /*async*/); 311 } 312 SL_LOGD("GenericPlayer::onPrepare() done, mStateFlags=0x%x", mStateFlags); 313} 314 315 316void GenericPlayer::onNotify(const sp<AMessage> &msg) { 317 if (NULL == mNotifyClient) { 318 return; 319 } 320 321 int32_t val1, val2; 322 if (msg->findInt32(PLAYEREVENT_PREFETCHSTATUSCHANGE, &val1)) { 323 SL_LOGV("GenericPlayer notifying %s = %d", PLAYEREVENT_PREFETCHSTATUSCHANGE, val1); 324 mNotifyClient(kEventPrefetchStatusChange, val1, 0, mNotifyUser); 325 } else if (msg->findInt32(PLAYEREVENT_PREFETCHFILLLEVELUPDATE, &val1)) { 326 SL_LOGV("GenericPlayer notifying %s = %d", PLAYEREVENT_PREFETCHFILLLEVELUPDATE, val1); 327 mNotifyClient(kEventPrefetchFillLevelUpdate, val1, 0, mNotifyUser); 328 } else if (msg->findInt32(PLAYEREVENT_ENDOFSTREAM, &val1)) { 329 SL_LOGV("GenericPlayer notifying %s = %d", PLAYEREVENT_ENDOFSTREAM, val1); 330 mNotifyClient(kEventEndOfStream, val1, 0, mNotifyUser); 331 } else if (msg->findInt32(PLAYEREVENT_PREPARED, &val1)) { 332 SL_LOGV("GenericPlayer notifying %s = %d", PLAYEREVENT_PREPARED, val1); 333 mNotifyClient(kEventPrepared, val1, 0, mNotifyUser); 334 } else if (msg->findRect(PLAYEREVENT_VIDEO_SIZE_UPDATE, &val1, &val2, &val1, &val2)) { 335 SL_LOGV("GenericPlayer notifying %s = %d, %d", PLAYEREVENT_VIDEO_SIZE_UPDATE, val1, val2); 336 mNotifyClient(kEventHasVideoSize, val1, val2, mNotifyUser); 337 } 338} 339 340 341void GenericPlayer::onPlay() { 342 SL_LOGD("GenericPlayer::onPlay()"); 343 if ((mStateFlags & kFlagPrepared)) { 344 SL_LOGD("starting player"); 345 mStateFlags |= kFlagPlaying; 346 } else { 347 SL_LOGV("NOT starting player mStateFlags=0x%x", mStateFlags); 348 } 349} 350 351 352void GenericPlayer::onPause() { 353 SL_LOGD("GenericPlayer::onPause()"); 354 if ((mStateFlags & kFlagPrepared)) { 355 mStateFlags &= ~kFlagPlaying; 356 } 357} 358 359 360void GenericPlayer::onSeek(const sp<AMessage> &msg) { 361 SL_LOGV("GenericPlayer::onSeek"); 362} 363 364 365void GenericPlayer::onLoop(const sp<AMessage> &msg) { 366 SL_LOGV("GenericPlayer::onLoop"); 367} 368 369 370void GenericPlayer::onVolumeUpdate() { 371 372} 373 374 375void GenericPlayer::onSeekComplete() { 376 SL_LOGD("GenericPlayer::onSeekComplete()"); 377 mStateFlags &= ~kFlagSeeking; 378} 379 380 381void GenericPlayer::onBufferingUpdate(const sp<AMessage> &msg) { 382 383} 384 385 386void GenericPlayer::onSetBufferingUpdateThreshold(const sp<AMessage> &msg) { 387 int32_t thresholdPercent = 0; 388 if (msg->findInt32(WHATPARAM_BUFFERING_UPDATETHRESHOLD_PERCENT, &thresholdPercent)) { 389 Mutex::Autolock _l(mSettingsLock); 390 mCacheFillNotifThreshold = (int16_t)thresholdPercent; 391 } 392} 393 394 395//------------------------------------------------- 396void GenericPlayer::notifyStatus() { 397 notify(PLAYEREVENT_PREFETCHSTATUSCHANGE, (int32_t)mCacheStatus, true /*async*/); 398} 399 400 401void GenericPlayer::notifyCacheFill() { 402 mLastNotifiedCacheFill = mCacheFill; 403 notify(PLAYEREVENT_PREFETCHFILLLEVELUPDATE, (int32_t)mLastNotifiedCacheFill, true/*async*/); 404} 405 406 407void GenericPlayer::seekComplete() { 408 sp<AMessage> msg = new AMessage(kWhatSeekComplete, id()); 409 msg->post(); 410} 411 412 413void GenericPlayer::bufferingUpdate(int16_t fillLevelPerMille) { 414 sp<AMessage> msg = new AMessage(kWhatBufferingUpdate, id()); 415 msg->setInt32(WHATPARAM_BUFFERING_UPDATE, fillLevelPerMille); 416 msg->post(); 417} 418 419} // namespace android 420