/*
 * 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 <cutils/properties.h>
#include <log/log.h>
#include <tinyalsa/asoundlib.h>
#include <sound/audio_effects.h>
#include <audio_effects/effect_virtualizer.h>

#include "effect_api.h"
#include "virtualizer.h"

#define VIRUALIZER_MAX_LATENCY 30

#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 ((property_get_bool("vendor.audio.feature.afe_proxy.enable", false)) &&
        (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;

    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;
}
