From 46e079872cf1293539babdbb6bb0ec093fe637b3 Mon Sep 17 00:00:00 2001 From: Manish Dewangan Date: Thu, 13 Dec 2018 18:18:59 +0530 Subject: [PATCH] hal: Add API support to stop input stream Add API support to stop input stream. Expose in_stop in HAL via QAHW so that clients may call it when necessary. Change-Id: I5b1112166453371ab4d79c31fa99fb1f6b3bff3f --- hal/audio_extn/audio_extn.c | 11 +++++++--- hal/audio_extn/audio_extn.h | 3 ++- hal/audio_extn/compress_in.c | 17 ++++++++++++--- hal/audio_hw.c | 6 +++--- hal/audio_hw_extn_api.c | 21 ++++++++++++++++++ qahw/inc/qahw.h | 4 ++++ qahw/src/qahw.c | 42 ++++++++++++++++++++++++++++++++++-- qahw_api/inc/qahw_api.h | 4 ++++ qahw_api/src/qahw_api.cpp | 21 ++++++++++++++++++ 9 files changed, 117 insertions(+), 12 deletions(-) diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c index f47cf700..2b803027 100644 --- a/hal/audio_extn/audio_extn.c +++ b/hal/audio_extn/audio_extn.c @@ -98,9 +98,10 @@ bool cin_applicable_stream(struct stream_in *in); bool cin_attached_usecase(audio_usecase_t uc_id); bool cin_format_supported(audio_format_t format); size_t cin_get_buffer_size(struct stream_in *in); -int cin_start_input_stream(struct stream_in *in); +int cin_open_input_stream(struct stream_in *in); void cin_stop_input_stream(struct stream_in *in); void cin_close_input_stream(struct stream_in *in); +void cin_free_input_stream_resources(struct stream_in *in); int cin_read(struct stream_in *in, void *buffer, size_t bytes, size_t *bytes_read); int cin_configure_input_stream(struct stream_in *in); @@ -5063,9 +5064,9 @@ size_t audio_extn_cin_get_buffer_size(struct stream_in *in) { return (audio_extn_compress_in_enabled? cin_get_buffer_size(in): 0); } -int audio_extn_cin_start_input_stream(struct stream_in *in) +int audio_extn_cin_open_input_stream(struct stream_in *in) { - return (audio_extn_compress_in_enabled? cin_start_input_stream(in): -1); + return (audio_extn_compress_in_enabled? cin_open_input_stream(in): -1); } void audio_extn_cin_stop_input_stream(struct stream_in *in) { @@ -5075,6 +5076,10 @@ void audio_extn_cin_close_input_stream(struct stream_in *in) { (audio_extn_compress_in_enabled? cin_close_input_stream(in): NULL); } +void audio_extn_cin_free_input_stream_resources(struct stream_in *in) +{ + return (audio_extn_compress_in_enabled? cin_free_input_stream_resources(in): NULL); +} int audio_extn_cin_read(struct stream_in *in, void *buffer, size_t bytes, size_t *bytes_read) { diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h index b7942aec..a4937631 100644 --- a/hal/audio_extn/audio_extn.h +++ b/hal/audio_extn/audio_extn.h @@ -1011,9 +1011,10 @@ bool audio_extn_cin_applicable_stream(struct stream_in *in); bool audio_extn_cin_attached_usecase(audio_usecase_t uc_id); bool audio_extn_cin_format_supported(audio_format_t format); size_t audio_extn_cin_get_buffer_size(struct stream_in *in); -int audio_extn_cin_start_input_stream(struct stream_in *in); +int audio_extn_cin_open_input_stream(struct stream_in *in); void audio_extn_cin_stop_input_stream(struct stream_in *in); void audio_extn_cin_close_input_stream(struct stream_in *in); +void audio_extn_cin_free_input_stream_resources(struct stream_in *in); int audio_extn_cin_read(struct stream_in *in, void *buffer, size_t bytes, size_t *bytes_read); int audio_extn_cin_configure_input_stream(struct stream_in *in); diff --git a/hal/audio_extn/compress_in.c b/hal/audio_extn/compress_in.c index 6cf6b814..fd47b8ba 100644 --- a/hal/audio_extn/compress_in.c +++ b/hal/audio_extn/compress_in.c @@ -179,7 +179,7 @@ size_t cin_get_buffer_size(struct stream_in *in) return sz; } -int cin_start_input_stream(struct stream_in *in) +int cin_open_input_stream(struct stream_in *in) { int ret = -EINVAL; struct audio_device *adev = in->dev; @@ -206,6 +206,17 @@ void cin_stop_input_stream(struct stream_in *in) { cin_private_data_t *cin_data = (cin_private_data_t *) in->cin_extn; + ALOGV("%s: in %p, cin_data %p", __func__, in, cin_data); + if (cin_data->compr) { + compress_stop(cin_data->compr); + } +} + + +void cin_close_input_stream(struct stream_in *in) +{ + cin_private_data_t *cin_data = (cin_private_data_t *) in->cin_extn; + ALOGV("%s: in %p, cin_data %p", __func__, in, cin_data); if (cin_data->compr) { compress_close(cin_data->compr); @@ -213,7 +224,7 @@ void cin_stop_input_stream(struct stream_in *in) } } -void cin_close_input_stream(struct stream_in *in) +void cin_free_input_stream_resources(struct stream_in *in) { cin_private_data_t *cin_data = (cin_private_data_t *) in->cin_extn; @@ -332,6 +343,6 @@ int cin_configure_input_stream(struct stream_in *in) return ret; err_config: - cin_close_input_stream(in); + cin_free_input_stream_resources(in); return ret; } diff --git a/hal/audio_hw.c b/hal/audio_hw.c index 739a0bfb..76562925 100644 --- a/hal/audio_hw.c +++ b/hal/audio_hw.c @@ -2910,7 +2910,7 @@ int start_input_stream(struct stream_in *in) ALOGE("%s: failed to start ext hw plugin", __func__); if (audio_extn_cin_attached_usecase(in->usecase)) { - ret = audio_extn_cin_start_input_stream(in); + ret = audio_extn_cin_open_input_stream(in); if (ret) goto error_open; else @@ -6228,7 +6228,7 @@ static int in_standby(struct audio_stream *stream) in->capture_started = false; } else { if (audio_extn_cin_attached_usecase(in->usecase)) - audio_extn_cin_stop_input_stream(in); + audio_extn_cin_close_input_stream(in); } if (in->pcm) { @@ -9007,7 +9007,7 @@ static void adev_close_input_stream(struct audio_hw_device *dev, audio_extn_compr_cap_deinit(); if (audio_extn_cin_attached_usecase(in->usecase)) - audio_extn_cin_close_input_stream(in); + audio_extn_cin_free_input_stream_resources(in); if (in->is_st_session) { ALOGV("%s: sound trigger pcm stop lab", __func__); diff --git a/hal/audio_hw_extn_api.c b/hal/audio_hw_extn_api.c index af733752..fa3a8184 100644 --- a/hal/audio_hw_extn_api.c +++ b/hal/audio_hw_extn_api.c @@ -190,6 +190,27 @@ int qahwi_set_param_data(struct audio_hw_device *adev, return ret; } +int qahwi_in_stop(struct audio_stream_in* stream) { + struct stream_in *in = (struct stream_in *)stream; + struct audio_device *adev = in->dev; + + ALOGD("%s processing, in %p", __func__, in); + + pthread_mutex_lock(&adev->lock); + + if (!in->standby) { + if (in->pcm != NULL ) { + pcm_stop(in->pcm); + } else if (audio_extn_cin_format_supported(in->format)) { + audio_extn_cin_stop_input_stream(in); + } + } + + pthread_mutex_unlock(&adev->lock); + + return 0; +} + ssize_t qahwi_in_read_v2(struct audio_stream_in *stream, void* buffer, size_t bytes, uint64_t *timestamp) { diff --git a/qahw/inc/qahw.h b/qahw/inc/qahw.h index dd5b403f..5020c8f2 100644 --- a/qahw/inc/qahw.h +++ b/qahw/inc/qahw.h @@ -357,6 +357,10 @@ char* qahw_in_get_parameters_l(const qahw_stream_handle_t *in_handle, */ ssize_t qahw_in_read_l(qahw_stream_handle_t *in_handle, qahw_in_buffer_t *in_buf); +/* + * Stop input stream. Returns zero on success. + */ +int qahw_in_stop_l(qahw_stream_handle_t *in_handle); /* * Return the amount of input frames lost in the audio driver since the * last call of this function. diff --git a/qahw/src/qahw.c b/qahw/src/qahw.c index 3390c269..545152c1 100644 --- a/qahw/src/qahw.c +++ b/qahw/src/qahw.c @@ -61,6 +61,8 @@ typedef int (*qahwi_set_param_data_t) (audio_hw_device_t *, typedef uint64_t (*qahwi_in_read_v2_t)(audio_stream_in_t *in, void* buffer, size_t bytes, int64_t *timestamp); +typedef int (*qahwi_in_stop_t)(audio_stream_in_t *in); + typedef int (*qahwi_out_set_param_data_t)(struct audio_stream_out *out, qahw_param_id param_id, qahw_param_payload *payload); @@ -109,6 +111,7 @@ typedef struct { struct listnode list; pthread_mutex_t lock; qahwi_in_read_v2_t qahwi_in_read_v2; + qahwi_in_stop_t qahwi_in_stop; } qahw_stream_in_t; typedef enum { @@ -1034,6 +1037,31 @@ exit: return rc; } +/* + * Stop input stream. Returns zero on success. + */ +int qahw_in_stop_l(qahw_stream_handle_t *in_handle) +{ + int rc = -EINVAL; + qahw_stream_in_t *qahw_stream_in = (qahw_stream_in_t *)in_handle; + audio_stream_in_t *in = NULL; + + if (!is_valid_qahw_stream_l((void *)qahw_stream_in, STREAM_DIR_IN)) { + ALOGV("%s::Invalid in handle %p", __func__, in_handle); + goto exit; + } + ALOGD("%s", __func__); + + in = qahw_stream_in->stream; + + if (qahw_stream_in->qahwi_in_stop) + rc = qahw_stream_in->qahwi_in_stop(in); + ALOGD("%s: exit", __func__); + +exit: + return rc; +} + /* * Return the amount of input frames lost in the audio driver since the * last call of this function. @@ -1718,6 +1746,7 @@ int qahw_open_input_stream_l(qahw_module_handle_t *hw_module, qahw_module_t *qahw_module_temp = NULL; audio_hw_device_t *audio_device = NULL; qahw_stream_in_t *qahw_stream_in = NULL; + const char *error; pthread_mutex_lock(&qahw_module_init_lock); qahw_module_temp = get_qahw_module_by_ptr_l(qahw_module); @@ -1747,6 +1776,7 @@ int qahw_open_input_stream_l(qahw_module_handle_t *hw_module, if (rc) { ALOGE("%s::open input stream failed %d",__func__, rc); free(qahw_stream_in); + goto exit; } else { qahw_stream_in->module = hw_module; *in_handle = (void *)qahw_stream_in; @@ -1757,7 +1787,6 @@ int qahw_open_input_stream_l(qahw_module_handle_t *hw_module, /* dlsym qahwi_in_read_v2 if timestamp flag is used */ if (!rc && ((flags & QAHW_INPUT_FLAG_TIMESTAMP) || (flags & QAHW_INPUT_FLAG_PASSTHROUGH))) { - const char *error; /* clear any existing errors */ dlerror(); @@ -1769,7 +1798,16 @@ int qahw_open_input_stream_l(qahw_module_handle_t *hw_module, } } -exit: + /* clear any existing errors */ + dlerror(); + qahw_stream_in->qahwi_in_stop = (qahwi_in_stop_t) + dlsym(qahw_module->module->dso, "qahwi_in_stop"); + if ((error = dlerror()) != NULL) { + ALOGI("%s: dlsym error %s for qahwi_in_stop", __func__, error); + qahw_stream_in->qahwi_in_stop = NULL; + } + + exit: pthread_mutex_unlock(&qahw_module->lock); return rc; } diff --git a/qahw_api/inc/qahw_api.h b/qahw_api/inc/qahw_api.h index 823c6bb2..b37757d1 100644 --- a/qahw_api/inc/qahw_api.h +++ b/qahw_api/inc/qahw_api.h @@ -353,6 +353,10 @@ char* qahw_in_get_parameters(const qahw_stream_handle_t *in_handle, */ ssize_t qahw_in_read(qahw_stream_handle_t *in_handle, qahw_in_buffer_t *in_buf); +/* + * Stop input stream. Returns zero on success. + */ +int qahw_in_stop(qahw_stream_handle_t *in_handle); /* * Return the amount of input frames lost in the audio driver since the * last call of this function. diff --git a/qahw_api/src/qahw_api.cpp b/qahw_api/src/qahw_api.cpp index f1c75f45..0810ede3 100644 --- a/qahw_api/src/qahw_api.cpp +++ b/qahw_api/src/qahw_api.cpp @@ -678,6 +678,22 @@ ssize_t qahw_in_read(qahw_stream_handle_t *in_handle, } } +int qahw_in_stop(qahw_stream_handle_t *in_handle) +{ + if (g_binder_enabled) { + if (!g_qas_died) { + sp qas = get_qti_audio_server(); + if (qas_status(qas) == -1) + return -ENODEV; + return qas->qahw_in_stop(in_handle); + } else { + return -ENODEV; + } + } else { + return qahw_in_stop_l(in_handle); + } +} + uint32_t qahw_in_get_input_frames_lost(qahw_stream_handle_t *in_handle) { ALOGV("%d:%s",__LINE__, __func__); @@ -1544,6 +1560,11 @@ ssize_t qahw_in_read(qahw_stream_handle_t *in_handle, return qahw_in_read_l(in_handle, in_buf); } +int qahw_in_stop(qahw_stream_handle_t *in_handle) +{ + return qahw_in_stop_l(in_handle); +} + uint32_t qahw_in_get_input_frames_lost(qahw_stream_handle_t *in_handle) { ALOGV("%d:%s",__LINE__, __func__);