#include "mm_player_utils.h"
#include "mm_player_streaming.h"
-#define TO_THE_END 0
-
typedef struct {
gint byte_in_rate; // byte
gint byte_out_rate; // byte
- gdouble time_rate; // second
+ gint time_rate; // ms
guint buffer_criteria; // byte
} streaming_bitrate_info_t;
typedef struct {
guint buffering_bytes; // bytes
- gdouble buffering_time; // second
+ gint buffering_time; // ms
gdouble percent_byte;
gdouble percent_time;
} streaming_buffer_info_t;
static void streaming_check_buffer_percent(gdouble in_low, gdouble in_high, gdouble *out_low, gdouble *out_high);
static void streaming_set_buffer_percent(mm_player_streaming_t* streamer, BufferType type, gdouble low_percent, gdouble high_percent_byte, gdouble high_percent_time);
static void streaming_set_queue2_queue_type(mm_player_streaming_t* streamer, muxed_buffer_type_e type, gchar * file_path, guint64 content_size);
-static void streaming_set_buffer_size(mm_player_streaming_t* streamer, BufferType type, guint buffering_bytes, gdouble buffering_time);
+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);
static void streaming_get_current_bitrate_info(mm_player_streaming_t* streamer,
GstMessage *buffering_msg,
static void
streaming_handle_fixed_buffering_mode(mm_player_streaming_t* streamer,
gint byte_out_rate,
- gdouble fixed_buffering_time,
+ gint fixed_buffering_time,
streaming_buffer_info_t* buffer_info);
static void
streaming_handle_adaptive_buffering_mode(mm_player_streaming_t* streamer,
streamer->buffering_req.mode = MM_PLAYER_BUFFERING_MODE_ADAPTIVE;
streamer->buffering_req.is_pre_buffering = FALSE;
- streamer->buffering_req.initial_second = 0;
- streamer->buffering_req.runtime_second = 0;
+ 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->buffering_req.mode = MM_PLAYER_BUFFERING_MODE_ADAPTIVE;
streamer->buffering_req.is_pre_buffering = FALSE;
- streamer->buffering_req.initial_second = 0;
- streamer->buffering_req.runtime_second = 0;
+ 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;
}
static void
-streaming_set_buffer_size(mm_player_streaming_t* streamer, BufferType type, guint buffering_bytes, gdouble buffering_time)
+streaming_set_buffer_size(mm_player_streaming_t* streamer, BufferType type, guint buffering_bytes, gint buffering_time)
{
streaming_buffer_t* buffer_handle = NULL;
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-time", ((guint)ceil(buffering_time) * GST_SECOND),
+ "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);
- LOGD("max-size-time : %f", buffering_time);
+ LOGD("max-size-time : %d ms", buffering_time);
} else {
/* queue2 */
if (buffer_handle->is_live)
g_object_set(G_OBJECT(buffer_handle->buffer),
"max-size-bytes", buffering_bytes,
- "max-size-time", (guint64)(buffering_time*GST_SECOND),
+ "max-size-time", (guint64)(buffering_time*GST_MSECOND),
"max-size-buffers", 0,
"use-rate-estimate", TRUE, NULL);
else
GstElement* buffer,
gboolean use_buffering,
guint buffering_bytes,
- gdouble buffering_time,
+ gint buffering_time,
gdouble low_percent,
gdouble high_percent,
muxed_buffer_type_e type,
streamer->streaming_buffer_type = BUFFER_TYPE_MUXED;
if (content_size > 0) {
- if (streamer->buffering_req.initial_second > 0)
+ if (streamer->buffering_req.prebuffer_time > 0)
streamer->buffering_req.is_pre_buffering = TRUE;
else
- streamer->buffering_req.initial_second = (gint)ceil(buffering_time);
+ streamer->buffering_req.prebuffer_time = buffering_time;
} else {
LOGD("live streaming without mq");
streamer->buffer_handle[BUFFER_TYPE_MUXED].is_live = TRUE;
- streamer->buffering_req.initial_second = buffering_time = DEFAULT_BUFFERING_TIME;
+ streamer->buffering_req.prebuffer_time = buffering_time = DEFAULT_BUFFERING_TIME;
}
}
if ((streamer->need_sync) && (streamer->streaming_buffer_type == BUFFER_TYPE_DEMUXED)) {
g_object_set(G_OBJECT(decodebin),
"max-size-bytes", buffer_handle->buffering_bytes,
- "max-size-time", (guint64)(ceil(buffer_handle->buffering_time) * GST_SECOND),
+ "max-size-time", (guint64)(buffer_handle->buffering_time * GST_MSECOND),
"low-percent", (gint)buffer_handle->buffer_low_percent,
"high-percent", (gint)buffer_handle->buffer_high_percent, NULL);
void __mm_player_streaming_set_multiqueue(mm_player_streaming_t* streamer,
GstElement* buffer,
gboolean use_buffering,
- gdouble buffering_time,
+ gint buffering_time,
gdouble low_percent,
gdouble high_percent)
{
streaming_buffer_t* buffer_handle = NULL;
- gdouble pre_buffering_time = 0.0;
+ gint pre_buffering_time = 0;
MMPLAYER_FENTER();
MMPLAYER_RETURN_IF_FAIL(streamer);
buffer_handle = &(streamer->buffer_handle[BUFFER_TYPE_DEMUXED]);
- pre_buffering_time = (gdouble)streamer->buffering_req.initial_second;
+ pre_buffering_time = streamer->buffering_req.prebuffer_time;
if (buffer) {
buffer_handle->buffer = buffer;
g_object_set(G_OBJECT(buffer_handle->buffer), "use-buffering", use_buffering, NULL);
}
- LOGD("pre_buffering: %2.2f, during playing: %2.2f\n", pre_buffering_time, buffering_time);
+ LOGD("pre_buffering: %d ms, during playing: %d ms\n", pre_buffering_time, buffering_time);
- if (pre_buffering_time <= 0.0) {
+ if (pre_buffering_time <= 0) {
pre_buffering_time = GET_DEFAULT_PLAYING_TIME(streamer);
- streamer->buffering_req.initial_second = (gint)ceil(buffering_time);
+ streamer->buffering_req.prebuffer_time = buffering_time;
}
- high_percent = (pre_buffering_time * 100) / GET_MAX_BUFFER_TIME(streamer);
+ high_percent = (gdouble)(pre_buffering_time * 100) / GET_MAX_BUFFER_TIME(streamer);
LOGD("high_percent %2.3f %%\n", high_percent);
streaming_set_buffer_size(streamer, BUFFER_TYPE_DEMUXED, GET_MAX_BUFFER_BYTES(streamer), GET_MAX_BUFFER_TIME(streamer));
guint buffer_criteria = 0;
guint estimated_content_bitrate = 0;
- gdouble buffer_buffering_time = DEFAULT_BUFFERING_TIME;
+ gint buffer_buffering_time = DEFAULT_BUFFERING_TIME;
MMPLAYER_FENTER();
LOGW("There is no content bitrate information\n");
if ((in_rate > 0) && (out_rate > 0))
- buffer_buffering_time = (gdouble)out_rate / (gdouble)in_rate;
+ buffer_buffering_time = (gint)(out_rate / in_rate)*1000;
else if ((in_rate <= 0) && (out_rate > 0))
buffer_buffering_time = MAX_BUFFERING_TIME;
else
static void
streaming_handle_fixed_buffering_mode(mm_player_streaming_t* streamer,
gint byte_out_rate,
- gdouble fixed_buffering_time,
+ gint fixed_buffering_time,
streaming_buffer_info_t* buffer_info)
{
streaming_buffer_t* buffer_handle = NULL;
guint buffering_bytes = 0;
- gdouble buffering_time = 0.0;
+ gint buffering_time = 0;
gdouble per_byte = 0.0;
gdouble per_time = 0.0;
buffer_handle = &(streamer->buffer_handle[streamer->streaming_buffer_type]);
buffering_time = fixed_buffering_time;
- LOGD("buffering time: %2.2f sec, out rate: %d\n", buffering_time, byte_out_rate);
+ LOGD("buffering time: %d ms, out rate: %d\n", buffering_time, byte_out_rate);
if ((buffering_time > 0) && (byte_out_rate > 0)) {
buffering_bytes = GET_NEW_BUFFERING_BYTE(byte_out_rate * buffering_time);
GET_PERCENT(buffering_time, GET_CURRENT_BUFFERING_TIME(buffer_handle), buffer_handle->buffer_high_percent, per_time);
GET_PERCENT(buffering_bytes, GET_CURRENT_BUFFERING_BYTE(buffer_handle), buffer_handle->buffer_high_percent, per_byte);
- LOGD("bytes %d, time %f, per_byte %f, per_time %f\n",
+ LOGD("bytes %d, time %d, per_byte %f, per_time %f\n",
buffering_bytes, buffering_time, per_byte, per_time);
(*buffer_info).buffering_bytes = buffering_bytes;
gint buffering_bytes = 0;
gint adj_buffering_bytes = 0;
- gdouble buffer_buffering_time = 0.0;
+ gint buffer_buffering_time = 0;
gdouble per_byte = 0.0;
gdouble per_time = 0.0;
gdouble portion = 0.0;
- gdouble default_buffering_time = 0.0;
+ gint default_buffering_time = 0;
MMPLAYER_RETURN_IF_FAIL(streamer);
MMPLAYER_RETURN_IF_FAIL(buffer_info);
- LOGD("pos %lld, dur %lld, size %lld, in/out:%d/%d, buffer_criteria:%d, time_rate:%f, need:%d sec\n",
+ LOGD("pos %lld, dur %lld, size %lld, in/out:%d/%d, buffer_criteria:%d, time_rate:%d, need:%d ms\n",
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);
- if (((expected_play_time == TO_THE_END) && (content_info.position <= 0)) ||
- (content_info.duration <= 0) ||
+ if ((content_info.duration <= 0) ||
(content_info.content_size <= 0)) {
LOGW("keep previous setting.\n");
return;
buffer_handle = &(streamer->buffer_handle[streamer->streaming_buffer_type]);
if (bitrate_info.byte_in_rate < bitrate_info.byte_out_rate) {
- if (expected_play_time != TO_THE_END)
- portion = (double)(expected_play_time * GST_SECOND) / (double)content_info.duration;
- else
- portion = (1 - (double)content_info.position/(double)content_info.duration);
-
+ portion = (double)(expected_play_time * GST_MSECOND) / (double)content_info.duration;
buffering_bytes = GET_NEW_BUFFERING_BYTE(((double)content_info.content_size * portion) \
* (1 - (double)bitrate_info.byte_in_rate/(double)bitrate_info.byte_out_rate));
} else {
}
if (buffering_bytes > 0)
- buffer_buffering_time = (gdouble)buffering_bytes / (gdouble)bitrate_info.byte_out_rate;
+ buffer_buffering_time = (gint)(buffering_bytes / bitrate_info.byte_out_rate)*1000;
if (content_info.position <= 0) {
/* if the buffer is filled under 50%, MSL use the original default buffering time.
if not, MSL use just 2 sec as a default buffering time. (to reduce initial buffering time) */
- default_buffering_time = streamer->default_val.buffering_time - ((gdouble)streamer->buffering_percent/50);
+ default_buffering_time = streamer->default_val.buffering_time - ((gdouble)streamer->buffering_percent/50)*1000;
} else
default_buffering_time = streamer->default_val.buffering_time;
if (buffer_buffering_time < default_buffering_time) {
- LOGD("adjusted time: %2.2f -> %2.2f\n", buffer_buffering_time, default_buffering_time);
+ LOGD("adjusted time: %d -> %d ms\n", buffer_buffering_time, default_buffering_time);
LOGD("adjusted bytes : %d or %d or %d\n",
buffering_bytes,
- (gint)(bitrate_info.byte_out_rate * buffer_buffering_time),
- (gint)(bitrate_info.buffer_criteria * buffer_buffering_time));
+ (gint)(bitrate_info.byte_out_rate * buffer_buffering_time/1000),
+ (gint)(bitrate_info.buffer_criteria * buffer_buffering_time/1000));
/* start monitoring the abmormal state */
if (content_info.position > 0)
streamer->default_val.buffering_monitor = TRUE;
buffer_buffering_time = default_buffering_time;
- adj_buffering_bytes = GET_NEW_BUFFERING_BYTE(bitrate_info.byte_out_rate * (gint)ceil(buffer_buffering_time));
+ adj_buffering_bytes = GET_NEW_BUFFERING_BYTE(bitrate_info.byte_out_rate * (gint)ceil((gdouble)buffer_buffering_time/1000));
buffering_bytes = MAX(buffering_bytes, adj_buffering_bytes);
}
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:%f\n",
+ LOGD("buffering mode %d, new info in_r:%d, out_r:%d, cb:%d, bt:%d\n",
buffering_mode, bitrate_info.byte_in_rate, bitrate_info.byte_out_rate,
bitrate_info.buffer_criteria, bitrate_info.time_rate);
/********************
* (1) fixed mode *
********************/
- gdouble buffering_time = 0.0;
+ gint buffering_time = 0;
if (streamer->buffering_req.is_pre_buffering == TRUE)
- buffering_time = (gdouble)streamer->buffering_req.initial_second;
+ buffering_time = streamer->buffering_req.prebuffer_time;
else
- buffering_time = (gdouble)streamer->buffering_req.runtime_second;
+ buffering_time = streamer->buffering_req.rebuffer_time;
streaming_handle_fixed_buffering_mode(streamer, bitrate_info.byte_out_rate, buffering_time, &buffer_info);
- } else if (buffering_mode == MM_PLAYER_BUFFERING_MODE_SLINK) {
- /***********************************
- * (2) once mode for samsung link *
- ***********************************/
- streaming_handle_adaptive_buffering_mode(streamer, content_info, bitrate_info, &buffer_info, TO_THE_END);
} else {
/*********************************
- * (3) adaptive mode (default) *
+ * (2) adaptive mode (default) *
*********************************/
gint expected_play_time = DEFAULT_PLAYING_TIME;
- if (streamer->buffering_req.runtime_second > 0)
- expected_play_time = streamer->buffering_req.runtime_second;
+ if (streamer->buffering_req.rebuffer_time > 0)
+ expected_play_time = streamer->buffering_req.rebuffer_time;
else if ((position == 0) && (streamer->is_buffering))
- expected_play_time = streamer->buffering_req.initial_second;
+ expected_play_time = streamer->buffering_req.prebuffer_time;
if (expected_play_time <= 0)
expected_play_time = DEFAULT_PLAYING_TIME;
buffer_handle->buffering_time = buffer_info.buffering_time;
}
- LOGD("adj buffer(%d) %d->%d bytes/%2.2f->%2.2f sec\n",
+ LOGD("adj buffer(%d) %d->%d bytes/%d->%d ms\n",
streamer->streaming_buffer_type,
GET_CURRENT_BUFFERING_BYTE(buffer_handle), buffer_info.buffering_bytes,
GET_CURRENT_BUFFERING_TIME(buffer_handle), buffer_info.buffering_time);
if (((GET_CURRENT_BUFFERING_BYTE(buffer_handle) < buffer_info.buffering_bytes) && IS_MUXED_BUFFERING_MODE(streamer)) ||
((GET_CURRENT_BUFFERING_TIME(buffer_handle) < buffer_info.buffering_time) && IS_DEMUXED_BUFFERING_MODE(streamer))) {
if (duration > 0 && position > 0) {
- gdouble buffering_time_limit = (gdouble)(duration - position)/GST_SECOND;
+ gint buffering_time_limit = (gint)(duration - position)/GST_MSECOND;
if (buffer_info.buffering_time > buffering_time_limit)
buffer_info.buffering_time = buffering_time_limit;
streaming_set_buffer_percent(streamer, streamer->streaming_buffer_type, low_percent, buffer_info.percent_byte, buffer_info.percent_time);
- LOGD("buffer setting: size %d, time %f, per %f\n",
+ LOGD("buffer setting: size %d, time %d, per %f\n",
GET_CURRENT_BUFFERING_BYTE(buffer_handle),
GET_CURRENT_BUFFERING_TIME(buffer_handle),
buffer_handle->buffer_high_percent);
static void
streaming_adjust_min_threshold(mm_player_streaming_t* streamer, gint64 position)
{
-#define DEFAULT_TIME_PAD 1 /* sec */
+#define DEFAULT_TIME_PAD 1000 /* ms */
gint playing_time = 0;
MMPLAYER_FENTER();
MMPLAYER_RETURN_IF_FAIL(streamer);
- playing_time = (gint)((position - streamer->default_val.prev_pos) / GST_SECOND);
+ playing_time = (gint)((position - streamer->default_val.prev_pos) / GST_MSECOND);
LOGD("buffering monitor = %s\n", (streamer->default_val.buffering_monitor) ? "ON" : "OFF");
- LOGD("playing_time (%d sec) = %lld - %lld \n", playing_time, position, streamer->default_val.prev_pos);
- LOGD("default time : %2.3f, prev buffering t : %2.3f\n",
+ LOGD("playing_time (%d ms) = %lld - %lld \n", playing_time, position, streamer->default_val.prev_pos);
+ LOGD("default time : %d, prev buffering t : %d\n",
streamer->default_val.buffering_time, streamer->buffer_handle[streamer->streaming_buffer_type].buffering_time);
- if ((streamer->default_val.buffering_monitor) && (playing_time <= (gint)streamer->default_val.buffering_time)) {
+ if ((streamer->default_val.buffering_monitor) && (playing_time <= streamer->default_val.buffering_time)) {
gint time_gap = 0;
- time_gap = (gint)(streamer->default_val.buffering_time - DEFAULT_BUFFERING_TIME);
+ time_gap = streamer->default_val.buffering_time - DEFAULT_BUFFERING_TIME;
if (time_gap <= 0)
time_gap = DEFAULT_TIME_PAD;
streamer->default_val.buffering_time += time_gap*2;
streamer->default_val.buffering_time = MIN(streamer->default_val.buffering_time, MAX_BUFFERING_TIME);
- } else
+ } else {
streamer->default_val.buffering_time = DEFAULT_BUFFERING_TIME;
+ }
- LOGD("new default min value %2.3f \n", streamer->default_val.buffering_time);
+ LOGD("new default min value %d \n", streamer->default_val.buffering_time);
streamer->default_val.buffering_monitor = FALSE;
streamer->default_val.prev_pos = position;
streaming_update_buffering_status(mm_player_streaming_t* streamer, GstMessage *buffering_msg, gint64 position)
{
gint buffer_percent = 0;
- gboolean increased_per = TRUE;
MMPLAYER_FENTER();
LOGD("[%s] buffering %d%%....\n",
GST_OBJECT_NAME(GST_MESSAGE_SRC(buffering_msg)), buffer_percent);
streamer->buffering_percent = buffer_percent;
- } else
- increased_per = FALSE;
+ }
if ((streamer->buffering_percent == MAX_BUFFER_PERCENT) || (streamer->is_buffering_done == TRUE)) {
streamer->is_buffering = FALSE;
streamer->is_buffering_done = FALSE;
else
streamer->buffering_percent = MAX_BUFFER_PERCENT;
- } else {
- /* need to update periodically in case of slink mode */
- if ((increased_per == TRUE) &&
- (buffer_percent%10 == 0) &&
- (streamer->buffering_req.mode == MM_PLAYER_BUFFERING_MODE_SLINK) &&
- (streamer->buffering_req.is_pre_buffering == FALSE)) {
- /* Update buffer setting to reflect data receiving rate for slink mode */
- streamer->need_update = TRUE;
- }
}
}
MMPLAYER_RETURN_IF_FAIL((GST_MESSAGE_TYPE(buffering_msg) == GST_MESSAGE_BUFFERING));
if (buffering_msg) {
- if (position > (gint64)(streamer->buffering_req.initial_second * GST_SECOND))
+ if (position > (gint64)(streamer->buffering_req.prebuffer_time * GST_MSECOND))
streamer->buffering_req.is_pre_buffering = FALSE;
streaming_update_buffering_status(streamer, buffering_msg, position);