Merge "hal: Add NULL check before freeing snd_card_name"
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index 39ad4d1..ce8f965 100644
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -874,9 +874,7 @@
 static perf_lock_acquire_t perf_lock_acq;
 static perf_lock_release_t perf_lock_rel;
 
-static int perf_lock_handle;
 char opt_lib_path[512] = {0};
-int perf_lock_opts[1] = {0x20E};
 
 int audio_extn_perf_lock_init(void)
 {
@@ -914,19 +912,30 @@
     return ret;
 }
 
-void audio_extn_perf_lock_acquire(void)
+void audio_extn_perf_lock_acquire(int *handle, int duration,
+                                 int *perf_lock_opts, int size)
 {
-    if (perf_lock_acq)
-        perf_lock_handle = perf_lock_acq(perf_lock_handle, 0, perf_lock_opts, 1);
-    else
-        ALOGE("%s: Perf lock acquire error \n", __func__);
+
+    if (!perf_lock_opts || !size || !perf_lock_acq || !handle)
+        return -EINVAL;
+    /*
+     * Acquire performance lock for 1 sec during device path bringup.
+     * Lock will be released either after 1 sec or when perf_lock_release
+     * function is executed.
+     */
+    *handle = perf_lock_acq(*handle, duration, perf_lock_opts, size);
+    if (*handle <= 0)
+        ALOGE("%s: Failed to acquire perf lock, err: %d\n",
+              __func__, *handle);
 }
 
-void audio_extn_perf_lock_release(void)
+void audio_extn_perf_lock_release(int *handle)
 {
-    if (perf_lock_rel && perf_lock_handle)
-        perf_lock_rel(perf_lock_handle);
-    else
+    if (perf_lock_rel && handle && (*handle > 0)) {
+        perf_lock_rel(*handle);
+        *handle = 0;
+    } else {
         ALOGE("%s: Perf lock release error \n", __func__);
+    }
 }
 #endif /* KPI_OPTIMIZE_ENABLED */
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index 3645cdb..b4848a4 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -503,12 +503,14 @@
 
 #ifndef KPI_OPTIMIZE_ENABLED
 #define audio_extn_perf_lock_init() (0)
-#define audio_extn_perf_lock_acquire() (0)
-#define audio_extn_perf_lock_release() (0)
+#define audio_extn_perf_lock_acquire(handle, duration, opts, size) (0)
+#define audio_extn_perf_lock_release(handle) (0)
 #else
 int audio_extn_perf_lock_init(void);
