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 /* \file COutputMix.c OutputMix class */ 18 19 #include "sles_allinclusive.h" 20 21 22 /** \brief Hook called by Object::Realize when an output mix is realized */ 23 24 SLresult COutputMix_Realize(void *self, SLboolean async) 25 { 26 SLresult result = SL_RESULT_SUCCESS; 27 28 #ifdef ANDROID 29 COutputMix *thiz = (COutputMix *) self; 30 result = android_outputMix_realize(thiz, async); 31 #endif 32 33 return result; 34 } 35 36 37 /** \brief Hook called by Object::Resume when an output mix is resumed */ 38 39 SLresult COutputMix_Resume(void *self, SLboolean async) 40 { 41 return SL_RESULT_SUCCESS; 42 } 43 44 45 /** \brief Hook called by Object::Destroy when an output mix is destroyed */ 46 47 void COutputMix_Destroy(void *self) 48 { 49 #ifdef ANDROID 50 COutputMix *thiz = (COutputMix *) self; 51 android_outputMix_destroy(thiz); 52 #endif 53 } 54 55 56 /** \brief Hook called by Object::Destroy before an output mix is about to be destroyed */ 57 58 predestroy_t COutputMix_PreDestroy(void *self) 59 { 60 // Ignore destroy requests if there are any players attached to this output mix 61 COutputMix *outputMix = (COutputMix *) self; 62 // See design document for explanation 63 if (0 == outputMix->mObject.mStrongRefCount) { 64 #ifdef USE_OUTPUTMIXEXT 65 // We only support a single active output mix per engine, so check if this is the active mix 66 IEngine *thisEngine = &outputMix->mObject.mEngine->mEngine; 67 interface_lock_exclusive(thisEngine); 68 bool thisIsTheActiveOutputMix = false; 69 if (outputMix == thisEngine->mOutputMix) { 70 thisIsTheActiveOutputMix = true; 71 } 72 interface_unlock_exclusive(thisEngine); 73 if (thisIsTheActiveOutputMix) { 74 // Tell the asynchronous mixer callback that we want to destroy the output mix 75 outputMix->mOutputMixExt.mDestroyRequested = true; 76 while (outputMix->mOutputMixExt.mDestroyRequested) { 77 object_cond_wait(&outputMix->mObject); 78 } 79 #ifdef USE_SDL 80 // Mixer callback has acknowledged our request and unlinked output mix from engine. 81 // Disable SDL_callback from being called periodically by SDL's internal thread. 82 SDL_PauseAudio(1); 83 #endif 84 } 85 #endif 86 return predestroy_ok; 87 } 88 SL_LOGE("Object::Destroy(%p) for OutputMix ignored; %u players attached", outputMix, 89 outputMix->mObject.mStrongRefCount); 90 return predestroy_error; 91 } 92