Reset zero-pop timestamp when sink-input state is not running 45/110745/10 accepted/tizen/3.0/common/20170124.081259 accepted/tizen/3.0/ivi/20170124.042401 accepted/tizen/3.0/mobile/20170124.042234 accepted/tizen/3.0/tv/20170124.042307 accepted/tizen/3.0/wearable/20170124.042336 submit/tizen_3.0/20170123.123302
authorSeungbae Shin <seungbae.shin@samsung.com>
Tue, 17 Jan 2017 14:19:21 +0000 (23:19 +0900)
committerSeungbae Shin <seungbae.shin@samsung.com>
Mon, 23 Jan 2017 03:07:26 +0000 (12:07 +0900)
[Version] 5.0.106
[Profile] Common
[Issue Type] Fix bug

Change-Id: I46c730cbdd3f4debfa74b3e562ad7f8d2e85d328

src/pulsecore/protocol-native.c
src/pulsecore/sink-input.c
src/pulsecore/sink-input.h

index 453fbf1..30fef91 100644 (file)
@@ -1785,38 +1785,14 @@ static bool sink_input_process_underrun_cb(pa_sink_input *i) {
 
 #ifdef __TIZEN__
 static void _check_zero_pop_timeout(pa_sink_input *i) {
-    uint32_t zero_pop_time = 0;
     playback_stream *s = PLAYBACK_STREAM(i->userdata);
+    bool is_timeout = false;
 
-    if (pa_memblockq_get_length(s->memblockq) == 0) {
-        if (i->zero_pop_start_time) {
-            /* calculate zero pop time in seconds */
-            zero_pop_time = (uint32_t)((pa_rtclock_now() - i->zero_pop_start_time) / PA_USEC_PER_SEC);
-
-            /* check only once per seconds */
-            if (zero_pop_time > i->old_zero_pop_time) {
-                pa_log_debug("zero pop (no sink-input data) for [%u] sec., timeout in [%u] sec.",
-                             zero_pop_time, i->core->zero_pop_threshold);
-
-                if (zero_pop_time >= i->core->zero_pop_threshold) {
-                    pa_log_warn("async msgq post : PLAYBACK_STREAM_MESSAGE_POP_TIMEOUT");
-                    pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(s),
-                                      PLAYBACK_STREAM_MESSAGE_POP_TIMEOUT, NULL, 0, NULL, NULL);
-                    i->zero_pop_start_time = 0; /* this will make reset count */
-                } else {
-                    i->old_zero_pop_time = zero_pop_time;
-                }
-            }
-        } else {
-            pa_log_debug("zero pop start!!!");
-            i->zero_pop_start_time = pa_rtclock_now();
-            i->old_zero_pop_time = 0;
-        }
-    } else {
-        if (i->zero_pop_start_time) {
-            pa_log_debug("zero pop end...");
-            i->zero_pop_start_time = 0;
-        }
+    pa_sink_input_update_empty_pop(i, pa_memblockq_get_length(s->memblockq), &is_timeout);
+    if (is_timeout) {
+        pa_log_warn("async msgq post : PLAYBACK_STREAM_MESSAGE_POP_TIMEOUT");
+        pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(s),
+                          PLAYBACK_STREAM_MESSAGE_POP_TIMEOUT, NULL, 0, NULL, NULL);
     }
 }
 #endif
index 612f481..8356e25 100644 (file)
@@ -28,6 +28,7 @@
 #include <stdlib.h>
 #ifdef __TIZEN__
 #include <time.h>
+#include <pulse/timeval.h>
 #endif
 
 #include <pulse/utf8.h>