-void audio_extn_perf_lock_acquire(void);
-void audio_extn_perf_lock_release(void);
+void audio_extn_perf_lock_acquire(int *handle, int duration,
+                                 int *opts, int size);
+void audio_extn_perf_lock_release(int *handle);
+
 #endif /* KPI_OPTIMIZE_ENABLED */
 
 #ifndef AUDIO_EXTERNAL_HDMI_ENABLED
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index 38dbb46..a114b30 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -587,14 +587,13 @@
     } else if (usecase->type == PCM_PLAYBACK) {
         if ((24 == usecase->stream.out->bit_width) &&
             (usecase->stream.out->devices & AUDIO_DEVICE_OUT_SPEAKER)) {
-            sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
+            usecase->stream.out->app_type_cfg.sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
         } else if ((snd_device != SND_DEVICE_OUT_HEADPHONES_44_1 &&
             usecase->stream.out->sample_rate == OUTPUT_SAMPLING_RATE_44100) ||
             (usecase->stream.out->sample_rate < OUTPUT_SAMPLING_RATE_44100)) {
-            sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
-        } else {
-            sample_rate = usecase->stream.out->app_type_cfg.sample_rate;
+            usecase->stream.out->app_type_cfg.sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
         }
+        sample_rate = usecase->stream.out->app_type_cfg.sample_rate;
 
         app_type_cfg[len++] = usecase->stream.out->app_type_cfg.app_type;
         app_type_cfg[len++] = acdb_dev_id;
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index b98d71b..facb8d8 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -168,8 +168,9 @@
     [USECASE_AUDIO_PLAYBACK_ULL]         = "audio-ull-playback",
     [USECASE_AUDIO_PLAYBACK_MULTI_CH]    = "multi-channel-playback",
     [USECASE_AUDIO_PLAYBACK_OFFLOAD] = "compress-offload-playback",
-#ifdef MULTIPLE_OFFLOAD_ENABLED
+    //Enabled for Direct_PCM
     [USECASE_AUDIO_PLAYBACK_OFFLOAD2] = "compress-offload-playback2",
+#ifdef MULTIPLE_OFFLOAD_ENABLED
     [USECASE_AUDIO_PLAYBACK_OFFLOAD3] = "compress-offload-playback3",
     [USECASE_AUDIO_PLAYBACK_OFFLOAD4] = "compress-offload-playback4",
     [USECASE_AUDIO_PLAYBACK_OFFLOAD5] = "compress-offload-playback5",
@@ -178,7 +179,6 @@
     [USECASE_AUDIO_PLAYBACK_OFFLOAD8] = "compress-offload-playback8",
     [USECASE_AUDIO_PLAYBACK_OFFLOAD9] = "compress-offload-playback9",
 #endif
-    [USECASE_AUDIO_DIRECT_PCM_OFFLOAD] = "compress-offload-playback2",
 
     [USECASE_AUDIO_RECORD] = "audio-record",
     [USECASE_AUDIO_RECORD_COMPRESS] = "audio-record-compress",
@@ -214,8 +214,8 @@
 
 static const audio_usecase_t offload_usecases[] = {
     USECASE_AUDIO_PLAYBACK_OFFLOAD,
-#ifdef MULTIPLE_OFFLOAD_ENABLED
     USECASE_AUDIO_PLAYBACK_OFFLOAD2,
+#ifdef MULTIPLE_OFFLOAD_ENABLED
     USECASE_AUDIO_PLAYBACK_OFFLOAD3,
     USECASE_AUDIO_PLAYBACK_OFFLOAD4,
     USECASE_AUDIO_PLAYBACK_OFFLOAD5,
@@ -224,7 +224,6 @@
     USECASE_AUDIO_PLAYBACK_OFFLOAD8,
     USECASE_AUDIO_PLAYBACK_OFFLOAD9,
 #endif
-    USECASE_AUDIO_DIRECT_PCM_OFFLOAD,
 };
 
 #define STRING_TO_ENUM(string) { #string, string }
@@ -453,8 +452,8 @@
     audio_extn_dolby_ds2_set_endpoint(adev);
     audio_extn_sound_trigger_update_stream_status(usecase, ST_EVENT_STREAM_BUSY);
     audio_extn_listen_update_stream_status(usecase, LISTEN_EVENT_STREAM_BUSY);
-    audio_extn_utils_send_audio_calibration(adev, usecase);
     audio_extn_utils_send_app_type_cfg(adev, usecase);
+    audio_extn_utils_send_audio_calibration(adev, usecase);
     strcpy(mixer_path, use_case_table[usecase->id]);
     platform_add_backend_name(mixer_path, snd_device, usecase);
     ALOGD("%s: apply mixer and update path: %s", __func__, mixer_path);
@@ -1129,7 +1128,9 @@
     uc_info->out_snd_device = SND_DEVICE_NONE;
 
     list_add_tail(&adev->usecase_list, &uc_info->list);
-    audio_extn_perf_lock_acquire();
+    audio_extn_perf_lock_acquire(&adev->perf_lock_handle, 0,
+                                 adev->perf_lock_opts,
+                                 adev->perf_lock_opts_size);
     select_devices(adev, in->usecase);
 
     ALOGV("%s: Opening PCM device card_id(%d) device_id(%d), channels %d",
@@ -1171,16 +1172,14 @@
         goto error_open;
     }
 
-    audio_extn_perf_lock_release();
-
+    audio_extn_perf_lock_release(&adev->perf_lock_handle);
     ALOGD("%s: exit", __func__);
 
     return ret;
 
 error_open:
+    audio_extn_perf_lock_release(&adev->perf_lock_handle);
     stop_input_stream(in);
-    audio_extn_perf_lock_release();
-
 error_config:
     adev->active_input = NULL;
     /*
@@ -1249,35 +1248,50 @@
     return false;
 }
 
-static audio_usecase_t get_offload_usecase(struct audio_device *adev)
+static audio_usecase_t get_offload_usecase(struct audio_device *adev, bool is_direct_pcm)
 {
-    audio_usecase_t ret = USECASE_AUDIO_PLAYBACK_OFFLOAD;
-    unsigned int i, num_usecase = sizeof(offload_usecases)/sizeof(offload_usecases[0]);
-    char value[PROPERTY_VALUE_MAX] = {0};
+    audio_usecase_t ret_uc = USECASE_INVALID;
+    unsigned int offload_uc_index;
+    int num_usecase = sizeof(offload_usecases)/sizeof(offload_usecases[0]);
+    if (!adev->multi_offload_enable) {
+        if (is_direct_pcm)
+            ret_uc = USECASE_AUDIO_PLAYBACK_OFFLOAD2;
+        else
+            ret_uc = USECASE_AUDIO_PLAYBACK_OFFLOAD;
 
-    property_get("audio.offload.multiple.enabled", value, NULL);
-    if (!(atoi(value) || !strncmp("true", value, 4)))
-        num_usecase = 1; /* If prop is not set, limit the num of offload usecases to 1 */
+        pthread_mutex_lock(&adev->lock);
+        if (get_usecase_from_list(adev, ret_uc) != NULL)
+           ret_uc = USECASE_INVALID;
+        pthread_mutex_unlock(&adev->lock);
+
+        return ret_uc;
+    }
 
     ALOGV("%s: num_usecase: %d", __func__, num_usecase);
