[0.6.169] use attr for buffering criteria 45/198745/3
authorEunhae Choi <eunhae1.choi@samsung.com>
Tue, 29 Jan 2019 06:14:54 +0000 (15:14 +0900)
committerEunhae Choi <eunhae1.choi@samsung.com>
Tue, 29 Jan 2019 07:42:46 +0000 (16:42 +0900)
- Use attr for prebuffer_ms and rebuffer_ms value
  to seperate between platform default and user requirement.
- In case of TS content, update duration
  via gstreamer query when user ask the duration value
  TS duration is getting accurate over time.
- Add setting about low-watermark property to buffer
  based on the high-watermark.
  If not, according to the user request, the high-watermark
  can be similar with low-watermark which was fixed to 10% of buffer size.

Change-Id: I23f977280479d7264449eea8d947a0997781a9d2

packaging/libmm-player.spec
src/include/mm_player.h
src/include/mm_player_priv.h
src/mm_player.c
src/mm_player_attrs.c
src/mm_player_priv.c
src/mm_player_streaming.c

index 462e070..d2548c4 100644 (file)
@@ -1,6 +1,6 @@
 Name:       libmm-player
 Summary:    Multimedia Framework Player Library
-Version:    0.6.168
+Version:    0.6.169
 Release:    0
 Group:      Multimedia/Libraries
 License:    Apache-2.0
index a75ccd9..2e0b8a6 100644 (file)
  */
 #define MM_PLAYER_AUDIO_CODEC_TYPE          "audio_codec_type"
 
+/**
+ * MM_PLAYER_PREBUFFER_MS
+ *
+ * prebuffer ms (int)
+ */
+#define MM_PLAYER_PREBUFFER_MS              "prebuffer_ms"
+
+/**
+ * MM_PLAYER_REBUFFER_MS
+ *
+ * rebuffer ms (int)
+ */
+#define MM_PLAYER_REBUFFER_MS               "rebuffer_ms"
+
 #define BUFFER_MAX_PLANE_NUM (4)
 
 typedef struct {
@@ -1414,10 +1428,9 @@ int mm_player_set_audio_only(MMHandleType player, bool audio_only);
 int mm_player_get_audio_only(MMHandleType player, bool *audio_only);
 
 /**
- * These functions are to set/get the streaming bufferint time
+ * These functions are to get the streaming bufferint time
  */
-int mm_player_set_streaming_buffering_time(MMHandleType player, int buffer_ms, int rebuffer_ms);
-int mm_player_get_streaming_buffering_time(MMHandleType player, int *buffer_ms, int *rebuffer_ms);
+int mm_player_get_streaming_buffering_time(MMHandleType player, int *prebuffer_ms, int *rebuffer_ms);
 
 /**
  * These functions are to display the 360 video content
index 6478b97..c0b05ee 100644 (file)
@@ -876,8 +876,7 @@ int _mmplayer_set_max_adaptive_variant_limit(MMHandleType hplayer, int bandwidth
 int _mmplayer_get_max_adaptive_variant_limit(MMHandleType hplayer, int *bandwidth, int *width, int *height);
 int _mmplayer_set_audio_only(MMHandleType hplayer, bool audio_only);
 int _mmplayer_get_audio_only(MMHandleType hplayer, bool *paudio_only);
-int _mmplayer_set_streaming_buffering_time(MMHandleType hplayer, int buffer_ms, int rebuffer_ms);
-int _mmplayer_get_streaming_buffering_time(MMHandleType hplayer, int *buffer_ms, int *rebuffer_ms);
+int _mmplayer_get_streaming_buffering_time(MMHandleType hplayer, int *prebuffer_ms, int *rebuffer_ms);
 int _mmplayer_set_codec_type(MMHandleType hplayer, MMPlayerStreamType stream_type, MMPlayerVideoCodecType codec_type);
 int _mmplayer_set_replaygain_enabled(MMHandleType hplayer, bool enabled);
 int _mmplayer_is_replaygain_enabled(MMHandleType hplayer, bool *enabled);
index e79c626..3d19cc3 100644 (file)
@@ -1045,30 +1045,16 @@ int mm_player_get_max_adaptive_variant_limit(MMHandleType player, int *bandwidth
        return result;
 }
 
-int mm_player_set_streaming_buffering_time(MMHandleType player, int buffer_ms, int rebuffer_ms)
-{
-       int result = MM_ERROR_NONE;
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-
-       MMPLAYER_CMD_LOCK(player);
-
-       result = _mmplayer_set_streaming_buffering_time(player, buffer_ms, rebuffer_ms);
-
-       MMPLAYER_CMD_UNLOCK(player);
-
-       return result;
-}
-
-int mm_player_get_streaming_buffering_time(MMHandleType player, int *buffer_ms, int *rebuffer_ms)
+int mm_player_get_streaming_buffering_time(MMHandleType player, int *prebuffer_ms, int *rebuffer_ms)
 {
        int result = MM_ERROR_NONE;
 
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-       MMPLAYER_RETURN_VAL_IF_FAIL(buffer_ms && rebuffer_ms, MM_ERROR_INVALID_ARGUMENT);
+       MMPLAYER_RETURN_VAL_IF_FAIL(prebuffer_ms && rebuffer_ms, MM_ERROR_INVALID_ARGUMENT);
 
        MMPLAYER_CMD_LOCK(player);
 
-       result = _mmplayer_get_streaming_buffering_time(player, buffer_ms, rebuffer_ms);
+       result = _mmplayer_get_streaming_buffering_time(player, prebuffer_ms, rebuffer_ms);
 
        MMPLAYER_CMD_UNLOCK(player);
 
index 14d340f..42dfd2b 100644 (file)
@@ -718,6 +718,24 @@ _mmplayer_construct_attribute(MMHandleType handle)
                        MM_PLAYER_CODEC_TYPE_DEFAULT,
                        MM_PLAYER_CODEC_TYPE_SW
                },
+               {
+                       "prebuffer_ms", /* user setting */
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) MIN_BUFFERING_TIME,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       MIN_BUFFERING_TIME,
+                       MMPLAYER_MAX_INT
+               },
+               {
+                       "rebuffer_ms", /* user setting */
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) MIN_BUFFERING_TIME,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       MIN_BUFFERING_TIME,
+                       MMPLAYER_MAX_INT
+               },
        };
 
        num_of_attrs = ARRAY_SIZE(player_attrs);