@@ -60,6 +61,8 @@ struct volume_factor_entry {
 
 #ifdef __TIZEN__
 #define PA_SINK_INPUT_DUMP_PATH_PREFIX      "/tmp/dump_ap_out_stream"
+static void _empty_pop_reset(pa_sink_input *i);
+static bool _empty_pop_is_started(pa_sink_input *i);
 #endif
 
 static struct volume_factor_entry *volume_factor_entry_new(const char *key, const pa_cvolume *volume) {
@@ -661,6 +664,11 @@ static void sink_input_set_state(pa_sink_input *i, pa_sink_input_state_t state)
     if (i->state == state)
         return;
 
+#ifdef __TIZEN__
+    if (state != PA_SINK_INPUT_RUNNING && _empty_pop_is_started(i))
+        _empty_pop_reset(i);
+#endif
+
     if (i->state == PA_SINK_INPUT_CORKED && state == PA_SINK_INPUT_RUNNING && pa_sink_used_by(i->sink) == 0 &&
         !pa_sample_spec_equal(&i->sample_spec, &i->sink->sample_spec)) {
         /* We were uncorked and the sink was not playing anything -- let's try
@@ -2099,6 +2107,11 @@ void pa_sink_input_set_state_within_thread(pa_sink_input *i, pa_sink_input_state
     if (state == i->thread_info.state)
         return;
 
+#ifdef __TIZEN__
+    if (state != PA_SINK_INPUT_RUNNING && _empty_pop_is_started(i))
+        _empty_pop_reset(i);
+#endif
+
     if ((state == PA_SINK_INPUT_DRAINED || state == PA_SINK_INPUT_RUNNING) &&
         !(i->thread_info.state == PA_SINK_INPUT_DRAINED || i->thread_info.state != PA_SINK_INPUT_RUNNING))
         pa_atomic_store(&i->thread_info.drained, 1);
@@ -2359,6 +2372,69 @@ void pa_sink_input_set_silence_to_first_peek(pa_sink_input *i, bool silence, pa_
 
     return;
 }
+
+/* empty pop - begin */
+static void _empty_pop_start(pa_sink_input *i) {
+    i->empty_pop_initial_timestamp = pa_rtclock_now();
+    i->empty_pop_previous_duration = 0;
+
+    pa_log_debug("[%u] empty pop started!!!", i->index);
+}
+
+static bool _empty_pop_is_started(pa_sink_input *i) {
+    if (i->empty_pop_initial_timestamp > 0)
+        return true;
+    else
+        return false;
+}
+
+static uint32_t _empty_pop_calc_duration(pa_sink_input *i) {
+    return (uint32_t)((pa_rtclock_now() - i->empty_pop_initial_timestamp) / PA_USEC_PER_SEC);
+}
+
+static void _empty_pop_print_duration(pa_sink_input *i, uint32_t empty_pop_duration) {
+    /* print only once per seconds */
+    if (empty_pop_duration <= i->empty_pop_previous_duration)
+        return;
+
+    i->empty_pop_previous_duration = empty_pop_duration;
+
+    pa_log_debug("[%u] empty pop (no sink-input data) for [%u] sec., timeout is [%u] sec.",
+                  i->index, empty_pop_duration, i->core->zero_pop_threshold);
+}
+
+static void _empty_pop_reset(pa_sink_input *i) {
+    i->empty_pop_initial_timestamp = 0;
+    i->empty_pop_previous_duration = 0;
+
+    pa_log_debug("[%u] empty pop reset...", i->index);
+}
+
+void pa_sink_input_update_empty_pop(pa_sink_input *i, size_t length, bool *is_timeout) {
+    pa_sink_input_assert_ref(i);
+    pa_assert(is_timeout);
+
+    if (length == 0) {
+        if (_empty_pop_is_started(i)) {
+            /* calculate empty pop duration in seconds */
+            uint32_t empty_pop_duration = _empty_pop_calc_duration(i);
+            if (empty_pop_duration >= i->core->zero_pop_threshold) {
+                *is_timeout = true;
+                _empty_pop_reset(i);
+                return;
+            }
+            _empty_pop_print_duration(i, empty_pop_duration);
+        } else {
+            _empty_pop_start(i);
+        }
+    } else {
+        if (_empty_pop_is_started(i))
+            _empty_pop_reset(i);
+    }
+
+    *is_timeout = false;
+}
+/* empty pop - end */
 #endif
 
 /* Called from main context */
index 53d6994..e2f9768 100644 (file)
@@ -271,8 +271,8 @@ struct pa_sink_input {
 
 #ifdef __TIZEN__
     FILE *dump_fp;
-    pa_usec_t zero_pop_start_time;
-    uint32_t old_zero_pop_time;
+    pa_usec_t empty_pop_initial_timestamp;
+    uint32_t empty_pop_previous_duration;
     bool is_virtual;
 #endif
 
@@ -450,6 +450,7 @@ pa_memchunk* pa_sink_input_get_silence(pa_sink_input *i, pa_memchunk *ret);
 
 #ifdef __TIZEN__
 void pa_sink_input_set_silence_to_first_peek(pa_sink_input *i, bool silence, pa_usec_t duration);
+void pa_sink_input_update_empty_pop(pa_sink_input *i, size_t length, bool *is_timeout);
 #endif
 
 /* Called from the main thread, from sink.c only. The normal way to set the