tizenaudio-source2: Use hardware interrupt for capture 54/262354/2
authorJaechul Lee <jcsing.lee@samsung.com>
Mon, 9 Aug 2021 03:41:48 +0000 (12:41 +0900)
committerJaechul Lee <jcsing.lee@samsung.com>
Mon, 9 Aug 2021 06:21:43 +0000 (15:21 +0900)
* Remove unused arguments
* Use fixed latency
* Use poll event

[Version] 13.0.70
[Issue Type] Improvement

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

index 6f220f20e0fdd694f426696554eeaba97047dfd0..9935f2822379824e637be25bdda6a0a97b0523e8 100644 (file)
@@ -1,6 +1,6 @@
 Name:             pulseaudio-modules-tizen
 Summary:          Pulseaudio modules for Tizen
-Version:          13.0.69
+Version:          13.0.70
 Release:          0
 Group:            Multimedia/Audio
 License:          LGPL-2.1+
index 790e2b2ddbcf9b28bab2f3ddf3e61330d4b46349..333bdbb3adc8e3ad6ede01c25b19c10cb52c2ce8 100644 (file)
@@ -63,10 +63,7 @@ PA_MODULE_USAGE(
         "fragment_size=<fragment size> ");
 
 
-#define DEFAULT_SOURCE_NAME "tizenaudio-source"
-
-/* BLOCK_USEC should be less than amount of fragment_size * fragments */
-#define BLOCK_USEC (PA_USEC_PER_SEC * 0.032)
+#define DEFAULT_SOURCE_NAME "tizenaudio-source2"
 
 #define DEVICE_NAME_MAX                     30
 
@@ -83,7 +80,6 @@ struct userdata {
     uint32_t nfrags;
     uint32_t frag_size;
 
-    pa_usec_t block_usec;
     pa_usec_t timestamp;
 
     char* card;
@@ -130,7 +126,7 @@ static int build_pollfd(struct userdata *u) {
         return -1;
     }
     pollfd->fd = fd;
-    pollfd->events = /* POLLIN | */ POLLERR | POLLNVAL;
+    pollfd->events = POLLIN | POLLERR | POLLNVAL;
 
     return 0;
 }
@@ -193,6 +189,7 @@ static int unsuspend(struct userdata *u) {
 
     u->read_count = 0;
     u->first = true;
+    u->timestamp = pa_rtclock_now();
 
     pa_log_info("Resumed successfully...");
 
@@ -261,8 +258,13 @@ static int source_process_msg(
 
     switch (code) {
         case PA_SOURCE_MESSAGE_GET_LATENCY: {
-            pa_usec_t now = pa_rtclock_now();
-            *((pa_usec_t*)data) = u->timestamp > now ? 0ULL : now - u->timestamp;
+            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));
+
+            *((int64_t *) data) = r;
+
             return 0;
         }
     }
@@ -270,72 +272,41 @@ static int source_process_msg(
     return pa_source_process_msg(o, code, data, offset, chunk);
 }
 
