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