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