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