-    for (i = 0; i < num_usecase; i++) {
-        if (!(adev->offload_usecases_state & (0x1<<i))) {
-            adev->offload_usecases_state |= 0x1 << i;
-            ret = offload_usecases[i];
+    for (offload_uc_index = 0; offload_uc_index < num_usecase; offload_uc_index++) {
+        if (!(adev->offload_usecases_state & (0x1 << offload_uc_index))) {
+            adev->offload_usecases_state |= 0x1 << offload_uc_index;
+            ret_uc = offload_usecases[offload_uc_index];
             break;
         }
     }
-    ALOGV("%s: offload usecase is %d", __func__, ret);
-    return ret;
+
+    ALOGV("%s: offload usecase is %d", __func__, ret_uc);
+    return ret_uc;
 }
 
 static void free_offload_usecase(struct audio_device *adev,
                                  audio_usecase_t uc_id)
 {
-    unsigned int i;
-    for (i = 0; i < sizeof(offload_usecases)/sizeof(offload_usecases[0]); i++) {
-        if (offload_usecases[i] == uc_id) {
-            adev->offload_usecases_state &= ~(0x1<<i);
+    unsigned int offload_uc_index;
+    int num_usecase = sizeof(offload_usecases)/sizeof(offload_usecases[0]);
+
+    if (!adev->multi_offload_enable)
+        return;
+
+    for (offload_uc_index = 0; offload_uc_index < num_usecase; offload_uc_index++) {
+        if (offload_usecases[offload_uc_index] == uc_id) {
+            adev->offload_usecases_state &= ~(0x1 << offload_uc_index);
             break;
         }
     }
@@ -1634,6 +1648,9 @@
     }
     list_add_tail(&adev->usecase_list, &uc_info->list);
 
+    audio_extn_perf_lock_acquire(&adev->perf_lock_handle, 0,
+                                 adev->perf_lock_opts,
+                                 adev->perf_lock_opts_size);
     select_devices(adev, out->usecase);
 
     ALOGV("%s: Opening PCM device card_id(%d) device_id(%d) format(%#x)",
@@ -1724,11 +1741,12 @@
             audio_extn_check_and_set_dts_hpx_state(adev);
         }
     }
-
+    audio_extn_perf_lock_release(&adev->perf_lock_handle);
     ALOGD("%s: exit", __func__);
 
     return 0;
 error_open:
+    audio_extn_perf_lock_release(&adev->perf_lock_handle);
     stop_output_stream(out);
 error_config:
     /*
@@ -2207,7 +2225,7 @@
             out->standby = true;
             goto exit;
         }
-        if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD && adev->adm_register_output_stream)
+        if (!is_offload_usecase(out->usecase) && adev->adm_register_output_stream)
             adev->adm_register_output_stream(adev->adm_data, out->handle, out->flags);
     }
 
@@ -2974,18 +2992,24 @@
         }
 
         if (out->flags & AUDIO_OUTPUT_FLAG_DIRECT_PCM) {
-            ALOGV("%s:: inserting DIRECT_PCM _USECASE", __func__);
-            out->usecase = USECASE_AUDIO_DIRECT_PCM_OFFLOAD;
+            out->usecase = get_offload_usecase(adev, true);
+            ALOGV("DIRECT_PCM usecase ... usecase selected %d ", out->usecase);
         } else {
-            ALOGV("%s:: inserting OFFLOAD_USECASE", __func__);
-            out->usecase = get_offload_usecase(adev);
-
             out->stream.set_callback = out_set_callback;
             out->stream.pause = out_pause;
             out->stream.resume = out_resume;
             out->stream.drain = out_drain;
             out->stream.flush = out_flush;
+            out->usecase = get_offload_usecase(adev, false);
+            ALOGV("Compress Offload usecase .. usecase selected %d", out->usecase);
         }
+
+        if (out->usecase == USECASE_INVALID) {
+            ALOGE("%s: Max allowed OFFLOAD usecase reached ... ");
+            ret = -EEXIST;
+            goto error_open;
+        }
+
         if (config->offload_info.channel_mask)
             out->channel_mask = config->offload_info.channel_mask;
         else if (config->channel_mask) {
@@ -3645,7 +3669,6 @@
     /* This stream could be for sound trigger lab,
        get sound trigger pcm if present */
     audio_extn_sound_trigger_check_and_get_session(in);
-    audio_extn_perf_lock_init();
 
     *stream_in = &in->stream;
     ALOGV("%s: exit", __func__);
@@ -3806,6 +3829,9 @@
     adev->cur_wfd_channels = 2;
     adev->offload_usecases_state = 0;
     adev->is_channel_status_set = false;
+    adev->perf_lock_opts[0] = 0x101;
+    adev->perf_lock_opts[1] = 0x20E;
+    adev->perf_lock_opts_size = 2;
 
     pthread_mutex_init(&adev->snd_card_status.lock, (const pthread_mutexattr_t *) NULL);
     adev->snd_card_status.state = SND_CARD_STATE_OFFLINE;
@@ -3917,11 +3943,13 @@
         }
     }
 
