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 #include <inttypes.h>
24
25 namespace android {
26
27 //--------------------------------------------------------------------------------------------------
GenericPlayer(const AudioPlayback_Parameters * params)28 GenericPlayer::GenericPlayer(const AudioPlayback_Parameters* params) :
29 mDataLocatorType(kDataLocatorNone),
30 mNotifyClient(NULL),
31 mNotifyUser(NULL),
32 mStateFlags(0),
33 mPlaybackParams(*params),
34 mDurationMsec(ANDROID_UNKNOWN_TIME),
35 mPlaybackRatePermille(1000),
36 mCacheStatus(kStatusEmpty),
37 mCacheFill(0),
38 mLastNotifiedCacheFill(0),
39 mCacheFillNotifThreshold(100),
40 mEventFlags(0),
41 mMarkerPositionMs(ANDROID_UNKNOWN_TIME),
42 mPositionUpdatePeriodMs(1000), // per spec
43 mOneShotGeneration(0),
44 mDeliveredNewPosMs(ANDROID_UNKNOWN_TIME),
45 mObservedPositionMs(ANDROID_UNKNOWN_TIME)
46 {
47 SL_LOGD("GenericPlayer::GenericPlayer()");
48
49 mLooper = new android::ALooper();
50
51 // Post-construction accesses need to be protected by mSettingsLock
52 mAndroidAudioLevels.mFinalVolume[0] = 1.0f;
53 mAndroidAudioLevels.mFinalVolume[1] = 1.0f;
54 }
55
56
~GenericPlayer()57 GenericPlayer::~GenericPlayer() {
58 SL_LOGV("GenericPlayer::~GenericPlayer()");
59
60 resetDataLocator();
61 }
62
63
init(const notif_cbf_t cbf,void * notifUser)64 void GenericPlayer::init(const notif_cbf_t cbf, void* notifUser) {
65 SL_LOGD("GenericPlayer::init()");
66
67 {
68 android::Mutex::Autolock autoLock(mNotifyClientLock);
69 mNotifyClient = cbf;
70 mNotifyUser = notifUser;
71 }
72
73 mLooper->registerHandler(this);
74 mLooper->start(false /*runOnCallingThread*/, false /*canCallJava*/, PRIORITY_DEFAULT);
75 }
76
77
preDestroy()78 void GenericPlayer::preDestroy() {
79 SL_LOGD("GenericPlayer::preDestroy()");
80 {
81 android::Mutex::Autolock autoLock(mNotifyClientLock);
82 mNotifyClient = NULL;
83 mNotifyUser = NULL;
84 }
85
86 mLooper->stop();
87 mLooper->unregisterHandler(id());
88 }
89
90
setDataSource(const char * uri)91 void GenericPlayer::setDataSource(const char *uri) {
92 SL_LOGV("GenericPlayer::setDataSource(uri=%s)", uri);
93 resetDataLocator();
94
95 mDataLocator.uriRef = uri;
96
97 mDataLocatorType = kDataLocatorUri;
98 }
99
100
setDataSource(int fd,int64_t offset,int64_t length,bool closeAfterUse)101 void GenericPlayer::setDataSource(int fd, int64_t offset, int64_t length, bool closeAfterUse) {
102 SL_LOGV("GenericPlayer::setDataSource(fd=%d, offset=%lld, length=%lld, closeAfterUse=%s)", fd,
103 offset, length, closeAfterUse ? "true" : "false");
104 resetDataLocator();
105
106 mDataLocator.fdi.fd = fd;
107
108 struct stat sb;
109 int ret = fstat(fd, &sb);
110 if (ret != 0) {
111 SL_LOGE("GenericPlayer::setDataSource: fstat(%d) failed: %d, %s", fd, ret, strerror(errno));
112 return;
113 }
114
115 if (offset >= sb.st_size) {
116 SL_LOGE("SfPlayer::setDataSource: invalid offset");
117 return;
118 }
119 mDataLocator.fdi.offset = offset;
120
121 if (PLAYER_FD_FIND_FILE_SIZE == length) {
122 mDataLocator.fdi.length = sb.st_size;
123 } else if (offset + length > sb.st_size) {
124 mDataLocator.fdi.length = sb.st_size - offset;
125 } else {
126 mDataLocator.fdi.length = length;
127 }
128
129 mDataLocator.fdi.mCloseAfterUse = closeAfterUse;
130
131 mDataLocatorType = kDataLocatorFd;
132 }
133
134
prepare()135 void GenericPlayer::prepare() {
136 SL_LOGD("GenericPlayer::prepare()");
137 // do not attempt prepare more than once
138 if (!(mStateFlags & (kFlagPrepared | kFlagPreparedUnsuccessfully))) {
139 sp<AMessage> msg = new AMessage(kWhatPrepare, this);
140 msg->post();
141 }
142 }
143
144
play()145 void GenericPlayer::play() {
146 SL_LOGD("GenericPlayer::play()");
147 sp<AMessage> msg = new AMessage(kWhatPlay, this);
148 msg->post();
149 }
150
151
pause()152 void GenericPlayer::pause() {
153 SL_LOGD("GenericPlayer::pause()");
154 sp<AMessage> msg = new AMessage(kWhatPause, this);
155 msg->post();
156 }
157
158
stop()159 void GenericPlayer::stop() {
160 SL_LOGD("GenericPlayer::stop()");
161 (new AMessage(kWhatPause, this))->post();
162
163 // after a stop, playback should resume from the start.
164 seek(0);
165 }
166
167
seek(int64_t timeMsec)168 void GenericPlayer::seek(int64_t timeMsec) {
169 SL_LOGV("GenericPlayer::seek %lld", timeMsec);
170 if (timeMsec < 0 && timeMsec != ANDROID_UNKNOWN_TIME) {
171 SL_LOGE("GenericPlayer::seek error, can't seek to negative time %" PRId64 "ms", timeMsec);
172 return;
173 }
174 sp<AMessage> msg = new AMessage(kWhatSeek, this);
175 msg->setInt64(WHATPARAM_SEEK_SEEKTIME_MS, timeMsec);
176 msg->post();
177 }
178
179
loop(bool loop)180 void GenericPlayer::loop(bool loop) {
181 SL_LOGV("GenericPlayer::loop %s", loop ? "true" : "false");
182 sp<AMessage> msg = new AMessage(kWhatLoop, this);
183 msg->setInt32(WHATPARAM_LOOP_LOOPING, (int32_t)loop);
184 msg->post();
185 }
186
187
setBufferingUpdateThreshold(int16_t thresholdPercent)188 void GenericPlayer::setBufferingUpdateThreshold(int16_t thresholdPercent) {
189 SL_LOGV("GenericPlayer::setBufferingUpdateThreshold %d", thresholdPercent);
190 sp<AMessage> msg = new AMessage(kWhatBuffUpdateThres, this);
191 msg->setInt32(WHATPARAM_BUFFERING_UPDATETHRESHOLD_PERCENT, (int32_t)thresholdPercent);
192 msg->post();
193 }
194
195
196 //--------------------------------------------------
getDurationMsec(int * msec)197 void GenericPlayer::getDurationMsec(int* msec) {
198 Mutex::Autolock _l(mSettingsLock);
199 *msec = mDurationMsec;
200 }
201
202 //--------------------------------------------------
setVolume(float leftVol,float rightVol)203 void GenericPlayer::setVolume(float leftVol, float rightVol)
204 {
205 {
206 Mutex::Autolock _l(mSettingsLock);
207 mAndroidAudioLevels.mFinalVolume[0] = leftVol;
208 mAndroidAudioLevels.mFinalVolume[1] = rightVol;
209 }
210 // send a message for the volume to be updated by the object which implements the volume
211 (new AMessage(kWhatVolumeUpdate, this))->post();
212 }
213
214
215 //--------------------------------------------------
attachAuxEffect(int32_t effectId)216 void GenericPlayer::attachAuxEffect(int32_t effectId)
217 {
218 SL_LOGV("GenericPlayer::attachAuxEffect(id=%d)", effectId);
219 sp<AMessage> msg = new AMessage(kWhatAttachAuxEffect, this);
220 msg->setInt32(WHATPARAM_ATTACHAUXEFFECT, effectId);
221 msg->post();
222 }
223
224
225 //--------------------------------------------------
setAuxEffectSendLevel(float level)226 void GenericPlayer::setAuxEffectSendLevel(float level)
227 {
228 SL_LOGV("GenericPlayer::setAuxEffectSendLevel(level=%g)", level);
229 sp<AMessage> msg = new AMessage(kWhatSetAuxEffectSendLevel, this);
230 msg->setFloat(WHATPARAM_SETAUXEFFECTSENDLEVEL, level);
231 msg->post();
232 }
233
234
235 //--------------------------------------------------
setPlaybackRate(int32_t ratePermille)236 void GenericPlayer::setPlaybackRate(int32_t ratePermille) {
237 SL_LOGV("GenericPlayer::setPlaybackRate(ratePermille=%d)", ratePermille);
238 {
239 Mutex::Autolock _l(mSettingsLock);
240 mPlaybackRatePermille = (int16_t)ratePermille;
241 }
242 }
243
244 //--------------------------------------------------
245 // Call after changing any of the IPlay settings related to SL_PLAYEVENT_*
setPlayEvents(int32_t eventFlags,int32_t markerPositionMs,int32_t positionUpdatePeriodMs)246 void GenericPlayer::setPlayEvents(int32_t eventFlags, int32_t markerPositionMs,
247 int32_t positionUpdatePeriodMs)
248 {
249 // Normalize ms that are within the valid unsigned range, but not in the int32_t range
250 if (markerPositionMs < 0) {
251 markerPositionMs = ANDROID_UNKNOWN_TIME;
252 }
253 if (positionUpdatePeriodMs < 0) {
254 positionUpdatePeriodMs = ANDROID_UNKNOWN_TIME;
255 }
256 // markers are delivered accurately, but new position updates are limited to every 100 ms
257 if (positionUpdatePeriodMs < 100) {
258 positionUpdatePeriodMs = 100;
259 }
260 sp<AMessage> msg = new AMessage(kWhatSetPlayEvents, this);
261 msg->setInt32(WHATPARAM_SETPLAYEVENTS_FLAGS, eventFlags);
262 msg->setInt32(WHATPARAM_SETPLAYEVENTS_MARKER, markerPositionMs);
263 msg->setInt32(WHATPARAM_SETPLAYEVENTS_UPDATE, positionUpdatePeriodMs);
264 msg->post();
265 }
266
267
268 //--------------------------------------------------
269 /*
270 * post-condition: mDataLocatorType == kDataLocatorNone
271 *
272 */
resetDataLocator()273 void GenericPlayer::resetDataLocator() {
274 SL_LOGV("GenericPlayer::resetDataLocator()");
275 if (mDataLocatorType == kDataLocatorFd && mDataLocator.fdi.mCloseAfterUse) {
276 (void) ::close(mDataLocator.fdi.fd);
277 // would be redundant, as we're about to invalidate the union mDataLocator
278 //mDataLocator.fdi.fd = -1;
279 //mDataLocator.fdi.mCloseAfterUse = false;
280 }
281 mDataLocatorType = kDataLocatorNone;
282 }
283
284
notify(const char * event,int data,bool async)285 void GenericPlayer::notify(const char* event, int data, bool async) {
286 SL_LOGV("GenericPlayer::notify(event=%s, data=%d, async=%s)", event, data,
287 async ? "true" : "false");
288 sp<AMessage> msg = new AMessage(kWhatNotif, this);
289 msg->setInt32(event, (int32_t)data);
290 if (async) {
291 msg->post();
292 } else {
293 onNotify(msg);
294 }
295 }
296
297
notify(const char * event,int data1,int data2,bool async)298 void GenericPlayer::notify(const char* event, int data1, int data2, bool async) {
299 SL_LOGV("GenericPlayer::notify(event=%s, data1=%d, data2=%d, async=%s)", event, data1, data2,
300 async ? "true" : "false");
301 sp<AMessage> msg = new AMessage(kWhatNotif, this);
302 msg->setRect(event, 0, 0, (int32_t)data1, (int32_t)data2);
303 if (async) {
304 msg->post();
305 } else {
306 onNotify(msg);
307 }
308 }
309
310
311 //--------------------------------------------------
312 // AHandler implementation
onMessageReceived(const sp<AMessage> & msg)313 void GenericPlayer::onMessageReceived(const sp<AMessage> &msg) {
314 SL_LOGV("GenericPlayer::onMessageReceived()");
315 switch (msg->what()) {
316 case kWhatPrepare:
317 SL_LOGV("kWhatPrepare");
318 onPrepare();
319 break;
320
321 case kWhatNotif:
322 SL_LOGV("kWhatNotif");
323 onNotify(msg);
324 break;
325
326 case kWhatPlay:
327 SL_LOGV("kWhatPlay");
328 onPlay();
329 break;
330
331 case kWhatPause:
332 SL_LOGV("kWhatPause");
333 onPause();
334 break;
335
336 case kWhatSeek:
337 SL_LOGV("kWhatSeek");
338 onSeek(msg);
339 break;
340
341 case kWhatLoop:
342 SL_LOGV("kWhatLoop");
343 onLoop(msg);
344 break;
345
346 case kWhatVolumeUpdate:
347 SL_LOGV("kWhatVolumeUpdate");
348 onVolumeUpdate();
349 break;
350
351 case kWhatSeekComplete:
352 SL_LOGV("kWhatSeekComplete");
353 onSeekComplete();
354 break;
355
356 case kWhatBufferingUpdate:
357 SL_LOGV("kWhatBufferingUpdate");
358 onBufferingUpdate(msg);
359 break;
360
361 case kWhatBuffUpdateThres:
362 SL_LOGV("kWhatBuffUpdateThres");
363 onSetBufferingUpdateThreshold(msg);
364 break;
365
366 case kWhatAttachAuxEffect:
367 SL_LOGV("kWhatAttachAuxEffect");
368 onAttachAuxEffect(msg);
369 break;
370
371 case kWhatSetAuxEffectSendLevel:
372 SL_LOGV("kWhatSetAuxEffectSendLevel");
373 onSetAuxEffectSendLevel(msg);
374 break;
375
376 case kWhatSetPlayEvents:
377 SL_LOGV("kWhatSetPlayEvents");
378 onSetPlayEvents(msg);
379 break;
380
381 case kWhatOneShot:
382 SL_LOGV("kWhatOneShot");
383 onOneShot(msg);
384 break;
385
386 default:
387 SL_LOGE("GenericPlayer::onMessageReceived unknown message %d", msg->what());
388 TRESPASS();
389 }
390 }
391
392
393 //--------------------------------------------------
394 // Event handlers
395 // it is strictly verboten to call those methods outside of the event loop
396
onPrepare()397 void GenericPlayer::onPrepare() {
398 SL_LOGV("GenericPlayer::onPrepare()");
399 // Subclass is responsible for indicating whether prepare was successful or unsuccessful
400 // by updating mStateFlags accordingly. It must set exactly one of these two flags.
401 assert(!(mStateFlags & kFlagPrepared) != !(mStateFlags & kFlagPreparedUnsuccessfully));
402 notify(PLAYEREVENT_PREPARED, mStateFlags & kFlagPrepared ? PLAYER_SUCCESS : PLAYER_FAILURE,
403 true /*async*/);
404 SL_LOGD("GenericPlayer::onPrepare() done, mStateFlags=0x%x", mStateFlags);
405 }
406
407
onNotify(const sp<AMessage> & msg)408 void GenericPlayer::onNotify(const sp<AMessage> &msg) {
409 SL_LOGV("GenericPlayer::onNotify()");
410 notif_cbf_t notifClient;
411 void* notifUser;
412 {
413 android::Mutex::Autolock autoLock(mNotifyClientLock);
414 if (NULL == mNotifyClient) {
415 return;
416 } else {
417 notifClient = mNotifyClient;
418 notifUser = mNotifyUser;
419 }
420 }
421
422 int32_t val1, val2;
423 if (msg->findInt32(PLAYEREVENT_PREFETCHSTATUSCHANGE, &val1)) {
424 SL_LOGV("GenericPlayer notifying %s = %d", PLAYEREVENT_PREFETCHSTATUSCHANGE, val1);
425 notifClient(kEventPrefetchStatusChange, val1, 0, notifUser);
426 // There is exactly one notification per message, hence "else if" instead of "if"
427 } else if (msg->findInt32(PLAYEREVENT_PREFETCHFILLLEVELUPDATE, &val1)) {
428 SL_LOGV("GenericPlayer notifying %s = %d", PLAYEREVENT_PREFETCHFILLLEVELUPDATE, val1);
429 notifClient(kEventPrefetchFillLevelUpdate, val1, 0, notifUser);
430 } else if (msg->findInt32(PLAYEREVENT_ENDOFSTREAM, &val1)) {
431 SL_LOGV("GenericPlayer notifying %s = %d", PLAYEREVENT_ENDOFSTREAM, val1);
432 notifClient(kEventEndOfStream, val1, 0, notifUser);
433 } else if (msg->findInt32(PLAYEREVENT_PREPARED, &val1)) {
434 SL_LOGV("GenericPlayer notifying %s = %d", PLAYEREVENT_PREPARED, val1);
435 notifClient(kEventPrepared, val1, 0, notifUser);
436 } else if (msg->findInt32(PLAYEREVENT_CHANNEL_COUNT, &val1)) {
437 SL_LOGV("GenericPlayer notifying %s = %d", PLAYEREVENT_CHANNEL_COUNT, val1);
438 notifClient(kEventChannelCount, val1, 0, notifUser);
439 } else if (msg->findRect(PLAYEREVENT_VIDEO_SIZE_UPDATE, &val1, &val2, &val1, &val2)) {
440 SL_LOGV("GenericPlayer notifying %s = %d, %d", PLAYEREVENT_VIDEO_SIZE_UPDATE, val1, val2);
441 notifClient(kEventHasVideoSize, val1, val2, notifUser);
442 } else if (msg->findInt32(PLAYEREVENT_PLAY, &val1)) {
443 SL_LOGV("GenericPlayer notifying %s = %d", PLAYEREVENT_PLAY, val1);
444 notifClient(kEventPlay, val1, 0, notifUser);
445 } else if (msg->findInt32(PLAYEREVENT_ERRORAFTERPREPARE, &val1)) {
446 SL_LOGV("GenericPlayer notifying %s = %d", PLAYEREVENT_ERRORAFTERPREPARE, val1);
447 notifClient(kEventErrorAfterPrepare, val1, 0, notifUser);
448 } else {
449 SL_LOGV("GenericPlayer notifying unknown");
450 }
451 }
452
453
onPlay()454 void GenericPlayer::onPlay() {
455 SL_LOGD("GenericPlayer::onPlay()");
456 if ((mStateFlags & (kFlagPrepared | kFlagPlaying)) == kFlagPrepared) {
457 SL_LOGD("starting player");
458 mStateFlags |= kFlagPlaying;
459 updateOneShot();
460 }
461 }
462
463
onPause()464 void GenericPlayer::onPause() {
465 SL_LOGD("GenericPlayer::onPause()");
466 if (!(~mStateFlags & (kFlagPrepared | kFlagPlaying))) {
467 SL_LOGV("pausing player");
468 mStateFlags &= ~kFlagPlaying;
469 updateOneShot();
470 }
471 }
472
473
onSeek(const sp<AMessage> & msg)474 void GenericPlayer::onSeek(const sp<AMessage> &msg) {
475 SL_LOGV("GenericPlayer::onSeek");
476 }
477
478
onLoop(const sp<AMessage> & msg)479 void GenericPlayer::onLoop(const sp<AMessage> &msg) {
480 SL_LOGV("GenericPlayer::onLoop");
481 }
482
483
onVolumeUpdate()484 void GenericPlayer::onVolumeUpdate() {
485 SL_LOGV("GenericPlayer::onVolumeUpdate");
486 }
487
488
onSeekComplete()489 void GenericPlayer::onSeekComplete() {
490 SL_LOGD("GenericPlayer::onSeekComplete()");
491 mStateFlags &= ~kFlagSeeking;
492 // avoid spurious or lost events caused by seeking past a marker
493 mDeliveredNewPosMs = ANDROID_UNKNOWN_TIME;
494 mObservedPositionMs = ANDROID_UNKNOWN_TIME;
495 updateOneShot();
496 }
497
498
onBufferingUpdate(const sp<AMessage> & msg)499 void GenericPlayer::onBufferingUpdate(const sp<AMessage> &msg) {
500 SL_LOGV("GenericPlayer::onBufferingUpdate");
501 }
502
503
onSetBufferingUpdateThreshold(const sp<AMessage> & msg)504 void GenericPlayer::onSetBufferingUpdateThreshold(const sp<AMessage> &msg) {
505 SL_LOGV("GenericPlayer::onSetBufferingUpdateThreshold");
506 int32_t thresholdPercent = 0;
507 if (msg->findInt32(WHATPARAM_BUFFERING_UPDATETHRESHOLD_PERCENT, &thresholdPercent)) {
508 Mutex::Autolock _l(mSettingsLock);
509 mCacheFillNotifThreshold = (int16_t)thresholdPercent;
510 }
511 }
512
513
onAttachAuxEffect(const sp<AMessage> & msg)514 void GenericPlayer::onAttachAuxEffect(const sp<AMessage> &msg) {
515 SL_LOGV("GenericPlayer::onAttachAuxEffect()");
516 }
517
518
onSetAuxEffectSendLevel(const sp<AMessage> & msg)519 void GenericPlayer::onSetAuxEffectSendLevel(const sp<AMessage> &msg) {
520 SL_LOGV("GenericPlayer::onSetAuxEffectSendLevel()");
521 }
522
523
onSetPlayEvents(const sp<AMessage> & msg)524 void GenericPlayer::onSetPlayEvents(const sp<AMessage> &msg) {
525 SL_LOGV("GenericPlayer::onSetPlayEvents()");
526 int32_t eventFlags, markerPositionMs, positionUpdatePeriodMs;
527 if (msg->findInt32(WHATPARAM_SETPLAYEVENTS_FLAGS, &eventFlags) &&
528 msg->findInt32(WHATPARAM_SETPLAYEVENTS_MARKER, &markerPositionMs) &&
529 msg->findInt32(WHATPARAM_SETPLAYEVENTS_UPDATE, &positionUpdatePeriodMs)) {
530 mEventFlags = eventFlags;
531 mMarkerPositionMs = markerPositionMs;
532 mPositionUpdatePeriodMs = positionUpdatePeriodMs;
533 updateOneShot();
534 }
535 }
536
537
onOneShot(const sp<AMessage> & msg)538 void GenericPlayer::onOneShot(const sp<AMessage> &msg) {
539 SL_LOGV("GenericPlayer::onOneShot()");
540 int32_t generation;
541 if (msg->findInt32(WHATPARAM_ONESHOT_GENERATION, &generation)) {
542 if (generation != mOneShotGeneration) {
543 SL_LOGV("GenericPlayer::onOneShot() generation %d cancelled; latest is %d",
544 generation, mOneShotGeneration);
545 return;
546 }
547 updateOneShot();
548 }
549 }
550
551
552 //-------------------------------------------------
notifyStatus()553 void GenericPlayer::notifyStatus() {
554 SL_LOGV("GenericPlayer::notifyStatus");
555 notify(PLAYEREVENT_PREFETCHSTATUSCHANGE, (int32_t)mCacheStatus, true /*async*/);
556 }
557
558
notifyCacheFill()559 void GenericPlayer::notifyCacheFill() {
560 SL_LOGV("GenericPlayer::notifyCacheFill");
561 mLastNotifiedCacheFill = mCacheFill;
562 notify(PLAYEREVENT_PREFETCHFILLLEVELUPDATE, (int32_t)mLastNotifiedCacheFill, true/*async*/);
563 }
564
565
seekComplete()566 void GenericPlayer::seekComplete() {
567 SL_LOGV("GenericPlayer::seekComplete");
568 sp<AMessage> msg = new AMessage(kWhatSeekComplete, this);
569 msg->post();
570 }
571
572
bufferingUpdate(int16_t fillLevelPerMille)573 void GenericPlayer::bufferingUpdate(int16_t fillLevelPerMille) {
574 SL_LOGV("GenericPlayer::bufferingUpdate");
575 sp<AMessage> msg = new AMessage(kWhatBufferingUpdate, this);
576 msg->setInt32(WHATPARAM_BUFFERING_UPDATE, fillLevelPerMille);
577 msg->post();
578 }
579
580
581 // For the meaning of positionMs, see comment in declaration at android_GenericPlayer.h
updateOneShot(int positionMs)582 void GenericPlayer::updateOneShot(int positionMs)
583 {
584 SL_LOGV("GenericPlayer::updateOneShot");
585
586 // nop until prepared
587 if (!(mStateFlags & kFlagPrepared)) {
588 return;
589 }
590
591 // cancel any pending one-shot(s)
592 ++mOneShotGeneration;
593
594 // don't restart one-shot if player is paused or stopped
595 if (!(mStateFlags & kFlagPlaying)) {
596 return;
597 }
598
599 // get current player position in milliseconds
600 if (positionMs < 0) {
601 positionMs = ANDROID_UNKNOWN_TIME;
602 }
603 if (positionMs == ANDROID_UNKNOWN_TIME) {
604 getPositionMsec(&positionMs);
605 // normalize it
606 if (positionMs < 0) {
607 positionMs = ANDROID_UNKNOWN_TIME;
608 }
609 if (ANDROID_UNKNOWN_TIME == positionMs) {
610 // getPositionMsec is not working for some reason, give up
611 //ALOGV("Does anyone really know what time it is?");
612 return;
613 }
614 }
615
616 // if we observe the player position going backwards, even without without a seek, then recover
617 if (mObservedPositionMs != ANDROID_UNKNOWN_TIME && positionMs < mObservedPositionMs) {
618 mDeliveredNewPosMs = ANDROID_UNKNOWN_TIME;
619 mObservedPositionMs = positionMs;
620 }
621
622 // delayUs is the expected delay between current position and marker;
623 // the default is infinity in case there are no upcoming marker(s)
624 int64_t delayUs = -1;
625
626 // is there a marker?
627 if ((mEventFlags & SL_PLAYEVENT_HEADATMARKER) && (mMarkerPositionMs != ANDROID_UNKNOWN_TIME)) {
628 // check to see if we have observed the position passing through the marker
629 if (mObservedPositionMs <= mMarkerPositionMs && mMarkerPositionMs <= positionMs) {
630 notify(PLAYEREVENT_PLAY, (int32_t) SL_PLAYEVENT_HEADATMARKER, true /*async*/);
631 } else if (positionMs < mMarkerPositionMs) {
632 delayUs = (mMarkerPositionMs - positionMs) * 1000LL;
633 }
634 }
635
636 // are periodic position updates needed?
637 if ((mEventFlags & SL_PLAYEVENT_HEADATNEWPOS) &&
638 (mPositionUpdatePeriodMs != ANDROID_UNKNOWN_TIME)) {
639 // check to see if we have observed the position passing through a virtual marker, where the
640 // virtual marker is at the previously delivered new position plus position update period
641 int32_t virtualMarkerMs;
642 if (mDeliveredNewPosMs != ANDROID_UNKNOWN_TIME) {
643 virtualMarkerMs = mDeliveredNewPosMs + mPositionUpdatePeriodMs;
644 } else if (mObservedPositionMs != ANDROID_UNKNOWN_TIME) {
645 virtualMarkerMs = mObservedPositionMs + mPositionUpdatePeriodMs;
646 // pretend there has been an update in the past
647 mDeliveredNewPosMs = mObservedPositionMs;
648 } else {
649 virtualMarkerMs = positionMs + mPositionUpdatePeriodMs;
650 // pretend there has been an update in the past
651 mDeliveredNewPosMs = positionMs;
652 }
653 // nextVirtualMarkerMs will be set to the position of the next upcoming virtual marker
654 int32_t nextVirtualMarkerMs;
655 if (mObservedPositionMs <= virtualMarkerMs && virtualMarkerMs <= positionMs) {
656 // we did pass through the virtual marker, now compute the next virtual marker
657 mDeliveredNewPosMs = virtualMarkerMs;
658 nextVirtualMarkerMs = virtualMarkerMs + mPositionUpdatePeriodMs;
659 // re-synchronize if we missed an update
660 if (nextVirtualMarkerMs <= positionMs) {
661 SL_LOGW("Missed SL_PLAYEVENT_HEADATNEWPOS for position %d; current position %d",
662 nextVirtualMarkerMs, positionMs);
663 // try to catch up by setting next goal to current position plus update period
664 mDeliveredNewPosMs = positionMs;
665 nextVirtualMarkerMs = positionMs + mPositionUpdatePeriodMs;
666 }
667 notify(PLAYEREVENT_PLAY, (int32_t) SL_PLAYEVENT_HEADATNEWPOS, true /*async*/);
668 } else {
669 // we did not pass through the virtual marker yet, so use same marker again
670 nextVirtualMarkerMs = virtualMarkerMs;
671 }
672 // note that if arithmetic overflow occurred, nextVirtualMarkerMs will be negative
673 if (positionMs < nextVirtualMarkerMs) {
674 int64_t trialDelayUs;
675 trialDelayUs = (nextVirtualMarkerMs - positionMs) * 1000LL;
676 if (trialDelayUs > 0 && (delayUs == -1 || trialDelayUs < delayUs)) {
677 delayUs = trialDelayUs;
678 }
679 }
680 }
681
682 // we have a new observed position
683 mObservedPositionMs = positionMs;
684
685 if (mPlaybackRatePermille == 0) {
686 // playback is frozen, no update expected (and no division by zero below)
687 return;
688 }
689
690 // post the new one-shot message if needed
691 if (advancesPositionInRealTime() && delayUs >= 0) {
692 // scale delay according to playback rate (reported positions won't change, but reported
693 // time will advance slower or faster depending on rate)
694 {
695 Mutex::Autolock _l(mSettingsLock);
696 delayUs = delayUs * 1000 / mPlaybackRatePermille;
697 }
698
699 // 20 ms min delay to avoid near busy waiting
700 if (delayUs < 20000LL) {
701 delayUs = 20000LL;
702 }
703 // 1 minute max delay avoids indefinite memory leaks caused by cancelled one-shots
704 if (delayUs > 60000000LL) {
705 delayUs = 60000000LL;
706 }
707 //SL_LOGI("delayUs = %lld", delayUs);
708 sp<AMessage> msg = new AMessage(kWhatOneShot, this);
709 msg->setInt32(WHATPARAM_ONESHOT_GENERATION, mOneShotGeneration);
710 msg->post(delayUs);
711 }
712
713 }
714
715 } // namespace android
716