summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEunhae Choi <eunhae1.choi@samsung.com>2019-01-07 17:04:51 +0900
committerEunhae Choi <eunhae1.choi@samsung.com>2019-01-08 13:12:21 +0900
commite661c6c9400f122b603718c79c4b12ca68b69717 (patch)
tree23f5ec1b8c3297c796ee4bfd86f2235cb6359f7d
parentf73c8a7b6d9b6feaaabded7fc99d37b6260d7166 (diff)
downloadlibmm-player-e661c6c9400f122b603718c79c4b12ca68b69717.tar.gz
libmm-player-e661c6c9400f122b603718c79c4b12ca68b69717.tar.bz2
libmm-player-e661c6c9400f122b603718c79c4b12ca68b69717.zip
[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
-rw-r--r--packaging/libmm-player.spec2
-rw-r--r--src/include/mm_player_ini.h4
-rw-r--r--src/include/mm_player_streaming.h65
-rw-r--r--src/mm_player_ini.c6
-rw-r--r--src/mm_player_priv.c108
-rw-r--r--src/mm_player_streaming.c278
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();