diff --git a/frameworks/native/pulseaudio/modules/hdi/hdi_source.c b/frameworks/native/pulseaudio/modules/hdi/hdi_source.c index 6487824f972c55394ccc1ad6c9973a05daab2f00..63c1cd94413b862dd6fa8b957b27a18dc0e7d04c 100644 --- a/frameworks/native/pulseaudio/modules/hdi/hdi_source.c +++ b/frameworks/native/pulseaudio/modules/hdi/hdi_source.c @@ -65,7 +65,6 @@ #define AUDIO_FRAME_NUM_IN_BUF 30 #define HDI_WAKEUP_BUFFER_TIME (PA_USEC_PER_SEC * 2) #define DEVICE_TYPE_MIC 15 -#define BASE_TEN 10 const char *DEVICE_CLASS_REMOTE = "remote"; const int32_t SUCCESS = 0; diff --git a/frameworks/native/pulseaudio/modules/hdi/module_hdi_source.c b/frameworks/native/pulseaudio/modules/hdi/module_hdi_source.c index c4c50af387e39c1f141e10dd268bf91e8c50a3b5..2d198acaad759f7c5e21193d484fdc769d586d03 100644 --- a/frameworks/native/pulseaudio/modules/hdi/module_hdi_source.c +++ b/frameworks/native/pulseaudio/modules/hdi/module_hdi_source.c @@ -134,15 +134,8 @@ static void SetResampler(pa_source_output *so, const pa_sample_spec *algoConfig, } } -static pa_hook_result_t SourceOutputPutCb(pa_core *c, pa_source_output *so) +static pa_hook_result_t HandleSourceOutputPut(pa_source_output *so, struct Userdata *u) { - struct Userdata *u = (struct Userdata *)so->source->userdata; - if (u == NULL) { - AUDIO_ERR_LOG("Get Userdata failed! userdata is NULL"); - return PA_HOOK_OK; - } - AUDIO_INFO_LOG("Trigger SourceOutputPutCb"); - pa_assert(c); const char *sceneType = pa_proplist_gets(so->proplist, "scene.type"); uint32_t captureId = u->captureId; uint32_t renderId = u->renderId; @@ -175,15 +168,8 @@ static pa_hook_result_t SourceOutputPutCb(pa_core *c, pa_source_output *so) return PA_HOOK_OK; } -static pa_hook_result_t SourceOutputUnlinkCb(pa_core *c, pa_source_output *so) +static pa_hook_result_t HandleSourceOutputUnlink(pa_source_output *so, struct Userdata *u) { - AUDIO_INFO_LOG("Trigger SourceOutputUnlinkCb"); - struct Userdata *u = (struct Userdata *)so->source->userdata; - if (u == NULL) { - AUDIO_ERR_LOG("Get Userdata failed! userdata is NULL"); - return PA_HOOK_OK; - } - pa_assert(c); const char *sceneType = pa_proplist_gets(so->proplist, "scene.type"); uint32_t captureId = u->captureId; uint32_t renderId = u->renderId; @@ -207,6 +193,62 @@ static pa_hook_result_t SourceOutputUnlinkCb(pa_core *c, pa_source_output *so) return PA_HOOK_OK; } +static pa_hook_result_t CheckIfAvailSource(pa_source_output *so, struct Userdata *u) +{ + pa_source *soSource = so->source; + pa_source *thisSource = u->source; + if (soSource == NULL || thisSource == NULL) { + return PA_HOOK_CANCEL; + } + if (soSource->index != thisSource->index) { + AUDIO_INFO_LOG("NOT correspondant SOURCE %{public}s AND %{public}s.", soSource->name, thisSource->name); + return PA_HOOK_CANCEL; + } + return PA_HOOK_OK; +} + +static pa_hook_result_t SourceOutputPutCb(pa_core *c, pa_source_output *so, struct Userdata *u) +{ + AUDIO_INFO_LOG("Trigger SourceOutputPutCb"); + if (u == NULL) { + AUDIO_ERR_LOG("Get Userdata failed! userdata is NULL"); + return PA_HOOK_OK; + } + pa_assert(c); + if (CheckIfAvailSource(so, u) == PA_HOOK_CANCEL) { + return PA_HOOK_OK; + } + return HandleSourceOutputPut(so, u); +} + +static pa_hook_result_t SourceOutputUnlinkCb(pa_core *c, pa_source_output *so, struct Userdata *u) +{ + AUDIO_INFO_LOG("Trigger SourceOutputUnlinkCb"); + if (u == NULL) { + AUDIO_ERR_LOG("Get Userdata failed! userdata is NULL"); + return PA_HOOK_OK; + } + pa_assert(c); + if (CheckIfAvailSource(so, u) == PA_HOOK_CANCEL) { + return PA_HOOK_OK; + } + return HandleSourceOutputUnlink(so, u); +} + +static pa_hook_result_t SourceOutputMoveFinishCb(pa_core *c, pa_source_output *so, struct Userdata *u) +{ + AUDIO_INFO_LOG("Trigger SourceOutputMoveFinishCb"); + if (u == NULL) { + AUDIO_ERR_LOG("Get Userdata failed! userdata is NULL"); + return PA_HOOK_OK; + } + pa_assert(c); + if (CheckIfAvailSource(so, u) == PA_HOOK_CANCEL) { + return PA_HOOK_OK; + } + return HandleSourceOutputPut(so, u); +} + int pa__init(pa_module *m) { pa_modargs *ma = NULL; @@ -221,11 +263,14 @@ int pa__init(pa_module *m) if (!(m->userdata = PaHdiSourceNew(m, ma, __FILE__))) { goto fail; } + pa_source *source = (pa_source *)m->userdata; pa_module_hook_connect(m, &m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_PUT], PA_HOOK_LATE, - (pa_hook_cb_t)SourceOutputPutCb, NULL); + (pa_hook_cb_t)SourceOutputPutCb, source->userdata); pa_module_hook_connect(m, &m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_UNLINK], PA_HOOK_LATE, - (pa_hook_cb_t)SourceOutputUnlinkCb, NULL); + (pa_hook_cb_t)SourceOutputUnlinkCb, source->userdata); + pa_module_hook_connect(m, &m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_MOVE_FINISH], PA_HOOK_LATE, + (pa_hook_cb_t)SourceOutputMoveFinishCb, source->userdata); pa_modargs_free(ma); @@ -252,6 +297,19 @@ int pa__get_n_used(pa_module *m) return pa_source_linked_by(source); } +static void ReleaseAllChains(struct Userdata *u) +{ + void *state = NULL; + uint32_t *sceneKeyNum; + const void *sceneKey; + while ((sceneKeyNum = pa_hashmap_iterate(u->sceneToCountMap, &state, &sceneKey))) { + uint32_t sceneKeyCode = (uint32_t)strtoul((char *)sceneKey, NULL, BASE_TEN); + for (uint32_t count = 0; count < *sceneKeyNum; count++) { + EnhanceChainManagerReleaseCb(sceneKeyCode); + } + } +} + void pa__done(pa_module *m) { pa_source *source = NULL; @@ -259,6 +317,11 @@ void pa__done(pa_module *m) pa_assert(m); if ((source = m->userdata)) { + struct Userdata *u = (struct Userdata *)source->userdata; + if (u != NULL) { + AUDIO_INFO_LOG("Release all enhChains on [%{public}s]", source->name); + ReleaseAllChains(u); + } PaHdiSourceFree(source); } } diff --git a/frameworks/native/pulseaudio/modules/hdi/userdata.h b/frameworks/native/pulseaudio/modules/hdi/userdata.h index 161d0f6a6d5e6f78a4892c011d72d9425fdc16f0..49603711499f9f13d4c9fa5e71f667660502bd43 100644 --- a/frameworks/native/pulseaudio/modules/hdi/userdata.h +++ b/frameworks/native/pulseaudio/modules/hdi/userdata.h @@ -31,6 +31,7 @@ #define MAX_SCENE_NAME_LEN 100 #define SCENE_TYPE_OFFSET 16 #define CAPTURER_ID_OFFSET 8 +#define BASE_TEN 10 struct Userdata { pa_core *core;