Improve latency difference between reference and capture source 97/275797/12 submit/tizen/20220627.045454 submit/tizen/20220627.084702 submit/tizen/20220628.040455
authorJaechul Lee <jcsing.lee@samsung.com>
Thu, 2 Jun 2022 02:20:43 +0000 (11:20 +0900)
committerJaechul Lee <jcsing.lee@samsung.com>
Thu, 23 Jun 2022 07:59:03 +0000 (16:59 +0900)
 * Not allow negative latency
 * Added mchstreamer specific code
 * Fixed build warning on aarch64

[Version] 15.0.21
[Issue Type] Improvement

Change-Id: Idd6c4337ec6567e52dd86bbca5c194a897804b43
Signed-off-by: Jaechul Lee <jcsing.lee@samsung.com>
packaging/pulseaudio-modules-tizen.spec
src/echo-cancel/algo_reference_copy.c
src/echo-cancel/module-tizenaudio-echo-cancel.c
src/echo-cancel/processor.c
src/tizenaudio-sink2.c
src/tizenaudio-source2.c

index cd1cfef..1b6d631 100644 (file)
@@ -2,7 +2,7 @@
 
 Name:             pulseaudio-modules-tizen
 Summary:          Pulseaudio modules for Tizen
-Version:          15.0.20
+Version:          15.0.21
 Release:          0
 Group:            Multimedia/Audio
 License:          LGPL-2.1+
index 2d9cf0b..7b397ec 100644 (file)
@@ -94,13 +94,22 @@ int32_t reference_copy_change_reference_spec(void *priv, pa_sample_spec *source_
     pa_assert(map);
 
     channels = rc->ss.channels - source_ss->channels;
-    if (channels <= 0)
+    if (channels <= 0) {
+        pa_log_error("No empty channels. reference copy will be disabled");
         return -1;
+    }
+
+    /* TODO: temporary code for supporting mchstreamer. reference copy uses the last 2ch of its channels */
+    if (rc->ss.channels == 16)
+        channels = 2;
 
     *sample_spec = rc->ss;
     sample_spec->channels = rc->reference_channels = channels;
 
     pa_channel_map_init_auto(map, channels, PA_CHANNEL_MAP_AIFF);
 
+    pa_log_info("reference will be copied to empty channels(%d). source-output ch(%d), source ch(%d)",
+                    channels, rc->ss.channels, source_ss->channels);
+
     return 0;
 }
index f9e13c0..7697368 100644 (file)
@@ -298,7 +298,7 @@ static int process_msg(
 
     /* trigger resolves a race condition related to post_process between source and render thread */
     if (u->triggered) {
-        if (code == PA_ECHO_CANCEL_MESSAGE_PUSH_DATA || code == PA_ECHO_CANCEL_MESSAGE_PUSH_ECHO) {
+        if (code == PA_ECHO_CANCEL_MESSAGE_PUSH_ECHO) {
             pa_source_output *o = NULL;
             pa_usec_t latency;
 
index 0052ab8..dbce5fa 100644 (file)
@@ -43,6 +43,7 @@
 #endif
 
 #define MEMBLOCKQ_MAXLENGTH (16 * 1024 * 1024)
+#define MEMBLOCKQ_PUSH_REFERENCE_BLOCK_ALIGN
 
 typedef struct pa_processor_method_interface pa_processor_method_interface;
 struct pa_processor {
@@ -298,14 +299,24 @@ int pa_processor_setup_reference_memblockq_padding(pa_processor *processor, pa_u
     pa_assert(processor);
 
     bytes = pa_usec_to_bytes(latency, &processor->reference_memblockq_ss);
-    n = (bytes + (processor->reference_process_bytes - 1)) / processor->reference_process_bytes;
 
+#ifdef MEMBLOCKQ_PUSH_REFERENCE_BLOCK_ALIGN
+    n = (bytes + (processor->reference_process_bytes - 1)) / processor->reference_process_bytes;
     pa_silence_memchunk_get(
             &processor->core->silence_cache,
             processor->core->mempool,
             &silence,
             &processor->reference_memblockq_ss,
             processor->reference_process_bytes);
+#else
+    n = 1;
+    pa_silence_memchunk_get(
+            &processor->core->silence_cache,
+            processor->core->mempool,
+            &silence,
+            &processor->reference_memblockq_ss,
+            bytes);
+#endif
 
     write_index = pa_memblockq_get_write_index(processor->reference_memblockq);
     read_index = pa_memblockq_get_read_index(processor->reference_memblockq);
@@ -315,9 +326,10 @@ int pa_processor_setup_reference_memblockq_padding(pa_processor *processor, pa_u
 
     pa_memblock_unref(silence.memblock);
 
-    pa_log_info("push n(%u) silence blocks. ref_process_bytes(%zu) "
+    pa_log_info("push n(%u) silence blocks. latency(%" PRId64 "), ref_process_bytes(%zu) "
                 "write_index(%" PRId64 "->%" PRId64 "), read_index(%" PRId64 "->%" PRId64 ")",
                         pa_memblockq_get_nblocks(processor->reference_memblockq),
+                        latency,
                         processor->reference_process_bytes,
                         write_index, pa_memblockq_get_write_index(processor->reference_memblockq),
                         read_index, pa_memblockq_get_read_index(processor->reference_memblockq));
index ff0dbc7..f8601ac 100644 (file)
@@ -169,7 +169,6 @@ static int unsuspend(struct userdata *u) {
 
     u->write_count = 0;
     u->first = true;
-    u->timestamp = pa_rtclock_now();
 
     pa_log_info("Resumed successfully...");
 
@@ -245,8 +244,13 @@ static int sink_process_msg(
         case PA_SINK_MESSAGE_GET_LATENCY: {
             int64_t r = 0;
 
-            if (u->pcm_handle)
-                r = u->timestamp + pa_bytes_to_usec(u->write_count, &u->sink->sample_spec) - pa_rtclock_now();
+            if (u->pcm_handle) {
+                pa_usec_t now = pa_rtclock_now();
+                pa_usec_t write_latency = u->timestamp + pa_bytes_to_usec(u->write_count, &u->sink->sample_spec);
+
+                if (now < write_latency)
+                    r = write_latency - now;
+            }
 
             *((int64_t *) data) = r;
 
@@ -297,6 +301,9 @@ static int process_render(struct userdata *u) {
     pa_sink_render_full(u->sink, u->frag_size, &chunk);
     p = pa_memblock_acquire(chunk.memblock);
 
+    if (u->first)
+        u->timestamp = pa_rtclock_now();
+
     if (pa_hal_interface_pcm_write(u->hal_interface, u->pcm_handle, (const char*)p + chunk.index, (uint32_t)frames_to_write)) {
         pa_log_error("failed to write pcm. p(%p), size(%zu)", p, frames_to_write);
         return -1;
index 846b086..948e8f0 100644 (file)
@@ -248,8 +248,13 @@ static int source_process_msg(
         case PA_SOURCE_MESSAGE_GET_LATENCY: {
             uint64_t r = 0;
 
-            if (u->pcm_handle)
-                r = pa_rtclock_now() - (u->timestamp + pa_bytes_to_usec(u->read_count, &u->source->sample_spec));
+            if (u->pcm_handle) {
+                pa_usec_t now = pa_rtclock_now();
+                pa_usec_t read_latency = u->timestamp + pa_bytes_to_usec(u->read_count, &u->source->sample_spec);
+
+                if (now > read_latency)
+                    r = now - read_latency;
+            }
 
             *((int64_t *) data) = r;