1022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov/* 2022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov * Copyright (C) 2017 The Android Open Source Project 3022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov * 4022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov * Licensed under the Apache License, Version 2.0 (the "License"); 5022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov * you may not use this file except in compliance with the License. 6022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov * You may obtain a copy of the License at 7022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov * 8022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov * http://www.apache.org/licenses/LICENSE-2.0 9022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov * 10022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov * Unless required by applicable law or agreed to in writing, software 11022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov * distributed under the License is distributed on an "AS IS" BASIS, 12022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov * See the License for the specific language governing permissions and 14022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov * limitations under the License. 15022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov */ 16022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov 17022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov#include <atomic> 18022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov 19022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov#define LOG_TAG "EffectBufferHalHidl" 20022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov//#define LOG_NDEBUG 0 21022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov 2213a926879249276771b0097538459c7550e2f5ceSteven Moreland#include <android/hidl/allocator/1.0/IAllocator.h> 23022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov#include <hidlmemory/mapping.h> 24022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov#include <utils/Log.h> 25022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov 26022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov#include "ConversionHelperHidl.h" 27022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov#include "EffectBufferHalHidl.h" 28022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov 29022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganovusing ::android::hardware::Return; 3013a926879249276771b0097538459c7550e2f5ceSteven Morelandusing ::android::hidl::allocator::V1_0::IAllocator; 31022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov 32022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganovnamespace android { 33022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov 34022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov// static 35022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganovuint64_t EffectBufferHalHidl::makeUniqueId() { 36022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov static std::atomic<uint64_t> counter{1}; 37022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov return counter++; 38022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov} 39022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov 40022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov// static 41022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganovstatus_t EffectBufferHalInterface::allocate( 42022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov size_t size, sp<EffectBufferHalInterface>* buffer) { 43022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov return mirror(nullptr, size, buffer); 44022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov} 45022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov 46022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov// static 47022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganovstatus_t EffectBufferHalInterface::mirror( 48022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov void* external, size_t size, sp<EffectBufferHalInterface>* buffer) { 49022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov sp<EffectBufferHalInterface> tempBuffer = new EffectBufferHalHidl(size); 506b111f32247800dccd34dd396e731b9e7888b185Mikhail Naganov status_t result = static_cast<EffectBufferHalHidl*>(tempBuffer.get())->init(); 51022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov if (result == OK) { 52022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov tempBuffer->setExternalData(external); 53022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov *buffer = tempBuffer; 54022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov } 55022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov return result; 56022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov} 57022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov 58022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail NaganovEffectBufferHalHidl::EffectBufferHalHidl(size_t size) 5940be8a343e8ceb7ae087bfb8988247731fa5ae75Mikhail Naganov : mBufferSize(size), mFrameCountChanged(false), 6040be8a343e8ceb7ae087bfb8988247731fa5ae75Mikhail Naganov mExternalData(nullptr), mAudioBuffer{0, {nullptr}} { 61022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov mHidlBuffer.id = makeUniqueId(); 62022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov mHidlBuffer.frameCount = 0; 63022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov} 64022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov 65022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail NaganovEffectBufferHalHidl::~EffectBufferHalHidl() { 66022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov} 67022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov 68022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganovstatus_t EffectBufferHalHidl::init() { 69022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov sp<IAllocator> ashmem = IAllocator::getService("ashmem"); 70022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov if (ashmem == 0) { 71022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov ALOGE("Failed to retrieve ashmem allocator service"); 72022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov return NO_INIT; 73022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov } 74022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov status_t retval = NO_MEMORY; 75022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov Return<void> result = ashmem->allocate( 76022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov mBufferSize, 77022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov [&](bool success, const hidl_memory& memory) { 78022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov if (success) { 79022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov mHidlBuffer.data = memory; 80022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov retval = OK; 81022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov } 82022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov }); 83e67e893d0642dd345e4d7d1cc3e76b1f0936dae8Mikhail Naganov if (result.isOk() && retval == OK) { 84022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov mMemory = hardware::mapMemory(mHidlBuffer.data); 85022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov if (mMemory != 0) { 86022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov mMemory->update(); 87022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov mAudioBuffer.raw = static_cast<void*>(mMemory->getPointer()); 88022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov memset(mAudioBuffer.raw, 0, mMemory->getSize()); 89022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov mMemory->commit(); 90022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov } else { 91022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov ALOGE("Failed to map allocated ashmem"); 92022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov retval = NO_MEMORY; 93022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov } 94e67e893d0642dd345e4d7d1cc3e76b1f0936dae8Mikhail Naganov } else { 95e67e893d0642dd345e4d7d1cc3e76b1f0936dae8Mikhail Naganov ALOGE("Failed to allocate %d bytes from ashmem", (int)mBufferSize); 96022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov } 97e67e893d0642dd345e4d7d1cc3e76b1f0936dae8Mikhail Naganov return result.isOk() ? retval : FAILED_TRANSACTION; 98022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov} 99022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov 100022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganovaudio_buffer_t* EffectBufferHalHidl::audioBuffer() { 101022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov return &mAudioBuffer; 102022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov} 103022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov 104022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganovvoid* EffectBufferHalHidl::externalData() const { 105022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov return mExternalData; 106022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov} 107022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov 108022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganovvoid EffectBufferHalHidl::setFrameCount(size_t frameCount) { 109022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov mHidlBuffer.frameCount = frameCount; 110022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov mAudioBuffer.frameCount = frameCount; 11140be8a343e8ceb7ae087bfb8988247731fa5ae75Mikhail Naganov mFrameCountChanged = true; 11240be8a343e8ceb7ae087bfb8988247731fa5ae75Mikhail Naganov} 11340be8a343e8ceb7ae087bfb8988247731fa5ae75Mikhail Naganov 11440be8a343e8ceb7ae087bfb8988247731fa5ae75Mikhail Naganovbool EffectBufferHalHidl::checkFrameCountChange() { 11540be8a343e8ceb7ae087bfb8988247731fa5ae75Mikhail Naganov bool result = mFrameCountChanged; 11640be8a343e8ceb7ae087bfb8988247731fa5ae75Mikhail Naganov mFrameCountChanged = false; 11740be8a343e8ceb7ae087bfb8988247731fa5ae75Mikhail Naganov return result; 118022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov} 119022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov 120022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganovvoid EffectBufferHalHidl::setExternalData(void* external) { 121022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov mExternalData = external; 122022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov} 123022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov 124022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganovvoid EffectBufferHalHidl::update() { 12566916c26a7055c9e10471720502a29f759609819Mikhail Naganov update(mBufferSize); 12666916c26a7055c9e10471720502a29f759609819Mikhail Naganov} 12766916c26a7055c9e10471720502a29f759609819Mikhail Naganov 12866916c26a7055c9e10471720502a29f759609819Mikhail Naganovvoid EffectBufferHalHidl::commit() { 12966916c26a7055c9e10471720502a29f759609819Mikhail Naganov commit(mBufferSize); 13066916c26a7055c9e10471720502a29f759609819Mikhail Naganov} 13166916c26a7055c9e10471720502a29f759609819Mikhail Naganov 13266916c26a7055c9e10471720502a29f759609819Mikhail Naganovvoid EffectBufferHalHidl::update(size_t size) { 133022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov if (mExternalData == nullptr) return; 134022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov mMemory->update(); 13566916c26a7055c9e10471720502a29f759609819Mikhail Naganov if (size > mBufferSize) size = mBufferSize; 13666916c26a7055c9e10471720502a29f759609819Mikhail Naganov memcpy(mAudioBuffer.raw, mExternalData, size); 137022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov mMemory->commit(); 138022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov} 139022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov 14066916c26a7055c9e10471720502a29f759609819Mikhail Naganovvoid EffectBufferHalHidl::commit(size_t size) { 141022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov if (mExternalData == nullptr) return; 14266916c26a7055c9e10471720502a29f759609819Mikhail Naganov if (size > mBufferSize) size = mBufferSize; 14366916c26a7055c9e10471720502a29f759609819Mikhail Naganov memcpy(mExternalData, mAudioBuffer.raw, size); 144022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov} 145022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov 146022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov} // namespace android 147