+    adev->multi_offload_enable = property_get_bool("audio.offload.multiple.enabled", false);
     pthread_mutex_unlock(&adev_init_lock);
 
     if (adev->adm_init)
         adev->adm_data = adev->adm_init();
 
+    audio_extn_perf_lock_init();
     ALOGV("%s: exit", __func__);
     return 0;
 }
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index dc0970f..4ab9e6e 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -74,6 +74,8 @@
 #define SND_CARD_STATE_OFFLINE 0
 #define SND_CARD_STATE_ONLINE 1
 
+#define MAX_PERF_LOCK_OPTS 20
+
 /* These are the supported use cases by the hardware.
  * Each usecase is mapped to a specific PCM device.
  * Refer to pcm_device_table[].
@@ -85,8 +87,8 @@
     USECASE_AUDIO_PLAYBACK_LOW_LATENCY,
     USECASE_AUDIO_PLAYBACK_MULTI_CH,
     USECASE_AUDIO_PLAYBACK_OFFLOAD,
-#ifdef MULTIPLE_OFFLOAD_ENABLED
     USECASE_AUDIO_PLAYBACK_OFFLOAD2,
+#ifdef MULTIPLE_OFFLOAD_ENABLED
     USECASE_AUDIO_PLAYBACK_OFFLOAD3,
     USECASE_AUDIO_PLAYBACK_OFFLOAD4,
     USECASE_AUDIO_PLAYBACK_OFFLOAD5,
@@ -97,8 +99,6 @@
 #endif
     USECASE_AUDIO_PLAYBACK_ULL,
 
-    USECASE_AUDIO_DIRECT_PCM_OFFLOAD,
-
     /* FM usecase */
     USECASE_AUDIO_PLAYBACK_FM,
 
