SharedRingBuffer.cpp revision 5ed503c7a66c90f93759c90237a9b432dbd93f9f
12355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk/* 22355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk * Copyright (C) 2016 The Android Open Source Project 32355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk * 42355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk * Licensed under the Apache License, Version 2.0 (the "License"); 52355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk * you may not use this file except in compliance with the License. 62355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk * You may obtain a copy of the License at 72355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk * 82355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk * http://www.apache.org/licenses/LICENSE-2.0 92355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk * 102355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk * Unless required by applicable law or agreed to in writing, software 112355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk * distributed under the License is distributed on an "AS IS" BASIS, 122355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk * See the License for the specific language governing permissions and 142355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk * limitations under the License. 152355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk */ 162355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk 175ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk#define LOG_TAG "AAudioService" 182355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk//#define LOG_NDEBUG 0 192355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk#include <utils/Log.h> 202355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk 212355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk#include "AudioClock.h" 222355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk#include "AudioEndpointParcelable.h" 232355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk 245ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk//#include "AAudioServiceStreamBase.h" 255ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk//#include "AAudioServiceStreamFakeHal.h" 262355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk 272355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk#include "SharedRingBuffer.h" 282355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk 292355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burkusing namespace android; 305ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burkusing namespace aaudio; 312355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk 322355edbcacfcb6e852a8707d893aaca788d42fdcPhil BurkSharedRingBuffer::~SharedRingBuffer() 332355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk{ 342355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk if (mSharedMemory != nullptr) { 352355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk delete mFifoBuffer; 362355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk munmap(mSharedMemory, mSharedMemorySizeInBytes); 372355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk close(mFileDescriptor); 382355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk mSharedMemory = nullptr; 392355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk } 402355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk} 412355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk 425ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burkaaudio_result_t SharedRingBuffer::allocate(fifo_frames_t bytesPerFrame, 432355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk fifo_frames_t capacityInFrames) { 442355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk mCapacityInFrames = capacityInFrames; 452355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk 462355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk // Create shared memory large enough to hold the data and the read and write counters. 472355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk mDataMemorySizeInBytes = bytesPerFrame * capacityInFrames; 482355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk mSharedMemorySizeInBytes = mDataMemorySizeInBytes + (2 * (sizeof(fifo_counter_t))); 495ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk mFileDescriptor = ashmem_create_region("AAudioSharedRingBuffer", mSharedMemorySizeInBytes); 502355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk if (mFileDescriptor < 0) { 512355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk ALOGE("SharedRingBuffer::allocate() ashmem_create_region() failed %d", errno); 525ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return AAUDIO_ERROR_INTERNAL; 532355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk } 542355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk int err = ashmem_set_prot_region(mFileDescriptor, PROT_READ|PROT_WRITE); // TODO error handling? 552355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk if (err < 0) { 562355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk ALOGE("SharedRingBuffer::allocate() ashmem_set_prot_region() failed %d", errno); 572355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk close(mFileDescriptor); 585ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return AAUDIO_ERROR_INTERNAL; // TODO convert errno to a better AAUDIO_ERROR; 592355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk } 602355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk 612355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk // Map the fd to memory addresses. 622355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk mSharedMemory = (uint8_t *) mmap(0, mSharedMemorySizeInBytes, 632355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk PROT_READ|PROT_WRITE, 642355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk MAP_SHARED, 652355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk mFileDescriptor, 0); 662355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk if (mSharedMemory == MAP_FAILED) { 672355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk ALOGE("SharedRingBuffer::allocate() mmap() failed %d", errno); 682355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk close(mFileDescriptor); 695ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return AAUDIO_ERROR_INTERNAL; // TODO convert errno to a better AAUDIO_ERROR; 702355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk } 712355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk 722355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk // Get addresses for our counters and data from the shared memory. 732355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk fifo_counter_t *readCounterAddress = 742355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk (fifo_counter_t *) &mSharedMemory[SHARED_RINGBUFFER_READ_OFFSET]; 752355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk fifo_counter_t *writeCounterAddress = 762355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk (fifo_counter_t *) &mSharedMemory[SHARED_RINGBUFFER_WRITE_OFFSET]; 772355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk uint8_t *dataAddress = &mSharedMemory[SHARED_RINGBUFFER_DATA_OFFSET]; 782355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk 792355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk mFifoBuffer = new(std::nothrow) FifoBuffer(bytesPerFrame, capacityInFrames, 802355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk readCounterAddress, writeCounterAddress, dataAddress); 815ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return (mFifoBuffer == nullptr) ? AAUDIO_ERROR_NO_MEMORY : AAUDIO_OK; 822355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk} 832355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk 842355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burkvoid SharedRingBuffer::fillParcelable(AudioEndpointParcelable &endpointParcelable, 852355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk RingBufferParcelable &ringBufferParcelable) { 862355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk int fdIndex = endpointParcelable.addFileDescriptor(mFileDescriptor, mSharedMemorySizeInBytes); 872355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk ringBufferParcelable.setupMemory(fdIndex, 882355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk SHARED_RINGBUFFER_DATA_OFFSET, 892355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk mDataMemorySizeInBytes, 902355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk SHARED_RINGBUFFER_READ_OFFSET, 912355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk SHARED_RINGBUFFER_WRITE_OFFSET, 922355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk sizeof(fifo_counter_t)); 932355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk ringBufferParcelable.setBytesPerFrame(mFifoBuffer->getBytesPerFrame()); 942355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk ringBufferParcelable.setFramesPerBurst(1); 952355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk ringBufferParcelable.setCapacityInFrames(mCapacityInFrames); 962355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk} 97