NuPlayerDriver.cpp revision 0d268a3cae145afb2720c88ae38fb81550be5584
1/*
2 * Copyright (C) 2010 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 LOG_NDEBUG 0
18#define LOG_TAG "NuPlayerDriver"
19#include <utils/Log.h>
20
21#include "NuPlayerDriver.h"
22
23#include "NuPlayer.h"
24
25#include <media/stagefright/foundation/ADebug.h>
26#include <media/stagefright/foundation/ALooper.h>
27
28namespace android {
29
30NuPlayerDriver::NuPlayerDriver()
31    : mResetInProgress(false),
32      mDurationUs(-1),
33      mPositionUs(-1),
34      mNumFramesTotal(0),
35      mNumFramesDropped(0),
36      mLooper(new ALooper),
37      mState(UNINITIALIZED),
38      mAtEOS(false),
39      mStartupSeekTimeUs(-1) {
40    mLooper->setName("NuPlayerDriver Looper");
41
42    mLooper->start(
43            false, /* runOnCallingThread */
44            true,  /* canCallJava */
45            PRIORITY_AUDIO);
46
47    mPlayer = new NuPlayer;
48    mLooper->registerHandler(mPlayer);
49
50    mPlayer->setDriver(this);
51}
52
53NuPlayerDriver::~NuPlayerDriver() {
54    mLooper->stop();
55}
56
57status_t NuPlayerDriver::initCheck() {
58    return OK;
59}
60
61status_t NuPlayerDriver::setUID(uid_t uid) {
62    mPlayer->setUID(uid);
63
64    return OK;
65}
66
67status_t NuPlayerDriver::setDataSource(
68        const char *url, const KeyedVector<String8, String8> *headers) {
69    CHECK_EQ((int)mState, (int)UNINITIALIZED);
70
71    mPlayer->setDataSource(url, headers);
72
73    mState = STOPPED;
74
75    return OK;
76}
77
78status_t NuPlayerDriver::setDataSource(int fd, int64_t offset, int64_t length) {
79    CHECK_EQ((int)mState, (int)UNINITIALIZED);
80
81    mPlayer->setDataSource(fd, offset, length);
82
83    mState = STOPPED;
84
85    return OK;
86}
87
88status_t NuPlayerDriver::setDataSource(const sp<IStreamSource> &source) {
89    CHECK_EQ((int)mState, (int)UNINITIALIZED);
90
91    mPlayer->setDataSource(source);
92
93    mState = STOPPED;
94
95    return OK;
96}
97
98status_t NuPlayerDriver::setVideoSurfaceTexture(
99        const sp<ISurfaceTexture> &surfaceTexture) {
100    mPlayer->setVideoSurfaceTexture(surfaceTexture);
101
102    return OK;
103}
104
105status_t NuPlayerDriver::prepare() {
106    sendEvent(MEDIA_SET_VIDEO_SIZE, 0, 0);
107    return OK;
108}
109
110status_t NuPlayerDriver::prepareAsync() {
111    status_t err = prepare();
112
113    notifyListener(MEDIA_PREPARED);
114
115    return err;
116}
117
118status_t NuPlayerDriver::start() {
119    switch (mState) {
120        case UNINITIALIZED:
121            return INVALID_OPERATION;
122        case STOPPED:
123        {
124            mAtEOS = false;
125            mPlayer->start();
126
127            if (mStartupSeekTimeUs >= 0) {
128                if (mStartupSeekTimeUs == 0) {
129                    notifySeekComplete();
130                } else {
131                    mPlayer->seekToAsync(mStartupSeekTimeUs);
132                }
133
134                mStartupSeekTimeUs = -1;
135            }
136
137            break;
138        }
139        case PLAYING:
140            return OK;
141        default:
142        {
143            CHECK_EQ((int)mState, (int)PAUSED);
144
145            mPlayer->resume();
146            break;
147        }
148    }
149
150    mState = PLAYING;
151
152    return OK;
153}
154
155status_t NuPlayerDriver::stop() {
156    return pause();
157}
158
159status_t NuPlayerDriver::pause() {
160    switch (mState) {
161        case UNINITIALIZED:
162            return INVALID_OPERATION;
163        case STOPPED:
164            return OK;
165        case PLAYING:
166            mPlayer->pause();
167            break;
168        default:
169        {
170            CHECK_EQ((int)mState, (int)PAUSED);
171            return OK;
172        }
173    }
174
175    mState = PAUSED;
176
177    return OK;
178}
179
180bool NuPlayerDriver::isPlaying() {
181    return mState == PLAYING && !mAtEOS;
182}
183
184status_t NuPlayerDriver::seekTo(int msec) {
185    int64_t seekTimeUs = msec * 1000ll;
186
187    switch (mState) {
188        case UNINITIALIZED:
189            return INVALID_OPERATION;
190        case STOPPED:
191        {
192            mStartupSeekTimeUs = seekTimeUs;
193            break;
194        }
195        case PLAYING:
196        case PAUSED:
197        {
198            mAtEOS = false;
199            mPlayer->seekToAsync(seekTimeUs);
200            break;
201        }
202
203        default:
204            TRESPASS();
205            break;
206    }
207
208    return OK;
209}
210
211status_t NuPlayerDriver::getCurrentPosition(int *msec) {
212    Mutex::Autolock autoLock(mLock);
213
214    if (mPositionUs < 0) {
215        *msec = 0;
216    } else {
217        *msec = (mPositionUs + 500ll) / 1000;
218    }
219
220    return OK;
221}
222
223status_t NuPlayerDriver::getDuration(int *msec) {
224    Mutex::Autolock autoLock(mLock);
225
226    if (mDurationUs < 0) {
227        *msec = 0;
228    } else {
229        *msec = (mDurationUs + 500ll) / 1000;
230    }
231
232    return OK;
233}
234
235status_t NuPlayerDriver::reset() {
236    Mutex::Autolock autoLock(mLock);
237    mResetInProgress = true;
238
239    mPlayer->resetAsync();
240
241    while (mResetInProgress) {
242        mCondition.wait(mLock);
243    }
244
245    mDurationUs = -1;
246    mPositionUs = -1;
247    mState = UNINITIALIZED;
248    mStartupSeekTimeUs = -1;
249
250    return OK;
251}
252
253status_t NuPlayerDriver::setLooping(int loop) {
254    return INVALID_OPERATION;
255}
256
257player_type NuPlayerDriver::playerType() {
258    return NU_PLAYER;
259}
260
261status_t NuPlayerDriver::invoke(const Parcel &request, Parcel *reply) {
262    if (reply == NULL) {
263        ALOGE("reply is a NULL pointer");
264        return BAD_VALUE;
265    }
266
267    int32_t methodId;
268    status_t ret = request.readInt32(&methodId);
269    if (ret != OK) {
270        ALOGE("Failed to retrieve the requested method to invoke");
271        return ret;
272    }
273
274    switch (methodId) {
275        case INVOKE_ID_SET_VIDEO_SCALING_MODE:
276        {
277            int mode = request.readInt32();
278            return mPlayer->setVideoScalingMode(mode);
279        }
280        default:
281        {
282            return INVALID_OPERATION;
283        }
284    }
285}
286
287void NuPlayerDriver::setAudioSink(const sp<AudioSink> &audioSink) {
288    mPlayer->setAudioSink(audioSink);
289}
290
291status_t NuPlayerDriver::setParameter(int key, const Parcel &request) {
292    return INVALID_OPERATION;
293}
294
295status_t NuPlayerDriver::getParameter(int key, Parcel *reply) {
296    return INVALID_OPERATION;
297}
298
299status_t NuPlayerDriver::getMetadata(
300        const media::Metadata::Filter& ids, Parcel *records) {
301    return INVALID_OPERATION;
302}
303
304void NuPlayerDriver::notifyResetComplete() {
305    Mutex::Autolock autoLock(mLock);
306    CHECK(mResetInProgress);
307    mResetInProgress = false;
308    mCondition.broadcast();
309}
310
311void NuPlayerDriver::notifyDuration(int64_t durationUs) {
312    Mutex::Autolock autoLock(mLock);
313    mDurationUs = durationUs;
314}
315
316void NuPlayerDriver::notifyPosition(int64_t positionUs) {
317    Mutex::Autolock autoLock(mLock);
318    mPositionUs = positionUs;
319}
320
321void NuPlayerDriver::notifySeekComplete() {
322    notifyListener(MEDIA_SEEK_COMPLETE);
323}
324
325void NuPlayerDriver::notifyFrameStats(
326        int64_t numFramesTotal, int64_t numFramesDropped) {
327    Mutex::Autolock autoLock(mLock);
328    mNumFramesTotal = numFramesTotal;
329    mNumFramesDropped = numFramesDropped;
330}
331
332status_t NuPlayerDriver::dump(int fd, const Vector<String16> &args) const {
333    Mutex::Autolock autoLock(mLock);
334
335    FILE *out = fdopen(dup(fd), "w");
336
337    fprintf(out, " NuPlayer\n");
338    fprintf(out, "  numFramesTotal(%lld), numFramesDropped(%lld), "
339                 "percentageDropped(%.2f)\n",
340                 mNumFramesTotal,
341                 mNumFramesDropped,
342                 mNumFramesTotal == 0
343                    ? 0.0 : (double)mNumFramesDropped / mNumFramesTotal);
344
345    fclose(out);
346    out = NULL;
347
348    return OK;
349}
350
351void NuPlayerDriver::notifyListener(int msg, int ext1, int ext2) {
352    if (msg == MEDIA_PLAYBACK_COMPLETE || msg == MEDIA_ERROR) {
353        mAtEOS = true;
354    }
355
356    sendEvent(msg, ext1, ext2);
357}
358
359}  // namespace android
360