1// Copyright 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5// The file defines the symbols from OpenSLES that android is using. It then 6// loads the library dynamically on first use. 7 8// The openSLES API is using constant as part of the API. This file will define 9// proxies for those constants and redefine those when the library is first 10// loaded. For this, it need to be able to change their content and so import 11// the headers without const. This is correct because OpenSLES.h is a C API. 12#define const 13#include <SLES/OpenSLES.h> 14#include <SLES/OpenSLES_Android.h> 15#undef const 16 17#include "base/basictypes.h" 18#include "base/files/file_path.h" 19#include "base/logging.h" 20#include "base/native_library.h" 21 22// The constants used in chromium. SLInterfaceID is actually a pointer to 23// SLInterfaceID_. Those symbols are defined as extern symbols in the OpenSLES 24// headers. They will be initialized to their correct values when the library is 25// loaded. 26SLInterfaceID SL_IID_ENGINE = NULL; 27SLInterfaceID SL_IID_ANDROIDSIMPLEBUFFERQUEUE = NULL; 28SLInterfaceID SL_IID_ANDROIDCONFIGURATION = NULL; 29SLInterfaceID SL_IID_RECORD = NULL; 30SLInterfaceID SL_IID_BUFFERQUEUE = NULL; 31SLInterfaceID SL_IID_VOLUME = NULL; 32SLInterfaceID SL_IID_PLAY = NULL; 33 34namespace { 35 36// The name of the library to load. 37const char kOpenSLLibraryName[] = "libOpenSLES.so"; 38 39// Loads the OpenSLES library, and initializes all the proxies. 40base::NativeLibrary IntializeLibraryHandle() { 41 base::NativeLibrary handle = 42 base::LoadNativeLibrary(base::FilePath(kOpenSLLibraryName), NULL); 43 DCHECK(handle) << "Unable to load " << kOpenSLLibraryName; 44 45 // Setup the proxy for each symbol. 46 // Attach the symbol name to the proxy address. 47 struct SymbolDefinition { 48 const char* name; 49 SLInterfaceID* sl_iid; 50 }; 51 52 // The list of defined symbols. 53 const SymbolDefinition kSymbols[] = { 54 {"SL_IID_ENGINE", &SL_IID_ENGINE}, 55 {"SL_IID_ANDROIDSIMPLEBUFFERQUEUE", &SL_IID_ANDROIDSIMPLEBUFFERQUEUE}, 56 {"SL_IID_ANDROIDCONFIGURATION", &SL_IID_ANDROIDCONFIGURATION}, 57 {"SL_IID_RECORD", &SL_IID_RECORD}, 58 {"SL_IID_BUFFERQUEUE", &SL_IID_BUFFERQUEUE}, 59 {"SL_IID_VOLUME", &SL_IID_VOLUME}, 60 {"SL_IID_PLAY", &SL_IID_PLAY} 61 }; 62 63 for (size_t i = 0; i < sizeof(kSymbols) / sizeof(kSymbols[0]); ++i) { 64 memcpy(kSymbols[i].sl_iid, 65 base::GetFunctionPointerFromNativeLibrary(handle, kSymbols[i].name), 66 sizeof(SLInterfaceID)); 67 DCHECK(*kSymbols[i].sl_iid) << "Unable to find symbol for " 68 << kSymbols[i].name; 69 } 70 return handle; 71} 72 73// Returns the handler to the shared library. The library itself will be lazily 74// loaded during the first call to this function. 75base::NativeLibrary LibraryHandle() { 76 // The handle is lazily initialized on the first call. 77 static base::NativeLibrary g_opensles_LibraryHandle = 78 IntializeLibraryHandle(); 79 return g_opensles_LibraryHandle; 80} 81 82} // namespace 83 84// Redefine slCreateEngine symbol. 85SLresult slCreateEngine(SLObjectItf* engine, 86 SLuint32 num_options, 87 SLEngineOption* engine_options, 88 SLuint32 num_interfaces, 89 SLInterfaceID* interface_ids, 90 SLboolean* interfaces_required) { 91 typedef SLresult (*SlCreateEngineSignature)(SLObjectItf*, 92 SLuint32, 93 SLEngineOption*, 94 SLuint32, 95 SLInterfaceID*, 96 SLboolean*); 97 static SlCreateEngineSignature g_sl_create_engine_handle = 98 reinterpret_cast<SlCreateEngineSignature>( 99 base::GetFunctionPointerFromNativeLibrary(LibraryHandle(), 100 "slCreateEngine")); 101 DCHECK(g_sl_create_engine_handle) 102 << "Unable to find symbol for slCreateEngine"; 103 return g_sl_create_engine_handle(engine, 104 num_options, 105 engine_options, 106 num_interfaces, 107 interface_ids, 108 interfaces_required); 109} 110