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