@@ -355,6 +355,11 @@
     void (*offload_effects_get_parameters)(struct str_parms *,
                                            struct str_parms *);
     void (*offload_effects_set_parameters)(struct str_parms *);
+
+    bool multi_offload_enable;
+    int perf_lock_handle;
+    int perf_lock_opts[MAX_PERF_LOCK_OPTS];
+    int perf_lock_opts_size;
 };
 
 int select_devices(struct audio_device *adev,
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index b5f56c1..df81a68 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -282,8 +282,6 @@
     [USECASE_AUDIO_PLAYBACK_OFFLOAD8] = {-1, -1},
     [USECASE_AUDIO_PLAYBACK_OFFLOAD9] = {-1, -1},
 #endif
-    [USECASE_AUDIO_DIRECT_PCM_OFFLOAD] =
-                     {PLAYBACK_OFFLOAD_DEVICE, PLAYBACK_OFFLOAD_DEVICE},
     [USECASE_AUDIO_RECORD] = {AUDIO_RECORD_PCM_DEVICE, AUDIO_RECORD_PCM_DEVICE},
     [USECASE_AUDIO_RECORD_COMPRESS] = {COMPRESS_CAPTURE_DEVICE, COMPRESS_CAPTURE_DEVICE},
     [USECASE_AUDIO_RECORD_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
@@ -669,7 +667,6 @@
     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD8)},
     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD9)},
 #endif
-    {TO_NAME_INDEX(USECASE_AUDIO_DIRECT_PCM_OFFLOAD)},
     {TO_NAME_INDEX(USECASE_AUDIO_RECORD)},
     {TO_NAME_INDEX(USECASE_AUDIO_RECORD_LOW_LATENCY)},
     {TO_NAME_INDEX(USECASE_VOICE_CALL)},
@@ -3557,7 +3554,6 @@
     case USECASE_AUDIO_PLAYBACK_DEEP_BUFFER:
     case USECASE_AUDIO_PLAYBACK_MULTI_CH:
     case USECASE_AUDIO_PLAYBACK_OFFLOAD:
-    case USECASE_AUDIO_DIRECT_PCM_OFFLOAD:
         needs_event = true;
         break;
     /* concurrent playback in low latency allowed */
@@ -3621,7 +3617,6 @@
     case USECASE_AUDIO_PLAYBACK_DEEP_BUFFER:
     case USECASE_AUDIO_PLAYBACK_MULTI_CH:
     case USECASE_AUDIO_PLAYBACK_OFFLOAD:
-    case USECASE_AUDIO_DIRECT_PCM_OFFLOAD:
         needs_event = true;
         break;
     /* concurrent playback in low latency allowed */
