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