Refactoring Audio-HAL 77/41277/3
authorSun Young Jeong <sy7787.jeong@samsung.com>
Wed, 25 Feb 2015 12:21:32 +0000 (21:21 +0900)
committerHeechul Jeon <heechul.jeon@samsung.com>
Wed, 24 Jun 2015 06:20:08 +0000 (23:20 -0700)
Adjust latency using audio-hal

Change-Id: Iaaf30b959b06b117fd1a24a2f602cf28eba429e4
Signed-off-by: Sun Young Jeong <sy7787.jeong@samsung.com>
src/modules/module-policy.c
src/modules/tizen-audio.h
src/pulse/proplist.h [changed mode: 0644->0755]
src/pulsecore/protocol-native.c

index 41642fd..c6f13b6 100644 (file)
@@ -2740,6 +2740,34 @@ static pa_bool_t policy_is_available_high_latency(struct userdata *u)
     return true;
 }
 
+static void policy_get_buffer_attr(struct userdata       *u,
+                                   audio_latency_t       latency,
+                                   uint32_t              samplerate,
+                                   audio_sample_format_t format,
+                                   uint32_t              channels,
+                                   uint32_t              *maxlength,
+                                   uint32_t              *tlength,
+                                   uint32_t              *prebuf,
+                                   uint32_t              *minreq,
+                                   uint32_t              *fragsize)
+{
+    assert(u);
+    assert(maxlength);
+    assert(tlength);
+    assert(prebuf);
+    assert(minreq);
+    assert(fragsize);
+
+    pa_log_debug("hal-latency : u->intf.audio_mgr.get_buffer_attr(%p)", u->audio_mgr.intf.get_buffer_attr);
+    if (u->audio_mgr.intf.get_buffer_attr != NULL) {
+        audio_return_t ret = u->audio_mgr.intf.get_buffer_attr(u->audio_mgr.data, latency, samplerate, format, channels, maxlength, tlength, prebuf, minreq, fragsize);
+        if (ret != AUDIO_RET_OK) {
+            pa_log_error("Failed get_buffer_attr() - ret:%d", ret);
+        }
+    }
+
+    return;
+}
 #define EXT_VERSION 1
 
 static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connection *c, uint32_t tag, pa_tagstruct *t) {
@@ -3162,6 +3190,38 @@ static void __set_sink_input_role_type(pa_proplist *p, int gain_type)
 
     return;
 }
+
+static void __add_hal_buffer_attr_by_latency(struct userdata* u, pa_proplist* proplist, pa_sample_spec spec) {
+    assert(proplist);
+
+    int         latency       = 0;
+    uint32_t    maxlength     = -1,
+                tlength       = -1,
+                prebuf        = -1,
+                minreq        = -1,
+                fragsize      = -1;
+    const char* audio_latency = pa_proplist_gets(proplist, PA_PROP_MEDIA_TIZEN_AUDIO_LATENCY);
+
+    if (audio_latency == NULL) {
+        return;
+    }
+
+    pa_log_info("hal-latency - auido_latency : %s", audio_latency);
+
+    latency = atoi(audio_latency);
+    pa_log_info("hal-latency - policy_get_buffer_attr(latency:%d, rate:%d, format:%d, channels:%d)", latency, spec.rate, spec.format, spec.channels);
+    policy_get_buffer_attr(u, latency, spec.rate, spec.format, spec.channels,
+                           &maxlength, &tlength, &prebuf, &minreq, &fragsize);
+
+    pa_log_info("hal-latency - buffer_attr -> (maxlength:%d, tlength:%d, prebuf:%d, minreq:%d, fragsize:%d)", maxlength, tlength, prebuf, minreq, fragsize);
+
+    pa_proplist_setf(proplist, "maxlength", "%d", maxlength);
+    pa_proplist_setf(proplist, "tlength",   "%d", tlength);
+    pa_proplist_setf(proplist, "prebuf",    "%d", prebuf);
+    pa_proplist_setf(proplist, "minreq",    "%d", minreq);
+    pa_proplist_setf(proplist, "fragsize",  "%d", fragsize);
+}
+
 /*  Called when new sink-input is creating  */
 static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_new_data *new_data, struct userdata *u)
 {
@@ -3290,6 +3350,10 @@ static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_n
         __free_audio_info(&audio_info);
     }
 