diff --git a/hal/msm8960/platform.c b/hal/msm8960/platform.c
index b72cae9..8d5004d 100644
--- a/hal/msm8960/platform.c
+++ b/hal/msm8960/platform.c
@@ -374,7 +374,7 @@
 }
 
 void platform_add_backend_name(char *mixer_path, snd_device_t snd_device,
-                               struct audio_usecase *usecase)
+                               struct audio_usecase *usecase __unused)
 {
     if (snd_device == SND_DEVICE_IN_BT_SCO_MIC)
         strlcat(mixer_path, " bt-sco", MIXER_PATH_MAX_LENGTH);
@@ -1172,3 +1172,8 @@
 {
     return 0;
 }
+
+void platform_set_gsm_mode(void *platform __unused, bool enable __unused)
+{
+    ALOGE("%s: Not implemented", __func__);
+}
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 0a18c55..e9a2418 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -118,6 +118,7 @@
 #define AUDIO_PARAMETER_KEY_AUD_CALDATA   "cal_data"
 #define AUDIO_PARAMETER_KEY_AUD_CALRESULT "cal_result"
 
+#define AUDIO_PARAMETER_KEY_PERF_LOCK_OPTS "perf_lock_opts"
 
 /* Query external audio device connection status */
 #define AUDIO_PARAMETER_KEY_EXT_AUDIO_DEVICE "ext_audio_device"
@@ -257,9 +258,9 @@
                                          MULTIMEDIA2_PCM_DEVICE},
     [USECASE_AUDIO_PLAYBACK_OFFLOAD] =
                      {PLAYBACK_OFFLOAD_DEVICE, PLAYBACK_OFFLOAD_DEVICE},
-#ifdef MULTIPLE_OFFLOAD_ENABLED
     [USECASE_AUDIO_PLAYBACK_OFFLOAD2] =
                      {PLAYBACK_OFFLOAD_DEVICE2, PLAYBACK_OFFLOAD_DEVICE2},
+#ifdef MULTIPLE_OFFLOAD_ENABLED
     [USECASE_AUDIO_PLAYBACK_OFFLOAD3] =
                      {PLAYBACK_OFFLOAD_DEVICE3, PLAYBACK_OFFLOAD_DEVICE3},
     [USECASE_AUDIO_PLAYBACK_OFFLOAD4] =
@@ -276,8 +277,6 @@
                      {PLAYBACK_OFFLOAD_DEVICE9, PLAYBACK_OFFLOAD_DEVICE9},
 #endif
 
-    [USECASE_AUDIO_DIRECT_PCM_OFFLOAD] =
-                     {PLAYBACK_OFFLOAD_DEVICE2, PLAYBACK_OFFLOAD_DEVICE2},
 
     [USECASE_AUDIO_RECORD] = {AUDIO_RECORD_PCM_DEVICE, AUDIO_RECORD_PCM_DEVICE},
     [USECASE_AUDIO_RECORD_COMPRESS] = {COMPRESS_CAPTURE_DEVICE, COMPRESS_CAPTURE_DEVICE},
@@ -633,8 +632,8 @@
     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_ULL)},
     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_MULTI_CH)},
     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD)},
-#ifdef MULTIPLE_OFFLOAD_ENABLED
     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD2)},
+#ifdef MULTIPLE_OFFLOAD_ENABLED
     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD3)},
     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD4)},
     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD5)},
@@ -643,7 +642,6 @@
     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD8)},
     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD9)},
 #endif
-    {TO_NAME_INDEX(USECASE_AUDIO_DIRECT_PCM_OFFLOAD)},
     {TO_NAME_INDEX(USECASE_AUDIO_RECORD)},
     {TO_NAME_INDEX(USECASE_AUDIO_RECORD_LOW_LATENCY)},
     {TO_NAME_INDEX(USECASE_VOICE_CALL)},
@@ -1160,7 +1158,7 @@
 
         ret = 0;
 
