audio: hal: Add support for registering adsp events
Add support for AHAL clients to register for adsp events
and receive event callbacks when an event is triggered by adsp.
CRs-Fixed: 2023812
Change-Id: Ie22efee6e859c3d819ed3939e164cb7baebab71b
diff --git a/hal/audio_extn/qaf.c b/hal/audio_extn/qaf.c
index 5b88274..58b6e08 100644
--- a/hal/audio_extn/qaf.c
+++ b/hal/audio_extn/qaf.c
@@ -42,6 +42,20 @@
#define QAF_DEFAULT_COMPR_AUDIO_HANDLE 1001
#define QAF_DEFAULT_COMPR_PASSTHROUGH_HANDLE 1002
#define QAF_DEFAULT_PASSTHROUGH_HANDLE 1003
+
+#define MAX_QAF_OUT 4
+
+#define QAF_OUT_TRANSCODE_PASSTHROUGH 0 /* transcode passthrough via MS12 */
+#define QAF_DEFAULT_PASSTHROUGH 1 /* passthrough without MS12 */
+#define QAF_OUT_OFFLOAD_MCH 2
+#define QAF_OUT_OFFLOAD 3
+
+#define MAX_QAF_IN 3
+
+#define QAF_IN_MAIN 0
+#define QAF_IN_ASSOC 1
+#define QAF_IN_PCM 2
+
/*
* MS12 Latency (Input Buffer Processing latency)+
* Kernel Latency (Calculated based on the available offload buffer size) +
@@ -134,6 +148,13 @@
FILE *fp_output_writer_hdmi = NULL;
#endif
+struct qaf_adsp_hdlr_config_state {
+ struct audio_adsp_event event_params;
+ /* For holding client audio_adsp_event payload */
+ uint8_t event_payload[AUDIO_MAX_ADSP_STREAM_CMD_PAYLOAD_LEN];
+ bool adsp_hdlr_config_valid;
+};
+
struct qaf {
struct audio_device *adev;
audio_session_handle_t session_handle;
@@ -155,12 +176,12 @@
void (*qaf_register_event_callback)(audio_session_handle_t session_handle, void *priv_data,
notify_event_callback_t event_callback, audio_event_id_t event_id);
pthread_mutex_t lock;
- struct stream_out *stream_drain_main;
- struct stream_out *stream_drain_assoc;
- struct stream_out *qaf_compr_offload_out;
- struct stream_out *qaf_compr_offload_out_mch;
- struct stream_out *qaf_compr_passthrough_out;
- struct stream_out *qaf_passthrough_out;
+
+ struct stream_out *stream[MAX_QAF_IN];
+ struct stream_out *qaf_out[MAX_QAF_OUT];
+
+ struct qaf_adsp_hdlr_config_state adsp_hdlr_config[MAX_QAF_IN];
+
void *bt_hdl;
bool hdmi_connect;
int passthrough_enabled;
@@ -175,6 +196,16 @@
static struct qaf *qaf_mod = NULL;
static int qaf_stream_set_param(struct stream_out *out, const char *kv_pair) __attribute__ ((unused));
+/* find index of input stream */
+static int get_input_stream_index(struct stream_out *out)
+{ int count = -1;
+ for (count = 0; count < MAX_QAF_IN; count++) {
+ if (out == qaf_mod->stream[count])
+ break;
+ }
+ return count;
+}
+
static bool is_ms12_format(audio_format_t format)
{
if((format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_AC3)
@@ -225,7 +256,7 @@
{
struct stream_out *out = (struct stream_out *)cookie;
- out->offload_callback(event, NULL, out->offload_cookie);
+ out->client_callback(event, NULL, out->client_cookie);
return 0;
}
@@ -235,18 +266,18 @@
ALOGV("%s %d", __func__, __LINE__);
if ((handle_id == QAF_DEFAULT_PASSTHROUGH_HANDLE) &&
- (NULL == qaf_mod->qaf_passthrough_out)) {
+ (NULL == qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH])) {
pthread_mutex_lock(&qaf_mod->lock);
lock_output_stream(out);
ret = adev_open_output_stream((struct audio_hw_device *) qaf_mod->adev, handle_id, devices,
- flags, config, (struct audio_stream_out **) &(qaf_mod->qaf_passthrough_out), NULL);
+ flags, config, (struct audio_stream_out **) &(qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH]), NULL);
if (ret < 0) {
pthread_mutex_unlock(&out->lock);
pthread_mutex_unlock(&qaf_mod->lock);
ALOGE("%s: adev_open_output_stream failed with ret = %d!", __func__, ret);
return -EINVAL;
}
- qaf_mod->qaf_passthrough_out->stream.set_callback((struct audio_stream_out *)qaf_mod->qaf_passthrough_out, (stream_callback_t) qaf_out_callback, out);
+ qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH]->stream.set_callback((struct audio_stream_out *)qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH], (stream_callback_t) qaf_out_callback, out);
pthread_mutex_unlock(&out->lock);
pthread_mutex_unlock(&qaf_mod->lock);
}
@@ -288,12 +319,12 @@
stream, out->usecase, use_case_table[out->usecase]);
lock_output_stream(out);
- if (qaf_mod->qaf_passthrough_out && qaf_mod->hdmi_connect) {
+ if (qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH] && qaf_mod->hdmi_connect) {
if ((out->format == AUDIO_FORMAT_PCM_16_BIT) && (popcount(out->channel_mask) <= 2)) {
pthread_mutex_unlock(&out->lock);
return status;
}
- status = qaf_mod->qaf_passthrough_out->stream.common.standby((struct audio_stream *) qaf_mod->qaf_passthrough_out);
+ status = qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH]->stream.common.standby((struct audio_stream *) qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH]);
if (!out->standby) {
out->standby = true;
}
@@ -333,15 +364,15 @@
static int qaf_out_set_volume(struct audio_stream_out *stream __unused, float left,
float right)
{
- /* For ms12 formats, qaf_mod->qaf_compr_offload_out is allocated during the first
+ /* For ms12 formats, qaf_mod->qaf_out[QAF_OUT_OFFLOAD] is allocated during the first
* call of notify_event_callback(). Therefore, the volume levels set during session
* open have to be cached and applied later */
qaf_mod->vol_left = left;
qaf_mod->vol_right = right;
- if (qaf_mod->qaf_compr_offload_out != NULL) {
- return qaf_mod->qaf_compr_offload_out->stream.set_volume(
- (struct audio_stream_out *)qaf_mod->qaf_compr_offload_out, left, right);
+ if (qaf_mod->qaf_out[QAF_OUT_OFFLOAD] != NULL) {
+ return qaf_mod->qaf_out[QAF_OUT_OFFLOAD]->stream.set_volume(
+ (struct audio_stream_out *)qaf_mod->qaf_out[QAF_OUT_OFFLOAD], left, right);
}
return -ENOSYS;
}
@@ -390,14 +421,14 @@
ALOGV("qaf_out_write bytes = %d, usecase[%d] and flags[%x] for handle[%p]",(int)bytes, out->usecase, out->flags, out);
lock_output_stream(out);
- if (qaf_mod->qaf_passthrough_out && qaf_mod->hdmi_connect) {
+ if (qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH] && qaf_mod->hdmi_connect) {
if ((out->format == AUDIO_FORMAT_PCM_16_BIT) && (popcount(out->channel_mask) <= 2)) {
ALOGD(" %s : Drop data as compress passthrough session is going on", __func__);
usleep(bytes * 1000000 / audio_stream_out_frame_size(stream) /
out->stream.common.get_sample_rate(&out->stream.common));
goto exit;
}
- ret = qaf_mod->qaf_passthrough_out->stream.write((struct audio_stream_out *)(qaf_mod->qaf_passthrough_out), buffer, bytes);
+ ret = qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH]->stream.write((struct audio_stream_out *)(qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH]), buffer, bytes);
pthread_mutex_unlock(&out->lock);
return ret;
}
@@ -498,15 +529,15 @@
kvpairs = NULL;
}
// MS12 Latency + Kernel Latency + Dsp Latency
- if (qaf_mod->qaf_compr_offload_out != NULL) {
- out->platform_latency = latency + (COMPRESS_OFFLOAD_NUM_FRAGMENTS * qaf_get_pcm_offload_buffer_size(&qaf_mod->qaf_compr_offload_out->info) \
- /(popcount(qaf_mod->qaf_compr_offload_out->channel_mask) * sizeof(short))) \
- +((platform_render_latency(qaf_mod->qaf_compr_offload_out->usecase) * qaf_mod->qaf_compr_offload_out->sample_rate) / 1000000LL);
+ if (qaf_mod->qaf_out[QAF_OUT_OFFLOAD] != NULL) {
+ out->platform_latency = latency + (COMPRESS_OFFLOAD_NUM_FRAGMENTS * qaf_get_pcm_offload_buffer_size(&qaf_mod->qaf_out[QAF_OUT_OFFLOAD]->info) \
+ /(popcount(qaf_mod->qaf_out[QAF_OUT_OFFLOAD]->channel_mask) * sizeof(short))) \
+ +((platform_render_latency(qaf_mod->qaf_out[QAF_OUT_OFFLOAD]->usecase) * qaf_mod->qaf_out[QAF_OUT_OFFLOAD]->sample_rate) / 1000000LL);
} else if (audio_extn_bt_hal_get_output_stream(qaf_mod->bt_hdl) != NULL) {
out->platform_latency = latency + audio_extn_bt_hal_get_latency(qaf_mod->bt_hdl);
- } else if (NULL != qaf_mod->qaf_compr_passthrough_out) {
- out->platform_latency = latency + ((qaf_mod->qaf_compr_passthrough_out->format == AUDIO_FORMAT_AC3) ? TRANSCODE_LATENCY(COMPRESS_PASSTHROUGH_BUFFER_SIZE, DD_FRAME_SIZE, DD_ENCODER_OUTPUT_SIZE) : TRANSCODE_LATENCY(COMPRESS_PASSTHROUGH_BUFFER_SIZE, DD_FRAME_SIZE, DDP_ENCODER_OUTPUT_SIZE)) \
- + (COMPRESS_OFFLOAD_PLAYBACK_LATENCY * qaf_mod->qaf_compr_passthrough_out->sample_rate/1000);
+ } else if (NULL != qaf_mod->qaf_out[QAF_OUT_TRANSCODE_PASSTHROUGH]) {
+ out->platform_latency = latency + ((qaf_mod->qaf_out[QAF_OUT_TRANSCODE_PASSTHROUGH]->format == AUDIO_FORMAT_AC3) ? TRANSCODE_LATENCY(COMPRESS_PASSTHROUGH_BUFFER_SIZE, DD_FRAME_SIZE, DD_ENCODER_OUTPUT_SIZE) : TRANSCODE_LATENCY(COMPRESS_PASSTHROUGH_BUFFER_SIZE, DD_FRAME_SIZE, DDP_ENCODER_OUTPUT_SIZE)) \
+ + (COMPRESS_OFFLOAD_PLAYBACK_LATENCY * qaf_mod->qaf_out[QAF_OUT_TRANSCODE_PASSTHROUGH]->sample_rate/1000);
}
if(out->format & AUDIO_FORMAT_PCM_16_BIT) {
@@ -546,8 +577,8 @@
int ret = -1;
lock_output_stream(out);
- if (qaf_mod->qaf_passthrough_out && qaf_mod->hdmi_connect) {
- ret = qaf_mod->qaf_passthrough_out->stream.get_presentation_position((struct audio_stream_out *)qaf_mod->qaf_passthrough_out, frames, timestamp);
+ if (qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH] && qaf_mod->hdmi_connect) {
+ ret = qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH]->stream.get_presentation_position((struct audio_stream_out *)qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH], frames, timestamp);
pthread_mutex_unlock(&out->lock);
return ret;
}
@@ -574,8 +605,8 @@
ALOGE("%s", __func__);
lock_output_stream(out);
- if (qaf_mod->qaf_passthrough_out && qaf_mod->hdmi_connect) {
- status = qaf_mod->qaf_passthrough_out->stream.pause((struct audio_stream_out *) qaf_mod->qaf_passthrough_out);
+ if (qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH] && qaf_mod->hdmi_connect) {
+ status = qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH]->stream.pause((struct audio_stream_out *) qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH]);
out->offload_state = OFFLOAD_STATE_PAUSED;
pthread_mutex_unlock(&out->lock);
return status;
@@ -595,26 +626,18 @@
out->qaf_stream_handle, out->format);
lock_output_stream(out);
- if (qaf_mod->qaf_passthrough_out && qaf_mod->hdmi_connect) {
- status = qaf_mod->qaf_passthrough_out->stream.drain(
- (struct audio_stream_out*)(qaf_mod->qaf_passthrough_out), type);
+ if (qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH] && qaf_mod->hdmi_connect) {
+ status = qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH]->stream.drain(
+ (struct audio_stream_out*)(qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH]), type);
pthread_mutex_unlock(&out->lock);
return status;
}
- if (out->offload_callback && out->qaf_stream_handle) {
+ if (out->client_callback && out->qaf_stream_handle)
/* Stream stop will trigger EOS and on EOS_EVENT received
from callback DRAIN_READY command is sent */
status = audio_extn_qaf_stream_stop(out);
- if (out->format != AUDIO_FORMAT_PCM_16_BIT) {
- if (out->flags & AUDIO_OUTPUT_FLAG_ASSOCIATED) {
- qaf_mod->stream_drain_assoc = out;
- } else {
- qaf_mod->stream_drain_main = out;
- }
- }
- }
pthread_mutex_unlock(&out->lock);
return status;
}
@@ -635,8 +658,8 @@
int status = -ENOSYS;
lock_output_stream(out);
- if (qaf_mod->qaf_passthrough_out && qaf_mod->hdmi_connect) {
- status = qaf_mod->qaf_passthrough_out->stream.flush((struct audio_stream_out *)qaf_mod->qaf_passthrough_out);
+ if (qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH] && qaf_mod->hdmi_connect) {
+ status = qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH]->stream.flush((struct audio_stream_out *)qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH]);
out->offload_state = OFFLOAD_STATE_IDLE;
pthread_mutex_unlock(&out->lock);
return status;
@@ -655,8 +678,8 @@
lock_output_stream(out);
- if (qaf_mod->qaf_passthrough_out && qaf_mod->hdmi_connect) {
- latency = qaf_mod->qaf_passthrough_out->stream.get_latency((struct audio_stream_out *)qaf_mod->qaf_passthrough_out);
+ if (qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH] && qaf_mod->hdmi_connect) {
+ latency = qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH]->stream.get_latency((struct audio_stream_out *)qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH]);
ALOGV("%s: latency = %u", __FUNCTION__, latency);
pthread_mutex_unlock(&out->lock);
return latency;
@@ -709,31 +732,31 @@
ALOGVV("Device id %x %s %d, bytes to written %d",
device, __func__,__LINE__, size);
- if ((qaf_mod->qaf_passthrough_out != NULL) && qaf_mod->hdmi_connect) {
+ if ((qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH] != NULL) && qaf_mod->hdmi_connect) {
pthread_mutex_lock(&qaf_module->lock);
- if (qaf_mod->qaf_compr_offload_out != NULL) {
+ if (qaf_mod->qaf_out[QAF_OUT_OFFLOAD] != NULL) {
adev_close_output_stream(
(struct audio_hw_device *) qaf_mod->adev,
- (struct audio_stream_out *) (qaf_mod->qaf_compr_offload_out));
- qaf_mod->qaf_compr_offload_out = NULL;
+ (struct audio_stream_out *) (qaf_mod->qaf_out[QAF_OUT_OFFLOAD]));
+ qaf_mod->qaf_out[QAF_OUT_OFFLOAD] = NULL;
}
- if (qaf_mod->qaf_compr_offload_out_mch) {
+ if (qaf_mod->qaf_out[QAF_OUT_OFFLOAD_MCH]) {
adev_close_output_stream(
(struct audio_hw_device *) qaf_mod->adev,
(struct audio_stream_out *)
- (qaf_mod->qaf_compr_offload_out_mch));
- qaf_mod->qaf_compr_offload_out_mch = NULL;
+ (qaf_mod->qaf_out[QAF_OUT_OFFLOAD_MCH]));
+ qaf_mod->qaf_out[QAF_OUT_OFFLOAD_MCH] = NULL;
}
pthread_mutex_unlock(&qaf_module->lock);
ALOGV("%s %d DROPPING DATA", __func__, __LINE__);
return;
} else {
- if (qaf_mod->qaf_passthrough_out != NULL) {
+ if (qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH] != NULL) {
pthread_mutex_lock(&qaf_module->lock);
adev_close_output_stream(
(struct audio_hw_device *) qaf_mod->adev,
- (struct audio_stream_out *) qaf_mod->qaf_passthrough_out);
- qaf_mod->qaf_passthrough_out = NULL;
+ (struct audio_stream_out *) qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH]);
+ qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH] = NULL;
qaf_mod->main_output_active = false;
pthread_mutex_unlock(&qaf_module->lock);
}
@@ -744,17 +767,17 @@
(device ==
(AUDIO_DEVICE_OUT_AUX_DIGITAL | AUDIO_COMPRESSED_OUT_DDP))) {
- if (NULL == qaf_mod->qaf_compr_passthrough_out &&
+ if (NULL == qaf_mod->qaf_out[QAF_OUT_TRANSCODE_PASSTHROUGH] &&
qaf_mod->hdmi_connect) {
struct audio_config config;
audio_devices_t devices;
- if (qaf_mod->qaf_compr_offload_out_mch) {
+ if (qaf_mod->qaf_out[QAF_OUT_OFFLOAD_MCH]) {
adev_close_output_stream(
(struct audio_hw_device *) qaf_mod->adev,
(struct audio_stream_out *)
- (qaf_mod->qaf_compr_offload_out_mch));
- qaf_mod->qaf_compr_offload_out_mch = NULL;
+ (qaf_mod->qaf_out[QAF_OUT_OFFLOAD_MCH]));
+ qaf_mod->qaf_out[QAF_OUT_OFFLOAD_MCH] = NULL;
}
config.sample_rate = config.offload_info.sample_rate =
@@ -783,30 +806,30 @@
QAF_DEFAULT_COMPR_PASSTHROUGH_HANDLE, devices,
flags, &config,
(struct audio_stream_out **)
- &(qaf_mod->qaf_compr_passthrough_out), NULL);
+ &(qaf_mod->qaf_out[QAF_OUT_TRANSCODE_PASSTHROUGH]), NULL);
if (ret < 0) {
ALOGE("%s: adev_open_output_stream failed with ret = %d!",
__func__, ret);
pthread_mutex_unlock(&qaf_module->lock);
return;
}
- qaf_mod->qaf_compr_passthrough_out->compr_config.fragments =
+ qaf_mod->qaf_out[QAF_OUT_TRANSCODE_PASSTHROUGH]->compr_config.fragments =
COMPRESS_OFFLOAD_NUM_FRAGMENTS;
}
if (!qaf_mod->passthrough_enabled)
qaf_mod->passthrough_enabled = 1;
- if (qaf_mod->qaf_compr_passthrough_out) {
- ret = qaf_mod->qaf_compr_passthrough_out->stream.write(
+ if (qaf_mod->qaf_out[QAF_OUT_TRANSCODE_PASSTHROUGH]) {
+ ret = qaf_mod->qaf_out[QAF_OUT_TRANSCODE_PASSTHROUGH]->stream.write(
(struct audio_stream_out *)
- qaf_mod->qaf_compr_passthrough_out, buf, size);
+ qaf_mod->qaf_out[QAF_OUT_TRANSCODE_PASSTHROUGH], buf, size);
}
} else if ((device & AUDIO_DEVICE_OUT_AUX_DIGITAL) &&
((qaf_mod->hdmi_connect) &&
- (qaf_mod->qaf_passthrough_out == NULL) &&
+ (qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH] == NULL) &&
(qaf_mod->hdmi_sink_channels > 2))) {
- if (NULL == qaf_mod->qaf_compr_offload_out_mch) {
+ if (NULL == qaf_mod->qaf_out[QAF_OUT_OFFLOAD_MCH]) {
struct audio_config config;
audio_devices_t devices;
@@ -831,47 +854,78 @@
}
devices = AUDIO_DEVICE_OUT_AUX_DIGITAL;
flags = (AUDIO_OUTPUT_FLAG_DIRECT|
- AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD|
AUDIO_OUTPUT_FLAG_DIRECT_PCM);
ret = adev_open_output_stream(
(struct audio_hw_device *) qaf_mod->adev,
QAF_DEFAULT_COMPR_AUDIO_HANDLE, devices, flags,
&config, (struct audio_stream_out **)
- &(qaf_mod->qaf_compr_offload_out_mch), NULL);
+ &(qaf_mod->qaf_out[QAF_OUT_OFFLOAD_MCH]), NULL);
if (ret < 0) {
ALOGE("%s: adev_open_output_stream failed with ret = %d!",
__func__, ret);
pthread_mutex_unlock(&qaf_module->lock);
return;
}
- qaf_mod->qaf_compr_offload_out_mch->compr_config.fragments =
+ if (qaf_mod->stream[QAF_IN_MAIN] && qaf_mod->stream[QAF_IN_MAIN]->client_callback != NULL)
+ qaf_mod->qaf_out[QAF_OUT_OFFLOAD_MCH]->stream.set_callback((struct audio_stream_out *)
+ qaf_mod->qaf_out[QAF_OUT_OFFLOAD_MCH],
+ qaf_mod->stream[QAF_IN_MAIN]->client_callback,
+ qaf_mod->stream[QAF_IN_MAIN]->client_cookie);
+ else if (qaf_mod->stream[QAF_IN_PCM] && qaf_mod->stream[QAF_IN_PCM]->client_callback != NULL)
+ qaf_mod->qaf_out[QAF_OUT_OFFLOAD_MCH]->stream.set_callback((struct audio_stream_out *)
+ qaf_mod->qaf_out[QAF_OUT_OFFLOAD_MCH],
+ qaf_mod->stream[QAF_IN_PCM]->client_callback,
+ qaf_mod->stream[QAF_IN_PCM]->client_cookie);
+
+ qaf_mod->qaf_out[QAF_OUT_OFFLOAD_MCH]->compr_config.fragments =
COMPRESS_OFFLOAD_NUM_FRAGMENTS;
- qaf_mod->qaf_compr_offload_out_mch->compr_config.fragment_size =
+ qaf_mod->qaf_out[QAF_OUT_OFFLOAD_MCH]->compr_config.fragment_size =
qaf_get_pcm_offload_buffer_size(&config.offload_info);
+
+ int index = -1;
+ if (qaf_mod->adsp_hdlr_config[QAF_IN_MAIN].adsp_hdlr_config_valid)
+ index = (int)QAF_IN_MAIN;
+ else if (qaf_mod->adsp_hdlr_config[QAF_IN_PCM].adsp_hdlr_config_valid)
+ index = (int)QAF_IN_PCM;
+ if (index >= 0) {
+ if(qaf_mod->qaf_out[QAF_OUT_OFFLOAD_MCH]->standby)
+ qaf_mod->qaf_out[QAF_OUT_OFFLOAD_MCH]->stream.write(
+ (struct audio_stream_out *)
+ qaf_mod->qaf_out[QAF_OUT_OFFLOAD_MCH], NULL, 0);
+
+ lock_output_stream(qaf_mod->qaf_out[QAF_OUT_OFFLOAD_MCH]);
+ ret = audio_extn_out_set_param_data(
+ qaf_mod->qaf_out[QAF_OUT_OFFLOAD_MCH],
+ AUDIO_EXTN_PARAM_ADSP_STREAM_CMD,
+ (audio_extn_param_payload *)
+ &qaf_mod->adsp_hdlr_config[index].event_params);
+ pthread_mutex_unlock(&qaf_mod->qaf_out[QAF_OUT_OFFLOAD_MCH]->lock);
+
+ }
}
- if (qaf_mod->qaf_compr_offload_out_mch) {
- ret = qaf_mod->qaf_compr_offload_out_mch->stream.write(
+ if (qaf_mod->qaf_out[QAF_OUT_OFFLOAD_MCH]) {
+ ret = qaf_mod->qaf_out[QAF_OUT_OFFLOAD_MCH]->stream.write(
(struct audio_stream_out *)
- qaf_mod->qaf_compr_offload_out_mch, buf, size);
+ qaf_mod->qaf_out[QAF_OUT_OFFLOAD_MCH], buf, size);
}
} else {
bt_stream = audio_extn_bt_hal_get_output_stream(qaf_mod->bt_hdl);
if (bt_stream != NULL) {
- if (qaf_mod->qaf_compr_offload_out) {
+ if (qaf_mod->qaf_out[QAF_OUT_OFFLOAD]) {
adev_close_output_stream(
(struct audio_hw_device *) qaf_mod->adev,
(struct audio_stream_out *)
- (qaf_mod->qaf_compr_offload_out));
- qaf_mod->qaf_compr_offload_out = NULL;
+ (qaf_mod->qaf_out[QAF_OUT_OFFLOAD]));
+ qaf_mod->qaf_out[QAF_OUT_OFFLOAD] = NULL;
}
audio_extn_bt_hal_out_write(qaf_mod->bt_hdl, buf, size);
}
- if (NULL == qaf_mod->qaf_compr_offload_out && bt_stream == NULL &&
- qaf_mod->qaf_passthrough_out == NULL) {
+ if (NULL == qaf_mod->qaf_out[QAF_OUT_OFFLOAD] && bt_stream == NULL &&
+ qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH] == NULL) {
struct audio_config config;
audio_devices_t devices;
@@ -884,57 +938,91 @@
config.format = AUDIO_FORMAT_PCM_16_BIT;
config.offload_info.channel_mask = config.channel_mask =
AUDIO_CHANNEL_OUT_STEREO;
- devices = AUDIO_DEVICE_OUT_SPEAKER;
+ if(qaf_mod->stream[QAF_IN_MAIN])
+ devices = qaf_mod->stream[QAF_IN_MAIN]->devices;
+ else
+ devices = qaf_mod->stream[QAF_IN_PCM]->devices;
flags = (AUDIO_OUTPUT_FLAG_DIRECT|
- AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD|
AUDIO_OUTPUT_FLAG_DIRECT_PCM);
+
/* TODO:: Need to Propagate errors to framework */
ret = adev_open_output_stream(
(struct audio_hw_device *) qaf_mod->adev,
QAF_DEFAULT_COMPR_AUDIO_HANDLE, devices,
flags, &config,
(struct audio_stream_out **)
- &(qaf_mod->qaf_compr_offload_out), NULL);
+ &(qaf_mod->qaf_out[QAF_OUT_OFFLOAD]), NULL);
if (ret < 0) {
ALOGE("%s: adev_open_output_stream failed with ret = %d!",
__func__, ret);
pthread_mutex_unlock(&qaf_module->lock);
return;
}
+ if (qaf_mod->stream[QAF_IN_MAIN] && qaf_mod->stream[QAF_IN_MAIN]->client_callback != NULL)
+ qaf_mod->qaf_out[QAF_OUT_OFFLOAD]->stream.set_callback((struct audio_stream_out *)
+ qaf_mod->qaf_out[QAF_OUT_OFFLOAD],
+ qaf_mod->stream[QAF_IN_MAIN]->client_callback,
+ qaf_mod->stream[QAF_IN_MAIN]->client_cookie);
+ else if (qaf_mod->stream[QAF_IN_PCM] && qaf_mod->stream[QAF_IN_PCM]->client_callback != NULL)
+ qaf_mod->qaf_out[QAF_OUT_OFFLOAD]->stream.set_callback((struct audio_stream_out *)
+ qaf_mod->qaf_out[QAF_OUT_OFFLOAD],
+ qaf_mod->stream[QAF_IN_PCM]->client_callback,
+ qaf_mod->stream[QAF_IN_PCM]->client_cookie);
- qaf_mod->qaf_compr_offload_out->compr_config.fragments =
+
+ qaf_mod->qaf_out[QAF_OUT_OFFLOAD]->compr_config.fragments =
COMPRESS_OFFLOAD_NUM_FRAGMENTS;
- qaf_mod->qaf_compr_offload_out->compr_config.fragment_size =
+ qaf_mod->qaf_out[QAF_OUT_OFFLOAD]->compr_config.fragment_size =
qaf_get_pcm_offload_buffer_size(&config.offload_info);
- qaf_mod->qaf_compr_offload_out->info.channel_mask =
+ qaf_mod->qaf_out[QAF_OUT_OFFLOAD]->info.channel_mask =
config.offload_info.channel_mask;
- qaf_mod->qaf_compr_offload_out->info.format =
+ qaf_mod->qaf_out[QAF_OUT_OFFLOAD]->info.format =
config.offload_info.format;
- qaf_mod->qaf_compr_offload_out->info.sample_rate =
+ qaf_mod->qaf_out[QAF_OUT_OFFLOAD]->info.sample_rate =
config.offload_info.sample_rate;
- qaf_mod->qaf_compr_offload_out->stream.set_volume(
- (struct audio_stream_out *)qaf_mod->qaf_compr_offload_out,
+ qaf_mod->qaf_out[QAF_OUT_OFFLOAD]->stream.set_volume(
+ (struct audio_stream_out *)qaf_mod->qaf_out[QAF_OUT_OFFLOAD],
qaf_mod->vol_left, qaf_mod->vol_right);
+
+ int index = -1;
+ if (qaf_mod->adsp_hdlr_config[QAF_IN_MAIN].adsp_hdlr_config_valid)
+ index = (int)QAF_IN_MAIN;
+ else if (qaf_mod->adsp_hdlr_config[QAF_IN_PCM].adsp_hdlr_config_valid)
+ index = (int)QAF_IN_PCM;
+ if (index >= 0) {
+ if(qaf_mod->qaf_out[QAF_OUT_OFFLOAD]->standby)
+ qaf_mod->qaf_out[QAF_OUT_OFFLOAD]->stream.write(
+ (struct audio_stream_out *)
+ qaf_mod->qaf_out[QAF_OUT_OFFLOAD], NULL, 0);
+
+ lock_output_stream(qaf_mod->qaf_out[QAF_OUT_OFFLOAD]);
+ ret = audio_extn_out_set_param_data(
+ qaf_mod->qaf_out[QAF_OUT_OFFLOAD],
+ AUDIO_EXTN_PARAM_ADSP_STREAM_CMD,
+ (audio_extn_param_payload *)
+ &qaf_mod->adsp_hdlr_config[index].event_params);
+ pthread_mutex_unlock(&qaf_mod->qaf_out[QAF_OUT_OFFLOAD]->lock);
+ }
}
if (!qaf_mod->hdmi_connect &&
- (qaf_mod->qaf_compr_passthrough_out ||
- qaf_mod->qaf_compr_offload_out_mch)) {
+ (qaf_mod->qaf_out[QAF_OUT_TRANSCODE_PASSTHROUGH] ||
+ qaf_mod->qaf_out[QAF_OUT_OFFLOAD_MCH])) {
qaf_mod->passthrough_enabled = 0;
- if (qaf_mod->qaf_compr_passthrough_out) {
+ if (qaf_mod->qaf_out[QAF_OUT_TRANSCODE_PASSTHROUGH]) {
adev_close_output_stream(
(struct audio_hw_device *) qaf_mod->adev,
(struct audio_stream_out *)
- (qaf_mod->qaf_compr_passthrough_out));
- qaf_mod->qaf_compr_passthrough_out = NULL;
+ (qaf_mod->qaf_out[QAF_OUT_TRANSCODE_PASSTHROUGH]));
+ qaf_mod->qaf_out[QAF_OUT_TRANSCODE_PASSTHROUGH] = NULL;
}
- if (qaf_mod->qaf_compr_offload_out_mch) {
+ if (qaf_mod->qaf_out[QAF_OUT_OFFLOAD_MCH]) {
adev_close_output_stream(
(struct audio_hw_device *) qaf_mod->adev,
(struct audio_stream_out *)
- (qaf_mod->qaf_compr_offload_out_mch));
- qaf_mod->qaf_compr_offload_out_mch = NULL;
+ (qaf_mod->qaf_out[QAF_OUT_OFFLOAD_MCH]));
+ qaf_mod->qaf_out[QAF_OUT_OFFLOAD_MCH] = NULL;
}
}
@@ -942,10 +1030,10 @@
* TODO:: Since this is mixed data,
* need to identify to which stream the error should be sent
*/
- if (bt_stream == NULL && qaf_mod->qaf_compr_offload_out) {
- ret = qaf_mod->qaf_compr_offload_out->stream.write(
+ if (bt_stream == NULL && qaf_mod->qaf_out[QAF_OUT_OFFLOAD]) {
+ ret = qaf_mod->qaf_out[QAF_OUT_OFFLOAD]->stream.write(
(struct audio_stream_out *)
- qaf_mod->qaf_compr_offload_out, buf, size);
+ qaf_mod->qaf_out[QAF_OUT_OFFLOAD], buf, size);
}
}
@@ -955,8 +1043,8 @@
|| event_id == AUDIO_EOS_MAIN_AAC_EVENT
|| event_id == AUDIO_EOS_MAIN_AC4_EVENT
|| event_id == AUDIO_EOS_ASSOC_DD_DDP_EVENT) {
- struct stream_out *out = qaf_module->stream_drain_main;
- struct stream_out *out_assoc = qaf_module->stream_drain_assoc;
+ struct stream_out *out = qaf_module->stream[QAF_IN_MAIN];
+ struct stream_out *out_assoc = qaf_module->stream[QAF_IN_ASSOC];
/**
* TODO:: Only DD/DDP Associate Eos is handled, need to add support
@@ -964,16 +1052,15 @@
*/
if (event_id == AUDIO_EOS_ASSOC_DD_DDP_EVENT && out_assoc != NULL) {
lock_output_stream(out_assoc);
- out_assoc->offload_callback(STREAM_CBK_EVENT_DRAIN_READY, NULL,
- out_assoc->offload_cookie);
+ out_assoc->client_callback(STREAM_CBK_EVENT_DRAIN_READY, NULL,
+ out_assoc->client_cookie);
pthread_mutex_unlock(&out_assoc->lock);
- qaf_module->stream_drain_assoc = NULL;
+ qaf_module->stream[QAF_IN_ASSOC] = NULL;
} else if (out != NULL) {
lock_output_stream(out);
- out->offload_callback(STREAM_CBK_EVENT_DRAIN_READY, NULL,
- out->offload_cookie);
+ out->client_callback(STREAM_CBK_EVENT_DRAIN_READY, NULL, out->client_cookie);
pthread_mutex_unlock(&out->lock);
- qaf_module->stream_drain_main = NULL;
+ qaf_module->stream[QAF_IN_MAIN] = NULL;
ALOGV("%s %d sent DRAIN_READY", __func__, __LINE__);
}
}
@@ -1055,6 +1142,7 @@
/* TODO to send appropriated flags when support for system tones is added */
if (input_config.format == AUDIO_FORMAT_PCM_16_BIT) {
status = qaf_mod->qaf_audio_stream_open(qaf_mod->session_handle, &out->qaf_stream_handle, input_config, devices, /*flags*/AUDIO_STREAM_SYSTEM_TONE);
+ qaf_mod->stream[QAF_IN_PCM] = out;
} else if (input_config.format == AUDIO_FORMAT_AC3 ||
input_config.format == AUDIO_FORMAT_E_AC3 ||
input_config.format == AUDIO_FORMAT_AC4 ||
@@ -1067,12 +1155,14 @@
ALOGV("%s %d Open stream for Input with both Main and Associated stream contents with flag [%x] and stream handle [%p]", __func__, __LINE__, flags, out->qaf_stream_handle);
qaf_mod->main_output_active = true;
qaf_mod->assoc_output_active = true;
+ qaf_mod->stream[QAF_IN_MAIN] = out;
}
} else if (flags & AUDIO_OUTPUT_FLAG_MAIN) {
status = qaf_mod->qaf_audio_stream_open(qaf_mod->session_handle, &out->qaf_stream_handle, input_config, devices, /*flags*/AUDIO_STREAM_MAIN);
if (status == 0) {
ALOGV("%s %d Open stream for Input with only Main flag [%x] stream handle [%p]", __func__, __LINE__, flags, out->qaf_stream_handle);
qaf_mod->main_output_active = true;
+ qaf_mod->stream[QAF_IN_MAIN] = out;
}
} else if (flags & AUDIO_OUTPUT_FLAG_ASSOCIATED) {
ALOGE("%s %d Error main input is not active", __func__, __LINE__);
@@ -1082,6 +1172,7 @@
if (status == 0) {
ALOGV("%s %d Open stream for Local playback with flag [%x] stream handle [%p] ", __func__, __LINE__, flags, out->qaf_stream_handle);
qaf_mod->main_output_active = true;
+ qaf_mod->stream[QAF_IN_MAIN] = out;
}
}
} else {
@@ -1097,6 +1188,7 @@
if (status == 0) {
ALOGV("%s %d Open stream for Input with only Associated flag [%x] stream handle [%p]", __func__, __LINE__, flags, out->qaf_stream_handle);
qaf_mod->assoc_output_active = true;
+ qaf_mod->stream[QAF_IN_ASSOC] = out;
}
}
} else {
@@ -1138,10 +1230,10 @@
if ((!property_get_bool("audio.qaf.reencode", false)) &&
property_get_bool("audio.qaf.passthrough", false)) {
if (property_get_bool("audio.offload.passthrough", false)) {
- if (qaf_mod->qaf_passthrough_out && qaf_mod->hdmi_connect &&
+ if (qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH] && qaf_mod->hdmi_connect &&
(((out->format == AUDIO_FORMAT_E_AC3) && platform_is_edid_supported_format(qaf_mod->adev->platform, AUDIO_FORMAT_E_AC3)) ||
((out->format == AUDIO_FORMAT_AC3) && platform_is_edid_supported_format(qaf_mod->adev->platform, AUDIO_FORMAT_AC3)))) {
- status = qaf_mod->qaf_passthrough_out->stream.resume((struct audio_stream_out*) qaf_mod->qaf_passthrough_out);
+ status = qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH]->stream.resume((struct audio_stream_out*) qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH]);
if (!status)
out->offload_state = OFFLOAD_STATE_PLAYING;
pthread_mutex_unlock(&out->lock);
@@ -1151,13 +1243,13 @@
status = audio_extn_qaf_stream_open(out);
if (!status)
out->offload_state = OFFLOAD_STATE_PLAYING;
- out->offload_callback(STREAM_CBK_EVENT_WRITE_READY, NULL, out->offload_cookie);
+ out->client_callback(STREAM_CBK_EVENT_WRITE_READY, NULL, out->client_cookie);
}
}
} else {
if ((out->format == AUDIO_FORMAT_PCM_16_BIT) && (popcount(out->channel_mask) > 2)) {
- if (qaf_mod->qaf_passthrough_out && qaf_mod->hdmi_connect) {
- status = qaf_mod->qaf_passthrough_out->stream.resume((struct audio_stream_out*) qaf_mod->qaf_passthrough_out);
+ if (qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH] && qaf_mod->hdmi_connect) {
+ status = qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH]->stream.resume((struct audio_stream_out*) qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH]);
if (!status)
out->offload_state = OFFLOAD_STATE_PLAYING;
pthread_mutex_unlock(&out->lock);
@@ -1177,20 +1269,16 @@
{
ALOGV("%s %d", __func__, __LINE__);
if (qaf_mod != NULL) {
- if (qaf_mod->qaf_compr_offload_out != NULL)
- adev_close_output_stream((struct audio_hw_device *) qaf_mod->adev, (struct audio_stream_out *) (qaf_mod->qaf_compr_offload_out));
- if (qaf_mod->qaf_compr_passthrough_out != NULL)
- adev_close_output_stream((struct audio_hw_device *) qaf_mod->adev, (struct audio_stream_out *) (qaf_mod->qaf_compr_passthrough_out));
+ if (qaf_mod->qaf_out[QAF_OUT_OFFLOAD] != NULL)
+ adev_close_output_stream((struct audio_hw_device *) qaf_mod->adev, (struct audio_stream_out *) (qaf_mod->qaf_out[QAF_OUT_OFFLOAD]));
+ if (qaf_mod->qaf_out[QAF_OUT_TRANSCODE_PASSTHROUGH] != NULL)
+ adev_close_output_stream((struct audio_hw_device *) qaf_mod->adev, (struct audio_stream_out *) (qaf_mod->qaf_out[QAF_OUT_TRANSCODE_PASSTHROUGH]));
- if (qaf_mod->qaf_passthrough_out) {
- adev_close_output_stream((struct audio_hw_device *) qaf_mod->adev, (struct audio_stream_out *) (qaf_mod->qaf_passthrough_out));
- qaf_mod->qaf_passthrough_out = NULL;
+ if (qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH]) {
+ adev_close_output_stream((struct audio_hw_device *) qaf_mod->adev, (struct audio_stream_out *) (qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH]));
+ qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH] = NULL;
}
- if (qaf_mod->qaf_lib != NULL) {
- dlclose(qaf_mod->qaf_lib);
- qaf_mod->qaf_lib = NULL;
- }
free(qaf_mod);
qaf_mod = NULL;
}
@@ -1270,8 +1358,8 @@
break;
}
lock_output_stream(out);
- if (send_callback && out->offload_callback) {
- out->offload_callback(event, NULL, out->offload_cookie);
+ if (send_callback && out->client_callback) {
+ out->client_callback(event, NULL, out->client_cookie);
}
free(cmd);
}
@@ -1321,7 +1409,7 @@
ALOGV("%s: enter: usecase(%d: %s) kvpairs: %s",
__func__, out->usecase, use_case_table[out->usecase], kvpairs);
- if ((NULL != qaf_mod->qaf_compr_offload_out)) {
+ if ((NULL != qaf_mod->qaf_out[QAF_OUT_OFFLOAD])) {
if (qaf_mod->qaf_msmd_enabled) {
if (qaf_mod->passthrough_enabled && qaf_mod->hdmi_connect)
return 1;
@@ -1338,7 +1426,7 @@
val |= AUDIO_DEVICE_OUT_SPEAKER;
str_parms_add_int(new_parms, AUDIO_PARAMETER_STREAM_ROUTING, val);
new_kv_pairs = str_parms_to_str(new_parms);
- qaf_mod->qaf_compr_offload_out->stream.common.set_parameters((struct audio_stream *) qaf_mod->qaf_compr_offload_out, new_kv_pairs);
+ qaf_mod->qaf_out[QAF_OUT_OFFLOAD]->stream.common.set_parameters((struct audio_stream *) qaf_mod->qaf_out[QAF_OUT_OFFLOAD], new_kv_pairs);
free(new_kv_pairs);
str_parms_destroy(new_parms);
}
@@ -1346,7 +1434,7 @@
str_parms_destroy(parms);
} else {
if (!(qaf_mod->passthrough_enabled && qaf_mod->hdmi_connect))
- qaf_mod->qaf_compr_offload_out->stream.common.set_parameters((struct audio_stream *) qaf_mod->qaf_compr_offload_out, kvpairs);
+ qaf_mod->qaf_out[QAF_OUT_OFFLOAD]->stream.common.set_parameters((struct audio_stream *) qaf_mod->qaf_out[QAF_OUT_OFFLOAD], kvpairs);
parms = str_parms_create_str(kvpairs);
if (!parms) {
@@ -1385,7 +1473,7 @@
if (err >= 0) {
val = atoi(value);
if ((val & AUDIO_DEVICE_OUT_AUX_DIGITAL) &&
- (qaf_mod->qaf_passthrough_out == NULL)) {
+ (qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH] == NULL)) {
audio_output_flags_t flags;
struct audio_config config;
audio_devices_t devices;
@@ -1414,7 +1502,120 @@
str_parms_destroy(parms);
}
}
+ return ret;
+}
+bool audio_extn_is_qaf_stream(struct stream_out *out)
+{
+
+ return (audio_extn_qaf_is_enabled() && out && is_ms12_format(out->format));
+}
+
+/* API to send playback stream specific config parameters */
+int audio_extn_qaf_out_set_param_data(struct stream_out *out,
+ audio_extn_param_id param_id,
+ audio_extn_param_payload *payload)
+{
+ int ret = -EINVAL;
+ int count;
+ struct stream_out *new_out = NULL;
+ struct audio_adsp_event *adsp_event;
+
+ if (!out || !payload) {
+ ALOGE("%s:: Invalid Param",__func__);
+ return ret;
+ }
+
+ /* In qaf output render session may not be opened at this time.
+ to handle it store adsp_hdlr param info so that it can be
+ applied later after opening render session from ms12 callback
+ */
+ if (param_id == AUDIO_EXTN_PARAM_ADSP_STREAM_CMD) {
+ count = get_input_stream_index(out);
+ if (count < 0) {
+ ALOGE("%s:: Invalid stream", __func__);
+ return ret;
+ }
+ adsp_event = (struct audio_adsp_event *)payload;
+
+ if (payload->adsp_event_params.payload_length
+ <= AUDIO_MAX_ADSP_STREAM_CMD_PAYLOAD_LEN) {
+ memcpy(qaf_mod->adsp_hdlr_config[count].event_payload,
+ adsp_event->payload, adsp_event->payload_length);
+ qaf_mod->adsp_hdlr_config[count].event_params.payload =
+ qaf_mod->adsp_hdlr_config[count].event_payload;
+ qaf_mod->adsp_hdlr_config[count].event_params.payload_length
+ = adsp_event->payload_length;
+ qaf_mod->adsp_hdlr_config[count].adsp_hdlr_config_valid = true;
+ } else {
+ ALOGE("%s:: Invalid adsp event length %d", __func__,
+ adsp_event->payload_length);
+ return ret;
+ }
+ ret = 0;
+ }
+
+ /* apply param for all active out sessions */
+ for (count = 0; count < MAX_QAF_OUT; count++) {
+ new_out = qaf_mod->qaf_out[count];
+ if (!new_out)
+ continue;
+
+ /*ADSP event is not supported for passthrough*/
+ if ((param_id == AUDIO_EXTN_PARAM_ADSP_STREAM_CMD) &&
+ !(new_out->flags & AUDIO_OUTPUT_FLAG_DIRECT_PCM))
+ continue;
+ if (new_out->standby)
+ new_out->stream.write((struct audio_stream_out *)new_out, NULL, 0);
+ lock_output_stream(new_out);
+ ret = audio_extn_out_set_param_data(new_out, param_id, payload);
+ if(ret)
+ ALOGE("%s::audio_extn_out_set_param_data error %d", __func__, ret);
+ pthread_mutex_unlock(&new_out->lock);
+ }
+ return ret;
+}
+
+int audio_extn_qaf_out_get_param_data(struct stream_out *out,
+ audio_extn_param_id param_id,
+ audio_extn_param_payload *payload)
+{
+ int ret = -EINVAL;
+ struct stream_out *new_out = NULL;
+
+ if (!out || !payload) {
+ ALOGE("%s:: Invalid Param",__func__);
+ return ret;
+ }
+
+ if (!qaf_mod->hdmi_connect) {
+ ALOGE("%s:: hdmi not connected",__func__);
+ return ret;
+ }
+
+ /* get session which is routed to hdmi*/
+ if (qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH])
+ new_out = qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH];
+ else if (qaf_mod->qaf_out[QAF_OUT_TRANSCODE_PASSTHROUGH])
+ new_out = qaf_mod->qaf_out[QAF_OUT_TRANSCODE_PASSTHROUGH];
+ else if (qaf_mod->qaf_out[QAF_OUT_OFFLOAD_MCH])
+ new_out = qaf_mod->qaf_out[QAF_OUT_OFFLOAD_MCH];
+ else if (qaf_mod->qaf_out[QAF_OUT_OFFLOAD])
+ new_out = qaf_mod->qaf_out[QAF_OUT_OFFLOAD];
+
+ if (!new_out) {
+ ALOGE("%s:: No out session active",__func__);
+ return ret;
+ }
+
+ if (new_out->standby)
+ new_out->stream.write((struct audio_stream_out *)new_out, NULL, 0);
+
+ lock_output_stream(new_out);
+ ret = audio_extn_out_get_param_data(new_out, param_id, payload);
+ if(ret)
+ ALOGE("%s::audio_extn_out_get_param_data error %d", __func__, ret);
+ pthread_mutex_unlock(&new_out->lock);
return ret;
}
@@ -1485,14 +1686,15 @@
struct audio_stream_out *stream)
{
struct stream_out *out = (struct stream_out *)stream;
+ int index;
ALOGV("%s: enter:stream_handle(%p) format = %x", __func__, out, out->format);
- if (qaf_mod->qaf_passthrough_out) {
- ALOGD("%s %d closing stream handle %p", __func__, __LINE__, qaf_mod->qaf_passthrough_out);
+ if (qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH]) {
+ ALOGD("%s %d closing stream handle %p", __func__, __LINE__, qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH]);
pthread_mutex_lock(&qaf_mod->lock);
- adev_close_output_stream((struct audio_hw_device *) qaf_mod->adev, (struct audio_stream_out *) (qaf_mod->qaf_passthrough_out));
+ adev_close_output_stream((struct audio_hw_device *) qaf_mod->adev, (struct audio_stream_out *) (qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH]));
adev_close_output_stream(dev, stream);
- qaf_mod->qaf_passthrough_out = NULL;
+ qaf_mod->qaf_out[QAF_DEFAULT_PASSTHROUGH] = NULL;
qaf_mod->main_output_active = false;
pthread_mutex_unlock(&qaf_mod->lock);
return;
@@ -1501,7 +1703,15 @@
if (out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
qaf_destroy_offload_callback_thread(out);
}
- qaf_mod->stream_drain_main = NULL;
+
+ index = get_input_stream_index(out);
+ if (index < 0)
+ ALOGE("%s:: Invalid stream",__func__);
+ else
+ memset(&qaf_mod->adsp_hdlr_config[index], 0,
+ sizeof(struct qaf_adsp_hdlr_config_state));
+
+ qaf_mod->stream[index] = NULL;
lock_output_stream(out);
qaf_stream_close(out);
pthread_mutex_unlock(&out->lock);