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