1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker * Copyright (C) 2017 The Android Open Source Project
3*ec779b8eSAndroid Build Coastguard Worker *
4*ec779b8eSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*ec779b8eSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*ec779b8eSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*ec779b8eSAndroid Build Coastguard Worker *
8*ec779b8eSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*ec779b8eSAndroid Build Coastguard Worker *
10*ec779b8eSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*ec779b8eSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*ec779b8eSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*ec779b8eSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*ec779b8eSAndroid Build Coastguard Worker * limitations under the License.
15*ec779b8eSAndroid Build Coastguard Worker */
16*ec779b8eSAndroid Build Coastguard Worker
17*ec779b8eSAndroid Build Coastguard Worker #include <atomic>
18*ec779b8eSAndroid Build Coastguard Worker
19*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "EffectBufferHalHidl"
20*ec779b8eSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
21*ec779b8eSAndroid Build Coastguard Worker
22*ec779b8eSAndroid Build Coastguard Worker #include <android/hidl/allocator/1.0/IAllocator.h>
23*ec779b8eSAndroid Build Coastguard Worker #include <hidlmemory/mapping.h>
24*ec779b8eSAndroid Build Coastguard Worker #include <utils/Log.h>
25*ec779b8eSAndroid Build Coastguard Worker
26*ec779b8eSAndroid Build Coastguard Worker #include "EffectBufferHalHidl.h"
27*ec779b8eSAndroid Build Coastguard Worker
28*ec779b8eSAndroid Build Coastguard Worker using ::android::hardware::Return;
29*ec779b8eSAndroid Build Coastguard Worker using ::android::hidl::allocator::V1_0::IAllocator;
30*ec779b8eSAndroid Build Coastguard Worker
31*ec779b8eSAndroid Build Coastguard Worker namespace android {
32*ec779b8eSAndroid Build Coastguard Worker namespace effect {
33*ec779b8eSAndroid Build Coastguard Worker
34*ec779b8eSAndroid Build Coastguard Worker // static
makeUniqueId()35*ec779b8eSAndroid Build Coastguard Worker uint64_t EffectBufferHalHidl::makeUniqueId() {
36*ec779b8eSAndroid Build Coastguard Worker static std::atomic<uint64_t> counter{1};
37*ec779b8eSAndroid Build Coastguard Worker return counter++;
38*ec779b8eSAndroid Build Coastguard Worker }
39*ec779b8eSAndroid Build Coastguard Worker
allocate(size_t size,sp<EffectBufferHalInterface> * buffer)40*ec779b8eSAndroid Build Coastguard Worker status_t EffectBufferHalHidl::allocate(
41*ec779b8eSAndroid Build Coastguard Worker size_t size, sp<EffectBufferHalInterface>* buffer) {
42*ec779b8eSAndroid Build Coastguard Worker return mirror(nullptr, size, buffer);
43*ec779b8eSAndroid Build Coastguard Worker }
44*ec779b8eSAndroid Build Coastguard Worker
mirror(void * external,size_t size,sp<EffectBufferHalInterface> * buffer)45*ec779b8eSAndroid Build Coastguard Worker status_t EffectBufferHalHidl::mirror(
46*ec779b8eSAndroid Build Coastguard Worker void* external, size_t size, sp<EffectBufferHalInterface>* buffer) {
47*ec779b8eSAndroid Build Coastguard Worker sp<EffectBufferHalInterface> tempBuffer = new EffectBufferHalHidl(size);
48*ec779b8eSAndroid Build Coastguard Worker status_t result = static_cast<EffectBufferHalHidl*>(tempBuffer.get())->init();
49*ec779b8eSAndroid Build Coastguard Worker if (result == OK) {
50*ec779b8eSAndroid Build Coastguard Worker tempBuffer->setExternalData(external);
51*ec779b8eSAndroid Build Coastguard Worker *buffer = tempBuffer;
52*ec779b8eSAndroid Build Coastguard Worker }
53*ec779b8eSAndroid Build Coastguard Worker return result;
54*ec779b8eSAndroid Build Coastguard Worker }
55*ec779b8eSAndroid Build Coastguard Worker
EffectBufferHalHidl(size_t size)56*ec779b8eSAndroid Build Coastguard Worker EffectBufferHalHidl::EffectBufferHalHidl(size_t size)
57*ec779b8eSAndroid Build Coastguard Worker : mBufferSize(size), mFrameCountChanged(false),
58*ec779b8eSAndroid Build Coastguard Worker mExternalData(nullptr), mAudioBuffer{0, {nullptr}} {
59*ec779b8eSAndroid Build Coastguard Worker mHidlBuffer.id = makeUniqueId();
60*ec779b8eSAndroid Build Coastguard Worker mHidlBuffer.frameCount = 0;
61*ec779b8eSAndroid Build Coastguard Worker }
62*ec779b8eSAndroid Build Coastguard Worker
~EffectBufferHalHidl()63*ec779b8eSAndroid Build Coastguard Worker EffectBufferHalHidl::~EffectBufferHalHidl() {
64*ec779b8eSAndroid Build Coastguard Worker }
65*ec779b8eSAndroid Build Coastguard Worker
init()66*ec779b8eSAndroid Build Coastguard Worker status_t EffectBufferHalHidl::init() {
67*ec779b8eSAndroid Build Coastguard Worker sp<IAllocator> ashmem = IAllocator::getService("ashmem");
68*ec779b8eSAndroid Build Coastguard Worker if (ashmem == 0) {
69*ec779b8eSAndroid Build Coastguard Worker ALOGE("Failed to retrieve ashmem allocator service");
70*ec779b8eSAndroid Build Coastguard Worker return NO_INIT;
71*ec779b8eSAndroid Build Coastguard Worker }
72*ec779b8eSAndroid Build Coastguard Worker status_t retval = NO_MEMORY;
73*ec779b8eSAndroid Build Coastguard Worker Return<void> result = ashmem->allocate(
74*ec779b8eSAndroid Build Coastguard Worker mBufferSize,
75*ec779b8eSAndroid Build Coastguard Worker [&](bool success, const hidl_memory& memory) {
76*ec779b8eSAndroid Build Coastguard Worker if (success) {
77*ec779b8eSAndroid Build Coastguard Worker mHidlBuffer.data = memory;
78*ec779b8eSAndroid Build Coastguard Worker retval = OK;
79*ec779b8eSAndroid Build Coastguard Worker }
80*ec779b8eSAndroid Build Coastguard Worker });
81*ec779b8eSAndroid Build Coastguard Worker if (result.isOk() && retval == OK) {
82*ec779b8eSAndroid Build Coastguard Worker mMemory = hardware::mapMemory(mHidlBuffer.data);
83*ec779b8eSAndroid Build Coastguard Worker if (mMemory != 0) {
84*ec779b8eSAndroid Build Coastguard Worker mMemory->update();
85*ec779b8eSAndroid Build Coastguard Worker mAudioBuffer.raw = static_cast<void*>(mMemory->getPointer());
86*ec779b8eSAndroid Build Coastguard Worker memset(mAudioBuffer.raw, 0, mMemory->getSize());
87*ec779b8eSAndroid Build Coastguard Worker mMemory->commit();
88*ec779b8eSAndroid Build Coastguard Worker } else {
89*ec779b8eSAndroid Build Coastguard Worker ALOGE("Failed to map allocated ashmem");
90*ec779b8eSAndroid Build Coastguard Worker retval = NO_MEMORY;
91*ec779b8eSAndroid Build Coastguard Worker }
92*ec779b8eSAndroid Build Coastguard Worker } else {
93*ec779b8eSAndroid Build Coastguard Worker ALOGE("Failed to allocate %d bytes from ashmem", (int)mBufferSize);
94*ec779b8eSAndroid Build Coastguard Worker }
95*ec779b8eSAndroid Build Coastguard Worker return result.isOk() ? retval : FAILED_TRANSACTION;
96*ec779b8eSAndroid Build Coastguard Worker }
97*ec779b8eSAndroid Build Coastguard Worker
audioBuffer()98*ec779b8eSAndroid Build Coastguard Worker audio_buffer_t* EffectBufferHalHidl::audioBuffer() {
99*ec779b8eSAndroid Build Coastguard Worker return &mAudioBuffer;
100*ec779b8eSAndroid Build Coastguard Worker }
101*ec779b8eSAndroid Build Coastguard Worker
externalData() const102*ec779b8eSAndroid Build Coastguard Worker void* EffectBufferHalHidl::externalData() const {
103*ec779b8eSAndroid Build Coastguard Worker return mExternalData;
104*ec779b8eSAndroid Build Coastguard Worker }
105*ec779b8eSAndroid Build Coastguard Worker
setFrameCount(size_t frameCount)106*ec779b8eSAndroid Build Coastguard Worker void EffectBufferHalHidl::setFrameCount(size_t frameCount) {
107*ec779b8eSAndroid Build Coastguard Worker mHidlBuffer.frameCount = frameCount;
108*ec779b8eSAndroid Build Coastguard Worker mAudioBuffer.frameCount = frameCount;
109*ec779b8eSAndroid Build Coastguard Worker mFrameCountChanged = true;
110*ec779b8eSAndroid Build Coastguard Worker }
111*ec779b8eSAndroid Build Coastguard Worker
checkFrameCountChange()112*ec779b8eSAndroid Build Coastguard Worker bool EffectBufferHalHidl::checkFrameCountChange() {
113*ec779b8eSAndroid Build Coastguard Worker bool result = mFrameCountChanged;
114*ec779b8eSAndroid Build Coastguard Worker mFrameCountChanged = false;
115*ec779b8eSAndroid Build Coastguard Worker return result;
116*ec779b8eSAndroid Build Coastguard Worker }
117*ec779b8eSAndroid Build Coastguard Worker
setExternalData(void * external)118*ec779b8eSAndroid Build Coastguard Worker void EffectBufferHalHidl::setExternalData(void* external) {
119*ec779b8eSAndroid Build Coastguard Worker mExternalData = external;
120*ec779b8eSAndroid Build Coastguard Worker }
121*ec779b8eSAndroid Build Coastguard Worker
update()122*ec779b8eSAndroid Build Coastguard Worker void EffectBufferHalHidl::update() {
123*ec779b8eSAndroid Build Coastguard Worker update(mBufferSize);
124*ec779b8eSAndroid Build Coastguard Worker }
125*ec779b8eSAndroid Build Coastguard Worker
commit()126*ec779b8eSAndroid Build Coastguard Worker void EffectBufferHalHidl::commit() {
127*ec779b8eSAndroid Build Coastguard Worker commit(mBufferSize);
128*ec779b8eSAndroid Build Coastguard Worker }
129*ec779b8eSAndroid Build Coastguard Worker
update(size_t size)130*ec779b8eSAndroid Build Coastguard Worker void EffectBufferHalHidl::update(size_t size) {
131*ec779b8eSAndroid Build Coastguard Worker if (mExternalData == nullptr) return;
132*ec779b8eSAndroid Build Coastguard Worker mMemory->update();
133*ec779b8eSAndroid Build Coastguard Worker if (size > mBufferSize) size = mBufferSize;
134*ec779b8eSAndroid Build Coastguard Worker memcpy(mAudioBuffer.raw, mExternalData, size);
135*ec779b8eSAndroid Build Coastguard Worker mMemory->commit();
136*ec779b8eSAndroid Build Coastguard Worker }
137*ec779b8eSAndroid Build Coastguard Worker
commit(size_t size)138*ec779b8eSAndroid Build Coastguard Worker void EffectBufferHalHidl::commit(size_t size) {
139*ec779b8eSAndroid Build Coastguard Worker if (mExternalData == nullptr) return;
140*ec779b8eSAndroid Build Coastguard Worker if (size > mBufferSize) size = mBufferSize;
141*ec779b8eSAndroid Build Coastguard Worker memcpy(mExternalData, mAudioBuffer.raw, size);
142*ec779b8eSAndroid Build Coastguard Worker }
143*ec779b8eSAndroid Build Coastguard Worker
144*ec779b8eSAndroid Build Coastguard Worker } // namespace effect
145*ec779b8eSAndroid Build Coastguard Worker } // namespace android
146