• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
28 namespace android {
29 
NuPlayerDriver()30 NuPlayerDriver::NuPlayerDriver()
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("NuPlayerDriver Looper");
41 
42     mLooper->start(
43             false, /* runOnCallingThread */
44             true,  /* canCallJava */
45             PRIORITY_AUDIO);
46 
47     mPlayer = new NuPlayer;
48     mLooper->registerHandler(mPlayer);
49 
50     mPlayer->setDriver(this);
51 }
52 
~NuPlayerDriver()53 NuPlayerDriver::~NuPlayerDriver() {
54     mLooper->stop();
55 }
56 
initCheck()57 status_t NuPlayerDriver::initCheck() {
58     return OK;
59 }
60 
setUID(uid_t uid)61 status_t NuPlayerDriver::setUID(uid_t uid) {
62     mPlayer->setUID(uid);
63 
64     return OK;
65 }
66 
setDataSource(const char * url,const KeyedVector<String8,String8> * headers)67 status_t NuPlayerDriver::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 
setDataSource(int fd,int64_t offset,int64_t length)78 status_t NuPlayerDriver::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 
setDataSource(const sp<IStreamSource> & source)88 status_t NuPlayerDriver::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 
setVideoSurfaceTexture(const sp<ISurfaceTexture> & surfaceTexture)98 status_t NuPlayerDriver::setVideoSurfaceTexture(
99         const sp<ISurfaceTexture> &surfaceTexture) {
100     mPlayer->setVideoSurfaceTexture(surfaceTexture);
101 
102     return OK;
103 }
104 
prepare()105 status_t NuPlayerDriver::prepare() {
106     sendEvent(MEDIA_SET_VIDEO_SIZE, 0, 0);
107     return OK;
108 }
109 
prepareAsync()110 status_t NuPlayerDriver::prepareAsync() {
111     status_t err = prepare();
112 
113     notifyListener(MEDIA_PREPARED);
114 
115     return err;
116 }
117 
start()118 status_t NuPlayerDriver::start() {
119     switch (mState) {
120         case UNINITIALIZED:
121             return INVALID_OPERATION;
122         case STOPPED:
123         {
124             mAtEOS = false;
125             mPlayer->start();
126 
127             if (mStartupSeekTimeUs >= 0) {
128                 if (mStartupSeekTimeUs == 0) {
129                     notifySeekComplete();
130                 } else {
131                     mPlayer->seekToAsync(mStartupSeekTimeUs);
132                 }
133 
134                 mStartupSeekTimeUs = -1;
135             }
136 
137             break;
138         }
139         case PLAYING:
140             return OK;
141         default:
142         {
143             CHECK_EQ((int)mState, (int)PAUSED);
144 
145             mPlayer->resume();
146             break;
147         }
148     }
149 
150     mState = PLAYING;
151 
152     return OK;
153 }
154 
stop()155 status_t NuPlayerDriver::stop() {
156     return pause();
157 }
158 
pause()159 status_t NuPlayerDriver::pause() {
160     switch (mState) {
161         case UNINITIALIZED:
162             return INVALID_OPERATION;
163         case STOPPED:
164             return OK;
165         case PLAYING:
166             mPlayer->pause();
167             break;
168         default:
169         {
170             CHECK_EQ((int)mState, (int)PAUSED);
171             return OK;
172         }
173     }
174 
175     mState = PAUSED;
176 
177     return OK;
178 }
179 
isPlaying()180 bool NuPlayerDriver::isPlaying() {
181     return mState == PLAYING && !mAtEOS;
182 }
183 
seekTo(int msec)184 status_t NuPlayerDriver::seekTo(int msec) {
185     int64_t seekTimeUs = msec * 1000ll;
186 
187     switch (mState) {
188         case UNINITIALIZED:
189             return INVALID_OPERATION;
190         case STOPPED:
191         {
192             mStartupSeekTimeUs = seekTimeUs;
193             break;
194         }
195         case PLAYING:
196         case PAUSED:
197         {
198             mAtEOS = false;
199             mPlayer->seekToAsync(seekTimeUs);
200             break;
201         }
202 
203         default:
204             TRESPASS();
205             break;
206     }
207 
208     return OK;
209 }
210 
getCurrentPosition(int * msec)211 status_t NuPlayerDriver::getCurrentPosition(int *msec) {
212     Mutex::Autolock autoLock(mLock);
213 
214     if (mPositionUs < 0) {
215         *msec = 0;
216     } else {
217         *msec = (mPositionUs + 500ll) / 1000;
218     }
219 
220     return OK;
221 }
222 
getDuration(int * msec)223 status_t NuPlayerDriver::getDuration(int *msec) {
224     Mutex::Autolock autoLock(mLock);
225 
226     if (mDurationUs < 0) {
227         *msec = 0;
228     } else {
229         *msec = (mDurationUs + 500ll) / 1000;
230     }
231 
232     return OK;
233 }
234 
reset()235 status_t NuPlayerDriver::reset() {
236     Mutex::Autolock autoLock(mLock);
237     mResetInProgress = true;
238 
239     mPlayer->resetAsync();
240 
241     while (mResetInProgress) {
242         mCondition.wait(mLock);
243     }
244 
245     mDurationUs = -1;
246     mPositionUs = -1;
247     mState = UNINITIALIZED;
248     mStartupSeekTimeUs = -1;
249 
250     return OK;
251 }
252 
setLooping(int loop)253 status_t NuPlayerDriver::setLooping(int loop) {
254     return INVALID_OPERATION;
255 }
256 
playerType()257 player_type NuPlayerDriver::playerType() {
258     return NU_PLAYER;
259 }
260 
invoke(const Parcel & request,Parcel * reply)261 status_t NuPlayerDriver::invoke(const Parcel &request, Parcel *reply) {
262     if (reply == NULL) {
263         ALOGE("reply is a NULL pointer");
264         return BAD_VALUE;
265     }
266 
267     int32_t methodId;
268     status_t ret = request.readInt32(&methodId);
269     if (ret != OK) {
270         ALOGE("Failed to retrieve the requested method to invoke");
271         return ret;
272     }
273 
274     switch (methodId) {
275         case INVOKE_ID_SET_VIDEO_SCALING_MODE:
276         {
277             int mode = request.readInt32();
278             return mPlayer->setVideoScalingMode(mode);
279         }
280         default:
281         {
282             return INVALID_OPERATION;
283         }
284     }
285 }
286 
setAudioSink(const sp<AudioSink> & audioSink)287 void NuPlayerDriver::setAudioSink(const sp<AudioSink> &audioSink) {
288     mPlayer->setAudioSink(audioSink);
289 }
290 
setParameter(int key,const Parcel & request)291 status_t NuPlayerDriver::setParameter(int key, const Parcel &request) {
292     return INVALID_OPERATION;
293 }
294 
getParameter(int key,Parcel * reply)295 status_t NuPlayerDriver::getParameter(int key, Parcel *reply) {
296     return INVALID_OPERATION;
297 }
298 
getMetadata(const media::Metadata::Filter & ids,Parcel * records)299 status_t NuPlayerDriver::getMetadata(
300         const media::Metadata::Filter& ids, Parcel *records) {
301     return INVALID_OPERATION;
302 }
303 
notifyResetComplete()304 void NuPlayerDriver::notifyResetComplete() {
305     Mutex::Autolock autoLock(mLock);
306     CHECK(mResetInProgress);
307     mResetInProgress = false;
308     mCondition.broadcast();
309 }
310 
notifyDuration(int64_t durationUs)311 void NuPlayerDriver::notifyDuration(int64_t durationUs) {
312     Mutex::Autolock autoLock(mLock);
313     mDurationUs = durationUs;
314 }
315 
notifyPosition(int64_t positionUs)316 void NuPlayerDriver::notifyPosition(int64_t positionUs) {
317     Mutex::Autolock autoLock(mLock);
318     mPositionUs = positionUs;
319 }
320 
notifySeekComplete()321 void NuPlayerDriver::notifySeekComplete() {
322     notifyListener(MEDIA_SEEK_COMPLETE);
323 }
324 
notifyFrameStats(int64_t numFramesTotal,int64_t numFramesDropped)325 void NuPlayerDriver::notifyFrameStats(
326         int64_t numFramesTotal, int64_t numFramesDropped) {
327     Mutex::Autolock autoLock(mLock);
328     mNumFramesTotal = numFramesTotal;
329     mNumFramesDropped = numFramesDropped;
330 }
331 
dump(int fd,const Vector<String16> & args) const332 status_t NuPlayerDriver::dump(int fd, const Vector<String16> &args) const {
333     Mutex::Autolock autoLock(mLock);
334 
335     FILE *out = fdopen(dup(fd), "w");
336 
337     fprintf(out, " NuPlayer\n");
338     fprintf(out, "  numFramesTotal(%lld), numFramesDropped(%lld), "
339                  "percentageDropped(%.2f)\n",
340                  mNumFramesTotal,
341                  mNumFramesDropped,
342                  mNumFramesTotal == 0
343                     ? 0.0 : (double)mNumFramesDropped / mNumFramesTotal);
344 
345     fclose(out);
346     out = NULL;
347 
348     return OK;
349 }
350 
notifyListener(int msg,int ext1,int ext2)351 void NuPlayerDriver::notifyListener(int msg, int ext1, int ext2) {
352     if (msg == MEDIA_PLAYBACK_COMPLETE || msg == MEDIA_ERROR) {
353         mAtEOS = true;
354     }
355 
356     sendEvent(msg, ext1, ext2);
357 }
358 
359 }  // namespace android
360