NuPlayerDriver.cpp revision 43c3e6ce02215ca99d506458f596cb1211639f29
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      mLooper(new ALooper),
35      mState(UNINITIALIZED),
36      mStartupSeekTimeUs(-1) {
37    mLooper->setName("NuPlayerDriver Looper");
38
39    mLooper->start(
40            false, /* runOnCallingThread */
41            true,  /* canCallJava */
42            PRIORITY_AUDIO);
43
44    mPlayer = new NuPlayer;
45    mLooper->registerHandler(mPlayer);
46
47    mPlayer->setDriver(this);
48}
49
50NuPlayerDriver::~NuPlayerDriver() {
51    mLooper->stop();
52}
53
54status_t NuPlayerDriver::initCheck() {
55    return OK;
56}
57
58status_t NuPlayerDriver::setDataSource(
59        const char *url, const KeyedVector<String8, String8> *headers) {
60    CHECK_EQ((int)mState, (int)UNINITIALIZED);
61
62    mPlayer->setDataSource(url, headers);
63
64    mState = STOPPED;
65
66    return OK;
67}
68
69status_t NuPlayerDriver::setDataSource(int fd, int64_t offset, int64_t length) {
70    return INVALID_OPERATION;
71}
72
73status_t NuPlayerDriver::setDataSource(const sp<IStreamSource> &source) {
74    CHECK_EQ((int)mState, (int)UNINITIALIZED);
75
76    mPlayer->setDataSource(source);
77
78    mState = STOPPED;
79
80    return OK;
81}
82
83status_t NuPlayerDriver::setVideoSurface(const sp<Surface> &surface) {
84    mPlayer->setVideoSurface(surface);
85
86    return OK;
87}
88
89status_t NuPlayerDriver::prepare() {
90    return OK;
91}
92
93status_t NuPlayerDriver::prepareAsync() {
94    sendEvent(MEDIA_PREPARED);
95
96    return OK;
97}
98
99status_t NuPlayerDriver::start() {
100    switch (mState) {
101        case UNINITIALIZED:
102            return INVALID_OPERATION;
103        case STOPPED:
104        {
105            mPlayer->start();
106
107            if (mStartupSeekTimeUs >= 0) {
108                mPlayer->seekToAsync(mStartupSeekTimeUs);
109                mStartupSeekTimeUs = -1;
110            }
111            break;
112        }
113        case PLAYING:
114            return OK;
115        default:
116        {
117            CHECK_EQ((int)mState, (int)PAUSED);
118
119            mPlayer->resume();
120            break;
121        }
122    }
123
124    mState = PLAYING;
125
126    return OK;
127}
128
129status_t NuPlayerDriver::stop() {
130    return pause();
131}
132
133status_t NuPlayerDriver::pause() {
134    switch (mState) {
135        case UNINITIALIZED:
136            return INVALID_OPERATION;
137        case STOPPED:
138            return OK;
139        case PLAYING:
140            mPlayer->pause();
141            break;
142        default:
143        {
144            CHECK_EQ((int)mState, (int)PAUSED);
145            return OK;
146        }
147    }
148
149    mState = PAUSED;
150
151    return OK;
152}
153
154bool NuPlayerDriver::isPlaying() {
155    return mState == PLAYING;
156}
157
158status_t NuPlayerDriver::seekTo(int msec) {
159    int64_t seekTimeUs = msec * 1000ll;
160
161    switch (mState) {
162        case UNINITIALIZED:
163            return INVALID_OPERATION;
164        case STOPPED:
165        {
166            mStartupSeekTimeUs = seekTimeUs;
167            break;
168        }
169        case PLAYING:
170        case PAUSED:
171        {
172            mPlayer->seekToAsync(seekTimeUs);
173            break;
174        }
175
176        default:
177            TRESPASS();
178            break;
179    }
180
181    return OK;
182}
183
184status_t NuPlayerDriver::getCurrentPosition(int *msec) {
185    Mutex::Autolock autoLock(mLock);
186
187    if (mPositionUs < 0) {
188        *msec = 0;
189    } else {
190        *msec = (mPositionUs + 500ll) / 1000;
191    }
192
193    return OK;
194}
195
196status_t NuPlayerDriver::getDuration(int *msec) {
197    Mutex::Autolock autoLock(mLock);
198
199    if (mDurationUs < 0) {
200        *msec = 0;
201    } else {
202        *msec = (mDurationUs + 500ll) / 1000;
203    }
204
205    return OK;
206}
207
208status_t NuPlayerDriver::reset() {
209    Mutex::Autolock autoLock(mLock);
210    mResetInProgress = true;
211
212    mPlayer->resetAsync();
213
214    while (mResetInProgress) {
215        mCondition.wait(mLock);
216    }
217
218    mDurationUs = -1;
219    mPositionUs = -1;
220    mState = UNINITIALIZED;
221    mStartupSeekTimeUs = -1;
222
223    return OK;
224}
225
226status_t NuPlayerDriver::setLooping(int loop) {
227    return INVALID_OPERATION;
228}
229
230player_type NuPlayerDriver::playerType() {
231    return NU_PLAYER;
232}
233
234status_t NuPlayerDriver::invoke(const Parcel &request, Parcel *reply) {
235    return INVALID_OPERATION;
236}
237
238void NuPlayerDriver::setAudioSink(const sp<AudioSink> &audioSink) {
239    mPlayer->setAudioSink(audioSink);
240}
241
242status_t NuPlayerDriver::getMetadata(
243        const media::Metadata::Filter& ids, Parcel *records) {
244    return INVALID_OPERATION;
245}
246
247void NuPlayerDriver::notifyResetComplete() {
248    Mutex::Autolock autoLock(mLock);
249    CHECK(mResetInProgress);
250    mResetInProgress = false;
251    mCondition.broadcast();
252}
253
254void NuPlayerDriver::notifyDuration(int64_t durationUs) {
255    Mutex::Autolock autoLock(mLock);
256    mDurationUs = durationUs;
257}
258
259void NuPlayerDriver::notifyPosition(int64_t positionUs) {
260    Mutex::Autolock autoLock(mLock);
261    mPositionUs = positionUs;
262}
263
264void NuPlayerDriver::notifySeekComplete() {
265    sendEvent(MEDIA_SEEK_COMPLETE);
266}
267
268}  // namespace android
269