android_StreamPlayer.cpp revision 13837cf3f7be0eb8b1a9552bd99a89f98c987720
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); 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) : AVPlayer(params), 135 mAppProxy(0) 136{ 137 SL_LOGI("StreamPlayer::StreamPlayer()"); 138 139 mPlaybackParams = *params; 140 141} 142 143StreamPlayer::~StreamPlayer() { 144 SL_LOGI("StreamPlayer::~StreamPlayer()"); 145 146 mAppProxy.clear(); 147} 148 149 150void StreamPlayer::registerQueueCallback(slAndroidBufferQueueCallback callback, void *context, 151 const void *caller) { 152 SL_LOGI("StreamPlayer::registerQueueCallback"); 153 Mutex::Autolock _l(mLock); 154 155 mAppProxy = new StreamSourceAppProxy(callback, context, caller); 156 157 CHECK(mAppProxy != 0); 158 SL_LOGI("StreamPlayer::registerQueueCallback end"); 159} 160 161void StreamPlayer::appEnqueue(SLuint32 bufferId, SLuint32 length, SLAbufferQueueEvent event, 162 void *pData) { 163 Mutex::Autolock _l(mLock); 164 if (mAppProxy != 0) { 165 if (event != SL_ANDROIDBUFFERQUEUE_EVENT_NONE) { 166 if (event & SL_ANDROIDBUFFERQUEUE_EVENT_DISCONTINUITY) { 167 mAppProxy->receivedFromAppCommand(IStreamListener::DISCONTINUITY); 168 } 169 if (event & SL_ANDROIDBUFFERQUEUE_EVENT_EOS) { 170 mAppProxy->receivedFromAppCommand(IStreamListener::EOS); 171 } 172 } 173 if (length > 0) { 174 // FIXME PRIORITY1 verify given length isn't bigger than declared length in app callback 175 mAppProxy->receivedFromAppBuffer((size_t)bufferId, (size_t)length); 176 } 177 } 178} 179 180void StreamPlayer::appClear() { 181 Mutex::Autolock _l(mLock); 182 if (mAppProxy != 0) { 183 // FIXME PRIORITY1 implement 184 SL_LOGE("[ FIXME implement StreamPlayer::appClear() ]"); 185 } 186} 187 188 189//-------------------------------------------------- 190// Event handlers 191void StreamPlayer::onPrepare() { 192 SL_LOGI("StreamPlayer::onPrepare()"); 193 //Mutex::Autolock _l(mLock); 194 if (mAppProxy != 0) { 195 mPlayer = mMediaPlayerService->create(getpid(), mPlayerClient /*IMediaPlayerClient*/, 196 mAppProxy /*IStreamSource*/, mPlaybackParams.sessionId); 197 // blocks until mPlayer is prepared 198 AVPlayer::onPrepare(); 199 SL_LOGI("StreamPlayer::onPrepare() done"); 200 } else { 201 SL_LOGE("Nothing to do here because there is no registered callback"); 202 } 203} 204 205 206 207} // namespace android 208