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