SharedRingBuffer.cpp revision 942bdc0aebc88dc8b12c0e7742ec0003bbb8b80f
1/* 2 * Copyright (C) 2016 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 LOG_TAG "AAudioService" 18//#define LOG_NDEBUG 0 19#include <utils/Log.h> 20 21#include <sys/mman.h> 22 23#include "binding/RingBufferParcelable.h" 24#include "binding/AudioEndpointParcelable.h" 25 26#include "SharedRingBuffer.h" 27 28using namespace android; 29using namespace aaudio; 30 31SharedRingBuffer::~SharedRingBuffer() 32{ 33 if (mSharedMemory != nullptr) { 34 delete mFifoBuffer; 35 munmap(mSharedMemory, mSharedMemorySizeInBytes); 36 mSharedMemory = nullptr; 37 } 38 if (mFileDescriptor != -1) { 39 ALOGV("SharedRingBuffer: LEAK? close(mFileDescriptor = %d)\n", mFileDescriptor); 40 close(mFileDescriptor); 41 mFileDescriptor = -1; 42 } 43} 44 45aaudio_result_t SharedRingBuffer::allocate(fifo_frames_t bytesPerFrame, 46 fifo_frames_t capacityInFrames) { 47 mCapacityInFrames = capacityInFrames; 48 49 // Create shared memory large enough to hold the data and the read and write counters. 50 mDataMemorySizeInBytes = bytesPerFrame * capacityInFrames; 51 mSharedMemorySizeInBytes = mDataMemorySizeInBytes + (2 * (sizeof(fifo_counter_t))); 52 mFileDescriptor = ashmem_create_region("AAudioSharedRingBuffer", mSharedMemorySizeInBytes); 53 ALOGV("SharedRingBuffer::allocate() LEAK? mFileDescriptor = %d\n", mFileDescriptor); 54 if (mFileDescriptor < 0) { 55 ALOGE("SharedRingBuffer::allocate() ashmem_create_region() failed %d", errno); 56 return AAUDIO_ERROR_INTERNAL; 57 } 58 59 int err = ashmem_set_prot_region(mFileDescriptor, PROT_READ|PROT_WRITE); // TODO error handling? 60 if (err < 0) { 61 ALOGE("SharedRingBuffer::allocate() ashmem_set_prot_region() failed %d", errno); 62 close(mFileDescriptor); 63 return AAUDIO_ERROR_INTERNAL; // TODO convert errno to a better AAUDIO_ERROR; 64 } 65 66 // Map the fd to memory addresses. 67 mSharedMemory = (uint8_t *) mmap(0, mSharedMemorySizeInBytes, 68 PROT_READ|PROT_WRITE, 69 MAP_SHARED, 70 mFileDescriptor, 0); 71 if (mSharedMemory == MAP_FAILED) { 72 ALOGE("SharedRingBuffer::allocate() mmap() failed %d", errno); 73 close(mFileDescriptor); 74 return AAUDIO_ERROR_INTERNAL; // TODO convert errno to a better AAUDIO_ERROR; 75 } 76 77 // Get addresses for our counters and data from the shared memory. 78 fifo_counter_t *readCounterAddress = 79 (fifo_counter_t *) &mSharedMemory[SHARED_RINGBUFFER_READ_OFFSET]; 80 fifo_counter_t *writeCounterAddress = 81 (fifo_counter_t *) &mSharedMemory[SHARED_RINGBUFFER_WRITE_OFFSET]; 82 uint8_t *dataAddress = &mSharedMemory[SHARED_RINGBUFFER_DATA_OFFSET]; 83 84 mFifoBuffer = new FifoBuffer(bytesPerFrame, capacityInFrames, 85 readCounterAddress, writeCounterAddress, dataAddress); 86 return AAUDIO_OK; 87} 88 89void SharedRingBuffer::fillParcelable(AudioEndpointParcelable &endpointParcelable, 90 RingBufferParcelable &ringBufferParcelable) { 91 int fdIndex = endpointParcelable.addFileDescriptor(mFileDescriptor, mSharedMemorySizeInBytes); 92 ringBufferParcelable.setupMemory(fdIndex, 93 SHARED_RINGBUFFER_DATA_OFFSET, 94 mDataMemorySizeInBytes, 95 SHARED_RINGBUFFER_READ_OFFSET, 96 SHARED_RINGBUFFER_WRITE_OFFSET, 97 sizeof(fifo_counter_t)); 98 ringBufferParcelable.setBytesPerFrame(mFifoBuffer->getBytesPerFrame()); 99 ringBufferParcelable.setFramesPerBurst(1); 100 ringBufferParcelable.setCapacityInFrames(mCapacityInFrames); 101} 102