-static void source_update_requested_latency_cb(pa_source *s) {
-    struct userdata *u;
-    size_t nbytes;
-
-    pa_source_assert_ref(s);
-    pa_assert_se((u = s->userdata));
-
-    u->block_usec = pa_source_get_requested_latency_within_thread(s);
-
-    if (u->block_usec == (pa_usec_t)-1)
-        u->block_usec = s->thread_info.max_latency;
-
-    nbytes = pa_usec_to_bytes(u->block_usec, &s->sample_spec);
-    pa_source_set_max_rewind_within_thread(s, nbytes);
-}
-
-static int process_render(struct userdata *u, pa_usec_t now) {
-    int work_done = 0;
-    size_t ate = 0;
+static int process_render(struct userdata *u) {
     void *p;
-    size_t frames_to_read, frame_size;
+    size_t frame_size = pa_frame_size(&u->source->sample_spec);
+    size_t frames_to_read = u->frag_size / u->nfrags;
     uint32_t avail = 0;
+    pa_memchunk chunk;
 
     pa_assert(u);
 
     /* Fill the buffer up the latency size */
-    while (u->timestamp < now + u->block_usec) {
-        pa_memchunk chunk;
-        frame_size = pa_frame_size(&u->source->sample_spec);
-        if (frame_size == 0) {
-            pa_log_error("Unexpected frame size zero!");
-            break;
-        }
-
-        pa_hal_interface_pcm_available(u->hal_interface, u->pcm_handle, &avail);
-        if (avail == 0) {
-            break;
-        }
-
-        frames_to_read = (u->frag_size / u->nfrags);
-        chunk.length = frames_to_read * frame_size;
-        chunk.memblock = pa_memblock_new(u->core->mempool, chunk.length);
-
-        if (frames_to_read > (size_t)avail)
-            frames_to_read = (size_t)avail;
 
-        p = pa_memblock_acquire(chunk.memblock);
-        pa_hal_interface_pcm_read(u->hal_interface, u->pcm_handle, p, (uint32_t)frames_to_read);
-        pa_memblock_release(chunk.memblock);
+    pa_hal_interface_pcm_available(u->hal_interface, u->pcm_handle, &avail);
+    if (frames_to_read > avail) {
+        pa_log_debug("not enough avail size. frames_to_read(%d), avail(%d)", frames_to_read, avail);
+        return 0;
+    }
 
-        chunk.index = 0;
-        chunk.length = (size_t)frames_to_read * frame_size;
-        pa_source_post(u->source, &chunk);
-        pa_memblock_unref(chunk.memblock);
+    chunk.length = frames_to_read * frame_size;
+    chunk.memblock = pa_memblock_new(u->core->mempool, chunk.length);
 
-        u->timestamp += pa_bytes_to_usec(chunk.length, &u->source->sample_spec);
+    p = pa_memblock_acquire(chunk.memblock);
+    if (pa_hal_interface_pcm_read(u->hal_interface, u->pcm_handle, p, (uint32_t)frames_to_read)) {
+        pa_log_error("failed to read pcm. p(%p), size(%d)", p, frames_to_read);
+        return -1;
+    }
+    pa_memblock_release(chunk.memblock);
 
-        work_done = 1;
+    chunk.index = 0;
+    chunk.length = (size_t)frames_to_read * frame_size;
+    pa_source_post(u->source, &chunk);
+    pa_memblock_unref(chunk.memblock);
 
-        ate += chunk.length;
-        if (ate >= pa_usec_to_bytes(u->block_usec, &u->source->sample_spec)) {
-            break;
-        }
-    }
+    u->read_count += chunk.length;
 
-    return work_done;
+    return 0;
 }
 
 static void thread_func(void *userdata) {
@@ -350,36 +321,21 @@ static void thread_func(void *userdata) {
 
     pa_thread_mq_install(&u->thread_mq);
 
+    u->timestamp = pa_rtclock_now();
+
     for (;;) {
-        pa_usec_t now = 0;
         int ret;
 
-        if (PA_SOURCE_IS_OPENED(u->source->thread_info.state))
-            now = pa_rtclock_now();
-
         /* Render some data and drop it immediately */
         if (PA_SOURCE_IS_OPENED(u->source->thread_info.state)) {
-            int work_done;
+            if (process_render(u))
+                goto fail;
 
             if (u->first) {
                 pa_log_info("Starting capture.");
                 pa_hal_interface_pcm_start(u->hal_interface, u->pcm_handle);
                 u->first = false;
-                u->timestamp = now;
-            }
-
-            work_done = process_render(u, now);
-
-            if (work_done < 0)
-                goto fail;
-
-            if (work_done == 0) {
-                pa_rtpoll_set_timer_relative(u->rtpoll, (20 * PA_USEC_PER_MSEC));
-            } else {
-                pa_rtpoll_set_timer_absolute(u->rtpoll, u->timestamp);
             }
-        } else {
-            pa_rtpoll_set_timer_disabled(u->rtpoll);
         }
 
         /* Hmm, nothing to do. Let's sleep */
@@ -549,7 +505,6 @@ int pa__init(pa_module*m) {
 
     u->source->parent.process_msg = source_process_msg;
     u->source->set_state_in_io_thread = source_set_state_in_io_thread_cb;
-    u->source->update_requested_latency = source_update_requested_latency_cb;
     u->source->userdata = u;
 
     if (pa_hal_interface_pcm_open(u->hal_interface,
@@ -567,17 +522,13 @@ int pa__init(pa_module*m) {
     pa_source_set_asyncmsgq(u->source, u->thread_mq.inq);
     pa_source_set_rtpoll(u->source, u->rtpoll);
 
-    u->block_usec = BLOCK_USEC;
-    u->latency_time = u->block_usec;
     u->timestamp = 0ULL;
 
-    pa_source_set_max_rewind(u->source, 0);
-
     if (!(u->thread = pa_thread_new("tizenaudio-source", thread_func, u))) {
         pa_log_error("Failed to create thread.");
         goto fail;
     }
-    pa_source_set_fixed_latency(u->source, u->block_usec);
+    pa_source_set_fixed_latency(u->source, pa_bytes_to_usec(buffer_size, &ss));
     pa_source_put(u->source);
     pa_modargs_free(ma);