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 17fbf031e8f197c916ae9c399f42926494ebdeb497Phil Burk#define LOG_TAG "SharedRingBuffer" 182355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk//#define LOG_NDEBUG 0 192355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk#include <utils/Log.h> 202355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk 21478d5df3a0e1693669f5809176d5c7f6e8c9aa88Phil Burk#include <sys/mman.h> 22478d5df3a0e1693669f5809176d5c7f6e8c9aa88Phil Burk 23c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include "binding/RingBufferParcelable.h" 24c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include "binding/AudioEndpointParcelable.h" 252355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk 262355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk#include "SharedRingBuffer.h" 272355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk 282355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burkusing namespace android; 295ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burkusing namespace aaudio; 302355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk 312355edbcacfcb6e852a8707d893aaca788d42fdcPhil BurkSharedRingBuffer::~SharedRingBuffer() 322355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk{ 332355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk if (mSharedMemory != nullptr) { 342355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk delete mFifoBuffer; 352355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk munmap(mSharedMemory, mSharedMemorySizeInBytes); 362355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk mSharedMemory = nullptr; 372355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk } 382355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk} 392355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk 405ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burkaaudio_result_t SharedRingBuffer::allocate(fifo_frames_t bytesPerFrame, 412355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk fifo_frames_t capacityInFrames) { 422355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk mCapacityInFrames = capacityInFrames; 432355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk 442355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk // Create shared memory large enough to hold the data and the read and write counters. 452355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk mDataMemorySizeInBytes = bytesPerFrame * capacityInFrames; 462355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk mSharedMemorySizeInBytes = mDataMemorySizeInBytes + (2 * (sizeof(fifo_counter_t))); 47e72481c5c16d401c776e0ba49b84b80223769b91Phil Burk mFileDescriptor.reset(ashmem_create_region("AAudioSharedRingBuffer", mSharedMemorySizeInBytes)); 48e72481c5c16d401c776e0ba49b84b80223769b91Phil Burk if (mFileDescriptor.get() == -1) { 49fbf031e8f197c916ae9c399f42926494ebdeb497Phil Burk ALOGE("allocate() ashmem_create_region() failed %d", errno); 505ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return AAUDIO_ERROR_INTERNAL; 512355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk } 52fbf031e8f197c916ae9c399f42926494ebdeb497Phil Burk ALOGV("allocate() mFileDescriptor = %d\n", mFileDescriptor.get()); 53942bdc0aebc88dc8b12c0e7742ec0003bbb8b80fPhil Burk 54e72481c5c16d401c776e0ba49b84b80223769b91Phil Burk int err = ashmem_set_prot_region(mFileDescriptor.get(), PROT_READ|PROT_WRITE); // TODO error handling? 552355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk if (err < 0) { 56fbf031e8f197c916ae9c399f42926494ebdeb497Phil Burk ALOGE("allocate() ashmem_set_prot_region() failed %d", errno); 57e72481c5c16d401c776e0ba49b84b80223769b91Phil Burk mFileDescriptor.reset(); 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, 65e72481c5c16d401c776e0ba49b84b80223769b91Phil Burk mFileDescriptor.get(), 0); 662355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk if (mSharedMemory == MAP_FAILED) { 67fbf031e8f197c916ae9c399f42926494ebdeb497Phil Burk ALOGE("allocate() mmap() failed %d", errno); 68e72481c5c16d401c776e0ba49b84b80223769b91Phil Burk mFileDescriptor.reset(); 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 79942bdc0aebc88dc8b12c0e7742ec0003bbb8b80fPhil Burk mFifoBuffer = new FifoBuffer(bytesPerFrame, capacityInFrames, 802355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk readCounterAddress, writeCounterAddress, dataAddress); 81942bdc0aebc88dc8b12c0e7742ec0003bbb8b80fPhil Burk return 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