index 50e8b4b..dd0bf3e 100644 (file)
@@ -178,7 +178,7 @@ static void         __mmplayer_gst_caps_notify_cb(GstPad *pad, GParamSpec *unused, gpoi
 static void            __mmplayer_audio_stream_send_data(mm_player_t *player, mm_player_audio_stream_buff_t *a_buffer);
 static void            __mmplayer_initialize_storage_info(mm_player_t *player, MMPlayerPathType path_type);
 static int             __resource_release_cb(mm_resource_manager_h rm, mm_resource_manager_res_h res, void *user_data);
-static gboolean __mmplayer_update_duration_attrs(mm_player_t *player, MMHandleType attrs);
+static gboolean __mmplayer_update_duration_value(mm_player_t *player);
 static gboolean __mmplayer_update_audio_attrs(mm_player_t *player, MMHandleType attrs);
 static gboolean __mmplayer_update_video_attrs(mm_player_t *player, MMHandleType attrs);
 static gboolean __mmplayer_update_bitrate_attrs(mm_player_t *player, MMHandleType attrs);
@@ -284,7 +284,7 @@ __mmplayer_update_content_attrs(mm_player_t *player, enum content_attr_flag flag
        }
 
        if ((flag & ATTR_DURATION) || (!has_duration && missing_only) || all)
-               has_duration = __mmplayer_update_duration_attrs(player, attrs);
+               has_duration = __mmplayer_update_duration_value(player);
 
        if ((flag & ATTR_AUDIO) || (!has_audio_attrs && missing_only) || all)
                has_audio_attrs = __mmplayer_update_audio_attrs(player, attrs);
@@ -1108,7 +1108,7 @@ __mmplayer_gst_decode_pad_added(GstElement *elem, GstPad *pad, gpointer data)
 
                /* in case of exporting video frame, it requires the 360 video filter.
                 * it will be handled in _no_more_pads(). */
-               if ((stype == MM_DISPLAY_SURFACE_NULL) && (!player->set_mode.media_packet_video_stream)){
+               if ((stype == MM_DISPLAY_SURFACE_NULL) && (!player->set_mode.media_packet_video_stream)) {
                        __mmplayer_gst_make_fakesink(player, pad, name);
                        goto DONE;
                }
@@ -4804,8 +4804,27 @@ _mmplayer_realize(MMHandleType hplayer)
        __mmplayer_initialize_storage_info(player, MMPLAYER_PATH_MAX);
 
        if ((MMPLAYER_IS_STREAMING(player)) && (player->streamer == NULL)) {
+               gint prebuffer_ms = 0, rebuffer_ms = 0;
+
                player->streamer = __mm_player_streaming_create();
                __mm_player_streaming_initialize(player->streamer, TRUE);
+
+               mm_attrs_get_int_by_name(player->attrs, MM_PLAYER_PREBUFFER_MS, &prebuffer_ms);
+               mm_attrs_get_int_by_name(player->attrs, MM_PLAYER_REBUFFER_MS, &rebuffer_ms);
+
+               if (prebuffer_ms > 0) {
+                       prebuffer_ms = MAX(prebuffer_ms, 1000);
+                       player->streamer->buffering_req.prebuffer_time = prebuffer_ms;
+               }
+
+               if (rebuffer_ms > 0) {
+                       player->streamer->buffering_req.mode = MM_PLAYER_BUFFERING_MODE_FIXED;
+                       rebuffer_ms = MAX(rebuffer_ms, 1000);
+                       player->streamer->buffering_req.rebuffer_time = rebuffer_ms;
+               }
+
+               LOGD("buffering time %d ms, %d ms", player->streamer->buffering_req.prebuffer_time,
+                                                               player->streamer->buffering_req.rebuffer_time);
        }
 
        /* realize pipeline */
@@ -5542,6 +5561,9 @@ _mmplayer_get_duration(MMHandleType hplayer, gint64 *duration)
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
        MMPLAYER_RETURN_VAL_IF_FAIL(duration, MM_ERROR_COMMON_INVALID_ARGUMENT);
 
+       if (g_strrstr(player->type, "video/mpegts"))
+               __mmplayer_update_duration_value(player);
+
        *duration = player->duration;
        return ret;
 }
@@ -5651,11 +5673,16 @@ __mmplayer_update_content_type_info(mm_player_t *player)
                player->streamer->is_adaptive_streaming = TRUE;
        }
 
