• 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     return INVALID_OPERATION;
263 }
264 
setAudioSink(const sp<AudioSink> & audioSink)265 void NuPlayerDriver::setAudioSink(const sp<AudioSink> &audioSink) {
266     mPlayer->setAudioSink(audioSink);
267 }
268 
setParameter(int key,const Parcel & request)269 status_t NuPlayerDriver::setParameter(int key, const Parcel &request) {
270     return INVALID_OPERATION;
271 }
272 
getParameter(int key,Parcel * reply)273 status_t NuPlayerDriver::getParameter(int key, Parcel *reply) {
274     return INVALID_OPERATION;
275 }
276 
getMetadata(const media::Metadata::Filter & ids,Parcel * records)277 status_t NuPlayerDriver::getMetadata(
278         const media::Metadata::Filter& ids, Parcel *records) {
279     return INVALID_OPERATION;
280 }
281 
notifyResetComplete()282 void NuPlayerDriver::notifyResetComplete() {
283     Mutex::Autolock autoLock(mLock);
284     CHECK(mResetInProgress);
285     mResetInProgress = false;
286     mCondition.broadcast();
287 }
288 
notifyDuration(int64_t durationUs)289 void NuPlayerDriver::notifyDuration(int64_t durationUs) {
290     Mutex::Autolock autoLock(mLock);
291     mDurationUs = durationUs;
292 }
293 
notifyPosition(int64_t positionUs)294 void NuPlayerDriver::notifyPosition(int64_t positionUs) {
295     Mutex::Autolock autoLock(mLock);
296     mPositionUs = positionUs;
297 }
298 
notifySeekComplete()299 void NuPlayerDriver::notifySeekComplete() {
300     notifyListener(MEDIA_SEEK_COMPLETE);
301 }
302 
notifyFrameStats(int64_t numFramesTotal,int64_t numFramesDropped)303 void NuPlayerDriver::notifyFrameStats(
304         int64_t numFramesTotal, int64_t numFramesDropped) {
305     Mutex::Autolock autoLock(mLock);
306     mNumFramesTotal = numFramesTotal;
307     mNumFramesDropped = numFramesDropped;
308 }
309 
dump(int fd,const Vector<String16> & args) const310 status_t NuPlayerDriver::dump(int fd, const Vector<String16> &args) const {
311     Mutex::Autolock autoLock(mLock);
312 
313     FILE *out = fdopen(dup(fd), "w");
314 
315     fprintf(out, " NuPlayer\n");
316     fprintf(out, "  numFramesTotal(%lld), numFramesDropped(%lld), "
317                  "percentageDropped(%.2f)\n",
318                  mNumFramesTotal,
319                  mNumFramesDropped,
320                  mNumFramesTotal == 0
321                     ? 0.0 : (double)mNumFramesDropped / mNumFramesTotal);
322 
323     fclose(out);
324     out = NULL;
325 
326     return OK;
327 }
328 
notifyListener(int msg,int ext1,int ext2)329 void NuPlayerDriver::notifyListener(int msg, int ext1, int ext2) {
330     if (msg == MEDIA_PLAYBACK_COMPLETE || msg == MEDIA_ERROR) {
331         mAtEOS = true;
332     }
333 
334     sendEvent(msg, ext1, ext2);
335 }
336 
337 }  // namespace android
338