android_StreamPlayer.cpp revision d158d31a6bbb06426b71c3d097b7768bc3fb79a3
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 USE_LOG SLAndroidLogLevel_Verbose 18 19#include "sles_allinclusive.h" 20#include <media/IMediaPlayerService.h> 21 22//-------------------------------------------------------------------------------------------------- 23// FIXME abstract out the diff between CMediaPlayer and CAudioPlayer 24 25void android_StreamPlayer_realize_l(CAudioPlayer *ap, const notif_cbf_t cbf, void* notifUser) { 26 SL_LOGI("android_StreamPlayer_realize_l(%p)", ap); 27 28 AudioPlayback_Parameters ap_params; 29 ap_params.sessionId = ap->mSessionId; 30 ap_params.streamType = ap->mStreamType; 31 ap_params.trackcb = NULL; 32 ap_params.trackcbUser = NULL; 33 android::StreamPlayer* splr = new android::StreamPlayer(&ap_params, false /*hasVideo*/); 34 ap->mAPlayer = splr; 35 splr->init(cbf, notifUser); 36} 37 38 39//----------------------------------------------------------------------------- 40 41// FIXME abstract out the diff between CMediaPlayer and CAudioPlayer 42void android_StreamPlayer_enqueue_l(CAudioPlayer *ap, 43 SLuint32 bufferId, SLuint32 length, SLuint32 event, void *pData) { 44 if (ap->mAPlayer != 0) { 45 ((android::StreamPlayer*)ap->mAPlayer.get())->appEnqueue(bufferId, length, event, pData); 46 } 47} 48 49 50// FIXME abstract out the diff between CMediaPlayer and CAudioPlayer 51void android_StreamPlayer_clear_l(CAudioPlayer *ap) { 52 if (ap->mAPlayer != 0) { 53 ((android::StreamPlayer*)ap->mAPlayer.get())->appClear(); 54 } 55} 56 57//-------------------------------------------------------------------------------------------------- 58namespace android { 59 60StreamSourceAppProxy::StreamSourceAppProxy( 61 slAndroidBufferQueueCallback callback, 62 cb_buffAvailable_t notify, 63 const void* user, bool userIsAudioPlayer, 64 void *context, const void *caller) : 65 mCallback(callback), 66 mCbNotifyBufferAvailable(notify), 67 mUser(user), 68 mUserIsAudioPlayer(userIsAudioPlayer), 69 mAppContext(context), 70 mCaller(caller) 71{ 72 SL_LOGI("StreamSourceAppProxy::StreamSourceAppProxy()"); 73} 74 75StreamSourceAppProxy::~StreamSourceAppProxy() { 76 SL_LOGI("StreamSourceAppProxy::~StreamSourceAppProxy()"); 77 mListener.clear(); 78 mBuffers.clear(); 79} 80 81//-------------------------------------------------- 82// IStreamSource implementation 83void StreamSourceAppProxy::setListener(const sp<IStreamListener> &listener) { 84 Mutex::Autolock _l(mListenerLock); 85 mListener = listener; 86} 87 88void StreamSourceAppProxy::setBuffers(const Vector<sp<IMemory> > &buffers) { 89 mBuffers = buffers; 90} 91 92void StreamSourceAppProxy::onBufferAvailable(size_t index) { 93 SL_LOGD("StreamSourceAppProxy::onBufferAvailable(%d)", index); 94 95 CHECK_LT(index, mBuffers.size()); 96 sp<IMemory> mem = mBuffers.itemAt(index); 97 SLAint64 length = (SLAint64) mem->size(); 98 99 (*mCbNotifyBufferAvailable)(mUser, mUserIsAudioPlayer, index, mem->pointer(), mem->size()); 100 101#if 0 102 // FIXME remove 103 // FIXME PRIORITY1 needs to be called asynchronously, from AudioPlayer code after having 104 // obtained under lock the callback function pointer and context 105 (*mCallback)((SLAndroidBufferQueueItf)mCaller, /* SLAndroidBufferQueueItf self */ 106 mAppContext, /* void *pContext */ 107 index, /* SLuint32 bufferId */ 108 length, /* SLAint64 bufferLength */ 109 mem->pointer(),/* void *pBufferDataLocation */ 110 0, /* SLuint32 msgLength */ 111 NULL /*void *pMsgDataLocation*/ 112 ); 113#endif 114} 115 116void StreamSourceAppProxy::receivedFromAppCommand(IStreamListener::Command cmd) { 117 Mutex::Autolock _l(mListenerLock); 118 if (mListener != 0) { 119 mListener->issueCommand(cmd, false /* synchronous */); 120 } 121} 122 123void StreamSourceAppProxy::receivedFromAppBuffer(size_t buffIndex, size_t buffLength) { 124 Mutex::Autolock _l(mListenerLock); 125 if (mListener != 0) { 126 mListener->queueBuffer(buffIndex, buffLength); 127 } 128} 129 130 131//-------------------------------------------------------------------------------------------------- 132StreamPlayer::StreamPlayer(AudioPlayback_Parameters* params, bool hasVideo) : 133 GenericMediaPlayer(params, hasVideo), 134 mAppProxy(0) 135{ 136 SL_LOGI("StreamPlayer::StreamPlayer()"); 137 138 mPlaybackParams = *params; 139 140} 141 142StreamPlayer::~StreamPlayer() { 143 SL_LOGI("StreamPlayer::~StreamPlayer()"); 144 145 mAppProxy.clear(); 146} 147 148 149void StreamPlayer::registerQueueCallback( 150 slAndroidBufferQueueCallback callback, 151 cb_buffAvailable_t notify, 152 const void* user, bool userIsAudioPlayer, 153 void *context, 154 const void *caller) { 155 SL_LOGI("StreamPlayer::registerQueueCallback"); 156 Mutex::Autolock _l(mAppProxyLock); 157 158 mAppProxy = new StreamSourceAppProxy(callback, 159 notify, user, userIsAudioPlayer, 160 context, caller); 161 162 CHECK(mAppProxy != 0); 163 SL_LOGI("StreamPlayer::registerQueueCallback end"); 164} 165 166void StreamPlayer::appEnqueue(SLuint32 bufferId, SLuint32 length, SLuint32 event, 167 void *pData) { 168 Mutex::Autolock _l(mAppProxyLock); 169 if (mAppProxy != 0) { 170 if (event != SL_ANDROID_ITEMKEY_NONE) { 171 if (event & SL_ANDROID_ITEMKEY_DISCONTINUITY) { 172 mAppProxy->receivedFromAppCommand(IStreamListener::DISCONTINUITY); 173 } 174 if (event & SL_ANDROID_ITEMKEY_EOS) { 175 mAppProxy->receivedFromAppCommand(IStreamListener::EOS); 176 } 177 } 178 if (length > 0) { 179 // FIXME PRIORITY1 verify given length isn't bigger than declared length in app callback 180 mAppProxy->receivedFromAppBuffer((size_t)bufferId, (size_t)length); 181 } 182 } 183} 184 185void StreamPlayer::appClear() { 186 Mutex::Autolock _l(mAppProxyLock); 187 if (mAppProxy != 0) { 188 // FIXME PRIORITY1 implement 189 SL_LOGE("[ FIXME implement StreamPlayer::appClear() ]"); 190 } 191} 192 193 194//-------------------------------------------------- 195// Event handlers 196void StreamPlayer::onPrepare() { 197 SL_LOGI("StreamPlayer::onPrepare()"); 198 Mutex::Autolock _l(mAppProxyLock); 199 if (mAppProxy != 0) { 200 mPlayer = mMediaPlayerService->create(getpid(), mPlayerClient /*IMediaPlayerClient*/, 201 mAppProxy /*IStreamSource*/, mPlaybackParams.sessionId); 202 // blocks until mPlayer is prepared 203 GenericMediaPlayer::onPrepare(); 204 SL_LOGI("StreamPlayer::onPrepare() done"); 205 } else { 206 SL_LOGE("Nothing to do here because there is no registered callback"); 207 } 208} 209 210 211 212} // namespace android 213