-        if((plat_data->is_vbat_speaker) && (WCD9XXX_VBAT_CAL == type)) {
+        if ((plat_data->is_vbat_speaker) && (WCD9XXX_VBAT_CAL == type)) {
            ret = send_vbat_adc_data_to_acdb(plat_data, cal_name_info[type]);
            if (ret < 0)
                ALOGE("%s error in sending vbat adc data to acdb", __func__);
@@ -1670,7 +1668,7 @@
         return;
     }
 
-    if((snd_device == SND_DEVICE_OUT_VOICE_SPEAKER_VBAT) &&
+    if ((snd_device == SND_DEVICE_OUT_VOICE_SPEAKER_VBAT) &&
         !(usecase->type == VOICE_CALL || usecase->type == VOIP_CALL)) {
         ALOGI("%s: Not adding vbat speaker device to non voice use cases", __func__);
         return;
@@ -3008,6 +3006,44 @@
         free(dptr);
 }
 
+static void perf_lock_set_params(struct platform_data *platform,
+                          struct str_parms *parms,
+                          char *value, int len)
+{
+    int err = 0, i = 0, num_opts = 0;
+    char *test_r = NULL;
+    char *opts = NULL;
+    char *opts_size = NULL;
+
+    err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_PERF_LOCK_OPTS,
+                            value, len);
+    if (err >= 0) {
+        opts_size = strtok_r(value, ", ", &test_r);
+        if (opts_size == NULL) {
+            ALOGE("%s: incorrect perf lock opts\n", __func__);
+            return;
+        }
+        num_opts = atoi(opts_size);
+        if (num_opts > 0) {
+            if (num_opts > MAX_PERF_LOCK_OPTS) {
+                ALOGD("%s: num_opts %d exceeds max %d, setting to max\n",
+                      __func__, num_opts, MAX_PERF_LOCK_OPTS);
+                num_opts = MAX_PERF_LOCK_OPTS;
+            }
+            for (i = 0; i < num_opts; i++) {
+                opts = strtok_r(NULL, ", ", &test_r);
+                if (opts == NULL) {
+                    ALOGE("%s: incorrect perf lock opts\n", __func__);
+                    break;
+                }
+                platform->adev->perf_lock_opts[i] = strtoul(opts, NULL, 16);
+            }
+            platform->adev->perf_lock_opts_size = i;
+        }
+        str_parms_del(parms, AUDIO_PARAMETER_KEY_PERF_LOCK_OPTS);
+    }
+}
+
 int platform_set_parameters(void *platform, struct str_parms *parms)
 {
     struct platform_data *my_data = (struct platform_data *)platform;
@@ -3101,6 +3137,7 @@
     set_audiocal(platform, parms, value, len);
     native_audio_set_params(platform, parms, value, len);
     audio_extn_spkr_prot_set_parameters(parms, value, len);
+    perf_lock_set_params(platform, parms, value, len);
 done:
     ALOGV("%s: exit with code(%d)", __func__, ret);
     if(kv_pairs != NULL)
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index 54406b6..22d66e8 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -248,9 +248,13 @@
 #endif
 #define PLAYBACK_OFFLOAD_DEVICE 9
 
+// Direct_PCM
+#if defined (PLATFORM_MSM8994) || defined (PLATFORM_MSM8996) || defined (PLATFORM_APQ8084)
+#define PLAYBACK_OFFLOAD_DEVICE2 17
+#endif
+
 #ifdef MULTIPLE_OFFLOAD_ENABLED
 #ifdef PLATFORM_APQ8084
-#define PLAYBACK_OFFLOAD_DEVICE2 17
 #define PLAYBACK_OFFLOAD_DEVICE3 18
 #define PLAYBACK_OFFLOAD_DEVICE4 34
 #define PLAYBACK_OFFLOAD_DEVICE5 35
@@ -260,7 +264,6 @@
 #define PLAYBACK_OFFLOAD_DEVICE9 39
 #endif
 #if defined (PLATFORM_MSM8994) || defined (PLATFORM_MSM8996)
-#define PLAYBACK_OFFLOAD_DEVICE2 17
 #define PLAYBACK_OFFLOAD_DEVICE3 18
 #define PLAYBACK_OFFLOAD_DEVICE4 37
 #define PLAYBACK_OFFLOAD_DEVICE5 38
@@ -271,9 +274,6 @@
 #endif
 #endif
 
-// for DIRECT_PCM
-#define PLAYBACK_OFFLOAD_DEVICE2 17
-
 #define COMPRESS_VOIP_CALL_PCM_DEVICE 3
 
 #ifdef PLATFORM_MSM8610
diff --git a/policy_hal/AudioPolicyManager.cpp b/policy_hal/AudioPolicyManager.cpp
index 9fd6838..900e6cc 100644
--- a/policy_hal/AudioPolicyManager.cpp
+++ b/policy_hal/AudioPolicyManager.cpp
@@ -460,6 +460,14 @@
             ALOGV("isOffloadSupported: has_video == true, returning false");
             return false;
         }
+
+        const bool allowOffloadStreamingWithVideo = property_get_bool("av.streaming.offload.enable",
+                                                                   false /*default value*/);
+        if(offloadInfo.has_video && offloadInfo.is_streaming && !allowOffloadStreamingWithVideo) {
+            ALOGW("offload disabled by av.streaming.offload.enable = %s ", propValue );
+            return false;
+        }
+
     }
 
     //If duration is less than minimum value defined in property, return false