+    /* get buffer_attr by audio latency */
+    pa_log_info("hal-latency - get buffer attr by audio latency");
+    __add_hal_buffer_attr_by_latency(u, new_data->proplist, new_data->sample_spec);
+
 exit:
     if (s) {
         s_info = pa_strbuf_tostring_free(s);
@@ -3915,6 +3979,7 @@ static pa_source* policy_select_proper_source (pa_core *c, const char* policy)
 /*  Called when new source-output is creating  */
 static pa_hook_result_t source_output_new_hook_callback(pa_core *c, pa_source_output_new_data *new_data, struct userdata *u) {
     const char *policy = NULL;
+
     pa_assert(c);
     pa_assert(new_data);
     pa_assert(u);
@@ -3948,6 +4013,10 @@ static pa_hook_result_t source_output_new_hook_callback(pa_core *c, pa_source_ou
     new_data->source= policy_select_proper_source (c, policy);*/
     pa_log_debug("[POLICY][%s] set source of source-input to [%s]", __func__, (new_data->source)? new_data->source->name : "null");
 
+    /* get buffer_attr by audio latency */
+    pa_log_info("hal-latency - get buffer attr by audio latency");
+    __add_hal_buffer_attr_by_latency(u, new_data->proplist, new_data->sample_spec);
+
     return PA_HOOK_OK;
 }
 
@@ -4085,6 +4154,7 @@ int pa__init(pa_module *m)
         u->audio_mgr.intf.set_route = dlsym(u->audio_mgr.dl_handle, "audio_set_route");
         u->audio_mgr.intf.set_mixer_value_string = dlsym(u->audio_mgr.dl_handle, "audio_set_mixer_value_string");
 
+        u->audio_mgr.intf.get_buffer_attr = dlsym(u->audio_mgr.dl_handle, "audio_get_buffer_attr");
         if (u->audio_mgr.intf.init) {
             if (u->audio_mgr.intf.init(&u->audio_mgr.data, (void *)u) != AUDIO_RET_OK) {
                 pa_log_error("audio_mgr init failed");
index b9b12c3..d045cad 100755 (executable)
@@ -226,6 +226,38 @@ typedef enum audio_gain {
     AUDIO_GAIN_TYPE_MAX,
 } audio_gain_t;
 
+/* audio format */
+typedef enum audio_sample_format {
+    AUDIO_SAMPLE_U8,
+    AUDIO_SAMPLE_ALAW,
+    AUDIO_SAMPLE_ULAW,
+    AUDIO_SAMPLE_S16LE,
+    AUDIO_SAMPLE_S16BE,
+    AUDIO_SAMPLE_FLOAT32LE,
+    AUDIO_SAMPLE_FLOAT32BE,
+    AUDIO_SAMPLE_S32LE,
+    AUDIO_SAMPLE_S32BE,
+    AUDIO_SAMPLE_S24LE,
+    AUDIO_SAMPLE_S24BE,
+    AUDIO_SAMPLE_S24_32LE,
+    AUDIO_SAMPLE_S24_32BE,
+    AUDIO_SAMPLE_MAX,
+    AUDIO_SAMPLE_INVALID = -1
+}   audio_sample_format_t;
+
+/* stream latency */
+typedef enum audio_latency {
+    AUDIO_IN_LATENCY_LOW,
+    AUDIO_IN_LATENCY_MID,
+    AUDIO_IN_LATENCY_HIGH,
+    AUDIO_IN_LATENCY_VOIP,
+    AUDIO_OUT_LATENCY_LOW,
+    AUDIO_OUT_LATENCY_MID,
+    AUDIO_OUT_LATENCY_HIGH,
+    AUDIO_OUT_LATENCY_VOIP,
+    AUDIO_LATENCY_MAX
+}   audio_latency_t;
+
 typedef struct audio_stream_info {
     char *name;
     uint32_t samplerate;
@@ -272,7 +304,7 @@ typedef struct audio_interface {
     audio_return_t (*pcm_avail)(void *pcm_handle);
     audio_return_t (*pcm_write)(void *pcm_handle, const void *buffer, uint32_t frames);
     audio_return_t (*set_mixer_value_string)(void *userdata, const char* ctl, const char* value);
-
+    audio_return_t (*get_buffer_attr)(void *userdata, audio_latency_t latency, uint32_t samplerate, audio_sample_format_t format, uint32_t channels, uint32_t *maxlength, uint32_t *tlength, uint32_t *prebuf, uint32_t* minreq, uint32_t *fragsize);
 } audio_interface_t;
 
 int audio_get_revision (void);
@@ -297,4 +329,5 @@ audio_return_t audio_pcm_avail(void *pcm_handle);
 audio_return_t audio_pcm_write(void *pcm_handle, const void *buffer, uint32_t frames);
 audio_return_t audio_set_route (void *userdata, uint32_t session, uint32_t subsession, uint32_t device_in, uint32_t device_out, uint32_t route_flag);
 
+audio_return_t audio_get_buffer_attr(void *userdata, audio_latency_t latency, uint32_t samplerate, audio_sample_format_t format, uint32_t channels, uint32_t *maxlength, uint32_t *tlength, uint32_t *prebuf, uint32_t* minreq, uint32_t *fragsize);
 #endif
old mode 100644 (file)
new mode 100755 (executable)
index 65a93a5..44e03f6
@@ -40,6 +40,9 @@ PA_C_DECL_BEGIN
 #define PA_PROP_MEDIA_TIZEN_FADE_RETURN_VOLUME "media.tizen_fade_return_volume"
 /** For streams: the policy to ignore the preset sink rather use a sink picked by module-policy. One of the strings "yes", "no" */
 #define PA_PROP_MEDIA_POLICY_IGNORE_PRESET_SINK  "media.policy.ignore_preset_sink"
+#define PA_PROP_MEDIA_TIZEN_AUDIO_LATENCY      "media.tizen_audio_latency"
+/** For streams: logic role of this media. One of the strings "auto", "phone" */
+#define PA_PROP_MEDIA_POLICY                "media.policy"
 #endif
 
 /** For streams: localized media name, formatted as UTF-8. E.g. "Guns'N'Roses: Civil War".*/
@@ -74,9 +77,6 @@ PA_C_DECL_BEGIN
 /** For streams: logic role of this media. One of the strings "video", "music", "game", "event", "phone", "animation", "production", "a11y", "test" */
 #define PA_PROP_MEDIA_ROLE                     "media.role"
 
-/** For streams: logic role of this media. One of the strings "auto", "phone" */
-#define PA_PROP_MEDIA_POLICY                "media.policy"
-
 /** For streams: the name of a filter that is desired, e.g.\ "echo-cancel" or "equalizer-sink". PulseAudio may choose to not apply the filter if it does not make sense (for example, applying echo-cancellation on a Bluetooth headset probably does not make sense. \since 1.0 */
 #define PA_PROP_FILTER_WANT                    "filter.want"
 
index f0097b8..e25f55f 100644 (file)
@@ -652,6 +652,62 @@ static void fix_record_buffer_attr_post(record_stream *s) {
         s->buffer_attr.fragsize = s->buffer_attr.maxlength;
 }
 
+#ifdef __TIZEN__
+static int get_buffer_attr_from_hal(pa_proplist* proplist, pa_buffer_attr* ret_attr) {
+    pa_log_debug("hal-latency - __TIZEN__ : get_buffer_attr_from_hal()");
+    uint32_t maxlength = 0;
+    uint32_t tlength   = 0;
+    uint32_t prebuf    = 0;
+    uint32_t minreq    = 0;
+    uint32_t fragsize  = 0;
+
+    pa_assert(ret_attr);
+
+    const char* _propStr = NULL;
+
+    if ((_propStr = pa_proplist_gets(proplist, "maxlength")) == NULL) {
+        pa_log_debug("hal-latency - Failed to get maxlength from HAL");
+        return 0;
+    }
+    maxlength = atoi(_propStr);
+
+    if ((_propStr = pa_proplist_gets(proplist, "tlength")) == NULL) {
+        pa_log_error("hal-latency - Failed to get tlength from HAL");
+        return 0;
+    }
+    tlength = atoi(pa_proplist_gets(proplist, "tlength"));
+
+    if ((_propStr = pa_proplist_gets(proplist, "prebuf")) == NULL) {
+        pa_log_error("hal-latency - Failed to get prebuf from HAL");
+        return 0;
+    }
+    prebuf = atoi(pa_proplist_gets(proplist, "prebuf"));
+
+    if ((_propStr = pa_proplist_gets(proplist, "minreq")) == NULL) {
+        pa_log_error("hal-latency - Failed to get minreq from HAL");
+        return 0;
+    }
+    minreq = atoi(pa_proplist_gets(proplist, "minreq"));
+
+    if ((_propStr = pa_proplist_gets(proplist, "fragsize")) == NULL) {
+        pa_log_error("hal-latency - Failed to get fragsize from HAL");
+        return 0;
+    }
+    fragsize  = atoi(pa_proplist_gets(proplist, "fragsize"));
+
+    ret_attr->maxlength = maxlength;
+    ret_attr->tlength   = tlength;
+    ret_attr->prebuf    = prebuf;
+    ret_attr->minreq    = minreq;
+    ret_attr->fragsize  = fragsize;
+    pa_log_info("hal-latency - update ret_attr->buffer-attr value -> (maxlength:%d, tlength:%d, prebuf:%d, minreq:%d, fragsize:%d)",
+            ret_attr->maxlength, ret_attr->tlength, ret_attr->prebuf, ret_attr->minreq, ret_attr->fragsize);
+
+    return 1;
+}
+
+#endif
+
 /* Called from main context */
 static record_stream* record_stream_new(
         pa_native_connection *c,
@@ -711,6 +767,21 @@ static record_stream* record_stream_new(
 
     *ret = -pa_source_output_new(&source_output, c->protocol->core, &data);
 
+#ifdef __TIZEN__
+    /*
+     * TODO:
+     * Updates buffer_attr using HAL that is requested latency from client
+     */
+    {
+        pa_log_info("hal-latency - __TIZEN__ : playback_stream_new()");
+        pa_buffer_attr hal_attr;
+        if (get_buffer_attr_from_hal(source_output->proplist, &hal_attr) == 1) {
+            pa_log_info("hal-latency - __TIZEN__ : Updates buffer_attr");
+            *attr = hal_attr;
+        }
+    }
+#endif
+
     pa_source_output_new_data_done(&data);
 
     if (!source_output)
@@ -1179,6 +1250,21 @@ static playback_stream* playback_stream_new(
 
     *ret = -pa_sink_input_new(&sink_input, c->protocol->core, &data);
 
+#ifdef __TIZEN__
+    /*
+     * TODO:
+     * Updates buffer_attr using HAL that is requested latency from client
+     */
+    {
+        pa_log_info("hal-latency - __TIZEN__ : playback_stream_new()");
+        pa_buffer_attr hal_attr;
+        if (get_buffer_attr_from_hal(sink_input->proplist, &hal_attr) == 1) {
+            pa_log_info("hal-latency - __TIZEN__ : Updates buffer_attr");
+            *a = hal_attr;
+        }
+    }
+#endif
+
     pa_sink_input_new_data_done(&data);
 
     if (!sink_input)