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