preprocessor: Add bypass functionality 63/301663/4 accepted/tizen/unified/20231122.172550 accepted/tizen/unified/riscv/20231215.050530
authorJaechul Lee <jcsing.lee@samsung.com>
Tue, 21 Nov 2023 07:48:30 +0000 (16:48 +0900)
committerJaechul Lee <jcsing.lee@samsung.com>
Wed, 22 Nov 2023 01:00:50 +0000 (10:00 +0900)
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 <jcsing.lee@samsung.com>
packaging/pulseaudio-modules-tizen.spec
src/module-tizenaudio-sink.c
src/preprocessor/module-tizenaudio-preprocessor.c
src/preprocessor/processor-def.h
src/preprocessor/processor.c
src/preprocessor/processor_holder.c
src/preprocessor/processor_reference.c
src/preprocessor/processor_reference.h
src/tizenaudio-sink2.c

index 8d6e842..8736ad1 100644 (file)
@@ -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+
index 010f64f..e91aafd 100644 (file)
@@ -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;
             }
 
index 5b64cfb..f8527a0 100644 (file)
@@ -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;
 
index bf24164..2234c7d 100644 (file)
@@ -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,
 };
index 889801f..4441f54 100644 (file)
@@ -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) {
index 31f4a7d..177e9bd 100644 (file)
@@ -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;
             }
 
index b41ca99..a4fc660 100644 (file)
@@ -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;
 
index cacd5f5..b126aa9 100644 (file)
@@ -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);
index 9b03df7..73a91fd 100644 (file)
@@ -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;
             }