diff --git a/post_proc/volume_listener.c b/post_proc/volume_listener.c
index d4f418a..d540bf5 100644
--- a/post_proc/volume_listener.c
+++ b/post_proc/volume_listener.c
@@ -432,7 +432,7 @@
 
         // After changing the state and if device is speaker
         // recalculate gain dep cal level
-        if (context->dev_id & AUDIO_DEVICE_OUT_SPEAKER) {
+        if (context->dev_id == AUDIO_DEVICE_OUT_SPEAKER) {
                 check_and_set_gain_dep_cal();
         }
 
@@ -459,7 +459,7 @@
 
         // After changing the state and if device is speaker
         // recalculate gain dep cal level
-        if (context->dev_id & AUDIO_DEVICE_OUT_SPEAKER) {
+        if (context->dev_id == AUDIO_DEVICE_OUT_SPEAKER) {
             check_and_set_gain_dep_cal();
         }
 
@@ -490,8 +490,8 @@
                    __func__, context->dev_id, new_device);
 
             // check if old or new device is speaker
-            if ((context->dev_id & AUDIO_DEVICE_OUT_SPEAKER) ||
-                (new_device & AUDIO_DEVICE_OUT_SPEAKER)) {
+            if ((context->dev_id ==  AUDIO_DEVICE_OUT_SPEAKER) ||
+                (new_device == AUDIO_DEVICE_OUT_SPEAKER)) {
                 recompute_gain_dep_cal_Level = true;
             }
 
@@ -516,7 +516,7 @@
                 goto exit;
             }
 
-            if (context->dev_id & AUDIO_DEVICE_OUT_SPEAKER) {
+            if (context->dev_id == AUDIO_DEVICE_OUT_SPEAKER) {
                 recompute_gain_dep_cal_Level = true;
             }
 
@@ -696,7 +696,7 @@
             && (context->stream_type == recv_contex->stream_type)) {
             ALOGV("--- Found something to remove ---");
             PRINT_STREAM_TYPE(context->stream_type);
-            if (context->dev_id && AUDIO_DEVICE_OUT_SPEAKER) {
+            if (context->dev_id == AUDIO_DEVICE_OUT_SPEAKER) {
                 recompute_flag = true;
             }
             list_remove(&context->effect_list_node);