145ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie/*
245ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie * Copyright (C) 2015 The Android Open Source Project
345ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie *
445ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie * Licensed under the Apache License, Version 2.0 (the "License");
545ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie * you may not use this file except in compliance with the License.
645ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie * You may obtain a copy of the License at
745ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie *
845ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie *      http://www.apache.org/licenses/LICENSE-2.0
945ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie *
1045ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie * Unless required by applicable law or agreed to in writing, software
1145ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie * distributed under the License is distributed on an "AS IS" BASIS,
1245ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1345ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie * See the License for the specific language governing permissions and
1445ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie * limitations under the License.
1545ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie */
1645ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie
1745ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie#define LOG_TAG "APM::EffectDescriptor"
1845ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie//#define LOG_NDEBUG 0
1945ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie
2045ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie#include "EffectDescriptor.h"
2145ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie#include <utils/String8.h>
2245ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie
2345ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffienamespace android {
2445ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie
2545ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffiestatus_t EffectDescriptor::dump(int fd)
2645ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie{
2745ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    const size_t SIZE = 256;
2845ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    char buffer[SIZE];
2945ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    String8 result;
3045ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie
3145ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    snprintf(buffer, SIZE, " I/O: %d\n", mIo);
3245ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    result.append(buffer);
3345ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    snprintf(buffer, SIZE, " Strategy: %d\n", mStrategy);
3445ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    result.append(buffer);
3545ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    snprintf(buffer, SIZE, " Session: %d\n", mSession);
3645ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    result.append(buffer);
3745ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    snprintf(buffer, SIZE, " Name: %s\n",  mDesc.name);
3845ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    result.append(buffer);
3945ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    snprintf(buffer, SIZE, " %s\n",  mEnabled ? "Enabled" : "Disabled");
4045ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    result.append(buffer);
4145ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    write(fd, result.string(), result.size());
4245ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie
4345ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    return NO_ERROR;
4445ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie}
4545ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie
4645ed3b053d9af2250f5ece9ee4e826905c3763a7François GaffieEffectDescriptorCollection::EffectDescriptorCollection() :
4745ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    mTotalEffectsCpuLoad(0),
4845ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    mTotalEffectsMemory(0)
4945ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie{
5045ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie
5145ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie}
5245ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie
5345ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffiestatus_t EffectDescriptorCollection::registerEffect(const effect_descriptor_t *desc,
5445ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie                                                    audio_io_handle_t io,
5545ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie                                                    uint32_t strategy,
5645ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie                                                    int session,
5745ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie                                                    int id)
5845ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie{
5945ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    if (mTotalEffectsMemory + desc->memoryUsage > getMaxEffectsMemory()) {
6045ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie        ALOGW("registerEffect() memory limit exceeded for Fx %s, Memory %d KB",
6145ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie                desc->name, desc->memoryUsage);
6245ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie        return INVALID_OPERATION;
6345ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    }
6445ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    mTotalEffectsMemory += desc->memoryUsage;
6545ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    ALOGV("registerEffect() effect %s, io %d, strategy %d session %d id %d",
6645ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie            desc->name, io, strategy, session, id);
6745ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    ALOGV("registerEffect() memory %d, total memory %d", desc->memoryUsage, mTotalEffectsMemory);
6845ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie
6945ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    sp<EffectDescriptor> effectDesc = new EffectDescriptor();
7045ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    memcpy (&effectDesc->mDesc, desc, sizeof(effect_descriptor_t));
7145ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    effectDesc->mIo = io;
7245ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    effectDesc->mStrategy = static_cast<routing_strategy>(strategy);
7345ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    effectDesc->mSession = session;
7445ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    effectDesc->mEnabled = false;
7545ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie
7645ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    add(id, effectDesc);
7745ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie
7845ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    return NO_ERROR;
7945ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie}
8045ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie
8145ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffiestatus_t EffectDescriptorCollection::unregisterEffect(int id)
8245ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie{
8345ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    ssize_t index = indexOfKey(id);
8445ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    if (index < 0) {
8545ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie        ALOGW("unregisterEffect() unknown effect ID %d", id);
8645ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie        return INVALID_OPERATION;
8745ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    }
8845ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie
8945ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    sp<EffectDescriptor> effectDesc = valueAt(index);
9045ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie
9145ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    setEffectEnabled(effectDesc, false);
9245ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie
9345ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    if (mTotalEffectsMemory < effectDesc->mDesc.memoryUsage) {
9445ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie        ALOGW("unregisterEffect() memory %d too big for total %d",
9545ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie                effectDesc->mDesc.memoryUsage, mTotalEffectsMemory);
9645ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie        effectDesc->mDesc.memoryUsage = mTotalEffectsMemory;
9745ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    }
9845ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    mTotalEffectsMemory -= effectDesc->mDesc.memoryUsage;
9945ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    ALOGV("unregisterEffect() effect %s, ID %d, memory %d total memory %d",
10045ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie            effectDesc->mDesc.name, id, effectDesc->mDesc.memoryUsage, mTotalEffectsMemory);
10145ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie
10245ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    removeItem(id);
10345ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie
10445ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    return NO_ERROR;
10545ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie}
10645ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie
10745ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffiestatus_t EffectDescriptorCollection::setEffectEnabled(int id, bool enabled)
10845ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie{
10945ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    ssize_t index = indexOfKey(id);
11045ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    if (index < 0) {
11145ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie        ALOGW("unregisterEffect() unknown effect ID %d", id);
11245ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie        return INVALID_OPERATION;
11345ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    }
11445ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie
11545ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    return setEffectEnabled(valueAt(index), enabled);
11645ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie}
11745ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie
11845ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie
11945ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffiestatus_t EffectDescriptorCollection::setEffectEnabled(const sp<EffectDescriptor> &effectDesc,
12045ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie                                                      bool enabled)
12145ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie{
12245ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    if (enabled == effectDesc->mEnabled) {
12345ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie        ALOGV("setEffectEnabled(%s) effect already %s",
12445ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie             enabled?"true":"false", enabled?"enabled":"disabled");
12545ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie        return INVALID_OPERATION;
12645ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    }
12745ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie
12845ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    if (enabled) {
12945ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie        if (mTotalEffectsCpuLoad + effectDesc->mDesc.cpuLoad > getMaxEffectsCpuLoad()) {
13045ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie            ALOGW("setEffectEnabled(true) CPU Load limit exceeded for Fx %s, CPU %f MIPS",
13145ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie                 effectDesc->mDesc.name, (float)effectDesc->mDesc.cpuLoad/10);
13245ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie            return INVALID_OPERATION;
13345ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie        }
13445ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie        mTotalEffectsCpuLoad += effectDesc->mDesc.cpuLoad;
13545ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie        ALOGV("setEffectEnabled(true) total CPU %d", mTotalEffectsCpuLoad);
13645ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    } else {
13745ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie        if (mTotalEffectsCpuLoad < effectDesc->mDesc.cpuLoad) {
13845ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie            ALOGW("setEffectEnabled(false) CPU load %d too high for total %d",
13945ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie                    effectDesc->mDesc.cpuLoad, mTotalEffectsCpuLoad);
14045ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie            effectDesc->mDesc.cpuLoad = mTotalEffectsCpuLoad;
14145ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie        }
14245ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie        mTotalEffectsCpuLoad -= effectDesc->mDesc.cpuLoad;
14345ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie        ALOGV("setEffectEnabled(false) total CPU %d", mTotalEffectsCpuLoad);
14445ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    }
14545ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    effectDesc->mEnabled = enabled;
14645ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    return NO_ERROR;
14745ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie}
14845ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie
14945ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffiebool EffectDescriptorCollection::isNonOffloadableEffectEnabled()
15045ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie{
15145ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    for (size_t i = 0; i < size(); i++) {
15245ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie        sp<EffectDescriptor> effectDesc = valueAt(i);
15345ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie        if (effectDesc->mEnabled && (effectDesc->mStrategy == STRATEGY_MEDIA) &&
15445ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie                ((effectDesc->mDesc.flags & EFFECT_FLAG_OFFLOAD_SUPPORTED) == 0)) {
15545ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie            ALOGV("isNonOffloadableEffectEnabled() non offloadable effect %s enabled on session %d",
15645ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie                  effectDesc->mDesc.name, effectDesc->mSession);
15745ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie            return true;
15845ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie        }
15945ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    }
16045ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    return false;
16145ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie}
16245ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie
16345ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffieuint32_t EffectDescriptorCollection::getMaxEffectsCpuLoad() const
16445ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie{
16545ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    return MAX_EFFECTS_CPU_LOAD;
16645ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie}
16745ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie
16845ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffieuint32_t EffectDescriptorCollection::getMaxEffectsMemory() const
16945ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie{
17045ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    return MAX_EFFECTS_MEMORY;
17145ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie}
17245ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie
17345ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffiestatus_t EffectDescriptorCollection::dump(int fd)
17445ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie{
17545ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    const size_t SIZE = 256;
17645ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    char buffer[SIZE];
17745ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie
17845ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    snprintf(buffer, SIZE, "\nTotal Effects CPU: %f MIPS, Total Effects memory: %d KB\n",
17945ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie             (float)mTotalEffectsCpuLoad/10, mTotalEffectsMemory);
18045ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    write(fd, buffer, strlen(buffer));
18145ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie
18245ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    snprintf(buffer, SIZE, "Registered effects:\n");
18345ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    write(fd, buffer, strlen(buffer));
18445ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    for (size_t i = 0; i < size(); i++) {
18545ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie        snprintf(buffer, SIZE, "- Effect %d dump:\n", keyAt(i));
18645ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie        write(fd, buffer, strlen(buffer));
18745ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie        valueAt(i)->dump(fd);
18845ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    }
18945ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    return NO_ERROR;
19045ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie}
19145ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie
19245ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie}; //namespace android
193