From e661c6c9400f122b603718c79c4b12ca68b69717 Mon Sep 17 00:00:00 2001 From: Eunhae Choi Date: Mon, 7 Jan 2019 17:04:51 +0900 Subject: [PATCH] [0.6.165] use unified pre-buffering time - use 3sec buffering time for pre-buffering with fixed mode buffering. - use 32MB/15sec buffer size for multiqueue regardless of the streaming type. - change the interface for setting queue2 and multiqueue. - remove unused ini attribute. Change-Id: I5e586bdf932fffcd0e636fa0d0396de86206262e --- packaging/libmm-player.spec | 2 +- src/include/mm_player_ini.h | 4 - src/include/mm_player_streaming.h | 65 ++++----- src/mm_player_ini.c | 6 - src/mm_player_priv.c | 108 +++++++-------- src/mm_player_streaming.c | 278 ++++++++++++++------------------------ 6 files changed, 184 insertions(+), 279 deletions(-) diff --git a/packaging/libmm-player.spec b/packaging/libmm-player.spec index 74ec0ba..64db238 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.164 +Version: 0.6.165 Release: 0 Group: Multimedia/Libraries License: Apache-2.0 diff --git a/src/include/mm_player_ini.h b/src/include/mm_player_ini.h index efb092c..3f998cf 100644 --- a/src/include/mm_player_ini.h +++ b/src/include/mm_player_ini.h @@ -92,8 +92,6 @@ typedef struct __mm_player_ini { gchar httpsrc_element[PLAYER_INI_MAX_STRLEN]; gboolean http_use_file_buffer; guint http_ring_buffer_size; - guint http_max_size_bytes; - gint http_buffering_time; /* ms */ gint http_timeout; /* audio effect */ @@ -167,8 +165,6 @@ typedef struct __mm_player_ini { #define DEFAULT_HTTPSRC "souphttpsrc" #define DEFAULT_HTTP_USE_FILE_BUFFER FALSE #define DEFAULT_HTTP_RING_BUFFER_SIZE (20*1024*1024) /* bytes : 20MBytes */ -#define DEFAULT_HTTP_MAX_SIZE_BYTES 1048576 /* bytes : 1 MBytes */ -#define DEFAULT_HTTP_BUFFERING_TIME 1.2 /* sec */ #define DEFAULT_HTTP_TIMEOUT -1 /* infinite retry */ /* dump buffer for debug */ diff --git a/src/include/mm_player_streaming.h b/src/include/mm_player_streaming.h index 077b6ba..c25b199 100644 --- a/src/include/mm_player_streaming.h +++ b/src/include/mm_player_streaming.h @@ -32,26 +32,27 @@ #define MAX_FILE_BUFFER_NAME_LEN 256 +#define DEFAULT_BUFFER_HIGH_PERCENT 99.0 #define MIN_BUFFER_PERCENT 0.0 #define MAX_BUFFER_PERCENT 100.0 -#define MIN_BUFFERING_TIME 3.0 -#define MAX_BUFFERING_TIME (10 * 1000) /* ms */ -#define MAX_DECODEBIN_BUFFER_BYTES (32 * 1024 * 1024) /* byte */ -#define MAX_DECODEBIN_BUFFER_TIME (15 * 1000) /* ms */ -#define MAX_DECODEBIN_ADAPTIVE_BUFFER_BYTES (2 * 1024 * 1024) /* byte */ -#define MAX_DECODEBIN_ADAPTIVE_BUFFER_TIME (5 * 1000) /* ms */ +/* buffering time criteria (ms) */ +#define DEFAULT_BUFFERING_TIME (3 * 1000) +#define MIN_BUFFERING_TIME (0) +#define MAX_BUFFERING_TIME (10 * 1000) -#define DEFAULT_BUFFER_SIZE_BYTES 4194304 /* 4 MBytes */ -#define DEFAULT_PLAYING_TIME (10 * 1000) /* ms */ -#define DEFAULT_ADAPTIVE_PLAYING_TIME (3 * 1000) /* ms */ +#define DEFAULT_PREBUFFERING_TIME (3 * 1000) +#define DEFAULT_REBUFFERING_TIME (10 * 1000) +#define DEFAULT_ADAPTIVE_REBUFFER_TIME (5 * 1000) +#define DEFAULT_LIVE_REBUFFER_TIME (3 * 1000) -#define DEFAULT_BUFFERING_TIME (3 * 1000) /* ms */ -#define DEFAULT_BUFFER_HIGH_PERCENT 99.0 -#define DEFAULT_RING_BUFFER_SIZE (20 * 1024 * 1024) /* 20MBytes */ +/* buffer size */ +#define DEFAULT_BUFFER_SIZE_BYTES (5 * 1024 * 1024) /* 5 MBytes */ +#define DEFAULT_RING_BUFFER_SIZE_BYTES (20 * 1024 * 1024) /* 20 MBytes, for queue2 */ +#define MIN_BUFFER_SIZE_BYTES (1 * 1024 * 1024) /* 1 MBytes */ +#define MAX_BUFFER_SIZE_BYTES (32 * 1024 * 1024) /* 32 MBytes */ +#define MAX_BUFFER_SIZE_TIME (15 * 1000) /* 15 sec, for mq */ -#define STREAMING_USE_FILE_BUFFER -#define STREAMING_USE_MEMORY_BUFFER #define GET_BYTE_FROM_BIT(bit) (bit / 8) #define GET_BIT_FROM_BYTE(byte) (byte * 8) @@ -76,10 +77,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_NEW_BUFFERING_BYTE(size) ((size) < MAX_DECODEBIN_BUFFER_BYTES) ? (size) : (MAX_DECODEBIN_BUFFER_BYTES) -#define GET_MAX_BUFFER_BYTES(sr) ((PLAYER_STREAM_CAST(sr)->is_adaptive_streaming) ? (MAX_DECODEBIN_ADAPTIVE_BUFFER_BYTES) : (MAX_DECODEBIN_BUFFER_BYTES)) -#define GET_MAX_BUFFER_TIME(sr) ((PLAYER_STREAM_CAST(sr)->is_adaptive_streaming) ? (MAX_DECODEBIN_ADAPTIVE_BUFFER_TIME) : (MAX_DECODEBIN_BUFFER_TIME)) -#define GET_DEFAULT_PLAYING_TIME(sr) ((PLAYER_STREAM_CAST(sr)->is_adaptive_streaming) ? (DEFAULT_ADAPTIVE_PLAYING_TIME) : (DEFAULT_PLAYING_TIME)) +#define GET_NEW_BUFFERING_BYTE(size) ((size) < MAX_BUFFER_SIZE_BYTES) ? (size) : (MAX_BUFFER_SIZE_BYTES) typedef enum { BUFFER_TYPE_DEFAULT, @@ -146,26 +144,21 @@ typedef struct { mm_player_streaming_t *__mm_player_streaming_create(void); -void __mm_player_streaming_initialize(mm_player_streaming_t *streaming_player); -void __mm_player_streaming_deinitialize(mm_player_streaming_t *streaming_player); + +void __mm_player_streaming_initialize(mm_player_streaming_t *streaming_player, gboolean buffer_init); + void __mm_player_streaming_destroy(mm_player_streaming_t *streaming_player); -void __mm_player_streaming_set_queue2(mm_player_streaming_t *streamer, - GstElement *buffer, - gboolean use_buffering, - guint buffering_bytes, - gint buffering_time, - MuxedBufferType type, - gchar *file_path, - guint64 content_size); -void __mm_player_streaming_set_multiqueue(mm_player_streaming_t *streamer, - GstElement *buffer, - gint buffering_time); + +void __mm_player_streaming_set_queue2(mm_player_streaming_t *streamer, GstElement *buffer, + gboolean use_buffering, MuxedBufferType type, gchar *file_path, guint64 content_size); + +void __mm_player_streaming_set_multiqueue(mm_player_streaming_t *streamer, GstElement *buffer); + void __mm_player_streaming_sync_property(mm_player_streaming_t *streamer, GstElement *decodebin); -void __mm_player_streaming_buffering(mm_player_streaming_t *streamer, - GstMessage *buffering_msg, - guint64 content_size, - gint64 position, - gint64 duration); + +void __mm_player_streaming_buffering(mm_player_streaming_t *streamer, GstMessage *buffering_msg, + guint64 content_size, gint64 position, gint64 duration); + void __mm_player_streaming_set_content_bitrate(mm_player_streaming_t *streaming_player, guint max_bitrate, guint avg_bitrate); #endif diff --git a/src/mm_player_ini.c b/src/mm_player_ini.c index 3c7e73d..5487d8e 100644 --- a/src/mm_player_ini.c +++ b/src/mm_player_ini.c @@ -184,8 +184,6 @@ mm_player_ini_load(mm_player_ini_t *ini) MMPLAYER_INI_GET_STRING(dict, ini->httpsrc_element, "http streaming:httpsrc element", DEFAULT_HTTPSRC); ini->http_use_file_buffer = iniparser_getboolean(dict, "http streaming:http use file buffer", DEFAULT_HTTP_USE_FILE_BUFFER); ini->http_ring_buffer_size = iniparser_getint(dict, "http streaming:http ring buffer size", DEFAULT_HTTP_RING_BUFFER_SIZE); - ini->http_max_size_bytes = iniparser_getint(dict, "http streaming:http max size bytes", DEFAULT_HTTP_MAX_SIZE_BYTES); - ini->http_buffering_time = (gint)(iniparser_getdouble(dict, "http streaming:http buffering time", DEFAULT_HTTP_BUFFERING_TIME) * 1000); ini->http_timeout = iniparser_getint(dict, "http streaming:http timeout", DEFAULT_HTTP_TIMEOUT); /* dump buffer for debug */ @@ -235,8 +233,6 @@ mm_player_ini_load(mm_player_ini_t *ini) strncpy(ini->httpsrc_element, DEFAULT_HTTPSRC, PLAYER_INI_MAX_STRLEN - 1); ini->http_use_file_buffer = DEFAULT_HTTP_USE_FILE_BUFFER; ini->http_ring_buffer_size = DEFAULT_HTTP_RING_BUFFER_SIZE; - ini->http_max_size_bytes = DEFAULT_HTTP_MAX_SIZE_BYTES; - ini->http_buffering_time = (gint)(DEFAULT_HTTP_BUFFERING_TIME * 1000); ini->http_timeout = DEFAULT_HTTP_TIMEOUT; /* dump buffer for debug */ @@ -294,8 +290,6 @@ mm_player_ini_load(mm_player_ini_t *ini) LOGD("httpsrc element : %s", ini->httpsrc_element); LOGD("http use file buffer : %d", ini->http_use_file_buffer); LOGD("http ring buffer size : %d", ini->http_ring_buffer_size); - LOGD("http max_size bytes : %d", ini->http_max_size_bytes); - LOGD("http buffering time : %d", ini->http_buffering_time); LOGD("http timeout : %d", ini->http_timeout); return MM_ERROR_NONE; diff --git a/src/mm_player_priv.c b/src/mm_player_priv.c index ee65161..7222ae2 100644 --- a/src/mm_player_priv.c +++ b/src/mm_player_priv.c @@ -1342,24 +1342,12 @@ __mmplayer_create_text_sink_path(mm_player_t *player, GstElement *text_selector) static gboolean __mmplayer_gst_set_queue2_buffering(mm_player_t *player) { -#define ESTIMATED_BUFFER_UNIT (1 * 1024 * 1024) - - gint init_buffering_time = 0; - guint buffer_bytes = 0; gint64 dur_bytes = 0L; MMPLAYER_FENTER(); MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline && player->pipeline->mainbin && player->streamer, FALSE); - init_buffering_time = player->streamer->buffering_req.prebuffer_time; - buffer_bytes = (guint)(init_buffering_time / 1000) * ESTIMATED_BUFFER_UNIT; - - buffer_bytes = MAX(buffer_bytes, player->streamer->buffer_handle[BUFFER_TYPE_MUXED].buffering_bytes); - LOGD("pre buffer time: %d ms, buffer size : %d", init_buffering_time, buffer_bytes); - - init_buffering_time = (init_buffering_time != 0) ? init_buffering_time : player->ini.http_buffering_time; - if (!gst_element_query_duration(player->pipeline->mainbin[MMPLAYER_M_SRC].gst, GST_FORMAT_BYTES, &dur_bytes)) LOGE("fail to get duration."); @@ -1368,8 +1356,6 @@ __mmplayer_gst_set_queue2_buffering(mm_player_t *player) __mm_player_streaming_set_queue2(player->streamer, player->pipeline->mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst, TRUE, /* use_buffering */ - buffer_bytes, - init_buffering_time, MUXED_BUFFER_TYPE_MAX, /* use previous buffer type setting */ NULL, ((dur_bytes > 0) ? ((guint64)dur_bytes) : 0)); @@ -4017,7 +4003,7 @@ __mmplayer_gst_destroy_pipeline(mm_player_t *player) __mmplayer_reset_gapless_state(player); if (player->streamer) { - __mm_player_streaming_deinitialize(player->streamer); + __mm_player_streaming_initialize(player->streamer, FALSE); __mm_player_streaming_destroy(player->streamer); player->streamer = NULL; } @@ -4831,7 +4817,7 @@ _mmplayer_realize(MMHandleType hplayer) if ((MMPLAYER_IS_STREAMING(player)) && (player->streamer == NULL)) { player->streamer = __mm_player_streaming_create(); - __mm_player_streaming_initialize(player->streamer); + __mm_player_streaming_initialize(player->streamer, TRUE); } /* realize pipeline */ @@ -5658,25 +5644,33 @@ __mmplayer_update_content_type_info(mm_player_t *player) if (__mmplayer_is_midi_type(player->type)) { player->bypass_audio_effect = TRUE; - } else if (g_strrstr(player->type, "application/x-hls")) { + return; + } + + if (!player->streamer) { + LOGD("no need to check streaming type"); + return; + } + + if (g_strrstr(player->type, "application/x-hls")) { /* If it can't know exact type when it parses uri because of redirection case, * it will be fixed by typefinder or when doing autoplugging. */ player->profile.uri_type = MM_PLAYER_URI_TYPE_HLS; - if (player->streamer) { - player->streamer->is_adaptive_streaming = TRUE; - player->streamer->buffering_req.mode = MM_PLAYER_BUFFERING_MODE_FIXED; - player->streamer->buffering_req.rebuffer_time = 5 * 1000; - } + player->streamer->is_adaptive_streaming = TRUE; } else if (g_strrstr(player->type, "application/dash+xml")) { player->profile.uri_type = MM_PLAYER_URI_TYPE_DASH; - if (player->streamer) { - player->streamer->is_adaptive_streaming = TRUE; - player->streamer->buffering_req.mode = MM_PLAYER_BUFFERING_MODE_FIXED; - } + player->streamer->is_adaptive_streaming = TRUE; + } + + if (player->streamer->is_adaptive_streaming) { + 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; } - LOGD("uri type : %d", player->profile.uri_type); + LOGD("uri type : %d, %d", player->profile.uri_type, player->streamer->buffering_req.rebuffer_time); MMPLAYER_FLEAVE(); } @@ -5801,7 +5795,6 @@ __mmplayer_gst_make_queue2(mm_player_t *player) { GstElement *queue2 = NULL; gint64 dur_bytes = 0L; - guint max_buffer_size_bytes = 0; MMPlayerGstElement *mainbin = NULL; MuxedBufferType type = MUXED_BUFFER_TYPE_MEM_QUEUE; @@ -5816,8 +5809,13 @@ __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)) - LOGE("failed to get duration from source %s", GST_ELEMENT_NAME(mainbin[MMPLAYER_M_SRC].gst)); + LOGW("failed to get duration from source %s", GST_ELEMENT_NAME(mainbin[MMPLAYER_M_SRC].gst)); LOGD("dur_bytes = %"G_GINT64_FORMAT, dur_bytes); @@ -5832,21 +5830,12 @@ __mmplayer_gst_make_queue2(mm_player_t *player) dur_bytes = 0; } - /* NOTE : in case of ts streaming, player cannot get the correct duration info * - * skip the pull mode(file or ring buffering) setting. */ - if (!g_strrstr(player->type, "video/mpegts")) { - max_buffer_size_bytes = (type == MUXED_BUFFER_TYPE_FILE) ? (player->ini.http_max_size_bytes) : (5 * 1024 * 1024); - LOGD("max_buffer_size_bytes = %d", max_buffer_size_bytes); - - __mm_player_streaming_set_queue2(player->streamer, - queue2, - FALSE, - max_buffer_size_bytes, - player->ini.http_buffering_time, - type, - player->http_file_buffering_path, - (guint64)dur_bytes); - } + __mm_player_streaming_set_queue2(player->streamer, + queue2, + FALSE, + type, + player->http_file_buffering_path, + (guint64)dur_bytes); return queue2; } @@ -5859,7 +5848,6 @@ __mmplayer_gst_create_decoder(mm_player_t *player, GstPad *srcpad, const GstCaps GstElement *queue2 = NULL; GstPad *sinkpad = NULL; GstPad *qsrcpad = NULL; - gint init_buffering_time = player->streamer->buffering_req.prebuffer_time; MMPLAYER_FENTER(); MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline && player->pipeline->mainbin, FALSE); @@ -5941,22 +5929,24 @@ __mmplayer_gst_create_decoder(mm_player_t *player, GstPad *srcpad, const GstCaps * in case of HLS/DASH, it does not need to have big buffer * * because it is kind of adaptive streaming. */ if (MMPLAYER_IS_HTTP_STREAMING(player) || MMPLAYER_IS_HTTP_LIVE_STREAMING(player) || MMPLAYER_IS_DASH_STREAMING(player)) { - gdouble high_percent = 0.0; + gint init_buffering_time = DEFAULT_PREBUFFERING_TIME; + gint high_percent = 0; + + if (player->streamer->buffering_req.prebuffer_time > MIN_BUFFERING_TIME) + init_buffering_time = player->streamer->buffering_req.prebuffer_time; - init_buffering_time = (init_buffering_time != 0) ? init_buffering_time : player->ini.http_buffering_time; - high_percent = (gdouble)(init_buffering_time * 100) / GET_MAX_BUFFER_TIME(player->streamer); + high_percent = (gint)ceil((gdouble)(init_buffering_time * 100) / MAX_BUFFER_SIZE_TIME); - LOGD("decodebin setting - bytes: %d, time: %d ms, per: 1~%d", - GET_MAX_BUFFER_BYTES(player->streamer), GET_MAX_BUFFER_TIME(player->streamer), (gint)high_percent); + LOGD("buffering time %d, per: 1~%d", init_buffering_time, high_percent); g_object_set(G_OBJECT(decodebin), "use-buffering", TRUE, - "high-percent", (gint)high_percent, - "max-size-bytes", GET_MAX_BUFFER_BYTES(player->streamer), - "max-size-time", (guint64)(GET_MAX_BUFFER_TIME(player->streamer) * GST_MSECOND), + "high-percent", high_percent, + "max-size-bytes", MAX_BUFFER_SIZE_BYTES, + "max-size-time", (guint64)(MAX_BUFFER_SIZE_TIME * GST_MSECOND), "max-size-buffers", 0, NULL); // disable or automatic } - if (GST_STATE_CHANGE_FAILURE == gst_element_sync_state_with_parent(decodebin)) { + if (gst_element_sync_state_with_parent(decodebin) == GST_STATE_CHANGE_FAILURE) { LOGE("failed to sync decodebin state with parent"); goto ERROR; } @@ -6383,7 +6373,7 @@ __mmplayer_activate_next_source(mm_player_t *player, GstState target) if (MMPLAYER_IS_HTTP_STREAMING(player)) { if (player->streamer == NULL) { player->streamer = __mm_player_streaming_create(); - __mm_player_streaming_initialize(player->streamer); + __mm_player_streaming_initialize(player->streamer, TRUE); } elem_idx = MMPLAYER_M_TYPEFIND; @@ -6557,7 +6547,7 @@ __mmplayer_deactivate_old_path(mm_player_t *player) __mmplayer_release_signal_connection(player, MM_PLAYER_SIGNAL_TYPE_AUTOPLUG); if (player->streamer) { - __mm_player_streaming_deinitialize(player->streamer); + __mm_player_streaming_initialize(player->streamer, FALSE); __mm_player_streaming_destroy(player->streamer); player->streamer = NULL; } @@ -7200,7 +7190,7 @@ __mmplayer_gst_element_added(GstElement *bin, GstElement *element, gpointer data (MMPLAYER_IS_HTTP_LIVE_STREAMING(player)) || (MMPLAYER_IS_DASH_STREAMING(player))) { /* in case of multiqueue, max bytes size is defined with fixed value in mm_player_streaming.h*/ - __mm_player_streaming_set_multiqueue(player->streamer, element, player->ini.http_buffering_time); + __mm_player_streaming_set_multiqueue(player->streamer, element); __mm_player_streaming_sync_property(player->streamer, player->pipeline->mainbin[MMPLAYER_M_AUTOPLUG].gst); } @@ -8398,7 +8388,7 @@ _mmplayer_set_streaming_buffering_time(MMHandleType hplayer, int buffer_ms, int if (player->streamer == NULL) { player->streamer = __mm_player_streaming_create(); - __mm_player_streaming_initialize(player->streamer); + __mm_player_streaming_initialize(player->streamer, TRUE); } if (buffer_ms >= 0) @@ -8424,7 +8414,7 @@ _mmplayer_get_streaming_buffering_time(MMHandleType hplayer, int *buffer_ms, int if (player->streamer == NULL) { player->streamer = __mm_player_streaming_create(); - __mm_player_streaming_initialize(player->streamer); + __mm_player_streaming_initialize(player->streamer, TRUE); } *buffer_ms = player->streamer->buffering_req.prebuffer_time; diff --git a/src/mm_player_streaming.c b/src/mm_player_streaming.c index c0aa81d..2fecdc0 100644 --- a/src/mm_player_streaming.c +++ b/src/mm_player_streaming.c @@ -25,6 +25,8 @@ #include "mm_player_utils.h" #include "mm_player_streaming.h" +#define ESTIMATED_BUFFER_UNIT (1 * 1024 * 1024) /* 1 MBytes */ + typedef struct { gint byte_in_rate; // byte gint byte_out_rate; // byte @@ -71,8 +73,7 @@ streaming_update_buffer_setting(mm_player_streaming_t *streamer, gint64 position, gint64 duration); -mm_player_streaming_t * -__mm_player_streaming_create(void) +mm_player_streaming_t *__mm_player_streaming_create(void) { mm_player_streaming_t *streamer = NULL; @@ -89,8 +90,7 @@ __mm_player_streaming_create(void) return streamer; } -static void -streaming_buffer_initialize(streaming_buffer_t *buffer_handle, gboolean buffer_init) +static void streaming_buffer_initialize(streaming_buffer_t *buffer_handle, gboolean buffer_init) { if (buffer_init) buffer_handle->buffer = NULL; @@ -102,52 +102,18 @@ streaming_buffer_initialize(streaming_buffer_t *buffer_handle, gboolean buffer_i } -void -__mm_player_streaming_initialize(mm_player_streaming_t *streamer) -{ - MMPLAYER_FENTER(); - - streamer->streaming_buffer_type = BUFFER_TYPE_DEFAULT; // multi-queue - - streaming_buffer_initialize(&(streamer->buffer_handle[BUFFER_TYPE_MUXED]), TRUE); - streaming_buffer_initialize(&(streamer->buffer_handle[BUFFER_TYPE_DEMUXED]), TRUE); - - streamer->buffering_req.mode = MM_PLAYER_BUFFERING_MODE_ADAPTIVE; - streamer->buffering_req.is_pre_buffering = FALSE; - streamer->buffering_req.prebuffer_time = 0; - streamer->buffering_req.rebuffer_time = 0; - - streamer->default_val.buffering_monitor = FALSE; - streamer->default_val.buffering_time = DEFAULT_BUFFERING_TIME; - - streamer->buffer_avg_bitrate = 0; - streamer->buffer_max_bitrate = 0; - streamer->need_update = FALSE; - streamer->need_sync = FALSE; - - streamer->buffering_state = MM_PLAYER_BUFFERING_DEFAULT; - streamer->is_adaptive_streaming = FALSE; - - streamer->buffering_percent = -1; - streamer->ring_buffer_size = DEFAULT_RING_BUFFER_SIZE; - - MMPLAYER_FLEAVE(); - return; -} - -void -__mm_player_streaming_deinitialize(mm_player_streaming_t *streamer) +void __mm_player_streaming_initialize(mm_player_streaming_t *streamer, gboolean buffer_init) { MMPLAYER_FENTER(); MMPLAYER_RETURN_IF_FAIL(streamer); - streamer->streaming_buffer_type = BUFFER_TYPE_DEFAULT; // multi-queue + streamer->streaming_buffer_type = BUFFER_TYPE_DEFAULT; - streaming_buffer_initialize(&(streamer->buffer_handle[BUFFER_TYPE_MUXED]), FALSE); - streaming_buffer_initialize(&(streamer->buffer_handle[BUFFER_TYPE_DEMUXED]), FALSE); + streaming_buffer_initialize(&(streamer->buffer_handle[BUFFER_TYPE_MUXED]), buffer_init); + streaming_buffer_initialize(&(streamer->buffer_handle[BUFFER_TYPE_DEMUXED]), buffer_init); streamer->buffering_req.mode = MM_PLAYER_BUFFERING_MODE_ADAPTIVE; - streamer->buffering_req.is_pre_buffering = FALSE; + streamer->buffering_req.is_pre_buffering = TRUE; streamer->buffering_req.prebuffer_time = 0; streamer->buffering_req.rebuffer_time = 0; @@ -163,14 +129,13 @@ __mm_player_streaming_deinitialize(mm_player_streaming_t *streamer) streamer->is_adaptive_streaming = FALSE; streamer->buffering_percent = -1; - streamer->ring_buffer_size = DEFAULT_RING_BUFFER_SIZE; + streamer->ring_buffer_size = DEFAULT_RING_BUFFER_SIZE_BYTES; MMPLAYER_FLEAVE(); return; } -void -__mm_player_streaming_destroy(mm_player_streaming_t *streamer) +void __mm_player_streaming_destroy(mm_player_streaming_t *streamer) { MMPLAYER_FENTER(); @@ -181,8 +146,8 @@ __mm_player_streaming_destroy(mm_player_streaming_t *streamer) return; } -void -__mm_player_streaming_set_content_bitrate(mm_player_streaming_t *streamer, guint max_bitrate, guint avg_bitrate) +void __mm_player_streaming_set_content_bitrate( + mm_player_streaming_t *streamer, guint max_bitrate, guint avg_bitrate) { MMPLAYER_FENTER(); @@ -207,7 +172,7 @@ __mm_player_streaming_set_content_bitrate(mm_player_streaming_t *streamer, guint } if (avg_bitrate > 0 && streamer->buffer_avg_bitrate != avg_bitrate) { - LOGD("set averate bitrate(%dbps).", avg_bitrate); + LOGD("set average bitrate(%dbps).", avg_bitrate); streamer->buffer_avg_bitrate = avg_bitrate; if (streamer->buffering_req.is_pre_buffering == FALSE) { @@ -224,11 +189,8 @@ __mm_player_streaming_set_content_bitrate(mm_player_streaming_t *streamer, guint return; } -static void -streaming_set_buffer_percent(mm_player_streaming_t *streamer, - BufferType type, - gdouble high_percent_byte, - gdouble high_percent_time) +static void streaming_set_buffer_percent(mm_player_streaming_t *streamer, + BufferType type, gdouble high_percent_byte, gdouble high_percent_time) { gdouble high_percent = 0.0; @@ -274,8 +236,8 @@ streaming_set_buffer_percent(mm_player_streaming_t *streamer, return; } -static void -streaming_set_queue2_queue_type(mm_player_streaming_t *streamer, MuxedBufferType type, gchar *file_path, guint64 content_size) +static void streaming_set_queue2_queue_type(mm_player_streaming_t *streamer, + MuxedBufferType type, gchar *file_path, guint64 content_size) { streaming_buffer_t *buffer_handle = NULL; guint64 storage_available_size = 0; /* bytes */ @@ -320,7 +282,7 @@ streaming_set_queue2_queue_type(mm_player_streaming_t *streamer, MuxedBufferType if (type == MUXED_BUFFER_TYPE_FILE && file_path && strlen(file_path) > 0) { if (statfs((const char *)file_path, &buf) < 0) { LOGW("[Queue2] fail to get available storage capacity. set mem ring buffer instead of file buffer."); - buffer_size = (guint64)((streamer->ring_buffer_size > 0) ? (streamer->ring_buffer_size) : DEFAULT_RING_BUFFER_SIZE); + buffer_size = (guint64)((streamer->ring_buffer_size > 0) ? (streamer->ring_buffer_size) : DEFAULT_RING_BUFFER_SIZE_BYTES); } else { storage_available_size = (guint64)buf.f_bavail * (guint64)buf.f_bsize; //bytes @@ -342,7 +304,7 @@ streaming_set_queue2_queue_type(mm_player_streaming_t *streamer, MuxedBufferType g_object_set(G_OBJECT(buffer_handle->buffer), "temp-template", file_buffer_name, NULL); } } else { - buffer_size = (guint64)((streamer->ring_buffer_size > 0) ? (streamer->ring_buffer_size) : DEFAULT_RING_BUFFER_SIZE); + buffer_size = (guint64)((streamer->ring_buffer_size > 0) ? (streamer->ring_buffer_size) : DEFAULT_RING_BUFFER_SIZE_BYTES); } LOGW("[Queue2] set ring buffer size: %"G_GUINT64_FORMAT, buffer_size); @@ -352,8 +314,8 @@ streaming_set_queue2_queue_type(mm_player_streaming_t *streamer, MuxedBufferType return; } -static void -streaming_set_buffer_size(mm_player_streaming_t *streamer, BufferType type, guint buffering_bytes, gint buffering_time) +static void streaming_set_buffer_size(mm_player_streaming_t *streamer, + BufferType type, guint buffering_bytes, gint buffering_time) { streaming_buffer_t *buffer_handle = NULL; @@ -371,12 +333,12 @@ streaming_set_buffer_size(mm_player_streaming_t *streamer, BufferType type, guin buffering_time = GET_CURRENT_BUFFERING_TIME(buffer_handle); g_object_set(G_OBJECT(buffer_handle->buffer), - "max-size-bytes", GET_MAX_BUFFER_BYTES(streamer), /* mq size is fixed, control it with high/low percent value*/ + "max-size-bytes", MAX_BUFFER_SIZE_BYTES, /* mq size is fixed, control it with high/low percent value*/ "max-size-time", (guint64)(buffering_time * GST_MSECOND), "max-size-buffers", 0, NULL); /* disable */ buffer_handle->buffering_time = buffering_time; - buffer_handle->buffering_bytes = GET_MAX_BUFFER_BYTES(streamer); + buffer_handle->buffering_bytes = MAX_BUFFER_SIZE_BYTES; LOGD("max-size-time : %d ms", buffering_time); } else { @@ -405,55 +367,61 @@ streaming_set_buffer_size(mm_player_streaming_t *streamer, BufferType type, guin return; } -void -__mm_player_streaming_set_queue2(mm_player_streaming_t *streamer, - GstElement *buffer, - gboolean use_buffering, - guint buffering_bytes, - gint buffering_time, - MuxedBufferType type, - gchar *file_path, - guint64 content_size) +void __mm_player_streaming_set_queue2(mm_player_streaming_t *streamer, GstElement *buffer, + gboolean use_buffering, MuxedBufferType type, gchar *file_path, guint64 content_size) { + guint queue_size_bytes = 0; + guint queue_size_time = 0; + MMPLAYER_FENTER(); - MMPLAYER_RETURN_IF_FAIL(streamer); + MMPLAYER_RETURN_IF_FAIL(streamer && buffer); - if (buffer) { - LOGD("USE-BUFFERING : %s", (use_buffering) ? "OOO" : "XXX"); + LOGD("use queue2 buffering %d", use_buffering); - streamer->buffer_handle[BUFFER_TYPE_MUXED].buffer = buffer; + streamer->buffer_handle[BUFFER_TYPE_MUXED].buffer = buffer; - if (use_buffering) { - streamer->streaming_buffer_type = BUFFER_TYPE_MUXED; + if (use_buffering) { /* audio only content use queue2 for buffering */ + streamer->streaming_buffer_type = BUFFER_TYPE_MUXED; - if (content_size > 0) { - if (streamer->buffering_req.prebuffer_time > 0) - streamer->buffering_req.is_pre_buffering = TRUE; - else - streamer->buffering_req.prebuffer_time = buffering_time; - } else { - LOGD("live streaming without mq"); + if (streamer->buffering_req.prebuffer_time <= MIN_BUFFERING_TIME) + streamer->buffering_req.prebuffer_time = DEFAULT_PREBUFFERING_TIME; - streamer->buffer_handle[BUFFER_TYPE_MUXED].is_live = TRUE; - streamer->buffering_req.prebuffer_time = buffering_time = DEFAULT_BUFFERING_TIME; - } + if (content_size == 0) { + LOGD("live streaming without mq"); + streamer->buffer_handle[BUFFER_TYPE_MUXED].is_live = TRUE; + } + + queue_size_bytes = (guint)(streamer->buffering_req.prebuffer_time / 1000) * ESTIMATED_BUFFER_UNIT; + queue_size_bytes = MAX(queue_size_bytes, DEFAULT_BUFFER_SIZE_BYTES); + } else { + if (type >= MUXED_BUFFER_TYPE_MAX) { + LOGE("invalid queue type"); + return; } - g_object_set(G_OBJECT(streamer->buffer_handle[BUFFER_TYPE_MUXED].buffer), "use-buffering", use_buffering, NULL); + /* set the simple queue size */ + if (type == MUXED_BUFFER_TYPE_FILE) + queue_size_bytes = MIN_BUFFER_SIZE_BYTES; + else + queue_size_bytes = DEFAULT_BUFFER_SIZE_BYTES; + + streaming_set_queue2_queue_type(streamer, type, file_path, content_size); } - /* initial setting */ - streaming_set_buffer_size(streamer, BUFFER_TYPE_MUXED, buffering_bytes, buffering_time); + /* 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); + streaming_set_buffer_size(streamer, BUFFER_TYPE_MUXED, queue_size_bytes, queue_size_time); streaming_set_buffer_percent(streamer, BUFFER_TYPE_MUXED, DEFAULT_BUFFER_HIGH_PERCENT, 0); - if (type < MUXED_BUFFER_TYPE_MAX) - streaming_set_queue2_queue_type(streamer, type, file_path, content_size); MMPLAYER_FLEAVE(); return; } -void -__mm_player_streaming_sync_property(mm_player_streaming_t *streamer, GstElement *decodebin) +void __mm_player_streaming_sync_property(mm_player_streaming_t *streamer, GstElement *decodebin) { streaming_buffer_t *buffer_handle = NULL; @@ -473,10 +441,7 @@ __mm_player_streaming_sync_property(mm_player_streaming_t *streamer, GstElement streamer->need_sync = FALSE; } -void -__mm_player_streaming_set_multiqueue(mm_player_streaming_t *streamer, - GstElement *buffer, - gint buffering_time) +void __mm_player_streaming_set_multiqueue(mm_player_streaming_t *streamer, GstElement *buffer) { streaming_buffer_t *buffer_handle = NULL; gdouble high_percent = 0.0; @@ -485,25 +450,21 @@ __mm_player_streaming_set_multiqueue(mm_player_streaming_t *streamer, MMPLAYER_RETURN_IF_FAIL(streamer && buffer); buffer_handle = &(streamer->buffer_handle[BUFFER_TYPE_DEMUXED]); - buffer_handle->buffer = buffer; + LOGD("pre_buffering: %d ms", streamer->buffering_req.prebuffer_time); + streamer->streaming_buffer_type = BUFFER_TYPE_DEMUXED; g_object_set(G_OBJECT(buffer_handle->buffer), "use-buffering", TRUE, NULL); + if (streamer->buffering_req.prebuffer_time <= MIN_BUFFERING_TIME) + streamer->buffering_req.prebuffer_time = DEFAULT_PREBUFFERING_TIME; - LOGD("pre_buffering: %d ms, during playing: %d ms", streamer->buffering_req.prebuffer_time, buffering_time); - - if (streamer->buffering_req.prebuffer_time > 0) - streamer->buffering_req.is_pre_buffering = TRUE; - else - streamer->buffering_req.prebuffer_time = GET_DEFAULT_PLAYING_TIME(streamer); - - high_percent = (gdouble)(streamer->buffering_req.prebuffer_time * 100) / GET_MAX_BUFFER_TIME(streamer); + high_percent = (gdouble)(streamer->buffering_req.prebuffer_time * 100) / MAX_BUFFER_SIZE_TIME; LOGD("high_percent %2.3f %%", high_percent); /* initial setting */ - streaming_set_buffer_size(streamer, BUFFER_TYPE_DEMUXED, GET_MAX_BUFFER_BYTES(streamer), GET_MAX_BUFFER_TIME(streamer)); + streaming_set_buffer_size(streamer, BUFFER_TYPE_DEMUXED, MAX_BUFFER_SIZE_BYTES, MAX_BUFFER_SIZE_TIME); streaming_set_buffer_percent(streamer, BUFFER_TYPE_DEMUXED, 0, high_percent); streamer->need_sync = TRUE; @@ -512,13 +473,9 @@ __mm_player_streaming_set_multiqueue(mm_player_streaming_t *streamer, return; } -static void -streaming_get_current_bitrate_info(mm_player_streaming_t *streamer, - GstMessage *buffering_msg, - streaming_content_info_t content_info, - streaming_bitrate_info_t *bitrate_info) +static void streaming_get_current_bitrate_info(mm_player_streaming_t *streamer, + GstMessage *buffering_msg, streaming_content_info_t content_info, streaming_bitrate_info_t *bitrate_info) { - GstQuery *query = NULL; GstBufferingMode mode = GST_BUFFERING_STREAM; gint in_rate = 0; @@ -589,11 +546,8 @@ streaming_get_current_bitrate_info(mm_player_streaming_t *streamer, (*bitrate_info).buffer_criteria = buffer_criteria; } -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) +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) { streaming_buffer_t *buffer_handle = NULL; @@ -631,12 +585,9 @@ streaming_handle_fixed_buffering_mode(mm_player_streaming_t *streamer, (*buffer_info).percent_time = per_time; } -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) +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; @@ -722,17 +673,14 @@ streaming_handle_adaptive_buffering_mode(mm_player_streaming_t *streamer, } -static void -streaming_update_buffer_setting(mm_player_streaming_t *streamer, - GstMessage *buffering_msg, /* can be null */ - guint64 content_size, - gint64 position, - gint64 duration) +static void streaming_update_buffer_setting(mm_player_streaming_t *streamer, + GstMessage *buffering_msg, guint64 content_size, gint64 position, gint64 duration) { streaming_buffer_t *buffer_handle = NULL; MMPlayerBufferingMode buffering_mode = MM_PLAYER_BUFFERING_MODE_ADAPTIVE; + gint expected_play_time = DEFAULT_REBUFFERING_TIME; - streaming_buffer_info_t buffer_info; + streaming_buffer_info_t buffer_info; streaming_content_info_t content_info; streaming_bitrate_info_t bitrate_info; @@ -746,10 +694,24 @@ streaming_update_buffer_setting(mm_player_streaming_t *streamer, buffer_handle = &(streamer->buffer_handle[streamer->streaming_buffer_type]); - if (streamer->buffering_req.is_pre_buffering == TRUE) + if (streamer->buffering_req.is_pre_buffering == TRUE) { buffering_mode = MM_PLAYER_BUFFERING_MODE_FIXED; - else - buffering_mode = streamer->buffering_req.mode; + expected_play_time = streamer->buffering_req.prebuffer_time; + } else { + if (content_size == 0 || duration == 0) /* can not support adaptive mode */ + buffering_mode = MM_PLAYER_BUFFERING_MODE_FIXED; + else + buffering_mode = streamer->buffering_req.mode; + + if (buffering_mode == MM_PLAYER_BUFFERING_MODE_FIXED) { + if (streamer->buffering_req.rebuffer_time > 0) + expected_play_time = streamer->buffering_req.rebuffer_time; + else + expected_play_time = DEFAULT_LIVE_REBUFFER_TIME; + } + } + + 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; @@ -762,39 +724,15 @@ streaming_update_buffer_setting(mm_player_streaming_t *streamer, streaming_get_current_bitrate_info(streamer, buffering_msg, content_info, &bitrate_info); - LOGD("buffering mode %d, new info in_r:%d, out_r:%d, cb:%d, bt:%d", - buffering_mode, bitrate_info.byte_in_rate, bitrate_info.byte_out_rate, - bitrate_info.buffer_criteria, bitrate_info.time_rate); + LOGD("in_r:%d, out_r:%d", bitrate_info.byte_in_rate, bitrate_info.byte_out_rate); if (buffering_mode == MM_PLAYER_BUFFERING_MODE_FIXED) { - /******************** - * (1) fixed mode * - ********************/ - gint buffering_time = 0; - - if (streamer->buffering_req.is_pre_buffering == TRUE) - buffering_time = streamer->buffering_req.prebuffer_time; - else - buffering_time = streamer->buffering_req.rebuffer_time; - - streaming_handle_fixed_buffering_mode(streamer, bitrate_info.byte_out_rate, buffering_time, &buffer_info); + streaming_handle_fixed_buffering_mode(streamer, bitrate_info.byte_out_rate, expected_play_time, &buffer_info); } else { - /********************************* - * (2) adaptive mode (default) * - *********************************/ - gint expected_play_time = DEFAULT_PLAYING_TIME; - - if (streamer->buffering_req.rebuffer_time > 0) - expected_play_time = streamer->buffering_req.rebuffer_time; - else if ((position == 0) && (streamer->buffering_state & MM_PLAYER_BUFFERING_IN_PROGRESS)) - expected_play_time = streamer->buffering_req.prebuffer_time; - - if (expected_play_time <= 0) - expected_play_time = DEFAULT_PLAYING_TIME; - streaming_handle_adaptive_buffering_mode(streamer, content_info, bitrate_info, &buffer_info, expected_play_time); - if (IS_MUXED_BUFFERING_MODE(streamer)) // even if new byte size is smaller than the previous one, time need to be updated. + /* 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; } @@ -826,8 +764,7 @@ streaming_update_buffer_setting(mm_player_streaming_t *streamer, streamer->need_sync = TRUE; } -static void -streaming_adjust_min_threshold(mm_player_streaming_t *streamer, gint64 position) +static void streaming_adjust_min_threshold(mm_player_streaming_t *streamer, gint64 position) { #define DEFAULT_TIME_PAD 1000 /* ms */ gint playing_time = 0; @@ -861,8 +798,7 @@ streaming_adjust_min_threshold(mm_player_streaming_t *streamer, gint64 position) streamer->default_val.prev_pos = position; } -static void -streaming_update_buffering_status(mm_player_streaming_t *streamer, GstMessage *buffering_msg, gint64 position) +static void streaming_update_buffering_status(mm_player_streaming_t *streamer, GstMessage *buffering_msg, gint64 position) { gint buffer_percent = 0; @@ -904,12 +840,8 @@ streaming_update_buffering_status(mm_player_streaming_t *streamer, GstMessage *b } } -void -__mm_player_streaming_buffering(mm_player_streaming_t *streamer, - GstMessage *buffering_msg, - guint64 content_size, - gint64 position, - gint64 duration) +void __mm_player_streaming_buffering(mm_player_streaming_t *streamer, GstMessage *buffering_msg, + guint64 content_size, gint64 position, gint64 duration) { MMPLAYER_FENTER(); -- 2.7.4