From: Eunhae Choi Date: Mon, 11 Feb 2019 08:08:42 +0000 (+0900) Subject: [0.6.171] keep buffering minimum level stable X-Git-Tag: submit/tizen/20190213.031645^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ff2922247a8442dbbc6d1a984b9d18a08fb81fb4;p=platform%2Fcore%2Fmultimedia%2Flibmm-player.git [0.6.171] keep buffering minimum level stable - 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 --- diff --git a/packaging/libmm-player.spec b/packaging/libmm-player.spec index be484f5..f81460e 100644 --- a/packaging/libmm-player.spec +++ b/packaging/libmm-player.spec @@ -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 diff --git a/src/include/mm_player_streaming.h b/src/include/mm_player_streaming.h index cc91918..5e40663 100644 --- a/src/include/mm_player_streaming.h +++ b/src/include/mm_player_streaming.h @@ -34,6 +34,13 @@ #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 @@ -68,6 +75,16 @@ } \ } 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; diff --git a/src/mm_player_priv.c b/src/mm_player_priv.c index dd0bf3e..21cf032 100644 --- a/src/mm_player_priv.c +++ b/src/mm_player_priv.c @@ -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; diff --git a/src/mm_player_streaming.c b/src/mm_player_streaming.c index cf73ee1..e8dbf02 100644 --- a/src/mm_player_streaming.c +++ b/src/mm_player_streaming.c @@ -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; }