android_GenericPlayer.cpp revision 70c49ae2867094072a4365423417ea452bf82231
1/* 2 * Copyright (C) 2011 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 USE_LOG SLAndroidLogLevel_Verbose 18 19#include "sles_allinclusive.h" 20 21namespace android { 22 23//-------------------------------------------------------------------------------------------------- 24GenericPlayer::GenericPlayer(const AudioPlayback_Parameters* params) : 25 mDataLocatorType(kDataLocatorNone), 26 mNotifyClient(NULL), 27 mNotifyUser(NULL), 28 mStateFlags(0), 29 mLooperPriority(PRIORITY_DEFAULT), 30 mPlaybackParams(*params) 31{ 32 SL_LOGI("GenericPlayer::GenericPlayer()"); 33 34 mLooper = new android::ALooper(); 35 36} 37 38 39GenericPlayer::~GenericPlayer() { 40 SL_LOGI("GenericPlayer::~GenericPlayer()"); 41 42 mLooper->stop(); 43 mLooper->unregisterHandler(id()); 44 mLooper.clear(); 45 46} 47 48 49void GenericPlayer::init(const notif_cbf_t cbf, void* notifUser) { 50 SL_LOGI("GenericPlayer::init()"); 51 52 mNotifyClient = cbf; 53 mNotifyUser = notifUser; 54 55 mLooper->registerHandler(this); 56 mLooper->start(false /*runOnCallingThread*/, false /*canCallJava*/, mLooperPriority); 57} 58 59 60void GenericPlayer::setDataSource(const char *uri) { 61 resetDataLocator(); 62 63 mDataLocator.uriRef = uri; 64 65 mDataLocatorType = kDataLocatorUri; 66} 67 68 69void GenericPlayer::setDataSource(int fd, int64_t offset, int64_t length) { 70 resetDataLocator(); 71 72 mDataLocator.fdi.fd = fd; 73 74 struct stat sb; 75 int ret = fstat(fd, &sb); 76 if (ret != 0) { 77 SL_LOGE("GenericPlayer::setDataSource: fstat(%d) failed: %d, %s", fd, ret, strerror(errno)); 78 return; 79 } 80 81 if (offset >= sb.st_size) { 82 SL_LOGE("SfPlayer::setDataSource: invalid offset"); 83 return; 84 } 85 mDataLocator.fdi.offset = offset; 86 87 if (PLAYER_FD_FIND_FILE_SIZE == length) { 88 mDataLocator.fdi.length = sb.st_size; 89 } else if (offset + length > sb.st_size) { 90 mDataLocator.fdi.length = sb.st_size - offset; 91 } else { 92 mDataLocator.fdi.length = length; 93 } 94 95 mDataLocatorType = kDataLocatorFd; 96} 97 98 99void GenericPlayer::prepare() { 100 SL_LOGI("GenericPlayer::prepare()"); 101 sp<AMessage> msg = new AMessage(kWhatPrepare, id()); 102 msg->post(); 103} 104 105 106void GenericPlayer::play() { 107 SL_LOGI("GenericPlayer::play()"); 108 sp<AMessage> msg = new AMessage(kWhatPlay, id()); 109 msg->post(); 110} 111 112 113void GenericPlayer::pause() { 114 SL_LOGI("GenericPlayer::prepare()"); 115 sp<AMessage> msg = new AMessage(kWhatPause, id()); 116 msg->post(); 117} 118 119 120void GenericPlayer::stop() { 121 SL_LOGI("GenericPlayer::stop()"); 122 (new AMessage(kWhatPause, id()))->post(); 123 124 // after a stop, playback should resume from the start. 125 seek(0); 126} 127 128 129void GenericPlayer::seek(int64_t timeMsec) { 130 SL_LOGV("GenericPlayer::seek %lld", timeMsec); 131 sp<AMessage> msg = new AMessage(kWhatSeek, id()); 132 msg->setInt64(WHATPARAM_SEEK_SEEKTIME_MS, timeMsec); 133 msg->post(); 134} 135 136 137void GenericPlayer::loop(bool loop) { 138 sp<AMessage> msg = new AMessage(kWhatLoop, id()); 139 msg->setInt32(WHATPARAM_LOOP_LOOPING, (int32_t)loop); 140 msg->post(); 141} 142 143 144//-------------------------------------------------- 145void GenericPlayer::getDurationMsec(int* msec) { 146 // unknown duration 147 *msec = -1; 148} 149 150 151//-------------------------------------------------- 152/* 153 * post-condition: mDataLocatorType == kDataLocatorNone 154 * 155 */ 156void GenericPlayer::resetDataLocator() { 157 mDataLocatorType = kDataLocatorNone; 158} 159 160 161void GenericPlayer::notify(const char* event, int data, bool async) { 162 sp<AMessage> msg = new AMessage(kWhatNotif, id()); 163 msg->setInt32(event, (int32_t)data); 164 if (async) { 165 msg->post(); 166 } else { 167 this->onNotify(msg); 168 } 169} 170 171 172//-------------------------------------------------- 173// AHandler implementation 174void GenericPlayer::onMessageReceived(const sp<AMessage> &msg) { 175 switch (msg->what()) { 176 case kWhatPrepare: 177 onPrepare(); 178 break; 179 180 case kWhatNotif: 181 onNotify(msg); 182 break; 183 184 case kWhatPlay: 185 onPlay(); 186 break; 187 188 case kWhatPause: 189 onPause(); 190 break; 191 192 case kWhatSeek: 193 onSeek(msg); 194 break; 195 196 case kWhatLoop: 197 onLoop(msg); 198 break; 199 200 default: 201 TRESPASS(); 202 } 203} 204 205 206//-------------------------------------------------- 207// Event handlers 208void GenericPlayer::onPrepare() { 209 SL_LOGI("GenericPlayer::onPrepare()"); 210 if (!(mStateFlags & kFlagPrepared)) { 211 mStateFlags |= kFlagPrepared; 212 notify(PLAYEREVENT_PREPARED, PLAYER_SUCCESS, false /*async*/); 213 } 214 SL_LOGI("GenericPlayer::onPrepare() done, mStateFlags=0x%x", mStateFlags); 215} 216 217 218void GenericPlayer::onNotify(const sp<AMessage> &msg) { 219 if (NULL == mNotifyClient) { 220 return; 221 } 222 223 int32_t val; 224 if (msg->findInt32(PLAYEREVENT_PREPARED, &val)) { 225 SL_LOGV("GenericPlayer notifying %s = %d", PLAYEREVENT_PREPARED, val); 226 mNotifyClient(kEventPrepared, val, mNotifyUser); 227 } 228} 229 230 231void GenericPlayer::onPlay() { 232 SL_LOGI("GenericPlayer::onPlay()"); 233 if ((mStateFlags & kFlagPrepared)) { 234 SL_LOGI("starting player"); 235 mStateFlags |= kFlagPlaying; 236 } else { 237 SL_LOGV("NOT starting player mStateFlags=0x%x", mStateFlags); 238 } 239} 240 241 242void GenericPlayer::onPause() { 243 SL_LOGI("GenericPlayer::onPause()"); 244 if ((mStateFlags & kFlagPrepared)) { 245 mStateFlags &= ~kFlagPlaying; 246 } 247 248} 249 250 251void GenericPlayer::onSeek(const sp<AMessage> &msg) { 252 SL_LOGV("GenericPlayer::onSeek"); 253} 254 255 256void GenericPlayer::onLoop(const sp<AMessage> &msg) { 257 SL_LOGV("GenericPlayer::onLoop"); 258} 259 260} // namespace android 261