-       if (player->streamer->is_adaptive_streaming) {
+       /* in case of TS, fixed buffering mode should be used because player can not get exact duration time */
+       if ((player->streamer->is_adaptive_streaming) || (g_strrstr(player->type, "video/mpegts"))) {
                player->streamer->buffering_req.mode = MM_PLAYER_BUFFERING_MODE_FIXED;
 
-               if (player->streamer->buffering_req.rebuffer_time <= MIN_BUFFERING_TIME) /* if user did not set the rebuffer value */
-                       player->streamer->buffering_req.rebuffer_time = DEFAULT_ADAPTIVE_REBUFFER_TIME;
+               if (player->streamer->buffering_req.rebuffer_time <= MIN_BUFFERING_TIME) { /* if user did not set the rebuffer value */
+                       if (player->streamer->is_adaptive_streaming)
+                               player->streamer->buffering_req.rebuffer_time = DEFAULT_ADAPTIVE_REBUFFER_TIME;
+                       else
+                               player->streamer->buffering_req.rebuffer_time = DEFAULT_REBUFFERING_TIME;
+               }
        }
 
        LOGD("uri type : %d, %d", player->profile.uri_type, player->streamer->buffering_req.rebuffer_time);
@@ -5797,19 +5824,18 @@ __mmplayer_gst_make_queue2(mm_player_t *player)
                return NULL;
        }
 
-       /* NOTE : in case of ts streaming, player could not get the correct duration info *
-        *                skip the pull mode(file or ring buffering) setting. */
-       if (g_strrstr(player->type, "video/mpegts"))
-               return queue2;
-
        if (!gst_element_query_duration(mainbin[MMPLAYER_M_SRC].gst, GST_FORMAT_BYTES, &dur_bytes))
                LOGW("failed to get duration from source %s", GST_ELEMENT_NAME(mainbin[MMPLAYER_M_SRC].gst));
 
        LOGD("dur_bytes = %"G_GINT64_FORMAT, dur_bytes);
 
