From: Jaechul Lee Date: Tue, 21 Nov 2023 07:48:30 +0000 (+0900) Subject: preprocessor: Add bypass functionality X-Git-Tag: accepted/tizen/unified/20231122.172550^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=275386f6b50323eaa4855d13a33dd040cbf2f0fb;p=platform%2Fcore%2Fmultimedia%2Fpulseaudio-modules-tizen.git preprocessor: Add bypass functionality A source-output is stuck when the sink doesn't feed reference data enough. So, bypass mode was added in case there wasn't sink-inputs. [Version] 15.0.69 [Issue Type] Update Change-Id: I1e2a58723d6f2facada2d578bb35c51c9821eb40 Signed-off-by: Jaechul Lee --- diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index 8d6e842..8736ad1 100644 --- a/packaging/pulseaudio-modules-tizen.spec +++ b/packaging/pulseaudio-modules-tizen.spec @@ -2,7 +2,7 @@ Name: pulseaudio-modules-tizen Summary: Pulseaudio modules for Tizen -Version: 15.0.68 +Version: 15.0.69 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/module-tizenaudio-sink.c b/src/module-tizenaudio-sink.c index 010f64f..e91aafd 100644 --- a/src/module-tizenaudio-sink.c +++ b/src/module-tizenaudio-sink.c @@ -349,7 +349,11 @@ static int sink_process_msg( u->preprocess_on = true; pa_asyncmsgq_post(u->preprocessor_asyncmsgq, u->preprocessor, PA_SOURCE_MESSAGE_PREPROCESSOR_RESET_REFERENCE, (void *)true, 0, NULL, NULL); + pa_asyncmsgq_post(u->preprocessor_asyncmsgq, u->preprocessor, + PA_SOURCE_MESSAGE_PREPROCESSOR_REFERENCE_BYPASS, u->holder, (int64_t)false, NULL, NULL); } else { + pa_asyncmsgq_post(u->preprocessor_asyncmsgq, u->preprocessor, + PA_SOURCE_MESSAGE_PREPROCESSOR_REFERENCE_BYPASS, u->holder, (int64_t)true, NULL, NULL); u->preprocess_on = false; } diff --git a/src/preprocessor/module-tizenaudio-preprocessor.c b/src/preprocessor/module-tizenaudio-preprocessor.c index 5b64cfb..f8527a0 100644 --- a/src/preprocessor/module-tizenaudio-preprocessor.c +++ b/src/preprocessor/module-tizenaudio-preprocessor.c @@ -511,7 +511,7 @@ static int process_msg( if (u->reset_lazy_reference) { pa_processor_reference_reset(reference); pa_processor_reference_add_latency_padding(reference, get_round_trip_latency(source, sink)); - + pa_processor_reference_set_bypass(reference, false); u->reset_lazy_reference = false; } @@ -528,6 +528,21 @@ static int process_msg( u->reset_lazy_reference = true; break; + case PA_SOURCE_MESSAGE_PREPROCESSOR_REFERENCE_BYPASS: { + pa_processor_holder *holder = (pa_processor_holder *)data; + pa_processor_reference *reference = NULL; + bool bypass = !!offset; + + reference = pa_processor_holder_get_connected_processor_reference(holder); + if (!holder || !reference) { + pa_log_error("holder(%p), reference(%p) aren't set", holder, reference); + break; + } + + pa_processor_reference_set_bypass(reference, bypass); + + break; + } case PA_SOURCE_MESSAGE_PREPROCESSOR_DESTROY: { pa_source_output *output; diff --git a/src/preprocessor/processor-def.h b/src/preprocessor/processor-def.h index bf24164..2234c7d 100644 --- a/src/preprocessor/processor-def.h +++ b/src/preprocessor/processor-def.h @@ -41,6 +41,7 @@ enum { PA_SOURCE_MESSAGE_PREPROCESSOR_PUSH_DATA, PA_SOURCE_MESSAGE_PREPROCESSOR_PUSH_REFERENCE, PA_SOURCE_MESSAGE_PREPROCESSOR_RESET_REFERENCE, + PA_SOURCE_MESSAGE_PREPROCESSOR_REFERENCE_BYPASS, PA_SOURCE_MESSAGE_PREPROCESSOR_DESTROY, PA_SOURCE_MESSAGE_PREPROCESSOR_TERMINATE, }; diff --git a/src/preprocessor/processor.c b/src/preprocessor/processor.c index 889801f..4441f54 100644 --- a/src/preprocessor/processor.c +++ b/src/preprocessor/processor.c @@ -251,7 +251,6 @@ pa_usec_t pa_processor_get_process_usec(pa_processor *p) { /* Do not touch chunk value */ int pa_processor_process(pa_processor *processor, pa_memchunk *chunk) { - int r = -1; int8_t *recording = NULL; int8_t *reference = NULL; int8_t *output = NULL; @@ -264,8 +263,17 @@ int pa_processor_process(pa_processor *processor, pa_memchunk *chunk) { pa_assert(chunk); if (processor->reference) { - if ((r = pa_processor_reference_pull(processor->reference, &rchunk)) < 0) { - pa_log_warn("Failed to get memblock from reference memblockq. ret(%d)", r); + if (pa_processor_reference_get_bypass(processor->reference)) { + if (pa_memblockq_push(processor->result_memblockq, chunk) < 0) + pa_log_error("Bypass failed to push out chunk to result memblockq"); + + pa_log_debug("Bypass method(%d:%s). because reference sink isn't working now", + processor->method, pa_processor_method_str(processor->method)); + return 0; + } + + if (pa_processor_reference_pull(processor->reference, &rchunk) < 0) { + pa_log_debug("Underrun the reference memblock during a fall duplex situation. Buffering more reference memblocks."); return -PROCESSOR_ERR_BUFFERING; } @@ -281,8 +289,7 @@ int pa_processor_process(pa_processor *processor, pa_memchunk *chunk) { debug_timestamp_begin(processor); - r = audio_effect_process_reference(processor->audio_effect, recording, reference, output); - if (r < 0) { + if (audio_effect_process_reference(processor->audio_effect, recording, reference, output) < 0) { pa_log_warn("Failed to process memchunk"); goto fail; } @@ -324,7 +331,7 @@ int pa_processor_process(pa_processor *processor, pa_memchunk *chunk) { /* The memchunk in the result memblockq's refcount must be one */ pa_memblock_unref(ochunk.memblock); - return r; + return 0; fail: pa_memblock_release(chunk->memblock); @@ -337,7 +344,7 @@ fail: pa_memblock_unref(ochunk.memblock); - return r; + return -1; } pa_memblockq *pa_processor_get_result_memblockq(pa_processor *processor) { diff --git a/src/preprocessor/processor_holder.c b/src/preprocessor/processor_holder.c index 31f4a7d..177e9bd 100644 --- a/src/preprocessor/processor_holder.c +++ b/src/preprocessor/processor_holder.c @@ -34,7 +34,7 @@ #include "processor_holder.h" #define MEMBLOCKQ_MAXLENGTH (16*1024*1024) -#define DEFAULT_PREBUFFER_MSEC (300) +#define DEFAULT_PREBUFFER_MSEC (50) pa_processor_holder *pa_processor_holder_new(pa_core *core, pa_sample_spec *ss) { pa_processor_holder *holder; @@ -175,7 +175,11 @@ int pa_processor_holder_pump(pa_processor_holder *holder) { if ((ret = pa_processor_process(p, &chunk)) < 0) { pa_memblock_unref(chunk.memblock); pa_memblockq_drop(pull_queue, chunk.length); - pa_log_error("Failed to process"); + if (ret == -PROCESSOR_ERR_BUFFERING) + pa_log_debug("Buffering reference memblocks."); + else + pa_log_warn("Failed to process memblock. ret(%d)", ret); + return ret; } diff --git a/src/preprocessor/processor_reference.c b/src/preprocessor/processor_reference.c index b41ca99..a4fc660 100644 --- a/src/preprocessor/processor_reference.c +++ b/src/preprocessor/processor_reference.c @@ -38,6 +38,7 @@ typedef struct pa_processor_reference { pa_usec_t process_usec; size_t process_bytes; pa_sample_spec ss; + bool bypass; /* only for pull mode (audio-share) */ void *priv; @@ -106,6 +107,7 @@ pa_processor_reference *pa_processor_reference_new(pa_core *core, reference->ss = *request_ss; reference->process_bytes = pa_usec_to_bytes(reference->process_usec, &reference->ss); reference->sink = sink; + reference->bypass = true; pa_silence_memchunk_get(&core->silence_cache, core->mempool, &silence, request_ss, 0); reference->memblockq = pa_memblockq_new("reference memblockq", @@ -240,12 +242,10 @@ int pa_processor_reference_pull(pa_processor_reference *reference, pa_memchunk * exit: memblock_length = pa_memblockq_get_length(reference->memblockq); - if (memblock_length < length) { - pa_log_info("reference memblockq has less memblocks. memblock_length(%zu), length(%zu)", - memblock_length, length); + /* Needs to gather more reference memblocks */ + if (memblock_length < length) return -1; - } if ((r = pa_memblockq_peek_fixed_size(reference->memblockq, length, chunk)) < 0) { pa_log_error("Failed to get memblock from reference memblockq"); @@ -316,6 +316,25 @@ size_t pa_processor_reference_process_usec_to_bytes(pa_processor_reference *refe } +void pa_processor_reference_set_bypass(pa_processor_reference *reference, bool bypass) { + pa_assert(reference); + + if (reference->bypass == bypass) + return; + + reference->bypass = bypass; + + pa_log_info("set reference bypass(%d)", reference->bypass); +} + +bool pa_processor_reference_get_bypass(pa_processor_reference *reference) { + pa_assert(reference); + + pa_log_debug("get reference bypass(%d)", reference->bypass); + + return reference->bypass; +} + char *pa_processor_reference_dump_index(pa_processor_reference *reference) { int64_t windex, rindex; diff --git a/src/preprocessor/processor_reference.h b/src/preprocessor/processor_reference.h index cacd5f5..b126aa9 100644 --- a/src/preprocessor/processor_reference.h +++ b/src/preprocessor/processor_reference.h @@ -55,6 +55,8 @@ unsigned pa_processor_reference_get_nblocks(pa_processor_reference *reference); pa_usec_t pa_processor_reference_chunk_to_usec(pa_processor_reference *reference, pa_memchunk *chunk); size_t pa_processor_reference_process_usec_to_bytes(pa_processor_reference *reference); char *pa_processor_reference_dump_index(pa_processor_reference *reference); +void pa_processor_reference_set_bypass(pa_processor_reference *reference, bool bypass); +bool pa_processor_reference_get_bypass(pa_processor_reference *reference); pa_sink *pa_processor_reference_get_sink(pa_processor_reference *reference); pa_processor_reference_method_t pa_processor_reference_method_enum(const char *method); diff --git a/src/tizenaudio-sink2.c b/src/tizenaudio-sink2.c index 9b03df7..73a91fd 100644 --- a/src/tizenaudio-sink2.c +++ b/src/tizenaudio-sink2.c @@ -322,7 +322,11 @@ static int sink_process_msg( u->preprocess_on = true; pa_asyncmsgq_post(u->preprocessor_asyncmsgq, u->preprocessor, PA_SOURCE_MESSAGE_PREPROCESSOR_RESET_REFERENCE, (void *)true, 0, NULL, NULL); + pa_asyncmsgq_post(u->preprocessor_asyncmsgq, u->preprocessor, + PA_SOURCE_MESSAGE_PREPROCESSOR_REFERENCE_BYPASS, u->holder, (int64_t)false, NULL, NULL); } else { + pa_asyncmsgq_post(u->preprocessor_asyncmsgq, u->preprocessor, + PA_SOURCE_MESSAGE_PREPROCESSOR_REFERENCE_BYPASS, u->holder, (int64_t)true, NULL, NULL); u->preprocess_on = false; }