+static void __streaming_calc_watermark(mmplayer_streaming_t *streamer,
+ guint expected_play_bytes, gint expected_play_time, gdouble *low_wm, gdouble *high_wm)
+{
+#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;
+
+ MMPLAYER_RETURN_IF_FAIL(streamer && low_wm && high_wm);
+
+ 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));
+
+ 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);
+ }
+
+ 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;
+ }
+
+ LOGD("new watermark value [%f ~ %f]", *low_wm, *high_wm);
+}