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