1e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman/* 2e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * Copyright (C) 2015 The Android Open Source Project 3e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * 4e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * Licensed under the Apache License, Version 2.0 (the "License"); 5e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * you may not use this file except in compliance with the License. 6e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * You may obtain a copy of the License at 7e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * 8e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * http://www.apache.org/licenses/LICENSE-2.0 9e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * 10e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * Unless required by applicable law or agreed to in writing, software 11e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * distributed under the License is distributed on an "AS IS" BASIS, 12e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * See the License for the specific language governing permissions and 14e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * limitations under the License. 15e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman */ 16e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 17e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman#ifndef ANDROID_BUFFER_PROVIDERS_H 18e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman#define ANDROID_BUFFER_PROVIDERS_H 19e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 20e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman#include <stdint.h> 21e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman#include <sys/types.h> 22e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 23e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman#include <media/AudioBufferProvider.h> 24e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman#include <media/AudioResamplerPublic.h> 25e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman#include <system/audio.h> 26e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman#include <system/audio_effect.h> 27e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman#include <utils/StrongPointer.h> 28e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 29e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman// external forward declaration from external/sonic/sonic.h 30e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanstruct sonicStreamStruct; 31e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramantypedef struct sonicStreamStruct *sonicStream; 32e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 33e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramannamespace android { 34e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 35e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanclass EffectBufferHalInterface; 36e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanclass EffectHalInterface; 37e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanclass EffectsFactoryHalInterface; 38e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 39e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman// ---------------------------------------------------------------------------- 40e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 41e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanclass PassthruBufferProvider : public AudioBufferProvider { 42e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanpublic: 43e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman PassthruBufferProvider() : mTrackBufferProvider(NULL) { } 44e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 45e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman virtual ~PassthruBufferProvider() { } 46e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 47e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman // call this to release the buffer to the upstream provider. 48e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman // treat it as an audio discontinuity for future samples. 49e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman virtual void reset() { } 50e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 51e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman // set the upstream buffer provider. Consider calling "reset" before this function. 52e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman virtual void setBufferProvider(AudioBufferProvider *p) { 53e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman mTrackBufferProvider = p; 54e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman } 55e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 56e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanprotected: 57e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman AudioBufferProvider *mTrackBufferProvider; 58e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman}; 59e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 60e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman// Base AudioBufferProvider class used for DownMixerBufferProvider, RemixBufferProvider, 61e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman// and ReformatBufferProvider. 62e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman// It handles a private buffer for use in converting format or channel masks from the 63e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman// input data to a form acceptable by the mixer. 64e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman// TODO: Make a ResamplerBufferProvider when integers are entirely removed from the 65e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman// processing pipeline. 66e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanclass CopyBufferProvider : public PassthruBufferProvider { 67e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanpublic: 68e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman // Use a private buffer of bufferFrameCount frames (each frame is outputFrameSize bytes). 69e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman // If bufferFrameCount is 0, no private buffer is created and in-place modification of 70e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman // the upstream buffer provider's buffers is performed by copyFrames(). 71e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman CopyBufferProvider(size_t inputFrameSize, size_t outputFrameSize, 72e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman size_t bufferFrameCount); 73e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman virtual ~CopyBufferProvider(); 74e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 75e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman // Overrides AudioBufferProvider methods 76e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman virtual status_t getNextBuffer(Buffer *buffer); 77e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman virtual void releaseBuffer(Buffer *buffer); 78e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 79e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman // Overrides PassthruBufferProvider 80e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman virtual void reset(); 81e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 82e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman // this function should be supplied by the derived class. It converts 83e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman // #frames in the *src pointer to the *dst pointer. It is public because 84e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman // some providers will allow this to work on arbitrary buffers outside 85e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman // of the internal buffers. 86e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman virtual void copyFrames(void *dst, const void *src, size_t frames) = 0; 87e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 88e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanprotected: 89e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman const size_t mInputFrameSize; 90e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman const size_t mOutputFrameSize; 91e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanprivate: 92e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman AudioBufferProvider::Buffer mBuffer; 93e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman const size_t mLocalBufferFrameCount; 94e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman void *mLocalBufferData; 95e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman size_t mConsumed; 96e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman}; 97e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 98e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman// DownmixerBufferProvider derives from CopyBufferProvider to provide 99e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman// position dependent downmixing by an Audio Effect. 100e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanclass DownmixerBufferProvider : public CopyBufferProvider { 101e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanpublic: 102e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman DownmixerBufferProvider(audio_channel_mask_t inputChannelMask, 103e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman audio_channel_mask_t outputChannelMask, audio_format_t format, 104e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman uint32_t sampleRate, int32_t sessionId, size_t bufferFrameCount); 105e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman virtual ~DownmixerBufferProvider(); 106e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman //Overrides 107e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman virtual void copyFrames(void *dst, const void *src, size_t frames); 108e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 109e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman bool isValid() const { return mDownmixInterface.get() != NULL; } 110e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman static status_t init(); 111e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman static bool isMultichannelCapable() { return sIsMultichannelCapable; } 112e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 113e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanprotected: 114e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman sp<EffectsFactoryHalInterface> mEffectsFactory; 115e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman sp<EffectHalInterface> mDownmixInterface; 116e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman size_t mInFrameSize; 117e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman size_t mOutFrameSize; 118e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman sp<EffectBufferHalInterface> mInBuffer; 119e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman sp<EffectBufferHalInterface> mOutBuffer; 120e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman effect_config_t mDownmixConfig; 121e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 122e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman // effect descriptor for the downmixer used by the mixer 123e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman static effect_descriptor_t sDwnmFxDesc; 124e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman // indicates whether a downmix effect has been found and is usable by this mixer 125e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman static bool sIsMultichannelCapable; 126e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman // FIXME: should we allow effects outside of the framework? 127e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman // We need to here. A special ioId that must be <= -2 so it does not map to a session. 128e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman static const int32_t SESSION_ID_INVALID_AND_IGNORED = -2; 129e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman}; 130e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 131e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman// RemixBufferProvider derives from CopyBufferProvider to perform an 132e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman// upmix or downmix to the proper channel count and mask. 133e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanclass RemixBufferProvider : public CopyBufferProvider { 134e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanpublic: 135e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman RemixBufferProvider(audio_channel_mask_t inputChannelMask, 136e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman audio_channel_mask_t outputChannelMask, audio_format_t format, 137e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman size_t bufferFrameCount); 138e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman //Overrides 139e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman virtual void copyFrames(void *dst, const void *src, size_t frames); 140e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 141e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanprotected: 142e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman const audio_format_t mFormat; 143e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman const size_t mSampleSize; 144e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman const size_t mInputChannels; 145e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman const size_t mOutputChannels; 146e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman int8_t mIdxAry[sizeof(uint32_t) * 8]; // 32 bits => channel indices 147e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman}; 148e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 149e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman// ReformatBufferProvider derives from CopyBufferProvider to convert the input data 150e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman// to an acceptable mixer input format type. 151e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanclass ReformatBufferProvider : public CopyBufferProvider { 152e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanpublic: 153e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman ReformatBufferProvider(int32_t channelCount, 154e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman audio_format_t inputFormat, audio_format_t outputFormat, 155e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman size_t bufferFrameCount); 156e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman virtual void copyFrames(void *dst, const void *src, size_t frames); 157e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 158e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanprotected: 159e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman const uint32_t mChannelCount; 160e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman const audio_format_t mInputFormat; 161e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman const audio_format_t mOutputFormat; 162e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman}; 163e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 164e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman// TimestretchBufferProvider derives from PassthruBufferProvider for time stretching 165e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanclass TimestretchBufferProvider : public PassthruBufferProvider { 166e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanpublic: 167e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman TimestretchBufferProvider(int32_t channelCount, 168e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman audio_format_t format, uint32_t sampleRate, 169e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman const AudioPlaybackRate &playbackRate); 170e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman virtual ~TimestretchBufferProvider(); 171e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 172e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman // Overrides AudioBufferProvider methods 173e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman virtual status_t getNextBuffer(Buffer* buffer); 174e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman virtual void releaseBuffer(Buffer* buffer); 175e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 176e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman // Overrides PassthruBufferProvider 177e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman virtual void reset(); 178e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 179e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman virtual status_t setPlaybackRate(const AudioPlaybackRate &playbackRate); 180e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 181e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman // processes frames 182e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman // dstBuffer is where to place the data 183e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman // dstFrames [in/out] is the desired frames (return with actual placed in buffer) 184e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman // srcBuffer is the source data 185e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman // srcFrames [in/out] is the available source frames (return with consumed) 186e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman virtual void processFrames(void *dstBuffer, size_t *dstFrames, 187e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman const void *srcBuffer, size_t *srcFrames); 188e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 189e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanprotected: 190e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman const uint32_t mChannelCount; 191e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman const audio_format_t mFormat; 192e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman const uint32_t mSampleRate; // const for now (TODO change this) 193e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman const size_t mFrameSize; 194e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman AudioPlaybackRate mPlaybackRate; 195e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 196e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanprivate: 197e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman AudioBufferProvider::Buffer mBuffer; // for upstream request 198e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman size_t mLocalBufferFrameCount; // size of local buffer 199e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman void *mLocalBufferData; // internally allocated buffer for data returned 200e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman // to caller 201e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman size_t mRemaining; // remaining data in local buffer 202e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman sonicStream mSonicStream; // handle to sonic timestretch object 203e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman //FIXME: this dependency should be abstracted out 204e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman bool mFallbackFailErrorShown; // log fallback error only once 205e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman bool mAudioPlaybackRateValid; // flag for current parameters validity 206e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman}; 207e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 208e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman// ---------------------------------------------------------------------------- 209e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman} // namespace android 210e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 211e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman#endif // ANDROID_BUFFER_PROVIDERS_H 212