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