android_GenericPlayer.cpp revision 13837cf3f7be0eb8b1a9552bd99a89f98c987720
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//-------------------------------------------------- 145/* 146 * post-condition: mDataLocatorType == kDataLocatorNone 147 * 148 */ 149void GenericPlayer::resetDataLocator() { 150 mDataLocatorType = kDataLocatorNone; 151} 152 153 154void GenericPlayer::notify(const char* event, int data, bool async) { 155 sp<AMessage> msg = new AMessage(kWhatNotif, id()); 156 msg->setInt32(event, (int32_t)data); 157 if (async) { 158 msg->post(); 159 } else { 160 this->onNotify(msg); 161 } 162} 163 164 165//-------------------------------------------------- 166// AHandler implementation 167void GenericPlayer::onMessageReceived(const sp<AMessage> &msg) { 168 switch (msg->what()) { 169 case kWhatPrepare: 170 onPrepare(); 171 break; 172 173 case kWhatNotif: 174 onNotify(msg); 175 break; 176 177 case kWhatPlay: 178 onPlay(); 179 break; 180 181 case kWhatPause: 182 onPause(); 183 break; 184 185 case kWhatSeek: 186 onSeek(msg); 187 break; 188 189 case kWhatLoop: 190 onLoop(msg); 191 break; 192 193 default: 194 TRESPASS(); 195 } 196} 197 198 199//-------------------------------------------------- 200// Event handlers 201void GenericPlayer::onPrepare() { 202 SL_LOGI("GenericPlayer::onPrepare()"); 203 if (!(mStateFlags & kFlagPrepared)) { 204 mStateFlags |= kFlagPrepared; 205 notify(PLAYEREVENT_PREPARED, PLAYER_SUCCESS, false /*async*/); 206 } 207 SL_LOGI("GenericPlayer::onPrepare() done, mStateFlags=0x%x", mStateFlags); 208} 209 210 211void GenericPlayer::onNotify(const sp<AMessage> &msg) { 212 if (NULL == mNotifyClient) { 213 return; 214 } 215 216 int32_t val; 217 if (msg->findInt32(PLAYEREVENT_PREPARED, &val)) { 218 SL_LOGV("GenericPlayer notifying %s = %d", PLAYEREVENT_PREPARED, val); 219 mNotifyClient(kEventPrepared, val, mNotifyUser); 220 } 221} 222 223 224void GenericPlayer::onPlay() { 225 SL_LOGI("GenericPlayer::onPlay()"); 226 if ((mStateFlags & kFlagPrepared)) { 227 SL_LOGI("starting player"); 228 mStateFlags |= kFlagPlaying; 229 } else { 230 SL_LOGV("NOT starting player mStateFlags=0x%x", mStateFlags); 231 } 232} 233 234 235void GenericPlayer::onPause() { 236 SL_LOGI("GenericPlayer::onPause()"); 237 if ((mStateFlags & kFlagPrepared)) { 238 mStateFlags &= ~kFlagPlaying; 239 } 240 241} 242 243 244void GenericPlayer::onSeek(const sp<AMessage> &msg) { 245 SL_LOGV("GenericPlayer::onSeek"); 246} 247 248 249void GenericPlayer::onLoop(const sp<AMessage> &msg) { 250 SL_LOGV("GenericPlayer::onLoop"); 251} 252 253} // namespace android 254