android_GenericPlayer.cpp revision fa2bd93c3a9852a1f879663eeff598d13cf8fa81
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.mFinalVolume[0] = 1.0f;
48    mAndroidAudioLevels.mFinalVolume[1] = 1.0f;
49}
50
51
52GenericPlayer::~GenericPlayer() {
53    SL_LOGV("GenericPlayer::~GenericPlayer()");
54
55}
56
57
58void GenericPlayer::init(const notif_cbf_t cbf, void* notifUser) {
59    SL_LOGD("GenericPlayer::init()");
60
61    {
62        android::Mutex::Autolock autoLock(mNotifyClientLock);
63        mNotifyClient = cbf;
64        mNotifyUser = notifUser;
65    }
66
67    mLooper->registerHandler(this);
68    mLooper->start(false /*runOnCallingThread*/, false /*canCallJava*/, mLooperPriority);
69}
70
71
72void GenericPlayer::preDestroy() {
73    SL_LOGD("GenericPlayer::preDestroy()");
74    {
75        android::Mutex::Autolock autoLock(mNotifyClientLock);
76        mNotifyClient = NULL;
77        mNotifyUser = NULL;
78    }
79
80    mLooper->stop();
81    mLooper->unregisterHandler(id());
82}
83
84
85void GenericPlayer::setDataSource(const char *uri) {
86    SL_LOGV("GenericPlayer::setDataSource(uri=%s)", uri);
87    resetDataLocator();
88
89    mDataLocator.uriRef = uri;
90
91    mDataLocatorType = kDataLocatorUri;
92}
93
94
95void GenericPlayer::setDataSource(int fd, int64_t offset, int64_t length) {
96    SL_LOGV("GenericPlayer::setDataSource(fd=%d, offset=%lld, length=%lld)", fd, offset, length);
97    resetDataLocator();
98
99    mDataLocator.fdi.fd = fd;
100
101    struct stat sb;
102    int ret = fstat(fd, &sb);
103    if (ret != 0) {
104        SL_LOGE("GenericPlayer::setDataSource: fstat(%d) failed: %d, %s", fd, ret, strerror(errno));
105        return;
106    }
107
108    if (offset >= sb.st_size) {
109        SL_LOGE("SfPlayer::setDataSource: invalid offset");
110        return;
111    }
112    mDataLocator.fdi.offset = offset;
113
114    if (PLAYER_FD_FIND_FILE_SIZE == length) {
115        mDataLocator.fdi.length = sb.st_size;
116    } else if (offset + length > sb.st_size) {
117        mDataLocator.fdi.length = sb.st_size - offset;
118    } else {
119        mDataLocator.fdi.length = length;
120    }
121
122    mDataLocatorType = kDataLocatorFd;
123}
124
125
126void GenericPlayer::prepare() {
127    SL_LOGD("GenericPlayer::prepare()");
128    sp<AMessage> msg = new AMessage(kWhatPrepare, id());
129    msg->post();
130}
131
132
133void GenericPlayer::play() {
134    SL_LOGD("GenericPlayer::play()");
135    sp<AMessage> msg = new AMessage(kWhatPlay, id());
136    msg->post();
137}
138
139
140void GenericPlayer::pause() {
141    SL_LOGD("GenericPlayer::pause()");
142    sp<AMessage> msg = new AMessage(kWhatPause, id());
143    msg->post();
144}
145
146
147void GenericPlayer::stop() {
148    SL_LOGD("GenericPlayer::stop()");
149    (new AMessage(kWhatPause, id()))->post();
150
151    // after a stop, playback should resume from the start.
152    seek(0);
153}
154
155
156void GenericPlayer::seek(int64_t timeMsec) {
157    SL_LOGV("GenericPlayer::seek %lld", timeMsec);
158    if (timeMsec < 0) {
159        SL_LOGE("GenericPlayer::seek error, can't seek to negative time %lldms", timeMsec);
160        return;
161    }
162    sp<AMessage> msg = new AMessage(kWhatSeek, id());
163    msg->setInt64(WHATPARAM_SEEK_SEEKTIME_MS, timeMsec);
164    msg->post();
165}
166
167
168void GenericPlayer::loop(bool loop) {
169    SL_LOGV("GenericPlayer::loop %s", loop ? "true" : "false");
170    sp<AMessage> msg = new AMessage(kWhatLoop, id());
171    msg->setInt32(WHATPARAM_LOOP_LOOPING, (int32_t)loop);
172    msg->post();
173}
174
175
176void GenericPlayer::setBufferingUpdateThreshold(int16_t thresholdPercent) {
177    SL_LOGV("GenericPlayer::setBufferingUpdateThreshold %d", thresholdPercent);
178    sp<AMessage> msg = new AMessage(kWhatBuffUpdateThres, id());
179    msg->setInt32(WHATPARAM_BUFFERING_UPDATETHRESHOLD_PERCENT, (int32_t)thresholdPercent);
180    msg->post();
181}
182
183
184//--------------------------------------------------
185void GenericPlayer::getDurationMsec(int* msec) {
186    *msec = mDurationMsec;
187}
188
189void GenericPlayer::getPositionMsec(int* msec) {
190    *msec = mPositionMsec;
191}
192
193void GenericPlayer::getSampleRate(uint* hz) {
194    *hz = mSampleRateHz;
195}
196
197//--------------------------------------------------
198void GenericPlayer::setVolume(float leftVol, float rightVol)
199{
200    {
201        Mutex::Autolock _l(mSettingsLock);
202        mAndroidAudioLevels.mFinalVolume[0] = leftVol;
203        mAndroidAudioLevels.mFinalVolume[1] = rightVol;
204    }
205    // send a message for the volume to be updated by the object which implements the volume
206    (new AMessage(kWhatVolumeUpdate, id()))->post();
207}
208
209
210//--------------------------------------------------
211void GenericPlayer::attachAuxEffect(int32_t effectId)
212{
213    SL_LOGV("GenericPlayer::attachAuxEffect(id=%d)", effectId);
214    sp<AMessage> msg = new AMessage(kWhatAttachAuxEffect, id());
215    msg->setInt32(WHATPARAM_ATTACHAUXEFFECT, effectId);
216    msg->post();
217}
218
219
220//--------------------------------------------------
221void GenericPlayer::setAuxEffectSendLevel(float level)
222{
223    SL_LOGV("GenericPlayer::setAuxEffectSendLevel(level=%g)", level);
224    sp<AMessage> msg = new AMessage(kWhatSetAuxEffectSendLevel, id());
225    msg->setFloat(WHATPARAM_SETAUXEFFECTSENDLEVEL, level);
226    msg->post();
227}
228
229
230//--------------------------------------------------
231/*
232 * post-condition: mDataLocatorType == kDataLocatorNone
233 *
234 */
235void GenericPlayer::resetDataLocator() {
236    SL_LOGV("GenericPlayer::resetDataLocator()");
237    mDataLocatorType = kDataLocatorNone;
238}
239
240
241void GenericPlayer::notify(const char* event, int data, bool async) {
242    SL_LOGV("GenericPlayer::notify(event=%s, data=%d, async=%s)", event, data,
243            async ? "true" : "false");
244    sp<AMessage> msg = new AMessage(kWhatNotif, id());
245    msg->setInt32(event, (int32_t)data);
246    if (async) {
247        msg->post();
248    } else {
249        this->onNotify(msg);
250    }
251}
252
253
254void GenericPlayer::notify(const char* event, int data1, int data2, bool async) {
255    SL_LOGV("GenericPlayer::notify(event=%s, data1=%d, data2=%d, async=%s)", event, data1, data2,
256            async ? "true" : "false");
257    sp<AMessage> msg = new AMessage(kWhatNotif, id());
258    msg->setRect(event, 0, 0, (int32_t)data1, (int32_t)data2);
259    if (async) {
260        msg->post();
261    } else {
262        this->onNotify(msg);
263    }
264}
265
266
267//--------------------------------------------------
268// AHandler implementation
269void GenericPlayer::onMessageReceived(const sp<AMessage> &msg) {
270    SL_LOGV("GenericPlayer::onMessageReceived()");
271    switch (msg->what()) {
272        case kWhatPrepare:
273            SL_LOGV("kWhatPrepare");
274            onPrepare();
275            break;
276
277        case kWhatNotif:
278            SL_LOGV("kWhatNotif");
279            onNotify(msg);
280            break;
281
282        case kWhatPlay:
283            SL_LOGV("kWhatPlay");
284            onPlay();
285            break;
286
287        case kWhatPause:
288            SL_LOGV("kWhatPause");
289            onPause();
290            break;
291
292        case kWhatSeek:
293            SL_LOGV("kWhatSeek");
294            onSeek(msg);
295            break;
296
297        case kWhatLoop:
298            SL_LOGV("kWhatLoop");
299            onLoop(msg);
300            break;
301
302        case kWhatVolumeUpdate:
303            SL_LOGV("kWhatVolumeUpdate");
304            onVolumeUpdate();
305            break;
306
307        case kWhatSeekComplete:
308            SL_LOGV("kWhatSeekComplete");
309            onSeekComplete();
310            break;
311
312        case kWhatBufferingUpdate:
313            SL_LOGV("kWhatBufferingUpdate");
314            onBufferingUpdate(msg);
315            break;
316
317        case kWhatBuffUpdateThres:
318            SL_LOGV("kWhatBuffUpdateThres");
319            onSetBufferingUpdateThreshold(msg);
320            break;
321
322        case kWhatAttachAuxEffect:
323            SL_LOGV("kWhatAttachAuxEffect");
324            onAttachAuxEffect(msg);
325            break;
326
327        case kWhatSetAuxEffectSendLevel:
328            SL_LOGV("kWhatSetAuxEffectSendLevel");
329            onSetAuxEffectSendLevel(msg);
330            break;
331
332        default:
333            SL_LOGV("kWhatPlay");
334            TRESPASS();
335    }
336}
337
338
339//--------------------------------------------------
340// Event handlers
341//  it is strictly verboten to call those methods outside of the event loop
342
343void GenericPlayer::onPrepare() {
344    SL_LOGV("GenericPlayer::onPrepare()");
345    // Subclass is responsible for indicating whether prepare was successful or unsuccessful
346    // by updating mStateFlags accordingly.  It must set exactly one of these two flags.
347    assert(!(mStateFlags & kFlagPrepared) != !(mStateFlags & kFlagPreparedUnsuccessfully));
348    notify(PLAYEREVENT_PREPARED, mStateFlags & kFlagPrepared ? PLAYER_SUCCESS : PLAYER_FAILURE,
349            false /*async*/);
350    SL_LOGD("GenericPlayer::onPrepare() done, mStateFlags=0x%x", mStateFlags);
351}
352
353
354void GenericPlayer::onNotify(const sp<AMessage> &msg) {
355    SL_LOGV("GenericPlayer::onNotify()");
356    notif_cbf_t notifClient;
357    void*       notifUser;
358    {
359        android::Mutex::Autolock autoLock(mNotifyClientLock);
360        if (NULL == mNotifyClient) {
361            return;
362        } else {
363            notifClient = mNotifyClient;
364            notifUser   = mNotifyUser;
365        }
366    }
367
368    int32_t val1, val2;
369    if (msg->findInt32(PLAYEREVENT_PREFETCHSTATUSCHANGE, &val1)) {
370        SL_LOGV("GenericPlayer notifying %s = %d", PLAYEREVENT_PREFETCHSTATUSCHANGE, val1);
371        notifClient(kEventPrefetchStatusChange, val1, 0, notifUser);
372    } else if (msg->findInt32(PLAYEREVENT_PREFETCHFILLLEVELUPDATE, &val1)) {
373        SL_LOGV("GenericPlayer notifying %s = %d", PLAYEREVENT_PREFETCHFILLLEVELUPDATE, val1);
374        notifClient(kEventPrefetchFillLevelUpdate, val1, 0, notifUser);
375    } else if (msg->findInt32(PLAYEREVENT_ENDOFSTREAM, &val1)) {
376        SL_LOGV("GenericPlayer notifying %s = %d", PLAYEREVENT_ENDOFSTREAM, val1);
377        notifClient(kEventEndOfStream, val1, 0, notifUser);
378    } else if (msg->findInt32(PLAYEREVENT_PREPARED, &val1)) {
379        SL_LOGV("GenericPlayer notifying %s = %d", PLAYEREVENT_PREPARED, val1);
380        notifClient(kEventPrepared, val1, 0, notifUser);
381    } else if (msg->findInt32(PLAYEREVENT_CHANNEL_COUNT, &val1)) {
382        SL_LOGV("GenericPlayer notifying %s = %d", PLAYEREVENT_CHANNEL_COUNT, val1);
383        notifClient(kEventChannelCount, val1, 0, notifUser);
384    } else if (msg->findRect(PLAYEREVENT_VIDEO_SIZE_UPDATE, &val1, &val2, &val1, &val2)) {
385        SL_LOGV("GenericPlayer notifying %s = %d, %d", PLAYEREVENT_VIDEO_SIZE_UPDATE, val1, val2);
386        notifClient(kEventHasVideoSize, val1, val2, notifUser);
387    } else {
388        SL_LOGV("GenericPlayer notifying unknown");
389    }
390}
391
392
393void GenericPlayer::onPlay() {
394    SL_LOGD("GenericPlayer::onPlay()");
395    if ((mStateFlags & kFlagPrepared)) {
396        SL_LOGD("starting player");
397        mStateFlags |= kFlagPlaying;
398    } else {
399        SL_LOGV("NOT starting player mStateFlags=0x%x", mStateFlags);
400    }
401}
402
403
404void GenericPlayer::onPause() {
405    SL_LOGD("GenericPlayer::onPause()");
406    if ((mStateFlags & kFlagPrepared)) {
407        mStateFlags &= ~kFlagPlaying;
408    }
409}
410
411
412void GenericPlayer::onSeek(const sp<AMessage> &msg) {
413    SL_LOGV("GenericPlayer::onSeek");
414}
415
416
417void GenericPlayer::onLoop(const sp<AMessage> &msg) {
418    SL_LOGV("GenericPlayer::onLoop");
419}
420
421
422void GenericPlayer::onVolumeUpdate() {
423    SL_LOGV("GenericPlayer::onVolumeUpdate");
424}
425
426
427void GenericPlayer::onSeekComplete() {
428    SL_LOGD("GenericPlayer::onSeekComplete()");
429    mStateFlags &= ~kFlagSeeking;
430}
431
432
433void GenericPlayer::onBufferingUpdate(const sp<AMessage> &msg) {
434    SL_LOGV("GenericPlayer::onBufferingUpdate");
435}
436
437
438void GenericPlayer::onSetBufferingUpdateThreshold(const sp<AMessage> &msg) {
439    SL_LOGV("GenericPlayer::onSetBufferingUpdateThreshold");
440    int32_t thresholdPercent = 0;
441    if (msg->findInt32(WHATPARAM_BUFFERING_UPDATETHRESHOLD_PERCENT, &thresholdPercent)) {
442        Mutex::Autolock _l(mSettingsLock);
443        mCacheFillNotifThreshold = (int16_t)thresholdPercent;
444    }
445}
446
447
448void GenericPlayer::onAttachAuxEffect(const sp<AMessage> &msg) {
449    SL_LOGV("GenericPlayer::onAttachAuxEffect()");
450}
451
452
453void GenericPlayer::onSetAuxEffectSendLevel(const sp<AMessage> &msg) {
454    SL_LOGV("GenericPlayer::onSetAuxEffectSendLevel()");
455}
456
457
458//-------------------------------------------------
459void GenericPlayer::notifyStatus() {
460    SL_LOGV("GenericPlayer::notifyStatus");
461    notify(PLAYEREVENT_PREFETCHSTATUSCHANGE, (int32_t)mCacheStatus, true /*async*/);
462}
463
464
465void GenericPlayer::notifyCacheFill() {
466    SL_LOGV("GenericPlayer::notifyCacheFill");
467    mLastNotifiedCacheFill = mCacheFill;
468    notify(PLAYEREVENT_PREFETCHFILLLEVELUPDATE, (int32_t)mLastNotifiedCacheFill, true/*async*/);
469}
470
471
472void GenericPlayer::seekComplete() {
473    SL_LOGV("GenericPlayer::seekComplete");
474    sp<AMessage> msg = new AMessage(kWhatSeekComplete, id());
475    msg->post();
476}
477
478
479void GenericPlayer::bufferingUpdate(int16_t fillLevelPerMille) {
480    SL_LOGV("GenericPlayer::bufferingUpdate");
481    sp<AMessage> msg = new AMessage(kWhatBufferingUpdate, id());
482    msg->setInt32(WHATPARAM_BUFFERING_UPDATE, fillLevelPerMille);
483    msg->post();
484}
485
486} // namespace android
487