stream-manager: Update buffer attributes as per latency from stream-map.json 38/74338/7
authorSangchul Lee <sc11.lee@samsung.com>
Tue, 14 Jun 2016 02:21:45 +0000 (11:21 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Wed, 15 Jun 2016 08:24:30 +0000 (17:24 +0900)
Previously, buffer attributes are got from audio HAL.
But the audio HAL is not proper place to get these information because these are
very deeply related to the buffer mechanism of each stream on pulseaudio.

[Version] 5.0.56
[Profile] Common
[Issue Type] Feature Enhancement

Change-Id: I006afb9344e7ee4601a416e98486489dc8f5bb9b

packaging/pulseaudio-modules-tizen.spec
src/hal-interface.c
src/hal-interface.h
src/module-tizenaudio-sink.c
src/stream-manager-priv.h
src/stream-manager.c

index 9b5d88de17206997e668d5171739d76e0beccdfc..32abcab37160c92fcef68bebf1eab466a31a6fcc 100644 (file)
@@ -1,6 +1,6 @@
 Name:             pulseaudio-modules-tizen
 Summary:          Pulseaudio modules for Tizen
-Version:          5.0.55
+Version:          5.0.56
 Release:          0
 Group:            Multimedia/Audio
 License:          LGPL-2.1+
index 423b614123cf84369f77ae7980bd438d6288440b..658a78d6fe5f788020cd618ee27f16e221060070 100644 (file)
@@ -67,7 +67,6 @@ pa_hal_interface* pa_hal_interface_get(pa_core *core) {
         h->intf.update_route = dlsym(h->dl_handle, "audio_update_route");
         h->intf.update_route_option = dlsym(h->dl_handle, "audio_update_route_option");
         h->intf.notify_stream_connection_changed = dlsym(h->dl_handle, "audio_notify_stream_connection_changed");
-        h->intf.get_buffer_attr = dlsym(h->dl_handle, "audio_get_buffer_attr");
         h->intf.pcm_open = dlsym(h->dl_handle, "audio_pcm_open");
         h->intf.pcm_start = dlsym(h->dl_handle, "audio_pcm_start");
         h->intf.pcm_stop = dlsym(h->dl_handle, "audio_pcm_stop");
@@ -290,27 +289,6 @@ int32_t pa_hal_interface_notify_stream_connection_changed(pa_hal_interface *h, h
     return ret;
 }
 
-int32_t pa_hal_interface_get_buffer_attribute(pa_hal_interface *h, hal_stream_info *info,
-                                            uint32_t *maxlength, uint32_t *tlength, uint32_t *prebuf, uint32_t* minreq, uint32_t *fragsize) {
-    int32_t ret = 0;
-    audio_return_t hal_ret = AUDIO_RET_OK;
-
-    pa_assert(h);
-    pa_assert(info);
-
-    pa_log_info("latency:%s, rate:%u, format:%d, channels:%u",
-        info->latency, info->sample_spec->rate, info->sample_spec->format, info->sample_spec->channels);
-
-    if (AUDIO_RET_OK != (hal_ret = h->intf.get_buffer_attr(h->ah_handle, info->direction, info->latency, info->sample_spec->rate, info->sample_spec->format,
-                                                         info->sample_spec->channels, maxlength, tlength, prebuf, minreq, fragsize))) {
-        pa_log_error("get_buffer_attr returns error:0x%x", hal_ret);
-        ret = -1;
-    } else
-        pa_log_info("maxlength:%d, tlength:%d, prebuf:%d, minreq:%d, fragsize:%d", *maxlength, *tlength, *prebuf, *minreq, *fragsize);
-
-    return ret;
-}
-
 int32_t pa_hal_interface_pcm_open(pa_hal_interface *h, pcm_handle *pcm_h, io_direction_t direction, pa_sample_spec *sample_spec, uint32_t period_size, uint32_t periods) {
     int32_t ret = 0;
     audio_return_t hal_ret = AUDIO_RET_OK;
index 060b401da594ace89b9811dce7d024376a11a2f3..9741339c443de752533955cbc80f4a12cb01163c 100644 (file)
@@ -59,7 +59,6 @@ int32_t pa_hal_interface_set_volume_mute(pa_hal_interface *h, const char *volume
 int32_t pa_hal_interface_update_route(pa_hal_interface *h, hal_route_info *info);
 int32_t pa_hal_interface_update_route_option(pa_hal_interface *h, hal_route_option *option);
 int32_t pa_hal_interface_notify_stream_connection_changed(pa_hal_interface *h, hal_stream_connection_info *info);
-int32_t pa_hal_interface_get_buffer_attribute(pa_hal_interface *h, hal_stream_info *info, uint32_t *maxlength, uint32_t *tlength, uint32_t *prebuf, uint32_t* minreq, uint32_t *fragsize);
 int32_t pa_hal_interface_pcm_open(pa_hal_interface *h, pcm_handle *pcm_h, io_direction_t direction, pa_sample_spec *sample_spec, uint32_t period_size, uint32_t periods);
 int32_t pa_hal_interface_pcm_start(pa_hal_interface *h, pcm_handle pcm_h);
 int32_t pa_hal_interface_pcm_stop(pa_hal_interface *h, pcm_handle pcm_h);
index 5c6efd2cb4e417482b10247ff674459e05b9ce15..095f6de2826597fedc0e897eb65872c1df7b6cb6 100644 (file)
@@ -486,6 +486,7 @@ int pa__init(pa_module*m) {
         pa_log_error("fragment_size or fragments are invalid.");
         goto fail;
     }
+    pa_log_info("fragment_size(%u), fragments(%u)", u->frag_size, u->nfrags);
 
     pa_sink_new_data_init(&data);
     data.driver = __FILE__;
index 3c505deda8c1ca1f1f42b11f473206990597827e..b20e8d135cd8448447b844d3c6496f78c2b70db1 100644 (file)
@@ -39,15 +39,6 @@ typedef enum _stream_direction {
 #define IS_FOCUS_ACQUIRED(focus, type) \
       (type == STREAM_SINK_INPUT ? (focus & STREAM_FOCUS_ACQUIRED_PLAYBACK) : (focus & STREAM_FOCUS_ACQUIRED_CAPTURE))
 
-typedef struct _stream_info {
-    int32_t priority;
-    stream_route_type_t route_type;
-    const char *volume_types[STREAM_DIRECTION_MAX];
-    pa_idxset *idx_avail_in_devices;
-    pa_idxset *idx_avail_out_devices;
-    pa_idxset *idx_avail_frameworks;
-} stream_info;
-
 typedef struct _volume_info {
     bool is_hal_volume_type;
     struct _values {
@@ -57,6 +48,23 @@ typedef struct _volume_info {
     } values[STREAM_DIRECTION_MAX];
 } volume_info;
 
+typedef struct _latency_info {
+    int32_t maxlength;
+    int32_t tlength_ms;
+    int32_t minreq_ms;
+    int32_t prebuf_ms;
+    int32_t fragsize_ms;
+} latency_info;
+
+typedef struct _stream_info {
+    int32_t priority;
+    stream_route_type_t route_type;
+    const char *volume_types[STREAM_DIRECTION_MAX];
+    pa_idxset *idx_avail_in_devices;
+    pa_idxset *idx_avail_out_devices;
+    pa_idxset *idx_avail_frameworks;
+} stream_info;
+
 typedef struct _prior_max_priority_stream {
     pa_sink_input *sink_input;
     pa_source_output *source_output;
@@ -79,6 +87,7 @@ struct _stream_manager {
     pa_hashmap *volume_infos;
     pa_hashmap *volume_modifiers;
     pa_hashmap *stream_infos;
+    pa_hashmap *latency_infos;
     pa_hashmap *stream_parents;
     pa_hashmap *muted_streams;
     cur_max_priority_stream cur_highest_priority;
index bd9f053569308a4f27943ace48e82ddac6437595..f4605602cca1e2ec2333fbeb2c189b108b3494dc 100644 (file)
@@ -358,6 +358,7 @@ typedef enum _process_command_type {
     PROCESS_COMMAND_UPDATE_VOLUME,
     PROCESS_COMMAND_ADD_PARENT_ID,
     PROCESS_COMMAND_REMOVE_PARENT_ID,
+    PROCESS_COMMAND_UPDATE_BUFFER_ATTR,
 } process_command_type_t;
 
 typedef enum _notify_command_type {
@@ -377,6 +378,7 @@ const char* process_command_type_str[] = {
     "UPDATE_VOLUME",
     "ADD_PARENT_ID",
     "REMOVE_PARENT_ID",
+    "UPDATE_BUFFER_ATTR",
 };
 
 const char* notify_command_type_str[] = {
@@ -392,6 +394,13 @@ const char* notify_command_type_str[] = {
 #define STREAM_MAP_VOLUMES "volumes"
 #define STREAM_MAP_VOLUME_TYPE "type"
 #define STREAM_MAP_VOLUME_IS_FOR_HAL "is-hal-volume"
+#define STREAM_MAP_LATENCIES "latencies"
+#define STREAM_MAP_LATENCY_TYPE "type"
+#define STREAM_MAP_LATENCY_FRAGSIZE_MS "fragsize-ms"
+#define STREAM_MAP_LATENCY_TLENGTH_MS "tlength-ms"
+#define STREAM_MAP_LATENCY_MINREQ_MS "minreq-ms"
+#define STREAM_MAP_LATENCY_PREBUF_MS "prebuf-ms"
+#define STREAM_MAP_LATENCY_MAXLENGTH "maxlength"
 #define STREAM_MAP_STREAMS "streams"
 #define STREAM_MAP_STREAM_ROLE "role"
 #define STREAM_MAP_STREAM_PRIORITY "priority"
@@ -1363,33 +1372,20 @@ static void dump_stream_map(pa_stream_manager *m) {
 static int init_stream_map(pa_stream_manager *m) {
     volume_info *v;
     stream_info *s;
+    latency_info *l;
     json_object *o;
-    json_object *volume_array_o;
-    json_object *stream_array_o;
-    json_object *volume_type_o;
-    json_object *is_hal_volume_o;
-    json_object *role_o;
-    json_object *priority_o;
-    json_object *route_type_o;
-    json_object *volume_types_o;
-    json_object *avail_in_devices_o;
-    json_object *avail_out_devices_o;
-    json_object *avail_frameworks_o;
-    int num_of_volume_types = 0;
-    int num_of_stream_types = 0;
-    const char *volume_type = NULL;
+    json_object *array_o;
+    json_object *array_item_o;
+    json_object *item_o;
+    json_object *sub_array_o;
+    int array_length = 0;
+    int sub_array_length = 0;
+    const char *type = NULL;
     const char *role = NULL;
     int i = 0, j = 0;
-    int num_of_avail_in_devices;
-    int num_of_avail_out_devices;
-    int num_of_avail_frameworks;
     json_object *out_device_o;
     json_object *in_device_o;
     json_object *framework_o;
-    json_object *volume_o;
-    json_object *stream_o;
-    json_object *volume_type_in_o;
-    json_object *volume_type_out_o;
     void *state = NULL;
 
     pa_assert(m);
@@ -1400,58 +1396,113 @@ static int init_stream_map(pa_stream_manager *m) {
         return -1;
     }
 
+    /* Latencies */
+    m->latency_infos = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+    if (json_object_object_get_ex(o, STREAM_MAP_LATENCIES, &array_o) && json_object_is_type(array_o, json_type_array)) {
+        array_length = json_object_array_length(array_o);
+        for (i = 0; i < array_length; i++) {
+            if ((array_item_o = json_object_array_get_idx(array_o, i)) && json_object_is_type(array_item_o, json_type_object)) {
+                l = pa_xmalloc0(sizeof(latency_info));
+                pa_log_debug("latency found [%d]", i);
+                if (json_object_object_get_ex(array_item_o, STREAM_MAP_LATENCY_TYPE, &item_o) && json_object_is_type(item_o, json_type_string)) {
+                    type = json_object_get_string(item_o);
+                    pa_log_debug(" - type : %s", type);
+                } else {
+                    pa_log_error("Get type failed");
+                    goto failed;
+                }
+                if (json_object_object_get_ex(array_item_o, STREAM_MAP_LATENCY_FRAGSIZE_MS, &item_o) && json_object_is_type(item_o, json_type_int)) {
+                    l->fragsize_ms = json_object_get_int(item_o);
+                    pa_log_debug(" - fragsize-ms : %d", l->fragsize_ms);
+                } else {
+                    pa_log_error("Get fragsize-ms failed");
+                    goto failed;
+                }
+                if (json_object_object_get_ex(array_item_o, STREAM_MAP_LATENCY_TLENGTH_MS, &item_o) && json_object_is_type(item_o, json_type_int)) {
+                    l->tlength_ms = json_object_get_int(item_o);
+                    pa_log_debug(" - tlength-ms : %d", l->tlength_ms);
+                } else {
+                    pa_log_error("Get tlength-ms failed");
+                    goto failed;
+                }
+                if (json_object_object_get_ex(array_item_o, STREAM_MAP_LATENCY_MINREQ_MS, &item_o) && json_object_is_type(item_o, json_type_int)) {
+                    l->minreq_ms = json_object_get_int(item_o);
+                    pa_log_debug(" - minreq-ms : %d", l->minreq_ms);
+                } else {
+                    pa_log_error("Get minreq-ms failed");
+                    goto failed;
+                }
+                if (json_object_object_get_ex(array_item_o, STREAM_MAP_LATENCY_PREBUF_MS, &item_o) && json_object_is_type(item_o, json_type_int)) {
+                    l->prebuf_ms = json_object_get_int(item_o);
+                    pa_log_debug(" - prebuf-ms : %d", l->prebuf_ms);
+                } else {
+                    pa_log_error("Get prebuf-ms failed");
+                    goto failed;
+                }
+                if (json_object_object_get_ex(array_item_o, STREAM_MAP_LATENCY_MAXLENGTH, &item_o) && json_object_is_type(item_o, json_type_int)) {
+                    l->maxlength = json_object_get_int(item_o);
+                    pa_log_debug(" - maxlength : %d", l->maxlength);
+                } else {
+                    pa_log_error("Get maxlength failed");
+                    goto failed;
+                }
+                pa_hashmap_put(m->latency_infos, (void*)type, l);
+            }
+        }
+    }
+
     /* Volumes */
     m->volume_infos = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
-    if (json_object_object_get_ex(o, STREAM_MAP_VOLUMES, &volume_array_o) && json_object_is_type(volume_array_o, json_type_array)) {
-        num_of_volume_types = json_object_array_length(volume_array_o);
-        for (i = 0; i < num_of_volume_types; i++) {
-            if ((volume_o = json_object_array_get_idx(volume_array_o, i)) && json_object_is_type(volume_o, json_type_object)) {
+    if (json_object_object_get_ex(o, STREAM_MAP_VOLUMES, &array_o) && json_object_is_type(array_o, json_type_array)) {
+        array_length = json_object_array_length(array_o);
+        for (i = 0; i < array_length; i++) {
+            if ((array_item_o = json_object_array_get_idx(array_o, i)) && json_object_is_type(array_item_o, json_type_object)) {
                 v = pa_xmalloc0(sizeof(volume_info));
                 pa_log_debug("volume found [%d]", i);
-                if (json_object_object_get_ex(volume_o, STREAM_MAP_VOLUME_TYPE, &volume_type_o) && json_object_is_type(volume_type_o, json_type_string)) {
-                    volume_type = json_object_get_string(volume_type_o);
-                    pa_log_debug(" - type : %s", volume_type);
+                if (json_object_object_get_ex(array_item_o, STREAM_MAP_VOLUME_TYPE, &item_o) && json_object_is_type(item_o, json_type_string)) {
+                    type = json_object_get_string(item_o);
+                    pa_log_debug(" - type : %s", type);
                 } else {
                     pa_log_error("Get volume type failed");
                     goto failed;
                 }
-                if (json_object_object_get_ex(volume_o, STREAM_MAP_VOLUME_IS_FOR_HAL, &is_hal_volume_o) && json_object_is_type(is_hal_volume_o, json_type_int)) {
-                    v->is_hal_volume_type = (bool)json_object_get_int(is_hal_volume_o);
+                if (json_object_object_get_ex(array_item_o, STREAM_MAP_VOLUME_IS_FOR_HAL, &item_o) && json_object_is_type(item_o, json_type_int)) {
+                    v->is_hal_volume_type = (bool)json_object_get_int(item_o);
                     pa_log_debug(" - is-hal-volume : %d", v->is_hal_volume_type);
                 } else {
                     pa_log_error("Get is-hal-volume failed");
                     goto failed;
                 }
-                pa_hashmap_put(m->volume_infos, (void*)volume_type, v);
+                pa_hashmap_put(m->volume_infos, (void*)type, v);
             }
         }
     }
 
     /* Streams */
     m->stream_infos = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
-    if (json_object_object_get_ex(o, STREAM_MAP_STREAMS, &stream_array_o) && json_object_is_type(stream_array_o, json_type_array)) {
-        num_of_stream_types = json_object_array_length(stream_array_o);
-        for (i = 0; i < num_of_stream_types; i++) {
+    if (json_object_object_get_ex(o, STREAM_MAP_STREAMS, &array_o) && json_object_is_type(array_o, json_type_array)) {
+        array_length = json_object_array_length(array_o);
+        for (i = 0; i < array_length; i++) {
 
-            if ((stream_o = json_object_array_get_idx(stream_array_o, i)) && json_object_is_type(stream_o, json_type_object)) {
+            if ((array_item_o = json_object_array_get_idx(array_o, i)) && json_object_is_type(array_item_o, json_type_object)) {
                 s = pa_xmalloc0(sizeof(stream_info));
                 pa_log_debug("stream found [%d]", i);
-                if (json_object_object_get_ex(stream_o, STREAM_MAP_STREAM_ROLE, &role_o) && json_object_is_type(role_o, json_type_string)) {
-                    role = json_object_get_string(role_o);
+                if (json_object_object_get_ex(array_item_o, STREAM_MAP_STREAM_ROLE, &item_o) && json_object_is_type(item_o, json_type_string)) {
+                    role = json_object_get_string(item_o);
                     pa_log_debug(" - role : %s", role);
                 } else {
                     pa_log_error("Get stream role failed");
                     goto failed;
                 }
-                if (json_object_object_get_ex(stream_o, STREAM_MAP_STREAM_PRIORITY, &priority_o) && json_object_is_type(priority_o, json_type_int)) {
-                    s->priority = json_object_get_int(priority_o);
+                if (json_object_object_get_ex(array_item_o, STREAM_MAP_STREAM_PRIORITY, &item_o) && json_object_is_type(item_o, json_type_int)) {
+                    s->priority = json_object_get_int(item_o);
                     pa_log_debug(" - priority : %d", s->priority);
                 } else {
                     pa_log_error("Get stream priority failed");
                     goto failed;
                 }
-                if (json_object_object_get_ex(stream_o, STREAM_MAP_STREAM_ROUTE_TYPE, &route_type_o) && json_object_is_type(route_type_o, json_type_string)) {
-                    if (convert_route_type(&(s->route_type), json_object_get_string(route_type_o))) {
+                if (json_object_object_get_ex(array_item_o, STREAM_MAP_STREAM_ROUTE_TYPE, &item_o) && json_object_is_type(item_o, json_type_string)) {
+                    if (convert_route_type(&(s->route_type), json_object_get_string(item_o))) {
                         pa_log_error("convert stream route-type failed");
                         goto failed;
                     }
@@ -1460,15 +1511,15 @@ static int init_stream_map(pa_stream_manager *m) {
                     pa_log_error("Get stream route-type failed");
                     goto failed;
                 }
-                if (json_object_object_get_ex(stream_o, STREAM_MAP_STREAM_VOLUME_TYPES, &volume_types_o) && json_object_is_type(volume_types_o, json_type_object)) {
-                    if (json_object_object_get_ex(volume_types_o, STREAM_MAP_STREAM_VOLUME_TYPE_IN, &volume_type_in_o) && json_object_is_type(volume_type_in_o, json_type_string))
-                        s->volume_types[STREAM_DIRECTION_IN] = json_object_get_string(volume_type_in_o);
+                if (json_object_object_get_ex(array_item_o, STREAM_MAP_STREAM_VOLUME_TYPES, &sub_array_o) && json_object_is_type(sub_array_o, json_type_object)) {
+                    if (json_object_object_get_ex(sub_array_o, STREAM_MAP_STREAM_VOLUME_TYPE_IN, &item_o) && json_object_is_type(item_o, json_type_string))
+                        s->volume_types[STREAM_DIRECTION_IN] = json_object_get_string(item_o);
                     else {
                         pa_log_error("Get stream volume-type-in failed");
                         goto failed;
                     }
-                    if (json_object_object_get_ex(volume_types_o, STREAM_MAP_STREAM_VOLUME_TYPE_OUT, &volume_type_out_o) && json_object_is_type(volume_type_out_o, json_type_string))
-                        s->volume_types[STREAM_DIRECTION_OUT] = json_object_get_string(volume_type_out_o);
+                    if (json_object_object_get_ex(sub_array_o, STREAM_MAP_STREAM_VOLUME_TYPE_OUT, &item_o) && json_object_is_type(item_o, json_type_string))
+                        s->volume_types[STREAM_DIRECTION_OUT] = json_object_get_string(item_o);
                     else {
                         pa_log_error("Get stream volume-type-out failed");
                         goto failed;
@@ -1478,13 +1529,13 @@ static int init_stream_map(pa_stream_manager *m) {
                     pa_log_error("Get stream volume-types failed");
                     goto failed;
                 }
-                if (json_object_object_get_ex(stream_o, STREAM_MAP_STREAM_AVAIL_IN_DEVICES, &avail_in_devices_o) && json_object_is_type(avail_in_devices_o, json_type_array)) {
+                if (json_object_object_get_ex(array_item_o, STREAM_MAP_STREAM_AVAIL_IN_DEVICES, &sub_array_o) && json_object_is_type(sub_array_o, json_type_array)) {
                     j = 0;
                     s->idx_avail_in_devices = pa_idxset_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
-                    num_of_avail_in_devices = json_object_array_length(avail_in_devices_o);
+                    sub_array_length = json_object_array_length(sub_array_o);
                     pa_log_debug(" - avail-in-devices");
-                    for (j = 0; j < num_of_avail_in_devices; j++) {
-                        if ((in_device_o = json_object_array_get_idx(avail_in_devices_o, j)) && json_object_is_type(in_device_o, json_type_string)) {
+                    for (j = 0; j < sub_array_length; j++) {
+                        if ((in_device_o = json_object_array_get_idx(sub_array_o, j)) && json_object_is_type(in_device_o, json_type_string)) {
                             pa_idxset_put(s->idx_avail_in_devices, (void*)json_object_get_string(in_device_o), NULL);
                             pa_log_debug("      device[%d] : %s", j, json_object_get_string(in_device_o));
                            }
@@ -1493,13 +1544,13 @@ static int init_stream_map(pa_stream_manager *m) {
                     pa_log_error("Get stream avail-in-devices failed");
                     goto failed;
                 }
-                if (json_object_object_get_ex(stream_o, STREAM_MAP_STREAM_AVAIL_OUT_DEVICES, &avail_out_devices_o) && json_object_is_type(avail_out_devices_o, json_type_array)) {
+                if (json_object_object_get_ex(array_item_o, STREAM_MAP_STREAM_AVAIL_OUT_DEVICES, &sub_array_o) && json_object_is_type(sub_array_o, json_type_array)) {
                     j = 0;
                     s->idx_avail_out_devices = pa_idxset_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
-                    num_of_avail_out_devices = json_object_array_length(avail_out_devices_o);
+                    sub_array_length = json_object_array_length(sub_array_o);
                     pa_log_debug(" - avail-out-devices");
-                    for (j = 0; j < num_of_avail_out_devices; j++) {
-                        if ((out_device_o = json_object_array_get_idx(avail_out_devices_o, j)) && json_object_is_type(out_device_o, json_type_string)) {
+                    for (j = 0; j < sub_array_length; j++) {
+                        if ((out_device_o = json_object_array_get_idx(sub_array_o, j)) && json_object_is_type(out_device_o, json_type_string)) {
                             pa_idxset_put(s->idx_avail_out_devices, (void*)json_object_get_string(out_device_o), NULL);
                             pa_log_debug("      device[%d] : %s", j, json_object_get_string(out_device_o));
                            }
@@ -1508,13 +1559,13 @@ static int init_stream_map(pa_stream_manager *m) {
                     pa_log_error("Get stream avail-out-devices failed");
                     goto failed;
                 }
-                if (json_object_object_get_ex(stream_o, STREAM_MAP_STREAM_AVAIL_FRAMEWORKS, &avail_frameworks_o) && json_object_is_type(avail_frameworks_o, json_type_array)) {
+                if (json_object_object_get_ex(array_item_o, STREAM_MAP_STREAM_AVAIL_FRAMEWORKS, &sub_array_o) && json_object_is_type(sub_array_o, json_type_array)) {
                     j = 0;
                     s->idx_avail_frameworks = pa_idxset_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
-                    num_of_avail_frameworks = json_object_array_length(avail_frameworks_o);
+                    sub_array_length = json_object_array_length(sub_array_o);
                     pa_log_debug(" - avail-frameworks");
-                    for (j = 0; j < num_of_avail_frameworks; j++) {
-                        if ((framework_o = json_object_array_get_idx(avail_frameworks_o, j)) && json_object_is_type(framework_o, json_type_string)) {
+                    for (j = 0; j < sub_array_length; j++) {
+                        if ((framework_o = json_object_array_get_idx(sub_array_o, j)) && json_object_is_type(framework_o, json_type_string)) {
                             pa_idxset_put(s->idx_avail_frameworks, (void*)json_object_get_string(framework_o), NULL);
                             pa_log_debug("      framework[%d] : %s", j, json_object_get_string(framework_o));
                            }
@@ -1554,12 +1605,19 @@ failed:
         }
         pa_hashmap_free(m->volume_infos);
     }
+    if (m->latency_infos) {
+        PA_HASHMAP_FOREACH(l, m->latency_infos, state) {
+            pa_xfree(l);
+        }
+        pa_hashmap_free(m->latency_infos);
+    }
     return -1;
 }
 
 static void deinit_stream_map(pa_stream_manager *m) {
     stream_info *s = NULL;
     volume_info *v = NULL;
+    latency_info *l = NULL;
     void *state = NULL;
 
     pa_assert(m);
@@ -1582,6 +1640,12 @@ static void deinit_stream_map(pa_stream_manager *m) {
         }
         pa_hashmap_free(m->volume_infos);
     }
+    if (m->latency_infos) {
+        PA_HASHMAP_FOREACH(l, m->latency_infos, state) {
+            pa_xfree(l);
+        }
+        pa_hashmap_free(m->latency_infos);
+    }
 
     return;
 }
@@ -1802,7 +1866,7 @@ static bool update_stream_parent_info(pa_stream_manager *m, process_command_type
 }
 
 static bool update_the_highest_priority_stream(pa_stream_manager *m, process_command_type_t command, void *mine,
-                                                    stream_type_t type, const char *role, bool is_new_data, bool *need_to_update) {
+                                               stream_type_t type, const char *role, bool is_new_data, bool *need_to_update) {
     uint32_t idx = 0;
     size_t size = 0;
     const int32_t *priority = NULL;
@@ -1999,6 +2063,85 @@ static bool update_the_highest_priority_stream(pa_stream_manager *m, process_com
     return true;
 }
 
+/* Update buffer attributes to new stream */
+static void update_buffer_attribute(pa_stream_manager *m, void *new_data, stream_type_t stream_type, bool is_new_data) {
+    pa_sample_spec *sample_spec;
+    const char *latency;
+    latency_info *li;
+    int32_t maxlength = -1;
+    /* playback only */
+    int32_t tlength = -1;
+    int32_t minreq = -1;
+    /* Note: pulseaudio recommends to set it to -1, but there's an issue related
+     * to a stream from gstreamer pulsesink which set this value to 0, so we set
+     * default value to 0 temporarily. */
+    int32_t prebuf = 0;
+    int32_t tlength_ms = -1;
+    int32_t minreq_ms = -1;
+    int32_t prebuf_ms = -1;
+    /* recording  only */
+    int32_t fragsize = -1;
+    int32_t fragsize_ms = -1;
+
+    pa_assert(m);
+    pa_assert(new_data);
+
+    if (!is_new_data) {
+        pa_log_warn("updating buffer attribute is only for new data, skip it");
+        return;
+    }
+
+    if ((latency = pa_proplist_gets(GET_STREAM_NEW_PROPLIST(new_data, stream_type), PA_PROP_MEDIA_TIZEN_AUDIO_LATENCY)))
+        pa_log_info("audio_latency : %s", latency);
+    else {
+        pa_log_warn("failed to get audio_latency");
+        return;
+    }
+
+    if (!(li = pa_hashmap_get(m->latency_infos, latency))) {
+        pa_log_warn("not support this latency type[%s]", latency);
+        return;
+    }
+
+    maxlength = li->maxlength;
+    pa_proplist_setf(GET_STREAM_NEW_PROPLIST(new_data, stream_type), PA_PROP_BUFFER_ATTR_MAXLENGTH, "%d", maxlength);
+
+    sample_spec = GET_STREAM_NEW_SAMPLE_SPEC_PTR(new_data, stream_type);
+    pa_log_info("*** sample_spec: format(%d), rate(%u), channels(%u)",
+                 sample_spec->format, sample_spec->rate, sample_spec->channels);
+
+    if (stream_type ==  STREAM_SINK_INPUT) {
+        tlength_ms = li->tlength_ms;
+        minreq_ms = li->minreq_ms;
+        prebuf_ms = li->prebuf_ms;
+
+        if (minreq_ms > 0)
+            minreq = pa_usec_to_bytes(minreq_ms * 1000, sample_spec);
+        if (tlength_ms > 0)
+            tlength = pa_usec_to_bytes(tlength_ms * 1000, sample_spec);
+        if (prebuf_ms >= 0)
+            prebuf = pa_usec_to_bytes(prebuf_ms * 1000, sample_spec);
+
+        pa_proplist_setf(GET_STREAM_NEW_PROPLIST(new_data, stream_type), PA_PROP_BUFFER_ATTR_TLENGTH, "%d", tlength);
+        pa_proplist_setf(GET_STREAM_NEW_PROPLIST(new_data, stream_type), PA_PROP_BUFFER_ATTR_MINREQ, "%d", minreq);
+        pa_proplist_setf(GET_STREAM_NEW_PROPLIST(new_data, stream_type), PA_PROP_BUFFER_ATTR_PREBUF, "%d", prebuf);
+
+        pa_log_info("*** maxlength:%d, tlength:%d, prebuf:%d, minreq:%d", maxlength, tlength, prebuf, minreq);
+
+    } else if (stream_type == STREAM_SOURCE_OUTPUT) {
+        fragsize_ms = li->fragsize_ms;
+
+        if (fragsize_ms > 0)
+            fragsize = pa_usec_to_bytes(fragsize_ms * 1000, sample_spec);
+
+        pa_proplist_setf(GET_STREAM_NEW_PROPLIST(new_data, stream_type), PA_PROP_BUFFER_ATTR_FRAGSIZE, "%d", fragsize);
+
+        pa_log_info("*** maxlength:%d, fragsize:%d", maxlength, fragsize);
+    }
+
+    return;
+}
+
 static void fill_device_info_to_hook_data(pa_stream_manager *m, void *hook_data, notify_command_type_t command, stream_type_t type, void *stream, bool is_new_data) {
     char *device_none = NULL;
     const char *p_idx = NULL;
@@ -2547,6 +2690,8 @@ static process_stream_result_t process_stream(pa_stream_manager *m, void *stream
                 //return PROCESS_STREAM_RESULT_STOP;
             }
         }
+    } else if (command == PROCESS_COMMAND_UPDATE_BUFFER_ATTR) {
+        update_buffer_attribute(m, stream, type, is_new_data);
     }
 
 FAILURE:
@@ -2554,43 +2699,6 @@ FAILURE:
     return result;
 }
 
-/* Set buffer attributes from HAL */
-static void set_buffer_attribute(pa_stream_manager *m, void *new_data, stream_type_t stream_type) {
-    int32_t maxlength = -1;
-    int32_t tlength = -1;
-    int32_t prebuf = -1;
-    int32_t minreq = -1;
-    int32_t fragsize = -1;
-    hal_stream_info info;
-
-    pa_assert(m);
-    pa_assert(new_data);
-
-    if (m->hal == NULL)
-        return;
-
-    if ((info.latency = pa_proplist_gets(GET_STREAM_NEW_PROPLIST(new_data, stream_type), PA_PROP_MEDIA_TIZEN_AUDIO_LATENCY)))
-        pa_log_info("audio_latency : %s", info.latency);
-    else {
-        pa_log_warn("failed to get audio_latency");
-        return;
-    }
-    info.direction = (io_direction_t)!stream_type;
-    info.sample_spec = GET_STREAM_NEW_SAMPLE_SPEC_PTR(new_data, stream_type);
-
-    if (!pa_hal_interface_get_buffer_attribute(m->hal, &info, (uint32_t*)&maxlength, (uint32_t*)&tlength,
-                                             (uint32_t*)&prebuf, (uint32_t*)&minreq, (uint32_t*)&fragsize)) {
-        pa_log_info(" - maxlength:%d, tlength:%d, prebuf:%d, minreq:%d, fragsize:%d", maxlength, tlength, prebuf, minreq, fragsize);
-        pa_proplist_setf(GET_STREAM_NEW_PROPLIST(new_data, stream_type), "maxlength", "%d", maxlength);
-        pa_proplist_setf(GET_STREAM_NEW_PROPLIST(new_data, stream_type), "tlength",   "%d", tlength);
-        pa_proplist_setf(GET_STREAM_NEW_PROPLIST(new_data, stream_type), "prebuf",    "%d", prebuf);
-        pa_proplist_setf(GET_STREAM_NEW_PROPLIST(new_data, stream_type), "minreq",    "%d", minreq);
-        pa_proplist_setf(GET_STREAM_NEW_PROPLIST(new_data, stream_type), "fragsize",  "%d", fragsize);
-    }
-
-    return;
-}
-
 /* Remove the sink-input from muted streams */
 static void remove_sink_input_from_muted_streams(pa_stream_manager *m, pa_sink_input *i) {
     pa_idxset *streams;
@@ -2614,7 +2722,7 @@ static pa_hook_result_t sink_input_new_cb(pa_core *core, pa_sink_input_new_data
     pa_log_info("start sink_input_new_cb");
 
     process_stream(m, new_data, STREAM_SINK_INPUT, PROCESS_COMMAND_PREPARE, true);
-    set_buffer_attribute(m, new_data, STREAM_SINK_INPUT);
+    process_stream(m, new_data, STREAM_SINK_INPUT, PROCESS_COMMAND_UPDATE_BUFFER_ATTR, true);
     process_stream(m, new_data, STREAM_SINK_INPUT, PROCESS_COMMAND_UPDATE_VOLUME, true);
     process_stream(m, new_data, STREAM_SINK_INPUT, PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_STARTED, true);
 
@@ -2708,7 +2816,7 @@ static pa_hook_result_t source_output_new_cb(pa_core *core, pa_source_output_new
     process_stream(m, new_data, STREAM_SOURCE_OUTPUT, PROCESS_COMMAND_PREPARE, true);
     if (check_restrictions(m, new_data, STREAM_SOURCE_OUTPUT))
         return PA_HOOK_CANCEL;
-    set_buffer_attribute(m, new_data, STREAM_SOURCE_OUTPUT);
+    process_stream(m, new_data, STREAM_SOURCE_OUTPUT, PROCESS_COMMAND_UPDATE_BUFFER_ATTR, true);
     process_stream(m, new_data, STREAM_SOURCE_OUTPUT, PROCESS_COMMAND_UPDATE_VOLUME, true);
     process_stream(m, new_data, STREAM_SOURCE_OUTPUT, PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_STARTED, true);