NuPlayerDriver.cpp revision 0d268a3cae145afb2720c88ae38fb81550be5584
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 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 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 98status_t NuPlayerDriver::setVideoSurfaceTexture( 99 const sp<ISurfaceTexture> &surfaceTexture) { 100 mPlayer->setVideoSurfaceTexture(surfaceTexture); 101 102 return OK; 103} 104 105status_t NuPlayerDriver::prepare() { 106 sendEvent(MEDIA_SET_VIDEO_SIZE, 0, 0); 107 return OK; 108} 109 110status_t NuPlayerDriver::prepareAsync() { 111 status_t err = prepare(); 112 113 notifyListener(MEDIA_PREPARED); 114 115 return err; 116} 117 118status_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 155status_t NuPlayerDriver::stop() { 156 return pause(); 157} 158 159status_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 180bool NuPlayerDriver::isPlaying() { 181 return mState == PLAYING && !mAtEOS; 182} 183 184status_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 211status_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 223status_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 235status_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 253status_t NuPlayerDriver::setLooping(int loop) { 254 return INVALID_OPERATION; 255} 256 257player_type NuPlayerDriver::playerType() { 258 return NU_PLAYER; 259} 260 261status_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 287void NuPlayerDriver::setAudioSink(const sp<AudioSink> &audioSink) { 288 mPlayer->setAudioSink(audioSink); 289} 290 291status_t NuPlayerDriver::setParameter(int key, const Parcel &request) { 292 return INVALID_OPERATION; 293} 294 295status_t NuPlayerDriver::getParameter(int key, Parcel *reply) { 296 return INVALID_OPERATION; 297} 298 299status_t NuPlayerDriver::getMetadata( 300 const media::Metadata::Filter& ids, Parcel *records) { 301 return INVALID_OPERATION; 302} 303 304void NuPlayerDriver::notifyResetComplete() { 305 Mutex::Autolock autoLock(mLock); 306 CHECK(mResetInProgress); 307 mResetInProgress = false; 308 mCondition.broadcast(); 309} 310 311void NuPlayerDriver::notifyDuration(int64_t durationUs) { 312 Mutex::Autolock autoLock(mLock); 313 mDurationUs = durationUs; 314} 315 316void NuPlayerDriver::notifyPosition(int64_t positionUs) { 317 Mutex::Autolock autoLock(mLock); 318 mPositionUs = positionUs; 319} 320 321void NuPlayerDriver::notifySeekComplete() { 322 notifyListener(MEDIA_SEEK_COMPLETE); 323} 324 325void NuPlayerDriver::notifyFrameStats( 326 int64_t numFramesTotal, int64_t numFramesDropped) { 327 Mutex::Autolock autoLock(mLock); 328 mNumFramesTotal = numFramesTotal; 329 mNumFramesDropped = numFramesDropped; 330} 331 332status_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 351void 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