| /* |
| * Copyright (c) 2013-2015, 2017-2019, The Linux Foundation. All rights reserved. |
| * Not a Contribution. |
| * |
| * Copyright (C) 2013 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #define LOG_TAG "offload_effect_virtualizer" |
| //#define LOG_NDEBUG 0 |
| |
| #include <cutils/list.h> |
| #include <log/log.h> |
| #include <tinyalsa/asoundlib.h> |
| #include <sound/audio_effects.h> |
| #include <audio_effects/effect_virtualizer.h> |
| #include <audio_feature_manager.h> |
| #include <dlfcn.h> |
| #include <unistd.h> |
| |
| #include "effect_api.h" |
| #include "virtualizer.h" |
| |
| #define VIRUALIZER_MAX_LATENCY 30 |
| |
| #define PRIMARY_HAL_PATH XSTR(LIB_AUDIO_HAL) |
| #define XSTR(x) STR(x) |
| #define STR(x) #x |
| |
| static bool (*is_feature_enabled)(audio_ext_feature); |
| |
| #ifdef AUDIO_FEATURE_ENABLED_GCOV |
| extern void __gcov_flush(); |
| static void enable_gcov() |
| { |
| __gcov_flush(); |
| } |
| #else |
| static void enable_gcov() |
| { |
| } |
| #endif |
| |
| /* Offload Virtualizer UUID: 509a4498-561a-4bea-b3b1-0002a5d5c51b */ |
| const effect_descriptor_t virtualizer_descriptor = { |
| {0x37cc2c00, 0xdddd, 0x11db, 0x8577, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, |
| {0x509a4498, 0x561a, 0x4bea, 0xb3b1, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // uuid |
| EFFECT_CONTROL_API_VERSION, |
| (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_DEVICE_IND | EFFECT_FLAG_HW_ACC_TUNNEL | |
| EFFECT_FLAG_VOLUME_CTRL), |
| 0, /* TODO */ |
| 1, |
| "MSM offload virtualizer", |
| "The Android Open Source Project", |
| }; |
| |
| /* |
| * Virtualizer operations |
| */ |
| |
| int virtualizer_get_strength(virtualizer_context_t *context) |
| { |
| ALOGV("%s: ctxt %p, strength: %d", __func__, context, context->strength); |
| return context->strength; |
| } |
| |
| int virtualizer_set_strength(virtualizer_context_t *context, uint32_t strength) |
| { |
| ALOGV("%s: ctxt %p, strength: %d", __func__, context, strength); |
| context->strength = strength; |
| |
| /* |
| * Zero strength is not equivalent to disable state as down mix |
| * is still happening for multichannel inputs. |
| * For better user experience, explicitly disable virtualizer module |
| * when strength is 0. |
| */ |
| if (context->enabled_by_client) |
| offload_virtualizer_set_enable_flag(&(context->offload_virt), |
| ((strength > 0) && !(context->temp_disabled)) ? |
| true : false); |
| offload_virtualizer_set_strength(&(context->offload_virt), strength); |
| if (context->ctl) |
| offload_virtualizer_send_params(context->ctl, &context->offload_virt, |
| OFFLOAD_SEND_VIRTUALIZER_ENABLE_FLAG | |
| OFFLOAD_SEND_VIRTUALIZER_STRENGTH); |
| if (context->hw_acc_fd > 0) |
| hw_acc_virtualizer_send_params(context->hw_acc_fd, |
| &context->offload_virt, |
| OFFLOAD_SEND_VIRTUALIZER_ENABLE_FLAG | |
| OFFLOAD_SEND_VIRTUALIZER_STRENGTH); |
| return 0; |
| } |
| |
| /* |
| * Check if an audio device is supported by this implementation |
| * |
| * [in] |
| * device device that is intented for processing (e.g. for binaural vs transaural) |
| * [out] |
| * false device is not applicable for effect |
| * true device is applicable for effect |
| */ |
| bool virtualizer_is_device_supported(audio_devices_t device) { |
| if (is_feature_enabled != NULL && |
| is_feature_enabled(AFE_PROXY)) { |
| if (device == AUDIO_DEVICE_OUT_PROXY) |
| return false; |
| } |
| |
| switch (device) { |
| case AUDIO_DEVICE_OUT_SPEAKER: |
| case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT: |
| case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER: |
| case AUDIO_DEVICE_OUT_AUX_DIGITAL: |
| case AUDIO_DEVICE_OUT_USB_ACCESSORY: |
| case AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET: |
| return false; |
| default : |
| return true; |
| } |
| } |
| |
| /* |
| * Check if a channel mask + audio device is supported by this implementation |
| * |
| * [in] |
| * channel_mask channel mask of input buffer |
| * device device that is intented for processing (e.g. for binaural vs transaural) |
| * [out] |
| * false if the configuration is not supported or it is unknown |
| * true if the configuration is supported |
| */ |
| bool virtualizer_is_configuration_supported(audio_channel_mask_t channel_mask, |
| audio_devices_t device) { |
| uint32_t channelCount = audio_channel_count_from_out_mask(channel_mask); |
| if ((channelCount == 0) || (channelCount > 2)) { |
| return false; |
| } |
| |
| return virtualizer_is_device_supported(device); |
| } |
| |
| /* |
| * Force the virtualization mode to that of the given audio device |
| * |
| * [in] |
| * context effect engine context |
| * forced_device device whose virtualization mode we'll always use |
| * [out] |
| * -EINVAL if the device is not supported or is unknown |
| * 0 if the device is supported and the virtualization mode forced |
| */ |
| int virtualizer_force_virtualization_mode(virtualizer_context_t *context, |
| audio_devices_t forced_device) { |
| virtualizer_context_t *virt_ctxt = (virtualizer_context_t *)context; |
| int status = 0; |
| bool use_virt = false; |
| int is_virt_enabled = virt_ctxt->enabled_by_client; |
| |
| ALOGV("%s: ctxt %p, forcedDev=0x%x enabled=%d tmpDisabled=%d", __func__, virt_ctxt, |
| forced_device, is_virt_enabled, virt_ctxt->temp_disabled); |
| |
| if (virtualizer_is_device_supported(forced_device) == false) { |
| if (forced_device != AUDIO_DEVICE_NONE) { |
| //forced device is not supported, make it behave as a reset of forced mode |
| forced_device = AUDIO_DEVICE_NONE; |
| // but return an error |
| status = -EINVAL; |
| } |
| } |
| |
| if (forced_device == AUDIO_DEVICE_NONE) { |
| // disabling forced virtualization mode: |
| // verify whether the virtualization should be enabled or disabled |
| if (virtualizer_is_device_supported(virt_ctxt->device)) { |
| use_virt = (is_virt_enabled == true); |
| } |
| virt_ctxt->forced_device = AUDIO_DEVICE_NONE; |
| } else { |
| // forcing virtualization mode: |
| // TODO: we assume device is supported, so hard coded a fixed one. |
| virt_ctxt->forced_device = AUDIO_DEVICE_OUT_WIRED_HEADPHONE; |
| // TODO: only enable for a supported mode, when the effect is enabled |
| use_virt = (is_virt_enabled == true); |
| } |
| |
| if (use_virt) { |
| if (virt_ctxt->temp_disabled == true) { |
| if (effect_is_active(&virt_ctxt->common)) { |
| offload_virtualizer_set_enable_flag(&(virt_ctxt->offload_virt), true); |
| if (virt_ctxt->ctl) |
| offload_virtualizer_send_params(virt_ctxt->ctl, |
| &virt_ctxt->offload_virt, |
| OFFLOAD_SEND_VIRTUALIZER_ENABLE_FLAG); |
| if (virt_ctxt->hw_acc_fd > 0) |
| hw_acc_virtualizer_send_params(virt_ctxt->hw_acc_fd, |
| &virt_ctxt->offload_virt, |
| OFFLOAD_SEND_VIRTUALIZER_ENABLE_FLAG); |
| } |
| ALOGV("%s: re-enable VIRTUALIZER", __func__); |
| virt_ctxt->temp_disabled = false; |
| } else { |
| ALOGV("%s: leaving VIRTUALIZER enabled", __func__); |
| } |
| } else { |
| if (virt_ctxt->temp_disabled == false) { |
| if (effect_is_active(&virt_ctxt->common)) { |
| offload_virtualizer_set_enable_flag(&(virt_ctxt->offload_virt), false); |
| if (virt_ctxt->ctl) |
| offload_virtualizer_send_params(virt_ctxt->ctl, |
| &virt_ctxt->offload_virt, |
| OFFLOAD_SEND_VIRTUALIZER_ENABLE_FLAG); |
| if (virt_ctxt->hw_acc_fd > 0) |
| hw_acc_virtualizer_send_params(virt_ctxt->hw_acc_fd, |
| &virt_ctxt->offload_virt, |
| OFFLOAD_SEND_VIRTUALIZER_ENABLE_FLAG); |
| } |
| ALOGV("%s: disable VIRTUALIZER", __func__); |
| virt_ctxt->temp_disabled = true; |
| } else { |
| ALOGV("%s: leaving VIRTUALIZER disabled", __func__); |
| } |
| } |
| |
| ALOGV("after %s: ctxt %p, enabled=%d tmpDisabled=%d", __func__, virt_ctxt, |
| is_virt_enabled, virt_ctxt->temp_disabled); |
| |
| return status; |
| } |
| |
| /* |
| * Get the virtual speaker angles for a channel mask + audio device configuration |
| * which is guaranteed to be supported by this implementation |
| * |
| * [in] |
| * channel_mask the channel mask of the input to virtualize |
| * device the type of device that affects the processing (e.g. for binaural vs transaural) |
| * [in/out] |
| * speaker_angles the array of integer where each speaker angle is written as a triplet in the |
| * following format: |
| * int32_t a bit mask with a single value selected for each speaker, following |
| * the convention of the audio_channel_mask_t type |
| * int32_t a value in degrees expressing the speaker azimuth, where 0 is in front |
| * of the user, 180 behind, -90 to the left, 90 to the right of the user |
| * int32_t a value in degrees expressing the speaker elevation, where 0 is the |
| * horizontal plane, +90 is directly above the user, -90 below |
| * |
| */ |
| void virtualizer_get_speaker_angles(audio_channel_mask_t channel_mask __unused, |
| audio_devices_t device __unused, int32_t *speaker_angles) { |
| // the channel count is guaranteed to be 1 or 2 |
| // the device is guaranteed to be of type headphone |
| // this virtualizer is always 2in with speakers at -90 and 90deg of azimuth, 0deg of elevation |
| *speaker_angles++ = (int32_t) AUDIO_CHANNEL_OUT_FRONT_LEFT; |
| *speaker_angles++ = -90; // azimuth |
| *speaker_angles++ = 0; // elevation |
| *speaker_angles++ = (int32_t) AUDIO_CHANNEL_OUT_FRONT_RIGHT; |
| *speaker_angles++ = 90; // azimuth |
| *speaker_angles = 0; // elevation |
| } |
| |
| /* |
| * Retrieve the current device whose processing mode is used by this effect |
| * |
| * [out] |
| * AUDIO_DEVICE_NONE if the effect is not virtualizing |
| * or the device type if the effect is virtualizing |
| */ |
| audio_devices_t virtualizer_get_virtualization_mode(virtualizer_context_t *context) { |
| virtualizer_context_t *virt_ctxt = (virtualizer_context_t *)context; |
| audio_devices_t device = AUDIO_DEVICE_NONE; |
| |
| if ((offload_virtualizer_get_enable_flag(&(virt_ctxt->offload_virt))) |
| && (virt_ctxt->temp_disabled == false)) { |
| if (virt_ctxt->forced_device != AUDIO_DEVICE_NONE) { |
| // virtualization mode is forced, return that device |
| device = virt_ctxt->forced_device; |
| } else { |
| // no forced mode, return the current device |
| device = virt_ctxt->device; |
| } |
| } |
| ALOGV("%s: returning 0x%x", __func__, device); |
| return device; |
| } |
| |
| int virtualizer_get_parameter(effect_context_t *context, effect_param_t *p, |
| uint32_t *size) |
| { |
| virtualizer_context_t *virt_ctxt = (virtualizer_context_t *)context; |
| int voffset = ((p->psize - 1) / sizeof(int32_t) + 1) * sizeof(int32_t); |
| int32_t *param_tmp = (int32_t *)p->data; |
| int32_t param = *param_tmp++; |
| void *value = p->data + voffset; |
| |
| ALOGV("%s: ctxt %p, param %d", __func__, virt_ctxt, param); |
| |
| p->status = 0; |
| |
| switch (param) { |
| case VIRTUALIZER_PARAM_STRENGTH_SUPPORTED: |
| if (p->vsize < sizeof(uint32_t)) |
| p->status = -EINVAL; |
| p->vsize = sizeof(uint32_t); |
| break; |
| case VIRTUALIZER_PARAM_STRENGTH: |
| if (p->vsize < sizeof(int16_t)) |
| p->status = -EINVAL; |
| p->vsize = sizeof(int16_t); |
| break; |
| case VIRTUALIZER_PARAM_VIRTUAL_SPEAKER_ANGLES: |
| // return value size can only be interpreted as relative to input value, |
| // deferring validity check to below |
| break; |
| case VIRTUALIZER_PARAM_VIRTUALIZATION_MODE: |
| if (p->vsize != sizeof(uint32_t)) |
| p->status = -EINVAL; |
| p->vsize = sizeof(uint32_t); |
| break; |
| case VIRTUALIZER_PARAM_LATENCY: |
| if (p->vsize < sizeof(uint32_t)) |
| p->status = -EINVAL; |
| p->vsize = sizeof(uint32_t); |
| break; |
| default: |
| p->status = -EINVAL; |
| } |
| |
| *size = sizeof(effect_param_t) + voffset + p->vsize; |
| |
| if (p->status != 0) |
| return 0; |
| |
| switch (param) { |
| case VIRTUALIZER_PARAM_STRENGTH_SUPPORTED: |
| *(uint32_t *)value = 1; |
| break; |
| |
| case VIRTUALIZER_PARAM_STRENGTH: |
| *(int16_t *)value = virtualizer_get_strength(virt_ctxt); |
| break; |
| |
| case VIRTUALIZER_PARAM_VIRTUAL_SPEAKER_ANGLES: |
| { |
| const audio_channel_mask_t channel_mask = (audio_channel_mask_t) *param_tmp++; |
| const audio_devices_t device = (audio_devices_t) *param_tmp; |
| uint32_t channel_cnt = audio_channel_count_from_out_mask(channel_mask); |
| |
| if (p->vsize < 3 * channel_cnt * sizeof(int32_t)){ |
| p->status = -EINVAL; |
| break; |
| } |
| // verify the configuration is supported |
| if(virtualizer_is_configuration_supported(channel_mask, device)) { |
| // configuration is supported, get the angles |
| virtualizer_get_speaker_angles(channel_mask, device, (int32_t *)value); |
| } else { |
| p->status = -EINVAL; |
| } |
| |
| break; |
| } |
| |
| case VIRTUALIZER_PARAM_VIRTUALIZATION_MODE: |
| *(uint32_t *)value = (uint32_t) virtualizer_get_virtualization_mode(virt_ctxt); |
| break; |
| |
| case VIRTUALIZER_PARAM_LATENCY: |
| *(uint32_t *)value = VIRUALIZER_MAX_LATENCY; |
| break; |
| |
| default: |
| p->status = -EINVAL; |
| break; |
| } |
| |
| return 0; |
| } |
| |
| int virtualizer_set_parameter(effect_context_t *context, effect_param_t *p, |
| uint32_t size __unused) |
| { |
| virtualizer_context_t *virt_ctxt = (virtualizer_context_t *)context; |
| int voffset = ((p->psize - 1) / sizeof(int32_t) + 1) * sizeof(int32_t); |
| void *value = p->data + voffset; |
| int32_t *param_tmp = (int32_t *)p->data; |
| int32_t param = *param_tmp++; |
| uint32_t strength; |
| |
| ALOGV("%s: ctxt %p, param %d", __func__, virt_ctxt, param); |
| |
| p->status = 0; |
| |
| switch (param) { |
| case VIRTUALIZER_PARAM_STRENGTH: |
| strength = (uint32_t)(*(int16_t *)value); |
| virtualizer_set_strength(virt_ctxt, strength); |
| break; |
| case VIRTUALIZER_PARAM_FORCE_VIRTUALIZATION_MODE: |
| { |
| const audio_devices_t device = *(audio_devices_t *)value; |
| if (0 != virtualizer_force_virtualization_mode(virt_ctxt, device)) { |
| p->status = -EINVAL; |
| } |
| break; |
| } |
| default: |
| p->status = -EINVAL; |
| break; |
| } |
| |
| return 0; |
| } |
| |
| int virtualizer_set_device(effect_context_t *context, uint32_t device) |
| { |
| virtualizer_context_t *virt_ctxt = (virtualizer_context_t *)context; |
| |
| ALOGV("%s: ctxt %p, device: 0x%x", __func__, virt_ctxt, device); |
| virt_ctxt->device = device; |
| |
| if (virt_ctxt->forced_device == AUDIO_DEVICE_NONE) { |
| // default case unless configuration is forced |
| if (virtualizer_is_device_supported(device) == false) { |
| if (!virt_ctxt->temp_disabled) { |
| if (effect_is_active(&virt_ctxt->common) && virt_ctxt->enabled_by_client) { |
| offload_virtualizer_set_enable_flag(&(virt_ctxt->offload_virt), false); |
| if (virt_ctxt->ctl) |
| offload_virtualizer_send_params(virt_ctxt->ctl, |
| &virt_ctxt->offload_virt, |
| OFFLOAD_SEND_VIRTUALIZER_ENABLE_FLAG); |
| if (virt_ctxt->hw_acc_fd > 0) |
| hw_acc_virtualizer_send_params(virt_ctxt->hw_acc_fd, |
| &virt_ctxt->offload_virt, |
| OFFLOAD_SEND_VIRTUALIZER_ENABLE_FLAG); |
| } |
| virt_ctxt->temp_disabled = true; |
| ALOGI("%s: ctxt %p, disabled based on device", __func__, virt_ctxt); |
| } |
| } else { |
| if (virt_ctxt->temp_disabled) { |
| if (effect_is_active(&virt_ctxt->common) && virt_ctxt->enabled_by_client) { |
| offload_virtualizer_set_enable_flag(&(virt_ctxt->offload_virt), true); |
| if (virt_ctxt->ctl) |
| offload_virtualizer_send_params(virt_ctxt->ctl, |
| &virt_ctxt->offload_virt, |
| OFFLOAD_SEND_VIRTUALIZER_ENABLE_FLAG); |
| if (virt_ctxt->hw_acc_fd > 0) |
| hw_acc_virtualizer_send_params(virt_ctxt->hw_acc_fd, |
| &virt_ctxt->offload_virt, |
| OFFLOAD_SEND_VIRTUALIZER_ENABLE_FLAG); |
| } |
| virt_ctxt->temp_disabled = false; |
| } |
| } |
| } |
| // else virtualization mode is forced to a certain device, nothing to do |
| |
| offload_virtualizer_set_device(&(virt_ctxt->offload_virt), device); |
| return 0; |
| } |
| |
| int virtualizer_reset(effect_context_t *context __unused) |
| { |
| return 0; |
| } |
| |
| int virtualizer_init(effect_context_t *context) |
| { |
| ALOGV("%s: ctxt %p", __func__, context); |
| virtualizer_context_t *virt_ctxt = (virtualizer_context_t *)context; |
| |
| if (access(PRIMARY_HAL_PATH, R_OK) == 0) { |
| void *hal_lib_pointer = dlopen(PRIMARY_HAL_PATH, RTLD_NOW); |
| if (hal_lib_pointer == NULL) |
| ALOGE("%s: DLOPEN failed for %s", __func__, PRIMARY_HAL_PATH); |
| else { |
| is_feature_enabled = |
| (bool (*)(audio_ext_feature))dlsym(hal_lib_pointer, |
| "audio_feature_manager_is_feature_enabled"); |
| if (is_feature_enabled == NULL) |
| ALOGE("%s: dlsym failed", __func__); |
| } |
| } else |
| ALOGE("%s: not able to acces lib %s ", __func__, PRIMARY_HAL_PATH); |
| |
| context->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ; |
| context->config.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO; |
| context->config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT; |
| context->config.inputCfg.samplingRate = 44100; |
| context->config.inputCfg.bufferProvider.getBuffer = NULL; |
| context->config.inputCfg.bufferProvider.releaseBuffer = NULL; |
| context->config.inputCfg.bufferProvider.cookie = NULL; |
| context->config.inputCfg.mask = EFFECT_CONFIG_ALL; |
| context->config.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE; |
| context->config.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO; |
| context->config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT; |
| context->config.outputCfg.samplingRate = 44100; |
| context->config.outputCfg.bufferProvider.getBuffer = NULL; |
| context->config.outputCfg.bufferProvider.releaseBuffer = NULL; |
| context->config.outputCfg.bufferProvider.cookie = NULL; |
| context->config.outputCfg.mask = EFFECT_CONFIG_ALL; |
| |
| set_config(context, &context->config); |
| |
| virt_ctxt->enabled_by_client = false; |
| virt_ctxt->temp_disabled = false; |
| virt_ctxt->hw_acc_fd = -1; |
| virt_ctxt->forced_device = AUDIO_DEVICE_NONE; |
| virt_ctxt->device = AUDIO_DEVICE_NONE; |
| memset(&(virt_ctxt->offload_virt), 0, sizeof(struct virtualizer_params)); |
| enable_gcov(); |
| return 0; |
| } |
| |
| int virtualizer_enable(effect_context_t *context) |
| { |
| virtualizer_context_t *virt_ctxt = (virtualizer_context_t *)context; |
| |
| ALOGV("%s: ctxt %p, strength %d", __func__, virt_ctxt, virt_ctxt->strength); |
| |
| virt_ctxt->enabled_by_client = true; |
| if (!offload_virtualizer_get_enable_flag(&(virt_ctxt->offload_virt)) && |
| !(virt_ctxt->temp_disabled)) { |
| offload_virtualizer_set_enable_flag(&(virt_ctxt->offload_virt), true); |
| if (virt_ctxt->ctl && virt_ctxt->strength) |
| offload_virtualizer_send_params(virt_ctxt->ctl, |
| &virt_ctxt->offload_virt, |
| OFFLOAD_SEND_VIRTUALIZER_ENABLE_FLAG | |
| OFFLOAD_SEND_VIRTUALIZER_STRENGTH); |
| if ((virt_ctxt->hw_acc_fd > 0) && virt_ctxt->strength) |
| hw_acc_virtualizer_send_params(virt_ctxt->hw_acc_fd, |
| &virt_ctxt->offload_virt, |
| OFFLOAD_SEND_VIRTUALIZER_ENABLE_FLAG | |
| OFFLOAD_SEND_VIRTUALIZER_STRENGTH); |
| } |
| enable_gcov(); |
| return 0; |
| } |
| |
| int virtualizer_disable(effect_context_t *context) |
| { |
| virtualizer_context_t *virt_ctxt = (virtualizer_context_t *)context; |
| |
| ALOGV("%s: ctxt %p", __func__, virt_ctxt); |
| |
| virt_ctxt->enabled_by_client = false; |
| if (offload_virtualizer_get_enable_flag(&(virt_ctxt->offload_virt))) { |
| offload_virtualizer_set_enable_flag(&(virt_ctxt->offload_virt), false); |
| if (virt_ctxt->ctl) |
| offload_virtualizer_send_params(virt_ctxt->ctl, |
| &virt_ctxt->offload_virt, |
| OFFLOAD_SEND_VIRTUALIZER_ENABLE_FLAG); |
| if (virt_ctxt->hw_acc_fd > 0) |
| hw_acc_virtualizer_send_params(virt_ctxt->hw_acc_fd, |
| &virt_ctxt->offload_virt, |
| OFFLOAD_SEND_VIRTUALIZER_ENABLE_FLAG); |
| } |
| enable_gcov(); |
| return 0; |
| } |
| |
| int virtualizer_start(effect_context_t *context, output_context_t *output) |
| { |
| virtualizer_context_t *virt_ctxt = (virtualizer_context_t *)context; |
| |
| ALOGV("%s: ctxt %p, ctl %p", __func__, virt_ctxt, output->ctl); |
| virt_ctxt->ctl = output->ctl; |
| if (offload_virtualizer_get_enable_flag(&(virt_ctxt->offload_virt))) { |
| if (virt_ctxt->ctl) |
| offload_virtualizer_send_params(virt_ctxt->ctl, &virt_ctxt->offload_virt, |
| OFFLOAD_SEND_VIRTUALIZER_ENABLE_FLAG | |
| OFFLOAD_SEND_VIRTUALIZER_STRENGTH); |
| if (virt_ctxt->hw_acc_fd > 0) |
| hw_acc_virtualizer_send_params(virt_ctxt->hw_acc_fd, |
| &virt_ctxt->offload_virt, |
| OFFLOAD_SEND_VIRTUALIZER_ENABLE_FLAG | |
| OFFLOAD_SEND_VIRTUALIZER_STRENGTH); |
| } |
| enable_gcov(); |
| return 0; |
| } |
| |
| int virtualizer_stop(effect_context_t *context, output_context_t *output __unused) |
| { |
| virtualizer_context_t *virt_ctxt = (virtualizer_context_t *)context; |
| |
| ALOGV("%s: ctxt %p", __func__, virt_ctxt); |
| if (offload_virtualizer_get_enable_flag(&(virt_ctxt->offload_virt)) && |
| virt_ctxt->ctl) { |
| struct virtualizer_params virt; |
| virt.enable_flag = false; |
| offload_virtualizer_send_params(virt_ctxt->ctl, &virt, |
| OFFLOAD_SEND_VIRTUALIZER_ENABLE_FLAG); |
| } |
| virt_ctxt->ctl = NULL; |
| enable_gcov(); |
| return 0; |
| } |
| |
| int virtualizer_set_mode(effect_context_t *context, int32_t hw_acc_fd) |
| { |
| virtualizer_context_t *virt_ctxt = (virtualizer_context_t *)context; |
| |
| ALOGV("%s: ctxt %p", __func__, virt_ctxt); |
| virt_ctxt->hw_acc_fd = hw_acc_fd; |
| if ((virt_ctxt->hw_acc_fd > 0) && |
| (offload_virtualizer_get_enable_flag(&(virt_ctxt->offload_virt)))) |
| hw_acc_virtualizer_send_params(virt_ctxt->hw_acc_fd, |
| &virt_ctxt->offload_virt, |
| OFFLOAD_SEND_VIRTUALIZER_ENABLE_FLAG | |
| OFFLOAD_SEND_VIRTUALIZER_STRENGTH); |
| return 0; |
| } |