[0.6.171] keep buffering minimum level stable 18/199418/1 accepted/tizen/unified/20190214.060530 submit/tizen/20190213.031645
authorEunhae Choi <eunhae1.choi@samsung.com>
Mon, 11 Feb 2019 08:08:42 +0000 (17:08 +0900)
committerEunhae Choi <eunhae1.choi@samsung.com>
Mon, 11 Feb 2019 08:08:44 +0000 (17:08 +0900)
- keep buffering minimum level to avoid consecutive buffering.
  if the buffer minimum level is changed according to the buffer size,
  unexpected buffering could be occurred as soon as pre-buffering is finished.
- remove unused code about buffer_criteria
- use macro for reading/writing about current buffering value

Change-Id: I9f29436c0989ef5c56c8b8a44127eac79b02e5da

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

index be484f5..f81460e 100644 (file)
@@ -1,6 +1,6 @@
 Name:       libmm-player
 Summary:    Multimedia Framework Player Library
-Version:    0.6.170
+Version:    0.6.171
 Release:    0
 Group:      Multimedia/Libraries
 License:    Apache-2.0
index cc91918..5e40663 100644 (file)
 #define MAX_BUFFER_PERCENT 100.0
 
 #define DEFAULT_BUFFER_HIGH_WATERMARK 0.99
+#define DEFAULT_BUFFER_LOW_WATERMARK  0.1 /* max of low watermark */
+
+/* low watermark min criteria to avoid buffer underrun */
+#define LOW_WATERMARK_MIN_BYTE_LEVEL 0.05
+#define LOW_WATERMARK_MIN_TIME_VALUE 500
+
+/* low and high watermark criteria */
 #define MIN_BUFFER_WATERMARK 0.0
 #define MAX_BUFFER_WATERMARK 1.0
 
                } \
        } while (0)
 
+#define GET_VALID_VALUE(a, min, max) \
+       do { \
+               if (min >= max) {\
+                       LOGW("invalid max value, take min"); \
+                       a = min; \
+               } else { \
+                       a = MAX(a, min); \
+                       a = MIN(a, max); \
+               } \
+       } while (0)
 
 #define PLAYER_BUFFER_CAST(handle)     ((streaming_buffer_t *)(handle))
 #define PLAYER_STREAM_CAST(sr)         ((mm_player_streaming_t *)(sr))
@@ -78,7 +95,7 @@
 #define IS_MUXED_BUFFERING_MODE(sr)            (PLAYER_STREAM_CAST(sr)->streaming_buffer_type == BUFFER_TYPE_MUXED) ? (TRUE) : (FALSE)
 #define IS_DEMUXED_BUFFERING_MODE(sr)  (PLAYER_STREAM_CAST(sr)->streaming_buffer_type == BUFFER_TYPE_DEMUXED) ? (TRUE) : (FALSE)
 
