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