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