-#define GET_MAX_BYTE_BUFFER_SIZE(type) ((type == BUFFER_TYPE_MUXED) ? (DEFAULT_RING_BUFFER_SIZE_BYTES) : (MAX_BUFFER_SIZE_BYTES))
+#define GET_MAX_BUFFER_SIZE_BYTES(type) ((type == BUFFER_TYPE_MUXED) ? (DEFAULT_RING_BUFFER_SIZE_BYTES) : (MAX_BUFFER_SIZE_BYTES))
 #define GET_NEW_BUFFERING_BYTE(size, max) ((size) < (max)) ? (size) : (max)
 
 typedef enum {
@@ -111,8 +128,8 @@ typedef struct {
 typedef struct {
        GstElement *buffer;                     /* buffering element of playback pipeline */
 
-       guint buffering_bytes;
-       gint buffering_time;            /* mq : max buffering time value till now */
+       guint buffering_bytes;          /* max buffer size of byte */
+       gint buffering_time;            /* max buffer size of time */
        gdouble buffer_high_watermark;
        gdouble buffer_low_watermark;
 
index dd0bf3e..21cf032 100644 (file)
@@ -8369,29 +8369,10 @@ _mmplayer_get_streaming_buffering_time(MMHandleType hplayer, int *prebuffer_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(player && player->streamer, MM_ERROR_PLAYER_NOT_INITIALIZED);
        MMPLAYER_RETURN_VAL_IF_FAIL(prebuffer_ms && rebuffer_ms, MM_ERROR_COMMON_INVALID_ARGUMENT);
-
-       attrs = MMPLAYER_GET_ATTRS(player);
-       MMPLAYER_RETURN_VAL_IF_FAIL(attrs, MM_ERROR_PLAYER_INTERNAL);
-
-       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);
-
-       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;
-
-               return ret;
-       }
-
-       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);
 
        *prebuffer_ms = player->streamer->buffering_req.prebuffer_time;
index cf73ee1..e8dbf02 100644 (file)
@@ -30,7 +30,6 @@ typedef struct {
        gint byte_in_rate;              // byte
        gint byte_out_rate;             // byte
        gint time_rate;                 // ms
-       guint buffer_criteria;  // byte
 } streaming_bitrate_info_t;
 
 typedef struct {
@@ -42,11 +41,11 @@ typedef struct {
 typedef struct {
        guint buffering_bytes;          // bytes
        gint buffering_time;            // ms
-       gdouble watermark_byte;
-       gdouble watermark_time;
+       gdouble low_watermark;
+       gdouble high_watermark;
 } 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_buffer_watermark(mm_player_streaming_t *streamer, BufferType type, gdouble low_watermark, gdouble high_watermark);
 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);
@@ -97,8 +96,8 @@ static void streaming_buffer_initialize(streaming_buffer_t *buffer_handle, gbool
        buffer_handle->buffering_bytes = DEFAULT_BUFFER_SIZE_BYTES;
        buffer_handle->buffering_time = DEFAULT_BUFFERING_TIME;
        buffer_handle->buffer_high_watermark = DEFAULT_BUFFER_HIGH_WATERMARK;
+       buffer_handle->buffer_low_watermark = DEFAULT_BUFFER_LOW_WATERMARK;
        buffer_handle->is_live = FALSE;
-
 }
 
 void __mm_player_streaming_initialize(mm_player_streaming_t *streamer, gboolean buffer_init)
@@ -153,17 +152,12 @@ void __mm_player_streaming_set_content_bitrate(
        MMPLAYER_FENTER();
        MMPLAYER_RETURN_IF_FAIL(streamer);
 
-       /* Note : Update buffering criterion bytes
-        *      1. maximum bitrate is considered first.
-        *      2. average bitrage * 3 is next.
-        *      3. if there are no updated bitrate, use default buffering limit.
-        */
-       if (max_bitrate > 0 && streamer->buffer_max_bitrate != max_bitrate) {
+       if (max_bitrate > 0 && max_bitrate != streamer->buffer_max_bitrate) {
                is_update = TRUE;
                streamer->buffer_max_bitrate = max_bitrate;
        }
 
-       if (avg_bitrate > 0 && streamer->buffer_avg_bitrate != avg_bitrate) {
+       if (avg_bitrate > 0 && avg_bitrate != streamer->buffer_avg_bitrate) {
                is_update = TRUE;
                streamer->buffer_avg_bitrate = avg_bitrate;
        }
@@ -182,31 +176,77 @@ void __mm_player_streaming_set_content_bitrate(
        return;
 }
 
-static gdouble streaming_get_min_watermark(gdouble high_watermark, gint max_size_time)
+static void streaming_calc_watermark(mm_player_streaming_t *streamer,
+       guint expected_play_bytes, gint expected_play_time, gdouble *low_wm, gdouble *high_wm)
 {
-       gdouble min_threshold = 0.05; /* 5% of buffer size */
-       gdouble max_threshold = 0.1;  /* 10% of buffer size */
-       gdouble low_watermark = 0.0;
+#define PORTION_OF_HIGH_WM 1.1 /* need to compensate about low level */
+#define PORTION_OF_LOW_WM 0.1
+
+       streaming_buffer_t *buffer_handle = NULL;
+       gdouble wm_byte = 0.0, wm_time = 0.0;
+       gint current_buffering_size = 0;
 
-       if (max_size_time > 0)
-               min_threshold = (gdouble)500 / max_size_time;  /* watermark for 500 ms */
+       MMPLAYER_RETURN_IF_FAIL(streamer && low_wm && high_wm);
 
-       low_watermark = high_watermark / 10; /* 10% of hig_watermark */
+       buffer_handle = &(streamer->buffer_handle[streamer->streaming_buffer_type]);
+
+       LOGD("type %d, bytes %d / %d, time %d / %d", streamer->streaming_buffer_type,
+               expected_play_bytes, GET_CURRENT_BUFFERING_BYTE(buffer_handle),
+               expected_play_time, GET_CURRENT_BUFFERING_TIME(buffer_handle));
 
-       LOGD("threshold [%1.3f ~ %1.3f] watermakr[%1.3f ~ %1.3f]",
-               min_threshold, max_threshold, low_watermark, high_watermark);
+       if (expected_play_bytes > 0) {
+               /* and buffer size will be increased */
+               current_buffering_size = MAX(GET_CURRENT_BUFFERING_BYTE(buffer_handle), (expected_play_bytes * PORTION_OF_HIGH_WM));
+               GET_WATERMARK((expected_play_bytes * PORTION_OF_HIGH_WM), current_buffering_size, buffer_handle->buffer_high_watermark, wm_byte);
+               wm_byte = MIN(wm_byte, DEFAULT_BUFFER_HIGH_WATERMARK);
+       }
 
-       low_watermark = MAX(low_watermark, min_threshold);
-       low_watermark = MIN(low_watermark, max_threshold);
+       if (IS_MUXED_BUFFERING_MODE(streamer)) {
+               *high_wm = wm_byte;
+               *low_wm = wm_byte * PORTION_OF_LOW_WM;
+
+               /* If user set the very low level buffering time,
+                  buffer underrun could be occurred even if the min range is considered. */
+               GET_VALID_VALUE((*low_wm), LOW_WATERMARK_MIN_BYTE_LEVEL, DEFAULT_BUFFER_LOW_WATERMARK);
+       } else {
+               gdouble prev_low_wm_time = 0.0;
+               gdouble low_wm_time = 0.0, high_wm_time = 0.0;
+
+               expected_play_time = MAX(expected_play_time, LOW_WATERMARK_MIN_TIME_VALUE);
+               low_wm_time = expected_play_time * PORTION_OF_LOW_WM;
+               high_wm_time = expected_play_time * PORTION_OF_HIGH_WM;
+
+               /* 1. Get min watermark value */
+               /* 1-1. get max buffer size, expected time could be greater than current one */
+               LOGE("low wm time : %.3f ms", low_wm_time);
+               current_buffering_size = MAX(GET_CURRENT_BUFFERING_TIME(buffer_handle), high_wm_time);
+
+               /* 1-2. get previous low time value to keep the minimum watermark */
+               prev_low_wm_time = GET_CURRENT_BUFFERING_TIME(buffer_handle) * buffer_handle->buffer_low_watermark;
+               GET_VALID_VALUE(low_wm_time, LOW_WATERMARK_MIN_TIME_VALUE, prev_low_wm_time);
+
+               /* 1-3. get min watermark value based on the max buffer size */
+               GET_WATERMARK(low_wm_time, current_buffering_size, buffer_handle->buffer_low_watermark, *low_wm);
+               *low_wm = MIN(*low_wm, DEFAULT_BUFFER_LOW_WATERMARK);
+
+               /* 2. Get high watermark value.
+                     If the expected time is greater than current one, the buffer size will be increased after */
+               GET_WATERMARK(high_wm_time, current_buffering_size, buffer_handle->buffer_high_watermark, wm_time);
+               *high_wm = MAX(wm_byte, wm_time);
+               *high_wm = MIN(*high_wm, DEFAULT_BUFFER_HIGH_WATERMARK);
+       }
+
+       if (*low_wm >= *high_wm) {
+               LOGW("invalid high wm value %1.3f", *high_wm);
+               *high_wm = DEFAULT_BUFFER_HIGH_WATERMARK;
+       }
 
-       return low_watermark;
+       LOGD("new watermark value [%f ~ %f]", *low_wm, *high_wm);
 }
 
 static void streaming_set_buffer_watermark(mm_player_streaming_t *streamer,
-       BufferType type, gdouble high_watermark_byte, gdouble high_watermark_time)
+       BufferType type, gdouble low_watermark, gdouble high_watermark)
 {
-       gdouble high_watermark = 0.0;
-
        streaming_buffer_t *buffer_handle = NULL;
        gchar *factory_name = NULL;
 
@@ -227,33 +267,23 @@ static void streaming_set_buffer_watermark(mm_player_streaming_t *streamer,
                return;
        }
 
-       if (type == BUFFER_TYPE_MUXED)
-               high_watermark = high_watermark_byte;
-       else
-               high_watermark = MAX(high_watermark_time, high_watermark_byte);
-
        if (high_watermark <= MIN_BUFFER_WATERMARK || high_watermark  >=  MAX_BUFFER_WATERMARK)
                high_watermark = DEFAULT_BUFFER_HIGH_WATERMARK;
 
-       /* if use-buffering is disabled, this settings do not have any meaning. */
-       LOGD("target buffer elem : %s (~ %1.3f)",
-               GST_ELEMENT_NAME(buffer_handle->buffer), high_watermark);
+       if (low_watermark <= MIN_BUFFER_WATERMARK || low_watermark >= MAX_BUFFER_WATERMARK)
+               low_watermark = DEFAULT_BUFFER_LOW_WATERMARK;
 
+       /* if use-buffering is disabled, this settings do not have any meaning. */
        if ((high_watermark == DEFAULT_BUFFER_HIGH_WATERMARK) ||
-               (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);
-
+               (buffer_handle->buffer_high_watermark != high_watermark) ||
+               (buffer_handle->buffer_low_watermark != low_watermark))
                g_object_set(G_OBJECT(buffer_handle->buffer), "high-watermark", high_watermark,
                                                        "low-watermark", low_watermark, NULL);
-       }
+
+       LOGD("update elem:%s, wm:%1.3f ~ %1.3f", GST_ELEMENT_NAME(buffer_handle->buffer), low_watermark, high_watermark);
 
        buffer_handle->buffer_high_watermark = high_watermark;
+       buffer_handle->buffer_low_watermark = low_watermark;
 
        MMPLAYER_FLEAVE();
        return;
@@ -314,10 +344,10 @@ static void streaming_set_buffer_size(mm_player_streaming_t *streamer,
                        g_object_set(G_OBJECT(buffer_handle->buffer),
                                                        "max-size-bytes", MAX_BUFFER_SIZE_BYTES,        /* mq size is fixed, control it with high/low watermark value*/
                                                        "max-size-time", (guint64)(buffering_time * GST_MSECOND),
-                                                       "max-size-buffers", 0, NULL);                                           /* disable */
+                                                       "max-size-buffers", 0, NULL);                           /* disable */
 
-                       buffer_handle->buffering_time = buffering_time;
-                       buffer_handle->buffering_bytes = MAX_BUFFER_SIZE_BYTES;
+                       GET_CURRENT_BUFFERING_TIME(buffer_handle) = buffering_time;
+                       GET_CURRENT_BUFFERING_BYTE(buffer_handle) = MAX_BUFFER_SIZE_BYTES;
 
                        LOGD("byte: %d, max-size-time : %d ms", buffering_bytes, buffering_time);
                } else {
@@ -335,8 +365,8 @@ static void streaming_set_buffer_size(mm_player_streaming_t *streamer,
                                                                "max-size-buffers", 0,
                                                                "use-rate-estimate", FALSE, NULL);
 
-                       buffer_handle->buffering_bytes = buffering_bytes;
-                       buffer_handle->buffering_time = buffering_time;
+                       GET_CURRENT_BUFFERING_BYTE(buffer_handle) = buffering_bytes;
+                       GET_CURRENT_BUFFERING_TIME(buffer_handle) = buffering_time;
 
                        LOGD("max-size-bytes : %d, time : %d", buffering_bytes, buffering_time);
                }
@@ -390,7 +420,7 @@ void __mm_player_streaming_set_queue2(mm_player_streaming_t *streamer, GstElemen
 
        LOGD("buffer time: %d ms, buffer bytes: %d", queue_size_time, queue_size_bytes);
        streaming_set_buffer_size(streamer, BUFFER_TYPE_MUXED, queue_size_bytes, queue_size_time);
-       streaming_set_buffer_watermark(streamer, BUFFER_TYPE_MUXED, DEFAULT_BUFFER_HIGH_WATERMARK, 0);
+       streaming_set_buffer_watermark(streamer, BUFFER_TYPE_MUXED, DEFAULT_BUFFER_LOW_WATERMARK, DEFAULT_BUFFER_HIGH_WATERMARK);
 
        MMPLAYER_FLEAVE();
        return;
@@ -399,7 +429,6 @@ 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);
@@ -410,14 +439,13 @@ void __mm_player_streaming_sync_property(mm_player_streaming_t *streamer, GstEle
        }
 
        buffer_handle = &(streamer->buffer_handle[BUFFER_TYPE_DEMUXED]);
-       low_watermark = streaming_get_min_watermark(buffer_handle->buffer_high_watermark, buffer_handle->buffering_time);
 
-       LOGD("sync : %1.3f ~ %1.3f", low_watermark, buffer_handle->buffer_high_watermark);
+       LOGD("sync : %1.3f ~ %1.3f", buffer_handle->buffer_low_watermark, buffer_handle->buffer_high_watermark);
        g_object_set(G_OBJECT(decodebin),
-                               "max-size-bytes", buffer_handle->buffering_bytes,
-                               "max-size-time", (guint64)(buffer_handle->buffering_time * GST_MSECOND),
+                               "max-size-bytes", GET_CURRENT_BUFFERING_BYTE(buffer_handle),
+                               "max-size-time", (guint64)(GET_CURRENT_BUFFERING_TIME(buffer_handle) * GST_MSECOND),
                                "high-percent", (gint)(buffer_handle->buffer_high_watermark * 100),
-                               "low-percent", (gint)(low_watermark * 100), NULL);
+                               "low-percent", (gint)(buffer_handle->buffer_low_watermark * 100), NULL);
 
        streamer->need_sync = FALSE;
 }
@@ -425,7 +453,7 @@ void __mm_player_streaming_sync_property(mm_player_streaming_t *streamer, GstEle
 void __mm_player_streaming_set_multiqueue(mm_player_streaming_t *streamer, GstElement *buffer)
 {
        streaming_buffer_t *buffer_handle = NULL;
-       gdouble high_watermark = 0.0;
+       gdouble high_wm = 0.0, low_wm = 0.0;
 
        MMPLAYER_FENTER();
        MMPLAYER_RETURN_IF_FAIL(streamer && buffer);
@@ -441,12 +469,11 @@ 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) / 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);
-       streaming_set_buffer_watermark(streamer, BUFFER_TYPE_DEMUXED, 0, high_watermark);
+
+       streaming_calc_watermark(streamer, 0, streamer->buffering_req.prebuffer_time, &low_wm, &high_wm);
+       streaming_set_buffer_watermark(streamer, BUFFER_TYPE_DEMUXED, low_wm, high_wm);
 
        streamer->need_sync = TRUE;
 
@@ -463,7 +490,6 @@ static void streaming_get_current_bitrate_info(mm_player_streaming_t *streamer,
        gint out_rate = 0;
        gint64 buffering_left = -1;
 
-       guint buffer_criteria = 0;
        guint estimated_content_bitrate = 0;
 
        gint buffer_buffering_time = DEFAULT_BUFFERING_TIME;
@@ -494,26 +520,18 @@ static void streaming_get_current_bitrate_info(mm_player_streaming_t *streamer,
        if (streamer->buffer_max_bitrate > 0) {
                streamer->buffer_max_bitrate = MAX(streamer->buffer_max_bitrate, streamer->buffer_avg_bitrate);
                streamer->buffer_max_bitrate = MAX(streamer->buffer_max_bitrate, estimated_content_bitrate);
+       }
 
-               buffer_criteria = GET_BYTE_FROM_BIT(streamer->buffer_max_bitrate);
-
-               if (streamer->buffer_avg_bitrate > estimated_content_bitrate)
-                       out_rate = GET_BYTE_FROM_BIT(streamer->buffer_avg_bitrate);
-               else if (estimated_content_bitrate != 0)
-                       out_rate = GET_BYTE_FROM_BIT(estimated_content_bitrate);
-               else
-                       out_rate = GET_BYTE_FROM_BIT(streamer->buffer_max_bitrate/3);
-
-               LOGD("(max)content_max_byte_rate %d, byte_out_rate %d", buffer_criteria, out_rate);
-       } else if (streamer->buffer_avg_bitrate > 0) {
-               buffer_criteria = GET_BYTE_FROM_BIT(streamer->buffer_avg_bitrate * 3);
+       if (streamer->buffer_avg_bitrate > 0)
                out_rate = GET_BYTE_FROM_BIT(MAX(streamer->buffer_avg_bitrate, estimated_content_bitrate));
+       else if (estimated_content_bitrate > 0)
+               out_rate = GET_BYTE_FROM_BIT(estimated_content_bitrate);
+       else if (streamer->buffer_max_bitrate > 0)
+               out_rate = GET_BYTE_FROM_BIT(streamer->buffer_max_bitrate/3);
+       else
+               LOGW("There is no content information");
 
-               LOGD("(avg)content_max_byte_rate %d, byte_out_rate %d", buffer_criteria, out_rate);
-       } else {
-               LOGW("There is no content bitrate information, use estimated value");
-               out_rate = estimated_content_bitrate;
-       }
+       LOGD("byte_out_rate %d", out_rate);
 
        if ((in_rate > 0) && (out_rate > 0))
                buffer_buffering_time =  (gint)(out_rate / in_rate) * 1000;
@@ -525,7 +543,6 @@ static void streaming_get_current_bitrate_info(mm_player_streaming_t *streamer,
        (*bitrate_info).byte_in_rate = in_rate;
        (*bitrate_info).byte_out_rate = out_rate;
        (*bitrate_info).time_rate = buffer_buffering_time;
-       (*bitrate_info).buffer_criteria = buffer_criteria;
 }
 
 static void streaming_handle_fixed_buffering_mode(mm_player_streaming_t *streamer,
@@ -534,8 +551,7 @@ static void streaming_handle_fixed_buffering_mode(mm_player_streaming_t *streame
        streaming_buffer_t *buffer_handle = NULL;
 
        guint expected_play_bytes = 0;
-       gdouble wm_byte = 0.0;
-       gdouble wm_time = 0.0;
+       gdouble high_wm = 0.0, low_wm = 0.0;
 
        MMPLAYER_RETURN_IF_FAIL(streamer);
        MMPLAYER_RETURN_IF_FAIL(buffer_info);
@@ -545,45 +561,38 @@ static void streaming_handle_fixed_buffering_mode(mm_player_streaming_t *streame
        LOGD("buffering time: %d ms, out rate: %d", expected_play_time, byte_out_rate);
 
        if (byte_out_rate > 0) {
-               guint max_size_byte = GET_MAX_BYTE_BUFFER_SIZE(streamer->streaming_buffer_type);
+               guint max_size_byte = GET_MAX_BUFFER_SIZE_BYTES(streamer->streaming_buffer_type);
                expected_play_bytes = (guint)GET_NEW_BUFFERING_BYTE((gdouble)(byte_out_rate * expected_play_time) / 1000, max_size_byte);
        } else {
                LOGW("content bitrate is not updated yet.");
                expected_play_bytes = GET_CURRENT_BUFFERING_BYTE(buffer_handle);
        }
 
-       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", expected_play_bytes, expected_play_time, wm_byte, wm_time);
+       streaming_calc_watermark(streamer, expected_play_bytes, expected_play_time, &low_wm, &high_wm);
 
        (*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;
+       (*buffer_info).high_watermark = high_wm;
+       (*buffer_info).low_watermark = low_wm;
 }
 
 static void streaming_handle_adaptive_buffering_mode(mm_player_streaming_t *streamer,
        streaming_content_info_t content_info, streaming_bitrate_info_t bitrate_info,
        streaming_buffer_info_t *buffer_info, gint expected_play_time)
 {
-       streaming_buffer_t *buffer_handle = NULL;
-
        gint buffering_bytes = 0;
        gint adj_buffering_bytes = 0;
        gint buffer_buffering_time = 0;
-       gdouble wm_byte = 0.0;
-       gdouble wm_time = 0.0;
+       gdouble high_wm = 0.0, low_wm = 0.0;
        gdouble portion = 0.0;
        gint default_buffering_time = 0;
 
        MMPLAYER_RETURN_IF_FAIL(streamer);
        MMPLAYER_RETURN_IF_FAIL(buffer_info);
 
-       LOGD("pos %"G_GINT64_FORMAT", dur %"G_GINT64_FORMAT", size %"G_GUINT64_FORMAT", in/out:%d/%d, buffer_criteria:%d, time_rate:%d, need:%d ms",
-                                                       content_info.position, content_info.duration, content_info.content_size,
-                                                       bitrate_info.byte_in_rate, bitrate_info.byte_out_rate,
-                                                       bitrate_info.buffer_criteria, bitrate_info.time_rate, expected_play_time);
+       LOGD("monitor %d, pos %"G_GINT64_FORMAT", dur %"G_GINT64_FORMAT", size %"G_GUINT64_FORMAT", in/out:%d/%d, time_rate:%d, need:%d ms",
+                                       streamer->default_val.buffering_monitor, content_info.position, content_info.duration, content_info.content_size,
+                                       bitrate_info.byte_in_rate, bitrate_info.byte_out_rate, bitrate_info.time_rate, expected_play_time);
 
        if ((content_info.duration <= 0) ||
                (content_info.content_size <= 0)) {
@@ -591,15 +600,13 @@ static void streaming_handle_adaptive_buffering_mode(mm_player_streaming_t *stre
                return;
        }
 
-       if ((bitrate_info.byte_out_rate <= 0) || (bitrate_info.buffer_criteria == 0)) {
+       if (bitrate_info.byte_out_rate <= 0) {
                LOGW("keep previous setting.");
                return;
        }
 
-       buffer_handle = &(streamer->buffer_handle[streamer->streaming_buffer_type]);
-
        if (bitrate_info.byte_in_rate < bitrate_info.byte_out_rate) {
-               guint max_size_byte = GET_MAX_BYTE_BUFFER_SIZE(streamer->streaming_buffer_type);
+               guint max_size_byte = GET_MAX_BUFFER_SIZE_BYTES(streamer->streaming_buffer_type);
                portion = (double)(expected_play_time * GST_MSECOND) / (double)content_info.duration;
                buffering_bytes = GET_NEW_BUFFERING_BYTE(
                        (((double)content_info.content_size * portion) *
@@ -624,13 +631,11 @@ static void streaming_handle_adaptive_buffering_mode(mm_player_streaming_t *stre
        }
 
        if (buffer_buffering_time < default_buffering_time) {
-               guint max_size_byte = GET_MAX_BYTE_BUFFER_SIZE(streamer->streaming_buffer_type);
+               guint max_size_byte = GET_MAX_BUFFER_SIZE_BYTES(streamer->streaming_buffer_type);
 
                LOGD("adjusted time: %d -> %d ms", buffer_buffering_time, default_buffering_time);
-               LOGD("adjusted bytes : %d or %d or %d",
-                       buffering_bytes,
-                       (gint)(bitrate_info.byte_out_rate * buffer_buffering_time / 1000),
-                       (gint)(bitrate_info.buffer_criteria * buffer_buffering_time / 1000));
+               LOGD("adjusted bytes : %d or %d", buffering_bytes,
+                       (gint)(bitrate_info.byte_out_rate * buffer_buffering_time / 1000));
 
                /* start monitoring the abmormal state */
                if (content_info.position > 0)
@@ -642,18 +647,12 @@ static void streaming_handle_adaptive_buffering_mode(mm_player_streaming_t *stre
                buffering_bytes = MAX(buffering_bytes, adj_buffering_bytes);
        }
 
-       GET_WATERMARK(buffering_bytes, GET_CURRENT_BUFFERING_BYTE(buffer_handle), buffer_handle->buffer_high_watermark, wm_byte);
-       GET_WATERMARK(buffer_buffering_time, GET_CURRENT_BUFFERING_TIME(buffer_handle), buffer_handle->buffer_high_watermark, wm_time);
-
-       LOGD("monitor %d, bytes %d, time %d, wm_byte %f, wm_time %f",
-                                                                               streamer->default_val.buffering_monitor,
-                                                                               buffering_bytes, buffer_buffering_time, wm_byte, wm_time);
+       streaming_calc_watermark(streamer, buffering_bytes, buffer_buffering_time, &low_wm, &high_wm);
 
        (*buffer_info).buffering_bytes = buffering_bytes;
        (*buffer_info).buffering_time = buffer_buffering_time;
-       (*buffer_info).watermark_byte = wm_byte;
-       (*buffer_info).watermark_time = wm_time;
-
+       (*buffer_info).high_watermark = high_wm;
+       (*buffer_info).low_watermark = low_wm;
 }
 
 static void streaming_update_buffer_setting(mm_player_streaming_t *streamer,
@@ -663,18 +662,13 @@ static void streaming_update_buffer_setting(mm_player_streaming_t *streamer,
        MMPlayerBufferingMode buffering_mode = MM_PLAYER_BUFFERING_MODE_ADAPTIVE;
        gint expected_play_time = DEFAULT_REBUFFERING_TIME;
 
-       streaming_buffer_info_t buffer_info;
-       streaming_content_info_t content_info;
-       streaming_bitrate_info_t bitrate_info;
+       streaming_buffer_info_t buffer_info = {0,};
+       streaming_content_info_t content_info = {0,};
+       streaming_bitrate_info_t bitrate_info = {0,};
 
        MMPLAYER_FENTER();
-
        MMPLAYER_RETURN_IF_FAIL(streamer);
 
-       memset(&buffer_info, 0x00, sizeof(streaming_buffer_info_t));
-       memset(&content_info, 0x00, sizeof(streaming_content_info_t));
-       memset(&bitrate_info, 0x00, sizeof(streaming_bitrate_info_t));
-
        buffer_handle = &(streamer->buffer_handle[streamer->streaming_buffer_type]);
 
        if (streamer->buffering_req.is_pre_buffering == TRUE) {
@@ -696,11 +690,6 @@ static void streaming_update_buffer_setting(mm_player_streaming_t *streamer,
 
        LOGD("buffering mode: %d, time: %d", buffering_mode, expected_play_time);
 
-       buffer_info.buffering_bytes = buffer_handle->buffering_bytes;
-       buffer_info.buffering_time = buffer_handle->buffering_time;
-       buffer_info.watermark_byte = buffer_handle->buffer_high_watermark;
-       buffer_info.watermark_time = buffer_handle->buffer_high_watermark;
-
        content_info.position = position;
        content_info.duration = duration;
        content_info.content_size = content_size;
@@ -716,7 +705,7 @@ static void streaming_update_buffer_setting(mm_player_streaming_t *streamer,
 
                /* even if new byte size is smaller than the previous one, time need to be updated. */
                if (IS_MUXED_BUFFERING_MODE(streamer))
-                       buffer_handle->buffering_time = buffer_info.buffering_time;
+                       GET_CURRENT_BUFFERING_TIME(buffer_handle) = buffer_info.buffering_time;
        }
 
        LOGD("adj buffer(%d) %d->%d bytes/%d->%d ms",
@@ -733,16 +722,13 @@ static void streaming_update_buffer_setting(mm_player_streaming_t *streamer,
                        if (buffer_info.buffering_time > buffering_time_limit)
                                buffer_info.buffering_time = buffering_time_limit;
                }
-
                streaming_set_buffer_size(streamer, streamer->streaming_buffer_type, buffer_info.buffering_bytes, buffer_info.buffering_time);
        }
 
-       streaming_set_buffer_watermark(streamer, streamer->streaming_buffer_type, buffer_info.watermark_byte, buffer_info.watermark_time);
+       streaming_set_buffer_watermark(streamer, streamer->streaming_buffer_type, buffer_info.low_watermark, buffer_info.high_watermark);
 
-       LOGD("buffer setting: size %d, time %d, watermark %f",
-               GET_CURRENT_BUFFERING_BYTE(buffer_handle),
-               GET_CURRENT_BUFFERING_TIME(buffer_handle),
-               buffer_handle->buffer_high_watermark);
+       LOGD("buffer setting: size %d, time %d, watermark %f", GET_CURRENT_BUFFERING_BYTE(buffer_handle),
+               GET_CURRENT_BUFFERING_TIME(buffer_handle), buffer_handle->buffer_high_watermark);
 
        streamer->need_sync = TRUE;
 }