tizen 2.3.1 release
[framework/multimedia/libmm-player.git] / src / mm_player_streaming.c
1 /*
2  * libmm-player
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YeJin Cho <cho.yejin@samsung.com>,
7  * Seungbae Shin <seungbae.shin@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  */
22
23 #include <sys/vfs.h>
24 #include "mm_player_utils.h"
25 #include "mm_player_streaming.h"
26
27 #define TO_THE_END 0
28
29 typedef struct{
30         gint byte_in_rate;              // byte
31         gint byte_out_rate;             // byte
32         gdouble time_rate;              // second
33         guint buffer_criteria;  // byte
34 }streaming_bitrate_info_t;
35
36 typedef struct{
37         gint64 position;        // ns
38         gint64 duration;        // ns
39         guint64 content_size;   // bytes
40 }streaming_content_info_t;
41
42 typedef struct{
43         guint buffering_bytes;          // bytes
44         gdouble buffering_time;         // second
45         gdouble percent_byte;
46         gdouble percent_time;
47 }streaming_buffer_info_t;
48
49 static void streaming_check_buffer_percent(gdouble in_low, gdouble in_high, gdouble *out_low, gdouble *out_high);
50 static void streaming_set_buffer_percent(mm_player_streaming_t* streamer, BufferType type, gdouble low_percent, gdouble high_percent_byte, gdouble high_percent_time);
51 static void streaming_set_queue2_queue_type (mm_player_streaming_t* streamer, gboolean use_file, gchar * file_path, guint64 content_size);
52 static void streaming_set_buffer_size(mm_player_streaming_t* streamer, BufferType type, guint buffering_bytes, gdouble buffering_time);
53 static void streaming_update_buffering_status(mm_player_streaming_t* streamer, GstMessage *buffering_msg, gint64 position);
54 static void streaming_get_current_bitrate_info( mm_player_streaming_t* streamer,
55                                                                                                 GstMessage *buffering_msg,
56                                                                                                 streaming_content_info_t content_info,
57                                                                                                 streaming_bitrate_info_t* bitrate_info);
58 static void
59 streaming_handle_fixed_buffering_mode(  mm_player_streaming_t* streamer,
60                                                                                 gint byte_out_rate,
61                                                                                 gdouble fixed_buffering_time,
62                                                                                 streaming_buffer_info_t* buffer_info);
63 static void
64 streaming_handle_adaptive_buffering_mode(       mm_player_streaming_t* streamer,
65                                                                                         streaming_content_info_t content_info,
66                                                                                         streaming_bitrate_info_t bitrate_info,
67                                                                                         streaming_buffer_info_t* buffer_info,
68                                                                                         gint expected_play_time);
69 static void
70 streaming_update_buffer_setting (       mm_player_streaming_t* streamer,
71                                                                         GstMessage *buffering_msg,
72                                                                         guint64 content_size,
73                                                                         gint64 position,
74                                                                         gint64 duration);
75
76 mm_player_streaming_t *
77 __mm_player_streaming_create (void)
78 {
79         mm_player_streaming_t *streamer = NULL;
80
81         MMPLAYER_FENTER();
82
83         streamer = (mm_player_streaming_t *) malloc (sizeof (mm_player_streaming_t));
84         if (!streamer)
85         {
86                 debug_error ("fail to create streaming player handle..\n");
87                 return NULL;
88         }
89
90         memset(streamer, 0, sizeof(mm_player_streaming_t));
91
92         MMPLAYER_FLEAVE();
93
94         return streamer;
95 }
96
97 static void
98 streaming_buffer_initialize (streaming_buffer_t* buffer_handle, gboolean buffer_init)
99 {
100         if (buffer_init)
101                 buffer_handle->buffer = NULL;
102
103         buffer_handle->buffering_bytes = DEFAULT_BUFFER_SIZE_BYTES;
104         buffer_handle->buffering_time = DEFAULT_BUFFERING_TIME;
105         buffer_handle->buffer_low_percent = DEFAULT_BUFFER_LOW_PERCENT;
106         buffer_handle->buffer_high_percent = DEFAULT_BUFFER_HIGH_PERCENT;
107         buffer_handle->is_live = FALSE;
108
109 }
110
111 void __mm_player_streaming_initialize (mm_player_streaming_t* streamer)
112 {
113         MMPLAYER_FENTER();
114
115         streamer->streaming_buffer_type = BUFFER_TYPE_DEFAULT;  // multi-queue
116
117         streaming_buffer_initialize(&(streamer->buffer_handle[BUFFER_TYPE_MUXED]), TRUE);
118         streaming_buffer_initialize(&(streamer->buffer_handle[BUFFER_TYPE_DEMUXED]), TRUE);
119
120         streamer->buffering_req.mode = MM_PLAYER_BUFFERING_MODE_ADAPTIVE;
121         streamer->buffering_req.is_pre_buffering = FALSE;
122         streamer->buffering_req.initial_second = 0;
123         streamer->buffering_req.runtime_second = 0;
124
125         streamer->default_val.buffering_monitor = FALSE;
126         streamer->default_val.buffering_time = DEFAULT_BUFFERING_TIME;
127
128         streamer->buffer_avg_bitrate = 0;
129         streamer->buffer_max_bitrate = 0;
130         streamer->need_update = FALSE;
131         streamer->need_sync = FALSE;
132
133         streamer->is_buffering = FALSE;
134         streamer->is_buffering_done = FALSE;
135         streamer->buffering_percent = -1;
136
137         MMPLAYER_FLEAVE();
138         return;
139 }
140
141 void __mm_player_streaming_deinitialize (mm_player_streaming_t* streamer)
142 {
143         MMPLAYER_FENTER();
144         return_if_fail(streamer);
145
146         streamer->streaming_buffer_type = BUFFER_TYPE_DEFAULT;  // multi-queue
147
148         streaming_buffer_initialize(&(streamer->buffer_handle[BUFFER_TYPE_MUXED]), FALSE);
149         streaming_buffer_initialize(&(streamer->buffer_handle[BUFFER_TYPE_DEMUXED]), FALSE);
150
151         streamer->buffering_req.mode = MM_PLAYER_BUFFERING_MODE_ADAPTIVE;
152         streamer->buffering_req.is_pre_buffering = FALSE;
153         streamer->buffering_req.initial_second = 0;
154         streamer->buffering_req.runtime_second = 0;
155
156         streamer->default_val.buffering_monitor = FALSE;
157         streamer->default_val.buffering_time = DEFAULT_BUFFERING_TIME;
158
159         streamer->buffer_avg_bitrate = 0;
160         streamer->buffer_max_bitrate = 0;
161         streamer->need_update = FALSE;
162         streamer->need_sync = FALSE;
163
164         streamer->is_buffering = FALSE;
165         streamer->is_buffering_done = FALSE;
166         streamer->buffering_percent = -1;
167
168         MMPLAYER_FLEAVE();
169         return;
170 }
171
172 void __mm_player_streaming_destroy (mm_player_streaming_t* streamer)
173 {
174         MMPLAYER_FENTER();
175
176         if(streamer)
177         {
178                 g_free (streamer);
179                 streamer = NULL;
180         }
181
182         MMPLAYER_FLEAVE();
183
184         return;
185 }
186
187 void __mm_player_streaming_set_content_bitrate(mm_player_streaming_t* streamer, guint max_bitrate, guint avg_bitrate)
188 {
189         MMPLAYER_FENTER();
190
191         return_if_fail(streamer);
192
193         /* Note : Update buffering criterion bytes
194         *      1. maximum bitrate is considered first.
195         *      2. average bitrage * 3 is next.
196         *      3. if there are no updated bitrate, use default buffering limit.
197         */
198         if (max_bitrate > 0 && streamer->buffer_max_bitrate != max_bitrate)
199         {
200                 debug_log("set maximum bitrate(%dbps).\n", max_bitrate);
201                 streamer->buffer_max_bitrate = max_bitrate;
202                 if (streamer->buffering_req.is_pre_buffering == FALSE)
203                 {
204                         streamer->need_update = TRUE;
205                 }
206                 else
207                 {
208                         debug_log("pre-buffering...\n");
209
210                         if (IS_MUXED_BUFFERING_MODE(streamer))
211                                 streaming_update_buffer_setting(streamer, NULL, 0, 0, 0);
212                 }
213         }
214
215         if (avg_bitrate > 0 && streamer->buffer_avg_bitrate != avg_bitrate)
216         {
217                 debug_log("set averate bitrate(%dbps).\n", avg_bitrate);
218                 streamer->buffer_avg_bitrate = avg_bitrate;
219
220                 if (streamer->buffering_req.is_pre_buffering == FALSE)
221                 {
222                         streamer->need_update = TRUE;
223                 }
224                 else
225                 {
226                         debug_log("pre-buffering...\n");
227
228                         if (IS_MUXED_BUFFERING_MODE(streamer))
229                                 streaming_update_buffer_setting(streamer, NULL, 0, 0, 0);
230                 }
231         }
232
233         MMPLAYER_FLEAVE();
234         return;
235 }
236
237 static void
238 streaming_check_buffer_percent(gdouble in_low, gdouble in_high, gdouble *out_low, gdouble *out_high)
239 {
240         gdouble buffer_low_percent = DEFAULT_BUFFER_LOW_PERCENT;
241         gdouble buffer_high_percent = DEFAULT_BUFFER_HIGH_PERCENT;
242
243         MMPLAYER_FENTER();
244
245         return_if_fail(out_low && out_high);
246
247         if (in_low <= MIN_BUFFER_PERCENT || in_low >= MAX_BUFFER_PERCENT)
248         {
249                 debug_warning("buffer low percent is out of range. use defaut value.");
250         }
251         else
252         {
253                 buffer_low_percent = in_low;
254         }
255
256         if (in_high  <=  MIN_BUFFER_PERCENT || in_high  >=  MAX_BUFFER_PERCENT)
257         {
258                 debug_warning("buffer high percent is out of range. use defaut value.");
259         }
260         else
261         {
262                 buffer_high_percent = in_high;
263         }
264
265         if (buffer_high_percent <= buffer_low_percent)
266                 buffer_high_percent =  buffer_low_percent + 1.0;
267
268         debug_log("set buffer percent to %2.3f ~ %2.3f.",  buffer_low_percent, buffer_high_percent);
269
270         *out_low = buffer_low_percent;
271         *out_high = buffer_high_percent;
272 }
273
274 static void
275 streaming_set_buffer_percent(   mm_player_streaming_t* streamer,
276                                                                 BufferType type,
277                                                                 gdouble low_percent,
278                                                                 gdouble high_percent_byte,
279                                                                 gdouble high_percent_time)
280 {
281         gdouble confirmed_low = DEFAULT_BUFFER_LOW_PERCENT;
282         gdouble confirmed_high = DEFAULT_BUFFER_HIGH_PERCENT;
283         gdouble high_percent = 0.0;
284
285         streaming_buffer_t* buffer_handle = NULL;
286         gchar* factory_name = NULL;
287
288         MMPLAYER_FENTER();
289         return_if_fail(streamer);
290         return_if_fail(type < BUFFER_TYPE_MAX);
291
292         buffer_handle = &(streamer->buffer_handle[type]);
293         if (!(buffer_handle && buffer_handle->buffer))
294         {
295                 debug_error("buffer_handle->buffer is NULL!");
296                 return;
297         }
298
299         factory_name = GST_PLUGIN_FEATURE_NAME(gst_element_get_factory(buffer_handle->buffer));
300
301         if (!factory_name)
302         {
303                 debug_error("Fail to get factory name!");
304                 return;
305         }
306
307         if (type == BUFFER_TYPE_MUXED)
308                 high_percent = high_percent_byte;
309         else
310                 high_percent = MAX(high_percent_time, high_percent_byte);
311
312         streaming_check_buffer_percent(low_percent, high_percent, &confirmed_low, &confirmed_high);
313
314         // if use-buffering is disabled, this settings do not have any meaning.
315         debug_log("target buffer elem : %s (%2.3f ~ %2.3f)",
316                 GST_ELEMENT_NAME(buffer_handle->buffer), confirmed_low, confirmed_high);
317
318         if ((confirmed_low == DEFAULT_BUFFER_LOW_PERCENT) ||
319                 (buffer_handle->buffer_low_percent != confirmed_low))
320         {
321                 if (g_strrstr(factory_name, "queue2"))
322                         g_object_set (G_OBJECT(buffer_handle->buffer), "low-percent", confirmed_low, NULL);
323                 else
324                         g_object_set (G_OBJECT(buffer_handle->buffer), "low-percent", (gint)confirmed_low, NULL);
325         }
326
327         if ((confirmed_high == DEFAULT_BUFFER_HIGH_PERCENT) ||
328                 (buffer_handle->buffer_high_percent != confirmed_high))
329         {
330                 if (g_strrstr(factory_name, "queue2"))
331                         g_object_set (G_OBJECT(buffer_handle->buffer), "high-percent", confirmed_high, NULL);
332                 else
333                         g_object_set (G_OBJECT(buffer_handle->buffer), "high-percent", (gint)confirmed_high, NULL);
334         }
335
336         buffer_handle->buffer_low_percent = confirmed_low;
337         buffer_handle->buffer_high_percent = confirmed_high;
338
339         MMPLAYER_FLEAVE();
340         return;
341 }
342
343 static void
344 streaming_set_queue2_queue_type (mm_player_streaming_t* streamer, gboolean use_file, gchar * file_path, guint64 content_size)
345 {
346         streaming_buffer_t* buffer_handle = NULL;
347         guint64 storage_available_size = 0L; //bytes
348         guint64 file_buffer_size = 0L;  //bytes
349         gchar file_buffer_name[MM_MAX_URL_LEN] = {0};
350         struct statfs buf = {0};
351         gchar* factory_name = NULL;
352
353         MMPLAYER_FENTER();
354         return_if_fail(streamer);
355         return_if_fail(streamer->buffer_handle[BUFFER_TYPE_MUXED].buffer);
356
357         buffer_handle = &(streamer->buffer_handle[BUFFER_TYPE_MUXED]);
358
359         if (!(buffer_handle && buffer_handle->buffer))
360         {
361                 debug_error("buffer_handle->buffer is NULL!");
362                 return;
363         }
364
365         factory_name = GST_PLUGIN_FEATURE_NAME(gst_element_get_factory(buffer_handle->buffer));
366
367         if (!factory_name)
368         {
369                 debug_error("Fail to get factory name!");
370                 return;
371         }
372
373         debug_log("target buffer elem : %s", GST_ELEMENT_NAME(buffer_handle->buffer));
374
375         if (!g_strrstr(factory_name, "queue2"))
376         {
377                 debug_log("only queue2 can use file buffer. not decodebin2 or multiQ\n");
378                 return;
379         }
380
381         if ((!use_file) || (!g_strrstr(factory_name, "queue2")))
382         {
383                 debug_log("use memory for buffering. streaming is played on push-based. \n"
384                                         "buffering position would not be updated.\n"
385                                         "buffered data would be flushed after played.\n"
386                                         "seeking and getting duration could be failed due to file format.");
387                 return;
388         }
389
390         debug_log("[Queue2] use file for buffering. streaming is played on pull-based. \n");
391
392         if (!file_path || strlen(file_path) <= 0)
393                 file_path = g_strdup(DEFAULT_FILE_BUFFER_PATH);
394
395         g_snprintf(file_buffer_name, MM_MAX_URL_LEN, "%s/XXXXXX", file_path);
396         secure_debug_log("[Queue2] the buffering file name is %s.\n", file_buffer_name);
397
398         if (statfs((const char *)file_path, &buf) < 0)
399         {
400                 debug_warning ("[Queue2] fail to get availabe storage capacity. just use file buffer.\n");
401                 file_buffer_size = 0L;
402         }
403         else
404         {
405                 storage_available_size = (guint64)buf.f_bavail * (guint64)buf.f_bsize; //bytes
406
407                 debug_log ("[Queue2] the number of available blocks : %"G_GUINT64_FORMAT
408                                         ", the block size is %"G_GUINT64_FORMAT".\n",
409                                         (guint64)buf.f_bavail, (guint64)buf.f_bsize);
410
411                 debug_log ("[Queue2] calculated availabe storage size is %"
412                                                         G_GUINT64_FORMAT" Bytes.\n", storage_available_size);
413
414                 if (content_size <= 0 || content_size >= storage_available_size)
415                         file_buffer_size = storage_available_size;
416                 else
417                         file_buffer_size = 0L;
418         }
419
420         if (file_buffer_size>0)
421                 debug_log("[Queue2] use file ring buffer for buffering.");
422
423         g_object_set (G_OBJECT(buffer_handle->buffer), "temp-template", file_buffer_name, NULL);
424         g_object_set (G_OBJECT(buffer_handle->buffer), "file-buffer-max-size", file_buffer_size, NULL);
425
426         MMPLAYER_FLEAVE();
427         return;
428 }
429
430 static void
431 streaming_set_buffer_size(mm_player_streaming_t* streamer, BufferType type, guint buffering_bytes, gdouble buffering_time)
432 {
433         streaming_buffer_t* buffer_handle = NULL;
434
435         MMPLAYER_FENTER();
436
437         return_if_fail(streamer);
438         return_if_fail(buffering_bytes > 0);
439         return_if_fail(type < BUFFER_TYPE_MAX);
440
441         buffer_handle = &(streamer->buffer_handle[type]);
442
443         if (buffer_handle && buffer_handle->buffer)
444         {
445                 if (g_strrstr(GST_ELEMENT_NAME(buffer_handle->buffer), "multiqueue"))
446                 {
447                         if (buffering_time <= 0)
448                                 buffering_time = GET_CURRENT_BUFFERING_TIME(buffer_handle);
449
450                         g_object_set (G_OBJECT(buffer_handle->buffer),
451                                                         "max-size-bytes", MAX_DECODEBIN_BUFFER_BYTES,   // fixed
452                                                         "max-size-time", ((guint)ceil(buffering_time) * GST_SECOND),
453                                                         "max-size-buffers", 0, NULL);                                   // disable
454
455                         buffer_handle->buffering_time = buffering_time;
456                         buffer_handle->buffering_bytes = MAX_DECODEBIN_BUFFER_BYTES;
457
458                         debug_log("[New][MQ] max-size-time : %f", buffering_time);
459                 }
460                 else    // queue2
461                 {
462                         if (buffer_handle->is_live)
463                         {
464                                 g_object_set (G_OBJECT(buffer_handle->buffer),
465                                                                 "max-size-bytes", buffering_bytes,
466                                                                 "max-size-time", (guint64)(buffering_time*GST_SECOND),
467                                                                 "max-size-buffers", 0,
468                                                                 "use-rate-estimate", TRUE, NULL);
469                         }
470                         else
471                         {
472                                 g_object_set (G_OBJECT(buffer_handle->buffer),
473                                                                 "max-size-bytes", buffering_bytes,
474                                                                 "max-size-time", (guint64)0,
475                                                                 "max-size-buffers", 0,
476                                                                 "use-rate-estimate", FALSE, NULL);
477                         }
478
479                         buffer_handle->buffering_bytes = buffering_bytes;
480                         buffer_handle->buffering_time = buffering_time;
481
482                         debug_log("[New][Q2] max-size-bytes : %d", buffering_bytes);
483                 }
484         }
485
486         MMPLAYER_FLEAVE();
487         return;
488 }
489
490 void __mm_player_streaming_set_queue2(  mm_player_streaming_t* streamer,
491                                                                                 GstElement* buffer,
492                                                                                 gboolean use_buffering,
493                                                                                 guint buffering_bytes,
494                                                                                 gdouble buffering_time,
495                                                                                 gdouble low_percent,
496                                                                                 gdouble high_percent,
497                                                                                 gboolean use_file,
498                                                                                 gchar* file_path,
499                                                                                 guint64 content_size)
500 {
501         MMPLAYER_FENTER();
502         return_if_fail(streamer);
503
504         if (buffer)
505         {
506                 debug_log("USE-BUFFERING : %s", (use_buffering)?"OOO":"XXX");
507
508                 streamer->buffer_handle[BUFFER_TYPE_MUXED].buffer = buffer;
509
510                 if (use_buffering)
511                 {
512                         streamer->streaming_buffer_type = BUFFER_TYPE_MUXED;
513
514                         if (content_size > 0)
515                         {
516                                 if (streamer->buffering_req.initial_second > 0)
517                                         streamer->buffering_req.is_pre_buffering = TRUE;
518                                 else
519                                         streamer->buffering_req.initial_second = (gint)ceil(buffering_time);
520                         }
521                         else
522                         {
523                                 debug_log("live streaming without mq");
524
525                                 streamer->buffer_handle[BUFFER_TYPE_MUXED].is_live = TRUE;
526                                 streamer->buffering_req.initial_second = buffering_time = DEFAULT_BUFFERING_TIME;
527                         }
528                 }
529
530                 g_object_set ( G_OBJECT (streamer->buffer_handle[BUFFER_TYPE_MUXED].buffer), "use-buffering", use_buffering, NULL );
531         }
532
533         streaming_set_buffer_size               (streamer, BUFFER_TYPE_MUXED, buffering_bytes, buffering_time);
534         streaming_set_buffer_percent    (streamer, BUFFER_TYPE_MUXED, low_percent, high_percent, 0);
535         streaming_set_queue2_queue_type (streamer, use_file, file_path, content_size);
536
537         MMPLAYER_FLEAVE();
538         return;
539 }
540
541 void __mm_player_streaming_sync_property(mm_player_streaming_t* streamer, GstElement* decodebin)
542 {
543         streaming_buffer_t* buffer_handle = NULL;
544
545         MMPLAYER_FENTER();
546
547         return_if_fail ( streamer && decodebin );
548
549         buffer_handle = &(streamer->buffer_handle[BUFFER_TYPE_DEMUXED]);
550
551         if ((streamer->need_sync) && (streamer->streaming_buffer_type == BUFFER_TYPE_DEMUXED))
552         {
553                 g_object_set (G_OBJECT(decodebin),
554                                         "max-size-bytes", buffer_handle->buffering_bytes,
555                                         "max-size-time", (guint64)(ceil(buffer_handle->buffering_time) * GST_SECOND),
556                                         "low-percent", (gint)buffer_handle->buffer_low_percent,
557                                         "high-percent", (gint)buffer_handle->buffer_high_percent, NULL);
558
559         }
560
561         streamer->need_sync = FALSE;
562 }
563
564 void __mm_player_streaming_set_multiqueue(      mm_player_streaming_t* streamer,
565                                                                                 GstElement* buffer,
566                                                                                 gboolean use_buffering,
567                                                                                 guint buffering_bytes,
568                                                                                 gdouble buffering_time,
569                                                                                 gdouble low_percent,
570                                                                                 gdouble high_percent)
571 {
572         streaming_buffer_t* buffer_handle = NULL;
573         gdouble pre_buffering_time = 0.0;
574
575         MMPLAYER_FENTER();
576         return_if_fail(streamer);
577
578         buffer_handle = &(streamer->buffer_handle[BUFFER_TYPE_DEMUXED]);
579         pre_buffering_time = (gdouble)streamer->buffering_req.initial_second;
580
581         if (buffer)
582         {
583                 debug_log("USE-BUFFERING : %s", (use_buffering)?"OOO":"XXX");
584
585                 buffer_handle->buffer = buffer;
586
587                 if (use_buffering)
588                 {
589                         streamer->streaming_buffer_type = BUFFER_TYPE_DEMUXED;
590
591                         // during prebuffering by requirement, buffer setting should not be changed.
592                         if (pre_buffering_time > 0)
593                                 streamer->buffering_req.is_pre_buffering = TRUE;
594                 }
595
596                 g_object_set ( G_OBJECT (buffer_handle->buffer), "use-buffering", use_buffering, NULL );
597         }
598
599         debug_log ("time req: %2.2f, default: %2.2f\n", pre_buffering_time, buffering_time);
600
601         if (pre_buffering_time <= 0.0)
602         {
603                 pre_buffering_time = DEFAULT_PLAYING_TIME;
604                 streamer->buffering_req.initial_second = (gint)ceil(buffering_time);
605         }
606
607         high_percent = (pre_buffering_time * 100) / MAX_DECODEBIN_BUFFER_TIME;
608         debug_log ("high_percent :  per %2.3f %%\n", high_percent);
609
610         streaming_set_buffer_size (streamer, BUFFER_TYPE_DEMUXED, MAX_DECODEBIN_BUFFER_BYTES, MAX_DECODEBIN_BUFFER_TIME);
611         streaming_set_buffer_percent (streamer, BUFFER_TYPE_DEMUXED, low_percent, 0, high_percent);
612
613         streamer->need_sync = TRUE;
614
615         MMPLAYER_FLEAVE();
616         return;
617 }
618
619 static void
620 streaming_get_current_bitrate_info(     mm_player_streaming_t* streamer,
621                                                                         GstMessage *buffering_msg,
622                                                                         streaming_content_info_t content_info,
623                                                                         streaming_bitrate_info_t* bitrate_info)
624 {
625
626         GstQuery *query = NULL;
627         GstBufferingMode mode = GST_BUFFERING_STREAM;
628         gint in_rate = 0;
629         gint out_rate = 0;
630         gint64 buffering_left = -1;
631
632         guint buffer_criteria = 0;
633         guint estimated_content_bitrate = 0;
634
635         gdouble buffer_buffering_time = DEFAULT_BUFFERING_TIME;
636
637         MMPLAYER_FENTER();
638
639         return_if_fail(streamer);
640         return_if_fail(bitrate_info);
641
642         if ((buffering_msg == NULL) ||
643                 ((streamer->buffer_handle[BUFFER_TYPE_DEMUXED].buffer != NULL) &&
644                 (streamer->buffer_handle[BUFFER_TYPE_MUXED].buffer != NULL) &&
645                 (buffering_msg->src == (GstObject *)streamer->buffer_handle[BUFFER_TYPE_DEMUXED].buffer)))
646         {
647                 query = gst_query_new_buffering (GST_FORMAT_PERCENT);
648
649                 if (gst_element_query ((streamer->buffer_handle[BUFFER_TYPE_MUXED].buffer), query))
650                 {
651                         gst_query_parse_buffering_stats (query, &mode, &in_rate, &out_rate, &buffering_left);
652                 }
653
654                 gst_query_unref (query);
655         }
656         else
657         {
658                 gst_message_parse_buffering_stats (buffering_msg, &mode, &in_rate, &out_rate, &buffering_left);
659         }
660
661         debug_log ("Streaming Info : in %d, out %d, left %lld\n", in_rate, out_rate, buffering_left);
662
663         if ((content_info.content_size > 0) && (content_info.duration > 0) && ((content_info.duration/GST_SECOND) > 0))
664                 estimated_content_bitrate = GET_BIT_FROM_BYTE((guint)(content_info.content_size / (content_info.duration/GST_SECOND)));
665
666         if (streamer->buffer_max_bitrate > 0)
667         {
668                 streamer->buffer_max_bitrate = MAX(streamer->buffer_max_bitrate, streamer->buffer_avg_bitrate);
669                 streamer->buffer_max_bitrate = MAX(streamer->buffer_max_bitrate, estimated_content_bitrate);
670
671                 buffer_criteria = GET_BYTE_FROM_BIT(streamer->buffer_max_bitrate);
672
673                 if (streamer->buffer_avg_bitrate > estimated_content_bitrate)
674                         out_rate = GET_BYTE_FROM_BIT(streamer->buffer_avg_bitrate);
675                 else if (estimated_content_bitrate != 0)
676                         out_rate = GET_BYTE_FROM_BIT(estimated_content_bitrate);
677                 else
678                         out_rate = GET_BYTE_FROM_BIT(streamer->buffer_max_bitrate/3);
679
680                 debug_log ("(max)content_max_byte_rate %d, byte_out_rate %d\n", buffer_criteria, out_rate);
681         }
682         else if (streamer->buffer_avg_bitrate > 0)
683         {
684                 buffer_criteria = GET_BYTE_FROM_BIT(streamer->buffer_avg_bitrate * 3);
685                 out_rate = GET_BYTE_FROM_BIT(MAX(streamer->buffer_avg_bitrate,estimated_content_bitrate));
686
687                 debug_log ("(avg)content_max_byte_rate %d, byte_out_rate %d\n", buffer_criteria, out_rate);
688         }
689         else
690         {
691                 debug_warning ("There is no content bitrate information\n");
692         }
693
694         if ((in_rate > 0) && (out_rate > 0))
695                 buffer_buffering_time =  (gdouble)out_rate / (gdouble)in_rate;
696         else if ((in_rate <= 0) && (out_rate > 0))
697                 buffer_buffering_time = MAX_BUFFERING_TIME;
698         else
699                 buffer_buffering_time = DEFAULT_BUFFERING_TIME;
700
701         (*bitrate_info).byte_in_rate = in_rate;
702         (*bitrate_info).byte_out_rate = out_rate;
703         (*bitrate_info).time_rate = buffer_buffering_time;
704         (*bitrate_info).buffer_criteria = buffer_criteria;
705 }
706
707 static void
708 streaming_handle_fixed_buffering_mode(  mm_player_streaming_t* streamer,
709                                                                                 gint byte_out_rate,
710                                                                                 gdouble fixed_buffering_time,
711                                                                                 streaming_buffer_info_t* buffer_info)
712 {
713         streaming_buffer_t* buffer_handle = NULL;
714
715         guint buffering_bytes = 0;
716         gdouble buffering_time = 0.0;
717         gdouble per_byte = 0.0;
718         gdouble per_time = 0.0;
719
720         return_if_fail(streamer);
721         return_if_fail(buffer_info);
722
723         buffer_handle = &(streamer->buffer_handle[streamer->streaming_buffer_type]);
724         buffering_time = fixed_buffering_time;
725
726         debug_log ("[IN] MM_PLAYER_BUFFERING_MODE_FIXED (%2.2f sec), out:%d\n", buffering_time, byte_out_rate);
727
728         if ((buffering_time > 0) && (byte_out_rate > 0))
729         {
730                 buffering_bytes = GET_NEW_BUFFERING_BYTE(byte_out_rate * buffering_time);
731         }
732         else
733         {
734                 if (buffering_time <= 0)
735                         buffering_time = GET_CURRENT_BUFFERING_TIME(buffer_handle);
736
737                 debug_warning ("content bitrate is not updated yet.\n");
738                 buffering_bytes = GET_CURRENT_BUFFERING_BYTE(buffer_handle);
739         }
740
741         GET_PERCENT(buffering_time, GET_CURRENT_BUFFERING_TIME(buffer_handle), buffer_handle->buffer_high_percent, per_time);
742         GET_PERCENT(buffering_bytes, GET_CURRENT_BUFFERING_BYTE(buffer_handle), buffer_handle->buffer_high_percent, per_byte);
743
744         debug_log ("[NEW] bytes %d, time %f, per_byte %f, per_time %f\n",
745                                                                                 buffering_bytes, buffering_time, per_byte, per_time);
746
747         (*buffer_info).buffering_bytes = buffering_bytes;
748         (*buffer_info).buffering_time = buffering_time;
749         (*buffer_info).percent_byte = per_byte;
750         (*buffer_info).percent_time = per_time;
751 }
752
753 static void
754 streaming_handle_adaptive_buffering_mode(       mm_player_streaming_t* streamer,
755                                                                                 streaming_content_info_t content_info,
756                                                                                 streaming_bitrate_info_t bitrate_info,
757                                                                                 streaming_buffer_info_t* buffer_info,
758                                                                                 gint expected_play_time)
759 {
760         streaming_buffer_t* buffer_handle = NULL;
761
762         gint buffering_bytes = 0;
763         gint adj_buffering_bytes = 0;
764         gdouble buffer_buffering_time = 0.0;
765         gdouble per_byte = 0.0;
766         gdouble per_time = 0.0;
767         gdouble portion = 0.0;
768         gdouble default_buffering_time = 0.0;
769
770         return_if_fail(streamer);
771         return_if_fail(buffer_info);
772
773         debug_log ("[IN] MM_PLAYER_BUFFERING_MODE_SLINK (pos %lld, dur %lld, size %lld), in/out:%d/%d, buffer_criteria:%d, time_rate:%f, need:%d sec\n",
774                                                                                 content_info.position, content_info.duration, content_info.content_size,
775                                                                                 bitrate_info.byte_in_rate, bitrate_info.byte_out_rate,
776                                                                                 bitrate_info.buffer_criteria, bitrate_info.time_rate, expected_play_time);
777
778         if (((expected_play_time == TO_THE_END) && (content_info.position <= 0)) ||
779                 (content_info.duration <= 0) ||
780                 (content_info.content_size <= 0))
781         {
782                 debug_warning ("Impossible to update buffer setting!! keep previous setting!\n");
783                 return;
784         }
785
786         if ((bitrate_info.byte_out_rate <= 0) || (bitrate_info.buffer_criteria == 0))
787         {
788                 debug_warning ("Don't need to change buffer setting(or impossible)!! keep previous setting!\n");
789                 return;
790         }
791
792         buffer_handle = &(streamer->buffer_handle[streamer->streaming_buffer_type]);
793
794         if (bitrate_info.byte_in_rate < bitrate_info.byte_out_rate)
795         {
796                 if (expected_play_time != TO_THE_END)
797                         portion = (double)(expected_play_time * GST_SECOND) / (double)content_info.duration;
798                 else
799                         portion = (1 - (double)content_info.position/(double)content_info.duration);
800
801                 buffering_bytes = GET_NEW_BUFFERING_BYTE(((double)content_info.content_size * portion)  \
802                                                                                                                         * (1 - (double)bitrate_info.byte_in_rate/(double)bitrate_info.byte_out_rate));
803         }
804         else
805         {
806                 // buffering_bytes will be set as streamer->default_val.buffering_time
807                 debug_warning ("*Warning : receiving rate(%d) > avg content bitrate(%d)!\n", bitrate_info.byte_in_rate, bitrate_info.byte_out_rate);
808                 debug_warning ("*Warning : There is no reason to buffering.!\n");
809                 debug_warning ("*Warning : in-rate or content bitrate has reported wrong value.!\n");
810         }
811
812         if (buffering_bytes > 0)
813                 buffer_buffering_time = (gdouble)buffering_bytes / (gdouble)bitrate_info.byte_out_rate;
814
815         if (content_info.position <= 0)
816         {
817                 /* if the buffer is filled under 50%, MSL use the original default buffering time.
818                    if not, MSL use just 2 sec as a default buffering time. (to reduce initial buffering time) */
819                 default_buffering_time = streamer->default_val.buffering_time - (streamer->buffering_percent/50);
820         }
821         else
822         {
823                 default_buffering_time = streamer->default_val.buffering_time;
824         }
825
826         if (buffer_buffering_time < default_buffering_time)
827         {
828                 debug_log ("[NEW- adj] buffering time : %2.2f --> %2.2f\n", buffer_buffering_time, default_buffering_time);
829                 debug_log ("[NEW- adj] buffering bytes : %d or %d or %d\n",
830                         buffering_bytes,
831                         (gint)(bitrate_info.byte_out_rate * buffer_buffering_time),
832                         (gint)(bitrate_info.buffer_criteria * buffer_buffering_time));
833
834                 if (content_info.position > 0)
835                 {
836                         // start monitoring the abmormal state
837                         streamer->default_val.buffering_monitor = TRUE;
838                 }
839
840                 buffer_buffering_time = default_buffering_time;
841                 adj_buffering_bytes = GET_NEW_BUFFERING_BYTE(bitrate_info.byte_out_rate * (gint)ceil(buffer_buffering_time));
842                 buffering_bytes = MAX(buffering_bytes, adj_buffering_bytes);
843         }
844
845         GET_PERCENT(buffering_bytes, GET_CURRENT_BUFFERING_BYTE(buffer_handle), buffer_handle->buffer_high_percent, per_byte);
846         GET_PERCENT(buffer_buffering_time, GET_CURRENT_BUFFERING_TIME(buffer_handle), buffer_handle->buffer_high_percent, per_time);
847
848         debug_log ("[NEW- last][buffering_monitor == %s] bytes %d, time %f, per_byte %f, per_time %f\n",
849                                                                                 (streamer->default_val.buffering_monitor)?"OO":"XX",
850                                                                                 buffering_bytes, buffer_buffering_time, per_byte, per_time);
851
852         (*buffer_info).buffering_bytes = buffering_bytes;
853         (*buffer_info).buffering_time = buffer_buffering_time;
854         (*buffer_info).percent_byte = per_byte;
855         (*buffer_info).percent_time = per_time;
856
857 }
858
859 static void
860 streaming_update_buffer_setting (       mm_player_streaming_t* streamer,
861                                                                         GstMessage *buffering_msg,      // can be null
862                                                                         guint64 content_size,
863                                                                         gint64 position,
864                                                                         gint64 duration)
865 {
866         streaming_buffer_t* buffer_handle = NULL;
867         MMPlayerBufferingMode buffering_mode = MM_PLAYER_BUFFERING_MODE_ADAPTIVE;
868
869         streaming_buffer_info_t buffer_info;
870         streaming_content_info_t content_info;
871         streaming_bitrate_info_t bitrate_info;
872
873         gdouble low_percent = 0.0;
874
875         MMPLAYER_FENTER();
876
877         return_if_fail ( streamer );
878
879         memset(&buffer_info, 0x00, sizeof(streaming_buffer_info_t));
880         memset(&content_info, 0x00, sizeof(streaming_content_info_t));
881         memset(&bitrate_info, 0x00, sizeof(streaming_bitrate_info_t));
882
883         buffer_handle = &(streamer->buffer_handle[streamer->streaming_buffer_type]);
884
885         if (streamer->buffering_req.is_pre_buffering == TRUE)
886                 buffering_mode = MM_PLAYER_BUFFERING_MODE_FIXED;
887         else
888                 buffering_mode = streamer->buffering_req.mode;
889
890         buffer_info.buffering_bytes = buffer_handle->buffering_bytes;
891         buffer_info.buffering_time = buffer_handle->buffering_time;
892         buffer_info.percent_byte = buffer_handle->buffer_high_percent;
893         buffer_info.percent_time = buffer_handle->buffer_high_percent;
894
895         content_info.position = position;
896         content_info.duration = duration;
897         content_info.content_size = content_size;
898
899         streaming_get_current_bitrate_info(streamer, buffering_msg, content_info, &bitrate_info);
900
901         debug_log ("buffering mode %d, new info in_r:%d, out_r:%d, cb:%d, bt:%f\n",
902                                         buffering_mode, bitrate_info.byte_in_rate, bitrate_info.byte_out_rate,
903                                         bitrate_info.buffer_criteria, bitrate_info.time_rate);
904
905         /* calculate buffer low/high percent */
906         low_percent = DEFAULT_BUFFER_LOW_PERCENT;
907
908         /********************
909          * (1) fixed mode   *
910          ********************/
911
912         if (buffering_mode == MM_PLAYER_BUFFERING_MODE_FIXED)
913         {
914                 gdouble buffering_time = 0.0;
915
916                 if (streamer->buffering_req.is_pre_buffering == TRUE)
917                         buffering_time = (gdouble)streamer->buffering_req.initial_second;
918                 else
919                         buffering_time = (gdouble)streamer->buffering_req.runtime_second;
920
921                 streaming_handle_fixed_buffering_mode(streamer, bitrate_info.byte_out_rate, buffering_time, &buffer_info);
922         }
923
924         /***********************************
925          * (2) once mode for samsung link  *
926          ***********************************/
927         else if (buffering_mode == MM_PLAYER_BUFFERING_MODE_SLINK)
928         {
929                 streaming_handle_adaptive_buffering_mode(streamer, content_info, bitrate_info, &buffer_info, TO_THE_END);
930         }
931
932         /*********************************
933          * (3) adaptive mode (default)   *
934          *********************************/
935         else
936         {
937                 gint expected_play_time = DEFAULT_PLAYING_TIME;
938
939                 if (streamer->buffering_req.runtime_second > 0)
940                 {
941                         expected_play_time = streamer->buffering_req.runtime_second;
942                 }
943                 else if ((position == 0) && (streamer->is_buffering))
944                 {
945                         expected_play_time = streamer->buffering_req.initial_second;
946                 }
947
948                 if (expected_play_time <= 0)
949                         expected_play_time = DEFAULT_PLAYING_TIME;
950
951                 streaming_handle_adaptive_buffering_mode(streamer, content_info, bitrate_info, &buffer_info, expected_play_time);
952
953                 if (IS_MUXED_BUFFERING_MODE(streamer))  // even if new byte size is smaller than the previous one, time need to be updated.
954                         buffer_handle->buffering_time = buffer_info.buffering_time;
955         }
956
957         debug_log ("new buffer size [%d -> %d bytes] / [%2.2f -> %2.2f sec] / %s \n",
958                                         GET_CURRENT_BUFFERING_BYTE(buffer_handle), buffer_info.buffering_bytes,
959                                         GET_CURRENT_BUFFERING_TIME(buffer_handle), buffer_info.buffering_time,
960                                         (IS_MUXED_BUFFERING_MODE(streamer))?"MUXED":((IS_DEMUXED_BUFFERING_MODE(streamer))?"DEMUXED":"----"));
961
962         // queue2 : bytes, multiqueue : time
963         if (((GET_CURRENT_BUFFERING_BYTE(buffer_handle) < buffer_info.buffering_bytes) && IS_MUXED_BUFFERING_MODE(streamer)) ||
964                 ((GET_CURRENT_BUFFERING_TIME(buffer_handle) < buffer_info.buffering_time) && IS_DEMUXED_BUFFERING_MODE(streamer)))
965         {
966                 if (duration > 0 && position > 0)
967                 {
968                         gdouble buffering_time_limit = (gdouble)(duration - position)/GST_SECOND;
969
970                         if (buffer_info.buffering_time > buffering_time_limit)
971                                 buffer_info.buffering_time = buffering_time_limit;
972                 }
973
974                 streaming_set_buffer_size(streamer, streamer->streaming_buffer_type, buffer_info.buffering_bytes, buffer_info.buffering_time);
975         }
976
977         streaming_set_buffer_percent(streamer, streamer->streaming_buffer_type, low_percent, buffer_info.percent_byte, buffer_info.percent_time);
978
979         debug_log("[FINAL] buffer setting : size %d, time %f, per %f\n",
980                                                         GET_CURRENT_BUFFERING_BYTE(buffer_handle),
981                                                         GET_CURRENT_BUFFERING_TIME(buffer_handle),
982                                                         buffer_handle->buffer_high_percent);
983
984         streamer->need_sync = TRUE;
985 }
986
987 static void
988 streaming_adjust_min_threshold(mm_player_streaming_t* streamer, gint64 position)
989 {
990 #define DEFAULT_TIME_PAD 1      // sec
991         gint playing_time = 0;
992
993         MMPLAYER_FENTER();
994
995         return_if_fail(streamer);
996
997         playing_time = (gint)((position - streamer->default_val.prev_pos) / GST_SECOND);
998
999         debug_log ("[GRACE_NEW] buffering monitor = %s\n", (streamer->default_val.buffering_monitor)?"ON":"OFF");
1000         debug_log ("[GRACE_NEW] playing_time ( %d sec) = %lld - %lld \n", playing_time, position, streamer->default_val.prev_pos);
1001         debug_log ("[GRACE_NEW] default time : %2.3f, prev buffering t : %2.3f\n",
1002                                         streamer->default_val.buffering_time, streamer->buffer_handle[streamer->streaming_buffer_type].buffering_time);
1003
1004         if ((streamer->default_val.buffering_monitor) && (playing_time <= (gint)streamer->default_val.buffering_time))
1005         {
1006                 gint time_gap = 0;
1007                 time_gap = (gint)(streamer->default_val.buffering_time - DEFAULT_BUFFERING_TIME);
1008                 if (time_gap <= 0)
1009                         time_gap = DEFAULT_TIME_PAD;
1010
1011                 streamer->default_val.buffering_time += time_gap*2;
1012                 streamer->default_val.buffering_time = MIN(streamer->default_val.buffering_time, MAX_BUFFERING_TIME);
1013         }
1014         else
1015         {
1016                 streamer->default_val.buffering_time = DEFAULT_BUFFERING_TIME;
1017         }
1018
1019         debug_log ("[GRACE_NEW] new default min value %2.3f \n", streamer->default_val.buffering_time);
1020
1021         streamer->default_val.buffering_monitor = FALSE;
1022         streamer->default_val.prev_pos = position;
1023 }
1024
1025 static void
1026 streaming_update_buffering_status(mm_player_streaming_t* streamer, GstMessage *buffering_msg, gint64 position)
1027 {
1028         gint buffer_percent = 0;
1029         gboolean increased_per = TRUE;
1030
1031         MMPLAYER_FENTER();
1032
1033         return_if_fail(streamer);
1034         return_if_fail(buffering_msg);
1035
1036         /* update when buffering has started. */
1037         if ( !streamer->is_buffering )
1038         {
1039                 debug_log ("buffering has started.\n");
1040                 streamer->is_buffering = TRUE;
1041                 streamer->is_buffering_done = FALSE;
1042                 streamer->buffering_percent = -1;
1043
1044                 if (!streamer->buffering_req.is_pre_buffering)
1045                 {
1046                         streamer->need_update = TRUE;
1047                         streaming_adjust_min_threshold(streamer, position);
1048                 }
1049         }
1050
1051         /* update buffer percent */
1052         gst_message_parse_buffering (buffering_msg, &buffer_percent);
1053
1054         if (streamer->buffering_percent < buffer_percent)
1055         {
1056                 debug_log ("[%s] buffering %d%%....\n", GST_OBJECT_NAME(GST_MESSAGE_SRC(buffering_msg)), buffer_percent);
1057                 streamer->buffering_percent = buffer_percent;
1058         }
1059         else
1060         {
1061                 increased_per = FALSE;
1062         }
1063
1064         if ((streamer->buffering_percent == MAX_BUFFER_PERCENT) || (streamer->is_buffering_done == TRUE))
1065         {
1066                 debug_log ("buffering had done. finished!!\n");
1067                 streamer->is_buffering = FALSE;
1068                 streamer->buffering_req.is_pre_buffering = FALSE;
1069                 if (streamer->buffering_percent == MAX_BUFFER_PERCENT)
1070                         streamer->is_buffering_done = FALSE;
1071                 else
1072                         streamer->buffering_percent = MAX_BUFFER_PERCENT;
1073         }
1074         else
1075         {
1076                 // need to update periodically in case of slink mode
1077                 if ((increased_per == TRUE) &&
1078                         (buffer_percent%10 == 0) &&
1079                         (streamer->buffering_req.mode == MM_PLAYER_BUFFERING_MODE_SLINK) &&
1080                         (streamer->buffering_req.is_pre_buffering == FALSE))
1081                 {
1082                         debug_log ("Update buffer setting to reflect data receiving rate (slink mode)\n");
1083                         streamer->need_update = TRUE;
1084                 }
1085         }
1086 }
1087
1088 void __mm_player_streaming_buffering( mm_player_streaming_t* streamer,
1089                                                                           GstMessage *buffering_msg,
1090                                                                           guint64 content_size,
1091                                                                           gint64 position,
1092                                                                           gint64 duration)
1093 {
1094         MMPLAYER_FENTER();
1095
1096         return_if_fail ( streamer );
1097         return_if_fail ( buffering_msg );
1098         return_if_fail ( GST_IS_MESSAGE ( buffering_msg ) );
1099         return_if_fail ( (GST_MESSAGE_TYPE ( buffering_msg ) == GST_MESSAGE_BUFFERING) );
1100
1101         if (buffering_msg)
1102         {
1103                 if (position > (gint64)(streamer->buffering_req.initial_second * GST_SECOND))
1104                         streamer->buffering_req.is_pre_buffering = FALSE;
1105
1106                 streaming_update_buffering_status(streamer, buffering_msg, position);
1107
1108                 if (!streamer->need_update)
1109                 {
1110                         //debug_log ("don't need to update buffering stats during buffering.\n");
1111                         return;
1112                 }
1113
1114                 streamer->need_update = FALSE;
1115         }
1116
1117         streaming_update_buffer_setting (streamer, buffering_msg, content_size, position, duration);
1118
1119         return;
1120 }
1121