blob: 7043404400af7c33068afa90135dee399961ca3e [file] [log] [blame]
Andreas Huberf9334412010-12-15 15:17:42 -08001/*
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
Andreas Huber1aef2112011-01-04 14:01:29 -080025#include <media/stagefright/foundation/ADebug.h>
Andreas Huberf9334412010-12-15 15:17:42 -080026#include <media/stagefright/foundation/ALooper.h>
27
28namespace android {
29
30NuPlayerDriver::NuPlayerDriver()
Andreas Huber1aef2112011-01-04 14:01:29 -080031 : mResetInProgress(false),
Andreas Huber57a339c2012-12-03 11:18:00 -080032 mSetSurfaceInProgress(false),
Andreas Huber43c3e6c2011-01-05 12:17:08 -080033 mDurationUs(-1),
34 mPositionUs(-1),
Andreas Huber3fe62152011-09-16 15:09:22 -070035 mNumFramesTotal(0),
36 mNumFramesDropped(0),
Andreas Huber1aef2112011-01-04 14:01:29 -080037 mLooper(new ALooper),
Andreas Huber43c3e6c2011-01-05 12:17:08 -080038 mState(UNINITIALIZED),
Andreas Hubera4af2142011-10-26 15:23:31 -070039 mAtEOS(false),
Andreas Huber43c3e6c2011-01-05 12:17:08 -080040 mStartupSeekTimeUs(-1) {
Andreas Huberf9334412010-12-15 15:17:42 -080041 mLooper->setName("NuPlayerDriver Looper");
42
43 mLooper->start(
44 false, /* runOnCallingThread */
45 true, /* canCallJava */
46 PRIORITY_AUDIO);
47
48 mPlayer = new NuPlayer;
49 mLooper->registerHandler(mPlayer);
50
Andreas Huber43c3e6c2011-01-05 12:17:08 -080051 mPlayer->setDriver(this);
Andreas Huberf9334412010-12-15 15:17:42 -080052}
53
54NuPlayerDriver::~NuPlayerDriver() {
55 mLooper->stop();
56}
57
58status_t NuPlayerDriver::initCheck() {
59 return OK;
60}
61
Andreas Huber9b80c2b2011-06-30 15:47:02 -070062status_t NuPlayerDriver::setUID(uid_t uid) {
63 mPlayer->setUID(uid);
64
65 return OK;
66}
67
Andreas Huberf9334412010-12-15 15:17:42 -080068status_t NuPlayerDriver::setDataSource(
69 const char *url, const KeyedVector<String8, String8> *headers) {
Andreas Huber43c3e6c2011-01-05 12:17:08 -080070 CHECK_EQ((int)mState, (int)UNINITIALIZED);
71
Andreas Huber5bc087c2010-12-23 10:27:40 -080072 mPlayer->setDataSource(url, headers);
73
Andreas Huber43c3e6c2011-01-05 12:17:08 -080074 mState = STOPPED;
75
Andreas Huber5bc087c2010-12-23 10:27:40 -080076 return OK;
Andreas Huberf9334412010-12-15 15:17:42 -080077}
78
79status_t NuPlayerDriver::setDataSource(int fd, int64_t offset, int64_t length) {
Andreas Huberafed0e12011-09-20 15:39:58 -070080 CHECK_EQ((int)mState, (int)UNINITIALIZED);
81
82 mPlayer->setDataSource(fd, offset, length);
83
84 mState = STOPPED;
85
86 return OK;
Andreas Huberf9334412010-12-15 15:17:42 -080087}
88
89status_t NuPlayerDriver::setDataSource(const sp<IStreamSource> &source) {
Andreas Huber43c3e6c2011-01-05 12:17:08 -080090 CHECK_EQ((int)mState, (int)UNINITIALIZED);
91
Andreas Huberf9334412010-12-15 15:17:42 -080092 mPlayer->setDataSource(source);
93
Andreas Huber43c3e6c2011-01-05 12:17:08 -080094 mState = STOPPED;
95
Andreas Huberf9334412010-12-15 15:17:42 -080096 return OK;
97}
98
Glenn Kasten11731182011-02-08 17:26:17 -080099status_t NuPlayerDriver::setVideoSurfaceTexture(
Andy McFadden8ba01022012-12-18 09:46:54 -0800100 const sp<IGraphicBufferProducer> &bufferProducer) {
Andreas Huber57a339c2012-12-03 11:18:00 -0800101 Mutex::Autolock autoLock(mLock);
102
103 if (mResetInProgress) {
104 return INVALID_OPERATION;
105 }
106
107 mSetSurfaceInProgress = true;
108
Andy McFadden8ba01022012-12-18 09:46:54 -0800109 mPlayer->setVideoSurfaceTextureAsync(bufferProducer);
Andreas Huber57a339c2012-12-03 11:18:00 -0800110
111 while (mSetSurfaceInProgress) {
112 mCondition.wait(mLock);
113 }
Glenn Kasten11731182011-02-08 17:26:17 -0800114
115 return OK;
116}
117
Andreas Huberf9334412010-12-15 15:17:42 -0800118status_t NuPlayerDriver::prepare() {
Andreas Huber0b7c9a32012-04-30 11:35:34 -0700119 sendEvent(MEDIA_SET_VIDEO_SIZE, 0, 0);
Andreas Huberf9334412010-12-15 15:17:42 -0800120 return OK;
121}
122
123status_t NuPlayerDriver::prepareAsync() {
Andreas Huberafed0e12011-09-20 15:39:58 -0700124 status_t err = prepare();
125
Andreas Hubera4af2142011-10-26 15:23:31 -0700126 notifyListener(MEDIA_PREPARED);
Andreas Huber5bc087c2010-12-23 10:27:40 -0800127
Andreas Huberafed0e12011-09-20 15:39:58 -0700128 return err;
Andreas Huberf9334412010-12-15 15:17:42 -0800129}
130
131status_t NuPlayerDriver::start() {
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800132 switch (mState) {
133 case UNINITIALIZED:
134 return INVALID_OPERATION;
135 case STOPPED:
136 {
Andreas Hubera4af2142011-10-26 15:23:31 -0700137 mAtEOS = false;
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800138 mPlayer->start();
139
140 if (mStartupSeekTimeUs >= 0) {
Andreas Huber2048d0c2011-07-15 16:25:41 -0700141 if (mStartupSeekTimeUs == 0) {
142 notifySeekComplete();
143 } else {
144 mPlayer->seekToAsync(mStartupSeekTimeUs);
145 }
146
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800147 mStartupSeekTimeUs = -1;
148 }
Andreas Huber2048d0c2011-07-15 16:25:41 -0700149
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800150 break;
151 }
152 case PLAYING:
153 return OK;
154 default:
155 {
156 CHECK_EQ((int)mState, (int)PAUSED);
157
158 mPlayer->resume();
159 break;
160 }
161 }
162
163 mState = PLAYING;
Andreas Huberf9334412010-12-15 15:17:42 -0800164
165 return OK;
166}
167
168status_t NuPlayerDriver::stop() {
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800169 return pause();
Andreas Huberf9334412010-12-15 15:17:42 -0800170}
171
172status_t NuPlayerDriver::pause() {
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800173 switch (mState) {
174 case UNINITIALIZED:
175 return INVALID_OPERATION;
176 case STOPPED:
177 return OK;
178 case PLAYING:
179 mPlayer->pause();
180 break;
181 default:
182 {
183 CHECK_EQ((int)mState, (int)PAUSED);
184 return OK;
185 }
186 }
187
188 mState = PAUSED;
189
Andreas Huberf9334412010-12-15 15:17:42 -0800190 return OK;
191}
192
193bool NuPlayerDriver::isPlaying() {
Andreas Hubera4af2142011-10-26 15:23:31 -0700194 return mState == PLAYING && !mAtEOS;
Andreas Huberf9334412010-12-15 15:17:42 -0800195}
196
197status_t NuPlayerDriver::seekTo(int msec) {
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800198 int64_t seekTimeUs = msec * 1000ll;
199
200 switch (mState) {
201 case UNINITIALIZED:
202 return INVALID_OPERATION;
203 case STOPPED:
204 {
205 mStartupSeekTimeUs = seekTimeUs;
206 break;
207 }
208 case PLAYING:
209 case PAUSED:
210 {
Andreas Hubera4af2142011-10-26 15:23:31 -0700211 mAtEOS = false;
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800212 mPlayer->seekToAsync(seekTimeUs);
213 break;
214 }
215
216 default:
217 TRESPASS();
218 break;
219 }
220
221 return OK;
Andreas Huberf9334412010-12-15 15:17:42 -0800222}
223
224status_t NuPlayerDriver::getCurrentPosition(int *msec) {
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800225 Mutex::Autolock autoLock(mLock);
226
227 if (mPositionUs < 0) {
228 *msec = 0;
229 } else {
230 *msec = (mPositionUs + 500ll) / 1000;
231 }
Andreas Huber5bc087c2010-12-23 10:27:40 -0800232
233 return OK;
Andreas Huberf9334412010-12-15 15:17:42 -0800234}
235
236status_t NuPlayerDriver::getDuration(int *msec) {
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800237 Mutex::Autolock autoLock(mLock);
238
239 if (mDurationUs < 0) {
240 *msec = 0;
241 } else {
242 *msec = (mDurationUs + 500ll) / 1000;
243 }
Andreas Huber5bc087c2010-12-23 10:27:40 -0800244
245 return OK;
Andreas Huberf9334412010-12-15 15:17:42 -0800246}
247
248status_t NuPlayerDriver::reset() {
Andreas Huber1aef2112011-01-04 14:01:29 -0800249 Mutex::Autolock autoLock(mLock);
250 mResetInProgress = true;
251
252 mPlayer->resetAsync();
253
254 while (mResetInProgress) {
255 mCondition.wait(mLock);
256 }
257
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800258 mDurationUs = -1;
259 mPositionUs = -1;
260 mState = UNINITIALIZED;
261 mStartupSeekTimeUs = -1;
262
Andreas Huberf9334412010-12-15 15:17:42 -0800263 return OK;
264}
265
266status_t NuPlayerDriver::setLooping(int loop) {
267 return INVALID_OPERATION;
268}
269
270player_type NuPlayerDriver::playerType() {
271 return NU_PLAYER;
272}
273
274status_t NuPlayerDriver::invoke(const Parcel &request, Parcel *reply) {
James Dong0d268a32012-08-31 12:18:27 -0700275 if (reply == NULL) {
276 ALOGE("reply is a NULL pointer");
277 return BAD_VALUE;
278 }
279
280 int32_t methodId;
281 status_t ret = request.readInt32(&methodId);
282 if (ret != OK) {
283 ALOGE("Failed to retrieve the requested method to invoke");
284 return ret;
285 }
286
287 switch (methodId) {
288 case INVOKE_ID_SET_VIDEO_SCALING_MODE:
289 {
290 int mode = request.readInt32();
291 return mPlayer->setVideoScalingMode(mode);
292 }
293 default:
294 {
295 return INVALID_OPERATION;
296 }
297 }
Andreas Huberf9334412010-12-15 15:17:42 -0800298}
299
300void NuPlayerDriver::setAudioSink(const sp<AudioSink> &audioSink) {
301 mPlayer->setAudioSink(audioSink);
302}
303
Gloria Wang4f9e47f2011-04-25 17:28:22 -0700304status_t NuPlayerDriver::setParameter(int key, const Parcel &request) {
305 return INVALID_OPERATION;
306}
307
308status_t NuPlayerDriver::getParameter(int key, Parcel *reply) {
309 return INVALID_OPERATION;
310}
311
Andreas Huberf9334412010-12-15 15:17:42 -0800312status_t NuPlayerDriver::getMetadata(
313 const media::Metadata::Filter& ids, Parcel *records) {
314 return INVALID_OPERATION;
315}
316
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800317void NuPlayerDriver::notifyResetComplete() {
Andreas Huber1aef2112011-01-04 14:01:29 -0800318 Mutex::Autolock autoLock(mLock);
319 CHECK(mResetInProgress);
320 mResetInProgress = false;
321 mCondition.broadcast();
322}
323
Andreas Huber57a339c2012-12-03 11:18:00 -0800324void NuPlayerDriver::notifySetSurfaceComplete() {
325 Mutex::Autolock autoLock(mLock);
326 CHECK(mSetSurfaceInProgress);
327 mSetSurfaceInProgress = false;
328 mCondition.broadcast();
329}
330
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800331void NuPlayerDriver::notifyDuration(int64_t durationUs) {
332 Mutex::Autolock autoLock(mLock);
333 mDurationUs = durationUs;
334}
335
336void NuPlayerDriver::notifyPosition(int64_t positionUs) {
337 Mutex::Autolock autoLock(mLock);
338 mPositionUs = positionUs;
339}
340
341void NuPlayerDriver::notifySeekComplete() {
Andreas Hubera4af2142011-10-26 15:23:31 -0700342 notifyListener(MEDIA_SEEK_COMPLETE);
Andreas Huber43c3e6c2011-01-05 12:17:08 -0800343}
344
Andreas Huber3fe62152011-09-16 15:09:22 -0700345void NuPlayerDriver::notifyFrameStats(
346 int64_t numFramesTotal, int64_t numFramesDropped) {
347 Mutex::Autolock autoLock(mLock);
348 mNumFramesTotal = numFramesTotal;
349 mNumFramesDropped = numFramesDropped;
350}
351
352status_t NuPlayerDriver::dump(int fd, const Vector<String16> &args) const {
353 Mutex::Autolock autoLock(mLock);
354
355 FILE *out = fdopen(dup(fd), "w");
356
357 fprintf(out, " NuPlayer\n");
358 fprintf(out, " numFramesTotal(%lld), numFramesDropped(%lld), "
359 "percentageDropped(%.2f)\n",
360 mNumFramesTotal,
361 mNumFramesDropped,
362 mNumFramesTotal == 0
363 ? 0.0 : (double)mNumFramesDropped / mNumFramesTotal);
364
365 fclose(out);
366 out = NULL;
367
368 return OK;
369}
370
Andreas Hubera4af2142011-10-26 15:23:31 -0700371void NuPlayerDriver::notifyListener(int msg, int ext1, int ext2) {
372 if (msg == MEDIA_PLAYBACK_COMPLETE || msg == MEDIA_ERROR) {
373 mAtEOS = true;
374 }
375
376 sendEvent(msg, ext1, ext2);
377}
378
Andreas Huberf9334412010-12-15 15:17:42 -0800379} // namespace android