android_StreamPlayer.cpp revision 262059f71a68edc5e510427c63f5f1623d3672a8
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#undef this // FIXME shouldn't have to do this, no pun intended 21#include <media/IMediaPlayerService.h> 22 23//-------------------------------------------------------------------------------------------------- 24// FIXME abstract out the diff between CMediaPlayer and CAudioPlayer 25 26void android_StreamPlayer_realize_l(CAudioPlayer *ap, const notif_client_t cbf, void* notifUser) { 27 SL_LOGI("android_StreamPlayer_realize_l(%p)", ap); 28 29 AudioPlayback_Parameters ap_params; 30 ap_params.sessionId = ap->mSessionId; 31 ap_params.streamType = ap->mStreamType; 32 ap_params.trackcb = NULL; 33 ap_params.trackcbUser = NULL; 34 ap->mStreamPlayer = new android::StreamPlayer(&ap_params); 35 ap->mStreamPlayer->init(cbf, notifUser); 36} 37 38 39// FIXME abstract out the diff between CMediaPlayer and CAudioPlayer 40void android_StreamPlayer_destroy(CAudioPlayer *ap) { 41 SL_LOGI("android_StreamPlayer_destroy(%p)", ap); 42 43 ap->mStreamPlayer.clear(); 44} 45 46 47//----------------------------------------------------------------------------- 48void android_StreamPlayer_androidBufferQueue_registerCallback(android::StreamPlayer *splr, 49 slAndroidBufferQueueCallback callback, void* context, const void* callerItf) 50{ 51 if (splr != NULL) { 52 SL_LOGI("android_Player_androidBufferQueue_registerCallback"); 53 splr->registerQueueCallback(callback, context, callerItf); 54 } 55} 56 57// FIXME abstract out the diff between CMediaPlayer and CAudioPlayer 58void android_StreamPlayer_enqueue_l(CAudioPlayer *ap, 59 SLuint32 bufferId, SLuint32 length, SLAbufferQueueEvent event, void *pData) { 60 if (ap->mStreamPlayer != 0) { 61 ap->mStreamPlayer->appEnqueue(bufferId, length, event, pData); 62 } 63} 64 65 66// FIXME abstract out the diff between CMediaPlayer and CAudioPlayer 67void android_StreamPlayer_clear_l(CAudioPlayer *ap) { 68 if (ap->mStreamPlayer != 0) { 69 ap->mStreamPlayer->appClear(); 70 } 71} 72 73//-------------------------------------------------------------------------------------------------- 74namespace android { 75 76StreamSourceAppProxy::StreamSourceAppProxy( 77 slAndroidBufferQueueCallback callback, void *context, const void *caller) : 78 mCallback(callback), 79 mAppContext(context), 80 mCaller(caller) 81{ 82 SL_LOGI("StreamSourceAppProxy::StreamSourceAppProxy()"); 83} 84 85StreamSourceAppProxy::~StreamSourceAppProxy() { 86 SL_LOGI("StreamSourceAppProxy::~StreamSourceAppProxy()"); 87 mListener.clear(); 88 mBuffers.clear(); 89} 90 91//-------------------------------------------------- 92// IStreamSource implementation 93void StreamSourceAppProxy::setListener(const sp<IStreamListener> &listener) { 94 Mutex::Autolock _l(mListenerLock); 95 mListener = listener; 96} 97 98void StreamSourceAppProxy::setBuffers(const Vector<sp<IMemory> > &buffers) { 99 mBuffers = buffers; 100} 101 102void StreamSourceAppProxy::onBufferAvailable(size_t index) { 103 SL_LOGD("StreamSourceAppProxy::onBufferAvailable(%d)", index); 104 105 CHECK_LT(index, mBuffers.size()); 106 sp<IMemory> mem = mBuffers.itemAt(index); 107 SLAint64 length = (SLAint64) mem->size(); 108 109 // FIXME PRIORITY1 needs to be called asynchronously, from AudioPlayer code after having 110 // obtained under lock the callback function pointer and context 111 (*mCallback)((SLAndroidBufferQueueItf)mCaller, /* SLAndroidBufferQueueItf self */ 112 mAppContext, /* void *pContext */ 113 index, /* SLuint32 bufferId */ 114 length, /* SLAint64 bufferLength */ 115 mem->pointer()/* void *pBufferDataLocation */ 116 ); 117} 118 119void StreamSourceAppProxy::receivedFromAppCommand(IStreamListener::Command cmd) { 120 Mutex::Autolock _l(mListenerLock); 121 if (mListener != 0) { 122 mListener->issueCommand(cmd, false /* synchronous */); 123 } 124} 125 126void StreamSourceAppProxy::receivedFromAppBuffer(size_t buffIndex, size_t buffLength) { 127 Mutex::Autolock _l(mListenerLock); 128 if (mListener != 0) { 129 mListener->queueBuffer(buffIndex, buffLength); 130 } 131} 132 133 134//-------------------------------------------------------------------------------------------------- 135StreamPlayer::StreamPlayer(AudioPlayback_Parameters* params) : AVPlayer(params), 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(mLock); 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(mLock); 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(mLock); 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(mLock); 195 if (mAppProxy != 0) { 196 mPlayer = mMediaPlayerService->create(getpid(), mPlayerClient /*IMediaPlayerClient*/, 197 mAppProxy /*IStreamSource*/, mPlaybackParams.sessionId); 198 // blocks until mPlayer is prepared 199 AVPlayer::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