+       /* NOTE : in case of ts streaming, player could not get the correct duration info *
+        *                skip the pull mode(file or ring buffering) setting. */
        if (dur_bytes > 0) {
-               type = MUXED_BUFFER_TYPE_MEM_RING_BUFFER;
-               player->streamer->ring_buffer_size = player->ini.http_ring_buffer_size;
+               if (!g_strrstr(player->type, "video/mpegts")) {
+                       type = MUXED_BUFFER_TYPE_MEM_RING_BUFFER;
+                       player->streamer->ring_buffer_size = player->ini.http_ring_buffer_size;
+               }
        } else {
                dur_bytes = 0;
        }
@@ -5818,7 +5844,7 @@ __mmplayer_gst_make_queue2(mm_player_t *player)
                                                                        queue2,
                                                                        FALSE,
                                                                        type,
-                                                                       (guint64)dur_bytes);
+                                                                       (guint64)dur_bytes); /* no meaning at the moment */
 
        return queue2;
 }
@@ -7943,7 +7969,7 @@ EXIT:
 }
 
 int
- _mmplayer_change_track_language(MMHandleType hplayer, MMPlayerTrackType type, int index)
+_mmplayer_change_track_language(MMHandleType hplayer, MMPlayerTrackType type, int index)
 {
        int result = MM_ERROR_NONE;
        mm_player_t *player = NULL;
@@ -8339,54 +8365,43 @@ _mmplayer_get_max_adaptive_variant_limit(MMHandleType hplayer, int *bandwidth, i
 }
 
 int
-_mmplayer_set_streaming_buffering_time(MMHandleType hplayer, int buffer_ms, int rebuffer_ms)
+_mmplayer_get_streaming_buffering_time(MMHandleType hplayer, int *prebuffer_ms, int *rebuffer_ms)
 {
        int ret = MM_ERROR_NONE;
        mm_player_t *player = (mm_player_t *)hplayer;
+       MMHandleType attrs = 0;
 
        MMPLAYER_FENTER();
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       MMPLAYER_RETURN_VAL_IF_FAIL(prebuffer_ms && rebuffer_ms, MM_ERROR_COMMON_INVALID_ARGUMENT);
 
-       if (MMPLAYER_CURRENT_STATE(player) !=  MM_PLAYER_STATE_NULL)
-               LOGW("buffer_ms will not be applied.");
-
-       LOGD("set buffering time %d ms / %d ms", buffer_ms, rebuffer_ms);
-
-       if (player->streamer == NULL) {
-               player->streamer = __mm_player_streaming_create();
-               __mm_player_streaming_initialize(player->streamer, TRUE);
-       }
-
-       if (buffer_ms >= 0)
-               player->streamer->buffering_req.prebuffer_time = buffer_ms;
+       attrs = MMPLAYER_GET_ATTRS(player);
+       MMPLAYER_RETURN_VAL_IF_FAIL(attrs, MM_ERROR_PLAYER_INTERNAL);
 
-       if (rebuffer_ms >= 0)
-               player->streamer->buffering_req.rebuffer_time = rebuffer_ms;
+       mm_attrs_get_int_by_name(attrs, MM_PLAYER_PREBUFFER_MS, prebuffer_ms);
+       mm_attrs_get_int_by_name(attrs, MM_PLAYER_REBUFFER_MS, rebuffer_ms);
 
-       MMPLAYER_FLEAVE();
-       return ret;
+       LOGD("attr buffering time %d ms / %d ms", *prebuffer_ms, *rebuffer_ms);
 
-}
+       if (MMPLAYER_CURRENT_STATE(player) < MM_PLAYER_STATE_READY) {
+               /* set the platform default (3000 ms) value */
+               if (*prebuffer_ms <= MIN_BUFFERING_TIME)
+                       *prebuffer_ms = DEFAULT_PREBUFFERING_TIME;
 
-int
-_mmplayer_get_streaming_buffering_time(MMHandleType hplayer, int *buffer_ms, int *rebuffer_ms)
-{
-       int ret = MM_ERROR_NONE;
-       mm_player_t *player = (mm_player_t *)hplayer;
+               return ret;
+       }
 
-       MMPLAYER_FENTER();
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-       MMPLAYER_RETURN_VAL_IF_FAIL(buffer_ms && rebuffer_ms, MM_ERROR_COMMON_INVALID_ARGUMENT);
+       MMPLAYER_RETURN_VAL_IF_FAIL(player->streamer, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       MMPLAYER_RETURN_VAL_IF_FAIL(MMPLAYER_IS_STREAMING(player), MM_ERROR_PLAYER_NO_OP);
 
-       if (player->streamer == NULL) {
-               player->streamer = __mm_player_streaming_create();
-               __mm_player_streaming_initialize(player->streamer, TRUE);
-       }
+       *prebuffer_ms = player->streamer->buffering_req.prebuffer_time;
 
-       *buffer_ms = player->streamer->buffering_req.prebuffer_time;
-       *rebuffer_ms = player->streamer->buffering_req.rebuffer_time;
+       if (player->streamer->buffering_req.rebuffer_time > MIN_BUFFERING_TIME)
+               *rebuffer_ms = player->streamer->buffering_req.rebuffer_time;
+       else /* live case */
+               *rebuffer_ms = DEFAULT_LIVE_REBUFFER_TIME;
 
-       LOGD("buffering time %d ms / %d ms", *buffer_ms, *rebuffer_ms);
+       LOGD("buffering time %d ms / %d ms", *prebuffer_ms, *rebuffer_ms);
 
        MMPLAYER_FLEAVE();
        return ret;
@@ -8587,7 +8602,7 @@ _mmplayer_get_video_roi_area(MMHandleType hplayer, double *scale_x, double *scal
 }
 
 static gboolean
-__mmplayer_update_duration_attrs(mm_player_t *player, MMHandleType attrs)
+__mmplayer_update_duration_value(mm_player_t *player)
 {
        gboolean ret = FALSE;
        gint64 dur_nsec = 0;
index 999ed33..6c88132 100644 (file)
@@ -47,7 +47,7 @@ typedef struct {
 } streaming_buffer_info_t;
 
 static void streaming_set_buffer_watermark(mm_player_streaming_t *streamer, BufferType type, gdouble high_watermark_byte, gdouble high_watermark_time);
-static void streaming_set_queue2_queue_type(mm_player_streaming_t *streamer, MuxedBufferType type, guint64 content_size);
+static void streaming_set_queue2_queue_type(mm_player_streaming_t *streamer, MuxedBufferType type);
 static void streaming_set_buffer_size(mm_player_streaming_t *streamer, BufferType type, guint buffering_bytes, gint buffering_time);
 static void streaming_update_buffering_status(mm_player_streaming_t *streamer, GstMessage *buffering_msg, gint64 position);
 static void streaming_get_current_bitrate_info(mm_player_streaming_t *streamer,
@@ -148,8 +148,9 @@ void __mm_player_streaming_destroy(mm_player_streaming_t *streamer)
 void __mm_player_streaming_set_content_bitrate(
        mm_player_streaming_t *streamer, guint max_bitrate, guint avg_bitrate)
 {
-       MMPLAYER_FENTER();
+       gboolean is_update = FALSE;
 
+       MMPLAYER_FENTER();
        MMPLAYER_RETURN_IF_FAIL(streamer);
 
        /* Note : Update buffering criterion bytes
@@ -158,29 +159,22 @@ void __mm_player_streaming_set_content_bitrate(
         *      3. if there are no updated bitrate, use default buffering limit.
         */
        if (max_bitrate > 0 && streamer->buffer_max_bitrate != max_bitrate) {
-               LOGD("set maximum bitrate(%dbps).", max_bitrate);
+               is_update = TRUE;
                streamer->buffer_max_bitrate = max_bitrate;
-               if (streamer->buffering_req.is_pre_buffering == FALSE) {
-                       streamer->need_update = TRUE;
-               } else {
-                       LOGD("pre-buffering...");
-
-                       if (IS_MUXED_BUFFERING_MODE(streamer))
-                               streaming_update_buffer_setting(streamer, NULL, 0, 0, 0);
-               }
        }
 
        if (avg_bitrate > 0 && streamer->buffer_avg_bitrate != avg_bitrate) {
-               LOGD("set average bitrate(%dbps).", avg_bitrate);
+               is_update = TRUE;
                streamer->buffer_avg_bitrate = avg_bitrate;
+       }
 
-               if (streamer->buffering_req.is_pre_buffering == FALSE) {
-                       streamer->need_update = TRUE;
-               } else {
-                       LOGD("pre-buffering...");
-
+       if (is_update) {
+               if (streamer->buffering_req.is_pre_buffering) {
+                       /* have to recalc queue2 size value after getting bitrate information */
                        if (IS_MUXED_BUFFERING_MODE(streamer))
                                streaming_update_buffer_setting(streamer, NULL, 0, 0, 0);
+               } else {
+                       streamer->need_update = TRUE;
                }
        }
 
@@ -188,6 +182,26 @@ void __mm_player_streaming_set_content_bitrate(
        return;
 }
 
+static gdouble streaming_get_min_watermark(gdouble high_watermark, gint max_size_time)
+{
+       gdouble min_threshold = 0.05; /* 5% of buffer size */
+       gdouble max_threshold = 0.1;  /* 10% of buffer size */
+       gdouble low_watermark = 0.0;
+
+       if (max_size_time > 0)
+               min_threshold = (gdouble)500 / max_size_time;  /* watermark for 500 ms */
+
+       low_watermark = high_watermark / 10; /* 10% of hig_watermark */
+
+       LOGD("threshold [%1.3f ~ %1.3f] watermakr[%1.3f ~ %1.3f]",
+               min_threshold, max_threshold, low_watermark, high_watermark);
+
+       low_watermark = MAX(low_watermark, min_threshold);
+       low_watermark = MIN(low_watermark, max_threshold);
+
+       return low_watermark;
+}
+
 static void streaming_set_buffer_watermark(mm_player_streaming_t *streamer,
        BufferType type, gdouble high_watermark_byte, gdouble high_watermark_time)
 {
@@ -226,8 +240,18 @@ static void streaming_set_buffer_watermark(mm_player_streaming_t *streamer,
                GST_ELEMENT_NAME(buffer_handle->buffer), high_watermark);
 
        if ((high_watermark == DEFAULT_BUFFER_HIGH_WATERMARK) ||
-               (buffer_handle->buffer_high_watermark != high_watermark))
-               g_object_set(G_OBJECT(buffer_handle->buffer), "high-watermark", high_watermark, NULL);
+               (buffer_handle->buffer_high_watermark != high_watermark)) {
+               gdouble low_watermark = 0.0;
+
+               /* if the low_watermark is too small, it can cause the underflow issue. */
+               low_watermark = streaming_get_min_watermark(high_watermark, ((type == BUFFER_TYPE_MUXED) ? (0) : (buffer_handle->buffering_time)));
+
+               LOGD("target buffer elem : %s ( %1.3f ~ %1.3f)",
+                       GST_ELEMENT_NAME(buffer_handle->buffer), low_watermark, high_watermark);
+
+               g_object_set(G_OBJECT(buffer_handle->buffer), "high-watermark", high_watermark,
+                                                       "low-watermark", low_watermark, NULL);
+       }
 
        buffer_handle->buffer_high_watermark = high_watermark;
 
@@ -235,8 +259,7 @@ static void streaming_set_buffer_watermark(mm_player_streaming_t *streamer,
        return;
 }
 
-static void streaming_set_queue2_queue_type(mm_player_streaming_t *streamer,
-       MuxedBufferType type, guint64 content_size)
+static void streaming_set_queue2_queue_type(mm_player_streaming_t *streamer, MuxedBufferType type)
 {
        streaming_buffer_t *buffer_handle = NULL;
        guint64 buffer_size = 0;  /* bytes */
@@ -296,7 +319,7 @@ static void streaming_set_buffer_size(mm_player_streaming_t *streamer,
                        buffer_handle->buffering_time = buffering_time;
                        buffer_handle->buffering_bytes = MAX_BUFFER_SIZE_BYTES;
 
-                       LOGD("max-size-time : %d ms", buffering_time);
+                       LOGD("byte: %d, max-size-time : %d ms", buffering_bytes, buffering_time);
                } else {
                        /* queue2 */
                        if (buffer_handle->is_live)
@@ -315,7 +338,7 @@ static void streaming_set_buffer_size(mm_player_streaming_t *streamer,
                        buffer_handle->buffering_bytes = buffering_bytes;
                        buffer_handle->buffering_time = buffering_time;
 
-                       LOGD("max-size-bytes : %d", buffering_bytes);
+                       LOGD("max-size-bytes : %d, time : %d", buffering_bytes, buffering_time);
                }
        }
 
@@ -347,8 +370,10 @@ void __mm_player_streaming_set_queue2(mm_player_streaming_t *streamer, GstElemen
                        streamer->buffer_handle[BUFFER_TYPE_MUXED].is_live = TRUE;
                }
 
-               queue_size_bytes = (guint)(streamer->buffering_req.prebuffer_time / 1000) * ESTIMATED_BUFFER_UNIT;
+               /* keep estimated value till the pipeline share the bitrate information */
+               queue_size_bytes = (guint)(streamer->buffering_req.prebuffer_time / 1000) * ESTIMATED_BUFFER_UNIT; /* temp size */
                queue_size_bytes = MAX(queue_size_bytes, DEFAULT_BUFFER_SIZE_BYTES);
+               queue_size_time = streamer->buffering_req.prebuffer_time;
        } else {
                if (type >= MUXED_BUFFER_TYPE_MAX) {
                        LOGE("invalid queue type");
@@ -357,12 +382,10 @@ void __mm_player_streaming_set_queue2(mm_player_streaming_t *streamer, GstElemen
 
                /* set the simple queue size */
                queue_size_bytes = DEFAULT_BUFFER_SIZE_BYTES;
-               streaming_set_queue2_queue_type(streamer, type, content_size);
+               streaming_set_queue2_queue_type(streamer, type);
+               queue_size_time = 0; /* set in case of use-buffering */
        }
 
-       /* queue_size_time will set to queue2 only in case of live buffering. */
-       queue_size_time = streamer->buffering_req.prebuffer_time;
-
        g_object_set(G_OBJECT(streamer->buffer_handle[BUFFER_TYPE_MUXED].buffer), "use-buffering", use_buffering, NULL);
 
        LOGD("buffer time: %d ms, buffer bytes: %d", queue_size_time, queue_size_bytes);
@@ -376,19 +399,24 @@ void __mm_player_streaming_set_queue2(mm_player_streaming_t *streamer, GstElemen
 void __mm_player_streaming_sync_property(mm_player_streaming_t *streamer, GstElement *decodebin)
 {
        streaming_buffer_t *buffer_handle = NULL;
+       gdouble low_watermark = 0.0;
 
        MMPLAYER_FENTER();
-
        MMPLAYER_RETURN_IF_FAIL(streamer && decodebin);
 
+       if ((!streamer->need_sync) || (streamer->streaming_buffer_type != BUFFER_TYPE_DEMUXED)) {
+               streamer->need_sync = FALSE;
+               return;
+       }
+
        buffer_handle = &(streamer->buffer_handle[BUFFER_TYPE_DEMUXED]);
+       low_watermark = streaming_get_min_watermark(buffer_handle->buffer_high_watermark, buffer_handle->buffering_time);
 
-       if ((streamer->need_sync) && (streamer->streaming_buffer_type == BUFFER_TYPE_DEMUXED)) {
-               g_object_set(G_OBJECT(decodebin),
-                                       "max-size-bytes", buffer_handle->buffering_bytes,
-                                       "max-size-time", (guint64)(buffer_handle->buffering_time * GST_MSECOND),
-                                       "high-percent", (gint)(buffer_handle->buffer_high_watermark * 100), NULL);
-       }
+       g_object_set(G_OBJECT(decodebin),
+                               "max-size-bytes", buffer_handle->buffering_bytes,
+                               "max-size-time", (guint64)(buffer_handle->buffering_time * GST_MSECOND),
+                               "high-percent", (gint)(buffer_handle->buffer_high_watermark * 100),
+                               "low-percent", (gint)(low_watermark * 100), NULL);
 
        streamer->need_sync = FALSE;
 }
@@ -412,8 +440,8 @@ void __mm_player_streaming_set_multiqueue(mm_player_streaming_t *streamer, GstEl
        if (streamer->buffering_req.prebuffer_time <= MIN_BUFFERING_TIME)
                streamer->buffering_req.prebuffer_time = DEFAULT_PREBUFFERING_TIME;
 
-       high_watermark = (gdouble)(streamer->buffering_req.prebuffer_time * 100) / MAX_BUFFER_SIZE_TIME;
-       LOGD("high_watermark %1.3f %%", high_watermark);
+       high_watermark = (gdouble)(streamer->buffering_req.prebuffer_time) / MAX_BUFFER_SIZE_TIME;
+       LOGD("new pre buffer time %d ms, high_watermark %1.3f %%", streamer->buffering_req.prebuffer_time, high_watermark);
 
        /* initial setting */
        streaming_set_buffer_size(streamer, BUFFER_TYPE_DEMUXED, MAX_BUFFER_SIZE_BYTES, MAX_BUFFER_SIZE_TIME);
@@ -482,7 +510,8 @@ static void streaming_get_current_bitrate_info(mm_player_streaming_t *streamer,
 
                LOGD("(avg)content_max_byte_rate %d, byte_out_rate %d", buffer_criteria, out_rate);
        } else {
-               LOGW("There is no content bitrate information");
+               LOGW("There is no content bitrate information, use estimated value");
+               out_rate = estimated_content_bitrate;
        }
 
        if ((in_rate > 0) && (out_rate > 0))
@@ -499,12 +528,11 @@ static void streaming_get_current_bitrate_info(mm_player_streaming_t *streamer,
 }
 
 static void streaming_handle_fixed_buffering_mode(mm_player_streaming_t *streamer,
-       gint byte_out_rate, gint fixed_buffering_time, streaming_buffer_info_t *buffer_info)
+       gint byte_out_rate, gint expected_play_time, streaming_buffer_info_t *buffer_info)
 {
        streaming_buffer_t *buffer_handle = NULL;
 
-       guint buffering_bytes = 0;
-       gint buffering_time = 0;
+       guint expected_play_bytes = 0;
        gdouble wm_byte = 0.0;
        gdouble wm_time = 0.0;
 
@@ -512,28 +540,24 @@ static void streaming_handle_fixed_buffering_mode(mm_player_streaming_t *streame
        MMPLAYER_RETURN_IF_FAIL(buffer_info);
 
        buffer_handle = &(streamer->buffer_handle[streamer->streaming_buffer_type]);
-       buffering_time = fixed_buffering_time;
 
-       LOGD("buffering time: %d ms, out rate: %d", buffering_time, byte_out_rate);
+       LOGD("buffering time: %d ms, out rate: %d", expected_play_time, byte_out_rate);
 
-       if ((buffering_time > 0) && (byte_out_rate > 0)) {
+       if (byte_out_rate > 0) {
                guint max_size_byte = GET_MAX_BYTE_BUFFER_SIZE(streamer->streaming_buffer_type);
-               buffering_bytes = (guint)GET_NEW_BUFFERING_BYTE((gdouble)(byte_out_rate * buffering_time) / 1000, max_size_byte);
+               expected_play_bytes = (guint)GET_NEW_BUFFERING_BYTE((gdouble)(byte_out_rate * expected_play_time) / 1000, max_size_byte);
        } else {
-               if (buffering_time <= 0)
-                       buffering_time = GET_CURRENT_BUFFERING_TIME(buffer_handle);
-
                LOGW("content bitrate is not updated yet.");
-               buffering_bytes = GET_CURRENT_BUFFERING_BYTE(buffer_handle);
+               expected_play_bytes = GET_CURRENT_BUFFERING_BYTE(buffer_handle);
        }
 
-       GET_WATERMARK(buffering_time, GET_CURRENT_BUFFERING_TIME(buffer_handle), buffer_handle->buffer_high_watermark, wm_time);
-       GET_WATERMARK(buffering_bytes, GET_CURRENT_BUFFERING_BYTE(buffer_handle), buffer_handle->buffer_high_watermark, wm_byte);
+       GET_WATERMARK(expected_play_time, GET_CURRENT_BUFFERING_TIME(buffer_handle), buffer_handle->buffer_high_watermark, wm_time);
+       GET_WATERMARK(expected_play_bytes, GET_CURRENT_BUFFERING_BYTE(buffer_handle), buffer_handle->buffer_high_watermark, wm_byte);
 
-       LOGD("bytes %d, time %d, wm_byte %f, wm_time %f", buffering_bytes, buffering_time, wm_byte, wm_time);
+       LOGD("bytes %d, time %d, wm_byte %f, wm_time %f", expected_play_bytes, expected_play_time, wm_byte, wm_time);
 
-       (*buffer_info).buffering_bytes = buffering_bytes;
-       (*buffer_info).buffering_time = buffering_time;
+       (*buffer_info).buffering_bytes = expected_play_bytes;
+       (*buffer_info).buffering_time = expected_play_time;
        (*buffer_info).watermark_byte = wm_byte;
        (*buffer_info).watermark_time = wm_time;
 }