14bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard/* 24bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard * Copyright (C) 2017 The Android Open Source Project 34bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard * 44bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard * Licensed under the Apache License, Version 2.0 (the "License"); 54bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard * you may not use this file except in compliance with the License. 64bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard * You may obtain a copy of the License at 74bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard * 84bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard * http://www.apache.org/licenses/LICENSE-2.0 94bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard * 104bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard * Unless required by applicable law or agreed to in writing, software 114bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard * distributed under the License is distributed on an "AS IS" BASIS, 124bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard * See the License for the specific language governing permissions and 144bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard * limitations under the License. 154bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard */ 164bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard 174bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard#include <atomic> 184bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard 194bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard#define LOG_TAG "EffectBufferHalHidl" 204bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard//#define LOG_NDEBUG 0 214bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard 224bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard#include <android/hidl/allocator/1.0/IAllocator.h> 234bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard#include <hidlmemory/mapping.h> 244bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard#include <utils/Log.h> 254bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard 264bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard#include "ConversionHelperHidl.h" 274bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard#include "EffectBufferHalHidl.h" 284bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard 294bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocardusing ::android::hardware::Return; 304bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocardusing ::android::hidl::allocator::V1_0::IAllocator; 314bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard 324bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocardnamespace android { 3351e076a8fc69d4275cabc3e6d54eab44d590280dKevin Rocardnamespace V4_0 { 344bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard 354bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard// static 364bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocarduint64_t EffectBufferHalHidl::makeUniqueId() { 374bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard static std::atomic<uint64_t> counter{1}; 384bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard return counter++; 394bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard} 404bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard 414bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocardstatus_t EffectBufferHalHidl::allocate( 424bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard size_t size, sp<EffectBufferHalInterface>* buffer) { 434bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard return mirror(nullptr, size, buffer); 444bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard} 454bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard 464bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocardstatus_t EffectBufferHalHidl::mirror( 474bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard void* external, size_t size, sp<EffectBufferHalInterface>* buffer) { 484bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard sp<EffectBufferHalInterface> tempBuffer = new EffectBufferHalHidl(size); 494bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard status_t result = static_cast<EffectBufferHalHidl*>(tempBuffer.get())->init(); 504bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard if (result == OK) { 514bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard tempBuffer->setExternalData(external); 524bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard *buffer = tempBuffer; 534bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard } 544bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard return result; 554bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard} 564bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard 574bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin RocardEffectBufferHalHidl::EffectBufferHalHidl(size_t size) 584bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard : mBufferSize(size), mFrameCountChanged(false), 594bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard mExternalData(nullptr), mAudioBuffer{0, {nullptr}} { 604bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard mHidlBuffer.id = makeUniqueId(); 614bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard mHidlBuffer.frameCount = 0; 624bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard} 634bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard 644bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin RocardEffectBufferHalHidl::~EffectBufferHalHidl() { 654bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard} 664bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard 674bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocardstatus_t EffectBufferHalHidl::init() { 684bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard sp<IAllocator> ashmem = IAllocator::getService("ashmem"); 694bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard if (ashmem == 0) { 704bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard ALOGE("Failed to retrieve ashmem allocator service"); 714bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard return NO_INIT; 724bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard } 734bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard status_t retval = NO_MEMORY; 744bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard Return<void> result = ashmem->allocate( 754bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard mBufferSize, 764bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard [&](bool success, const hidl_memory& memory) { 774bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard if (success) { 784bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard mHidlBuffer.data = memory; 794bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard retval = OK; 804bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard } 814bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard }); 824bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard if (result.isOk() && retval == OK) { 834bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard mMemory = hardware::mapMemory(mHidlBuffer.data); 844bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard if (mMemory != 0) { 854bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard mMemory->update(); 864bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard mAudioBuffer.raw = static_cast<void*>(mMemory->getPointer()); 874bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard memset(mAudioBuffer.raw, 0, mMemory->getSize()); 884bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard mMemory->commit(); 894bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard } else { 904bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard ALOGE("Failed to map allocated ashmem"); 914bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard retval = NO_MEMORY; 924bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard } 934bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard } else { 944bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard ALOGE("Failed to allocate %d bytes from ashmem", (int)mBufferSize); 954bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard } 964bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard return result.isOk() ? retval : FAILED_TRANSACTION; 974bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard} 984bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard 994bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocardaudio_buffer_t* EffectBufferHalHidl::audioBuffer() { 1004bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard return &mAudioBuffer; 1014bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard} 1024bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard 1034bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocardvoid* EffectBufferHalHidl::externalData() const { 1044bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard return mExternalData; 1054bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard} 1064bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard 1074bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocardvoid EffectBufferHalHidl::setFrameCount(size_t frameCount) { 1084bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard mHidlBuffer.frameCount = frameCount; 1094bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard mAudioBuffer.frameCount = frameCount; 1104bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard mFrameCountChanged = true; 1114bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard} 1124bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard 1134bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocardbool EffectBufferHalHidl::checkFrameCountChange() { 1144bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard bool result = mFrameCountChanged; 1154bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard mFrameCountChanged = false; 1164bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard return result; 1174bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard} 1184bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard 1194bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocardvoid EffectBufferHalHidl::setExternalData(void* external) { 1204bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard mExternalData = external; 1214bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard} 1224bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard 1234bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocardvoid EffectBufferHalHidl::update() { 1244bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard update(mBufferSize); 1254bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard} 1264bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard 1274bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocardvoid EffectBufferHalHidl::commit() { 1284bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard commit(mBufferSize); 1294bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard} 1304bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard 1314bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocardvoid EffectBufferHalHidl::update(size_t size) { 1324bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard if (mExternalData == nullptr) return; 1334bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard mMemory->update(); 1344bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard if (size > mBufferSize) size = mBufferSize; 1354bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard memcpy(mAudioBuffer.raw, mExternalData, size); 1364bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard mMemory->commit(); 1374bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard} 1384bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard 1394bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocardvoid EffectBufferHalHidl::commit(size_t size) { 1404bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard if (mExternalData == nullptr) return; 1414bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard if (size > mBufferSize) size = mBufferSize; 1424bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard memcpy(mExternalData, mAudioBuffer.raw, size); 1434bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard} 1444bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard 14551e076a8fc69d4275cabc3e6d54eab44d590280dKevin Rocard} // namespace V4_0 1464bcd67fbb4eca3654ea929742bdf6ccc7c70daecKevin Rocard} // namespace android 147