Merge branch 'tizen' into tizen_5.5_devel 93/227993/1
authorEunhye Choi <eunhae1.choi@samsung.com>
Wed, 18 Mar 2020 03:32:17 +0000 (12:32 +0900)
committerEunhye Choi <eunhae1.choi@samsung.com>
Wed, 18 Mar 2020 03:32:29 +0000 (12:32 +0900)
Change-Id: Ieef3d703fd018d2d91713144eccf86e668031c47

src/include/mm_player_ini.h
src/include/mm_player_priv.h
src/include/mm_player_utils.h
src/mm_player_gst.c
src/mm_player_ini.c
src/mm_player_priv.c
src/mm_player_streaming.c
src/mm_player_utils.c

index b75744b..b2bed73 100644 (file)
@@ -88,6 +88,8 @@ typedef struct {
        gint localplayback_state_change_timeout;
        gint delay_before_repeat;
        gint eos_delay;
+       gboolean video_playback_supported;
+       gboolean use_uridecodebin3; /* experimental feature */
 
        gchar gst_param[5][PLAYER_INI_MAX_PARAM_STRLEN];
        gchar exclude_element_keyword[PLAYER_INI_MAX_ELEMENT][PLAYER_INI_MAX_STRLEN];
@@ -175,6 +177,7 @@ typedef struct {
 #define DEFAULT_SUPPORT_PCM_EXPORTING                     FALSE /* with HW audio codec */
 #define DEFAULT_SUPPORT_PITCH_CONTROL                     FALSE /* with HW audio codec */
 #define DEFAULT_SUPPORT_REPLAYGAIN_CONTROL                FALSE /* with HW audio codec */
+#define DEFAULT_USE_URIDECODEBIN3                         FALSE
 
 /* http streaming */
 #define DEFAULT_HTTPSRC                                   "souphttpsrc"
index 25c944c..7d01910 100644 (file)
@@ -165,6 +165,7 @@ typedef enum {
        /* it could be a decodebin or could be a typefind. depends on player ini */
        MMPLAYER_M_TYPEFIND,
        MMPLAYER_M_AUTOPLUG,
+       MMPLAYER_M_AUTOPLUG_PARSEBIN,
 
        MMPLAYER_M_AUTOPLUG_V_DEC,
        MMPLAYER_M_AUTOPLUG_A_DEC,
@@ -891,6 +892,12 @@ void _mmplayer_typefind_have_type(GstElement *tf, guint probability, GstCaps *ca
 int _mmplayer_parse_profile(const char *uri, void *param, mmplayer_parse_profile_t *data);
 int _mmplayer_set_client_pid(MMHandleType hplayer, int pid);
 void _mmplayer_set_reconfigure_state(mmplayer_t *player, gboolean state);
+void _mmplayer_gst_decode_pad_removed(GstElement *elem, GstPad *new_pad, gpointer data);
+void _mmplayer_gst_decode_no_more_pads(GstElement *elem, gpointer data);
+void _mmplayer_gst_decode_drained(GstElement *bin, gpointer data);
+void _mmplayer_gst_decode_unknown_type(GstElement *elem, GstPad *pad, GstCaps *caps, gpointer data);
+gboolean _mmplayer_gst_decode_autoplug_continue(GstElement *bin, GstPad *pad, GstCaps *caps, gpointer data);
+void _mmplayer_pipeline_complete(GstElement *decodebin, gpointer data);
 
 #ifdef __cplusplus
        }
index 4f12889..8c3f42f 100644 (file)
 
 #define MMPLAYER_STREAM_TYPE_GET_NAME(type) _mmplayer_get_stream_type_name(type)
 
+#define MMPLAYER_USE_URIDECODEBIN3(x_player) _mmplayer_use_uridecodebin3(x_player)
+
 /*===========================================================================================
 |                                                                                                                                                                                      |
 |  GLOBAL FUNCTION PROTOTYPES                                                                                                                          |
@@ -303,6 +305,7 @@ gboolean _mmplayer_is_smooth_streaming(mmplayer_t *player);
 gboolean _mmplayer_is_ms_buff_src(mmplayer_t *player);
 gboolean _mmplayer_has_suffix(mmplayer_t *player, const gchar *suffix);
 gboolean _mmplayer_is_videosink_ready(mmplayer_t *player, int surface_type);
+gboolean _mmplayer_use_uridecodebin3(mmplayer_t *player);
 
 gboolean _mmplayer_post_message(mmplayer_t *player, enum MMMessageType msgtype, MMMessageParamType *param);
 gboolean _mmplayer_dump_pipeline_state(mmplayer_t *player);
index d6f8567..de2a740 100644 (file)
@@ -965,6 +965,7 @@ __mmplayer_gst_check_useful_message(mmplayer_t *player, GstMessage *message)
        case GST_MESSAGE_ELEMENT:
        case GST_MESSAGE_DURATION_CHANGED:
        case GST_MESSAGE_ASYNC_START:
+       case GST_MESSAGE_STREAM_COLLECTION:
                retval = TRUE;
                break;
        case GST_MESSAGE_ASYNC_DONE:
@@ -1000,6 +1001,35 @@ __mmplayer_gst_check_useful_message(mmplayer_t *player, GstMessage *message)
 
                break;
        }
+       case GST_MESSAGE_STREAMS_SELECTED:
+       {
+               if (!MMPLAYER_USE_URIDECODEBIN3(player))
+                       break; /* drop msg */
+
+               if ((MMPLAYER_IS_HTTP_STREAMING(player)) &&
+                       (!player->pipeline->mainbin[MMPLAYER_M_DEMUXED_S_BUFFER].gst) &&
+                       (player->pipeline->mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst)) {
+
+                       gint64 dur_bytes = 0L;
+
+                       if (!gst_element_query_duration(player->pipeline->mainbin[MMPLAYER_M_SRC].gst, GST_FORMAT_BYTES, &dur_bytes))
+                               LOGE("fail to get duration.");
+
+                       /* there is no mq, enable use-buffering on queue2 (ex) wav streaming
+                        * use file information was already set on Q2 when it was created. */
+                       _mm_player_streaming_set_queue2(player->streamer,
+                                                       player->pipeline->mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst,
+                                                       TRUE,                                                           /* use_buffering */
+                                                       MUXED_BUFFER_TYPE_MAX,                          /* use previous buffer type setting */
+                                                       ((dur_bytes > 0) ? ((guint64)dur_bytes) : 0));
+               }
+
+               LOGD("GST_MESSAGE_STREAMS_SELECTED");
+               player->no_more_pad = TRUE;
+               _mmplayer_pipeline_complete(NULL, player);
+               retval = TRUE;
+               break;
+       }
        default:
                retval = FALSE;
                break;
@@ -1998,6 +2028,12 @@ __mmplayer_gst_bus_msg_callback(GstMessage *msg, gpointer data)
        case GST_MESSAGE_ASYNC_DONE:
                __mmplayer_gst_handle_async_done_message(player, msg);
                break;
+       case GST_MESSAGE_STREAM_COLLECTION:
+               LOGD("GST_MESSAGE_STREAM_COLLECTION : %s", GST_ELEMENT_NAME(GST_MESSAGE_SRC(msg)));
+               break;
+       case GST_MESSAGE_STREAMS_SELECTED:
+               LOGD("GST_MESSAGE_STREAMS_SELECTED : %s", GST_ELEMENT_NAME(GST_MESSAGE_SRC(msg)));
+               break;
 
 #ifdef __DEBUG__
        case GST_MESSAGE_REQUEST_STATE:         LOGD("GST_MESSAGE_REQUEST_STATE"); break;
@@ -2630,7 +2666,7 @@ __mmplayer_gst_rtp_no_more_pads(GstElement *element,  gpointer data)
 
                if (!_mmplayer_gst_remove_fakesink(player,
                        &player->pipeline->mainbin[MMPLAYER_M_SRC_FAKESINK]))
-                       /* NOTE : __mmplayer_pipeline_complete() can be called several time. because
+                       /* NOTE : _mmplayer_pipeline_complete() can be called several time. because
                         * signaling mechanism(pad-added, no-more-pad, new-decoded-pad) from various
                         * source element are not same. To overcome this situation, this function will called
                         * several places and several times. Therefore, this is not an error case.
@@ -2688,6 +2724,243 @@ __mmplayer_gst_make_rtsp_src(mmplayer_t *player)
        return element;
 }
 
+void __mmplayer_http_src_setup(GstElement *element, GstElement *source, gpointer data)
+{
+#define HTTP_SOURCE_BLOCK_SIZE (64 * 1024)
+
+       mmplayer_t *player = (mmplayer_t *)data;
+       MMHandleType attrs = 0;
+       gchar *user_agent, *cookies, **cookie_list;
+       gint http_timeout = DEFAULT_HTTP_TIMEOUT;
+       user_agent = cookies = NULL;
+       cookie_list = NULL;
+
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_IF_FAIL(player);
+
+       LOGD("source element %s", GST_ELEMENT_NAME(source));
+
+       /* get profile attribute */
+       attrs = MMPLAYER_GET_ATTRS(player);
+       if (!attrs) {
+               LOGE("failed to get content attribute");
+               return;
+       }
+
+       player->pipeline->mainbin[MMPLAYER_M_SRC].id = MMPLAYER_M_SRC;
+       player->pipeline->mainbin[MMPLAYER_M_SRC].gst = source;
+
+       /* get attribute */
+       mm_attrs_get_string_by_name(attrs, "streaming_cookie", &cookies);
+       mm_attrs_get_string_by_name(attrs, "streaming_user_agent", &user_agent);
+
+       if (player->ini.http_timeout != DEFAULT_HTTP_TIMEOUT)
+               http_timeout = player->ini.http_timeout;
+
+       /* get attribute */
+       SECURE_LOGD("cookies : %s", cookies);
+       SECURE_LOGD("user_agent :  %s", user_agent);
+       LOGD("timeout : %d", http_timeout);
+
+       /* setting property to streaming source */
+       g_object_set(G_OBJECT(source), "timeout", http_timeout, "blocksize", (unsigned long)(HTTP_SOURCE_BLOCK_SIZE), NULL);
+
+       /* parsing cookies */
+       if ((cookie_list = _mmplayer_get_cookie_list((const char *)cookies))) {
+               g_object_set(G_OBJECT(source), "cookies", cookie_list, NULL);
+               g_strfreev(cookie_list);
+       }
+
+       if (user_agent)
+               g_object_set(G_OBJECT(source), "user-agent", user_agent, NULL);
+
+       MMPLAYER_FLEAVE();
+       return;
+}
+
+gint __mmplayer_gst_select_stream (GstElement * uridecodebin, GstStreamCollection * collection,
+    GstStream * stream, gpointer data)
+{
+       GstStreamType stype = gst_stream_get_stream_type (stream);
+
+       if (stype & GST_STREAM_TYPE_AUDIO)
+               LOGW("AUDIO type 0x%X", stype);
+       else if (stype & GST_STREAM_TYPE_VIDEO)
+               LOGW("VIDEO type 0x%X", stype);
+       else if (stype & GST_STREAM_TYPE_TEXT)
+               LOGW("TEXT type 0x%X", stype);
+
+       return 1;
+}
+
+void
+__mmplayer_gst_deep_element_added(GstElement *bin, GstBin *child, GstElement *element, gpointer data)
+{
+       gchar *factory_name = NULL;
+       mmplayer_t *player = (mmplayer_t *)data;
+       mmplayer_gst_element_t *mainbin = NULL;
+
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && player->pipeline->mainbin);
+
+       factory_name = GST_OBJECT_NAME(gst_element_get_factory(element));
+       mainbin = player->pipeline->mainbin;
+
+       LOGD("%s > %s > %s : %s", GST_ELEMENT_NAME(bin), GST_ELEMENT_NAME(child),
+               factory_name, GST_ELEMENT_NAME(element));
+
+       /* keep the first typefind reference only */
+       if (!mainbin[MMPLAYER_M_TYPEFIND].gst && g_strrstr(factory_name, "typefind")) {
+               mainbin[MMPLAYER_M_TYPEFIND].id = MMPLAYER_M_TYPEFIND;
+               mainbin[MMPLAYER_M_TYPEFIND].gst = element;
+
+               _mmplayer_add_signal_connection(player, G_OBJECT(element),
+                       MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "have-type", G_CALLBACK(_mmplayer_typefind_have_type), (gpointer)player);
+
+       } else if (!mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst && g_strrstr(factory_name, "queue2")) {
+
+               gint64 dur_bytes = 0L;
+               muxed_buffer_type_e type = MUXED_BUFFER_TYPE_MEM_QUEUE;
+
+               mainbin[MMPLAYER_M_MUXED_S_BUFFER].id = MMPLAYER_M_MUXED_S_BUFFER;
+               mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst = element;
+
+               if (!gst_element_query_duration(mainbin[MMPLAYER_M_SRC].gst, GST_FORMAT_BYTES, &dur_bytes))
+                       LOGW("failed to get duration from source %s", GST_ELEMENT_NAME(mainbin[MMPLAYER_M_SRC].gst));
+
+               LOGD("type %s, dur_bytes = %"G_GINT64_FORMAT, player->type, dur_bytes);
+
+               /* NOTE : in case of ts streaming, player could not get the correct duration info *
+                *                skip the pull mode(file or ring buffering) setting. */
+               if (dur_bytes > 0) {
+                       if ((!g_strrstr(player->type, "video/mpegts")) && (!g_strrstr(player->type, "application/x-hls"))) {
+                               type = MUXED_BUFFER_TYPE_MEM_RING_BUFFER;
+                               player->streamer->ring_buffer_size = player->ini.http_ring_buffer_size;
+                       }
+               } else {
+                       dur_bytes = 0;
+               }
+
+               _mm_player_streaming_set_queue2(player->streamer,
+                                                                               element,
+                                                                               FALSE,
+                                                                               type,
+                                                                               (guint64)dur_bytes); /* no meaning at the moment */
+
+       } else if (g_strrstr(factory_name, "parsebin")) {
+
+               if (!mainbin[MMPLAYER_M_DEMUXED_S_BUFFER].gst) {
+                       GstIterator *iter = NULL;
+                       GValue item = {0, };
+                       GstElement *ch_element = NULL;
+                       GstElementFactory *ch_factory = NULL;
+
+                       g_object_set(G_OBJECT(child), "message-forward", TRUE, NULL);
+
+                       iter = gst_bin_iterate_recurse(child);
+                       if (iter != NULL) {
+                               while (gst_iterator_next(iter, &item) == GST_ITERATOR_OK) {
+                                       ch_element = g_value_get_object(&item);
+                                       ch_factory = gst_element_get_factory(ch_element);
+
+                                       if (g_strrstr(GST_OBJECT_NAME(ch_factory), "multiqueue")) {
+                                               player->pipeline->mainbin[MMPLAYER_M_DEMUXED_S_BUFFER].id = MMPLAYER_M_DEMUXED_S_BUFFER;
+                                               player->pipeline->mainbin[MMPLAYER_M_DEMUXED_S_BUFFER].gst = ch_element;
+
+                                               if ((MMPLAYER_IS_HTTP_STREAMING(player)) ||
+                                                       (MMPLAYER_IS_HTTP_LIVE_STREAMING(player)) ||
+                                                       (MMPLAYER_IS_DASH_STREAMING(player))) {
+                                                       _mm_player_streaming_set_multiqueue(player->streamer, ch_element);
+                                               }
+                                               g_value_reset(&item);
+                                               break;
+                                       }
+                                       g_value_reset(&item);
+                               }
+                               gst_iterator_free(iter);
+                       }
+               }
+               mainbin[MMPLAYER_M_AUTOPLUG_PARSEBIN].id = MMPLAYER_M_AUTOPLUG_PARSEBIN;
+               mainbin[MMPLAYER_M_AUTOPLUG_PARSEBIN].gst = element;
+               _mmplayer_add_signal_connection(player, G_OBJECT(element),
+                       MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "unknown-type", G_CALLBACK(_mmplayer_gst_decode_unknown_type), (gpointer)player);
+
+               _mmplayer_add_signal_connection(player, G_OBJECT(element),
+                       MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "autoplug-continue", G_CALLBACK(_mmplayer_gst_decode_autoplug_continue), (gpointer)player);
+
+               if (player->need_video_dec_sorting || player->need_audio_dec_sorting)
+                       _mmplayer_add_signal_connection(player, G_OBJECT(element),
+                       MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "autoplug-sort", G_CALLBACK(_mmplayer_gst_decode_autoplug_sort), (gpointer)player);
+
+               _mmplayer_add_signal_connection(player, G_OBJECT(element),
+                       MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "autoplug-select", G_CALLBACK(_mmplayer_gst_decode_autoplug_select), (gpointer)player);
+
+       } else {
+               _mmplayer_gst_element_added((GstElement *)child, element, data);
+       }
+       return;
+}
+
+void
+__mmplayer_gst_deep_element_removed(GstElement *bin, GstBin *child, GstElement *element, gpointer data)
+{
+       LOGD("%s > %s > %s", GST_ELEMENT_NAME(bin), GST_ELEMENT_NAME(child), GST_ELEMENT_NAME(element));
+       return;
+}
+
+static GstElement *
+__mmplayer_gst_make_uridecodebin(mmplayer_t *player)
+{
+       GstElement *uridecodebin3 = NULL;
+
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, NULL);
+
+       uridecodebin3 = gst_element_factory_make("uridecodebin3", "uridecodebin3");
+       if (!uridecodebin3) {
+               LOGE("failed to create uridecodebin3");
+               return NULL;
+       }
+
+       /* get attribute */
+       SECURE_LOGD("uri : %s", player->profile.uri);
+
+       /* setting property to streaming source */
+       g_object_set(G_OBJECT(uridecodebin3), "uri", player->profile.uri, "message-forward", TRUE, NULL);
+
+       _mmplayer_add_signal_connection(player, G_OBJECT(uridecodebin3),
+               MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "source-setup", G_CALLBACK(__mmplayer_http_src_setup), (gpointer)player);
+
+       _mmplayer_add_signal_connection(player, G_OBJECT(uridecodebin3),
+               MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-added", G_CALLBACK(_mmplayer_gst_decode_pad_added), (gpointer)player);
+
+       _mmplayer_add_signal_connection(player, G_OBJECT(uridecodebin3),
+               MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-removed", G_CALLBACK(_mmplayer_gst_decode_pad_removed), (gpointer)player);
+
+       _mmplayer_add_signal_connection(player, G_OBJECT(uridecodebin3),
+               MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "no-more-pads", G_CALLBACK(_mmplayer_gst_decode_no_more_pads), (gpointer)player);
+
+       _mmplayer_add_signal_connection(player, G_OBJECT(uridecodebin3),
+               MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "select-stream", G_CALLBACK(__mmplayer_gst_select_stream), (gpointer)player);
+
+/* FIXME: need to be added for gapless playback
+       _mmplayer_add_signal_connection(player, G_OBJECT(element),
+               MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "about-to-finish", G_CALLBACK(_mmplayer_gst_decode_drained), (gpointer)player);
+*/
+
+       _mmplayer_add_signal_connection(player, G_OBJECT(uridecodebin3),
+               MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "deep-element-added", G_CALLBACK(__mmplayer_gst_deep_element_added), (gpointer)player);
+
+       _mmplayer_add_signal_connection(player, G_OBJECT(uridecodebin3),
+               MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "deep-element-removed", G_CALLBACK(__mmplayer_gst_deep_element_removed), (gpointer)player);
+
+       if (MMPLAYER_URL_HAS_DASH_SUFFIX(player))
+               LOGW("[DASH] this is still experimental feature");
+
+       MMPLAYER_FLEAVE();
+       return uridecodebin3;
+}
+
 static GstElement *
 __mmplayer_gst_make_http_src(mmplayer_t *player)
 {
@@ -3185,9 +3458,11 @@ _mmplayer_gst_pause(mmplayer_t *player, gboolean async)
                return ret;
        }
 
-       if ((!MMPLAYER_IS_RTSP_STREAMING(player)) && (!player->video_decoded_cb) &&
-               (!player->pipeline->videobin) && (!player->pipeline->audiobin))
-               return MM_ERROR_PLAYER_CODEC_NOT_FOUND;
+       if (!MMPLAYER_USE_URIDECODEBIN3(player)) {
+               if ((!MMPLAYER_IS_RTSP_STREAMING(player)) && (!player->video_decoded_cb) &&
+                       (!player->pipeline->videobin) && (!player->pipeline->audiobin))
+                       return MM_ERROR_PLAYER_CODEC_NOT_FOUND;
+       }
 
        MMPLAYER_SET_STATE(player, MM_PLAYER_STATE_PAUSED);
 
@@ -3720,6 +3995,8 @@ _mmplayer_gst_build_pipeline(mmplayer_t *player)
        MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline &&
                                player->pipeline->mainbin, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
+       mainbin = player->pipeline->mainbin;
+
        LOGD("uri type %d", player->profile.uri_type);
 
        /* create source element */
@@ -3728,6 +4005,10 @@ _mmplayer_gst_build_pipeline(mmplayer_t *player)
                src_elem = __mmplayer_gst_make_rtsp_src(player);
                break;
        case MM_PLAYER_URI_TYPE_URL_HTTP:
+               if (player->ini.use_uridecodebin3) { /* or MMPLAYER_USE_URIDECODEBIN3(player) */
+                       LOGD("uridecodebin include src element.");
+                       goto ADD_DECODEBIN;
+               }
                src_elem = __mmplayer_gst_make_http_src(player);
                break;
        case MM_PLAYER_URI_TYPE_FILE:
@@ -3780,8 +4061,6 @@ _mmplayer_gst_build_pipeline(mmplayer_t *player)
                return MM_ERROR_PLAYER_INTERNAL;
        }
 
-       mainbin = player->pipeline->mainbin;
-
        /* take source element */
        LOGD("source elem is created %s", GST_ELEMENT_NAME(src_elem));
 
@@ -3789,17 +4068,25 @@ _mmplayer_gst_build_pipeline(mmplayer_t *player)
        mainbin[MMPLAYER_M_SRC].gst = src_elem;
        element_bucket = g_list_append(element_bucket, &mainbin[MMPLAYER_M_SRC]);
 
-       /* create next element for auto-plugging */
+ADD_DECODEBIN: /* create next element for auto-plugging */
        if (MMPLAYER_IS_HTTP_STREAMING(player)) {
-               autoplug_elem_id = MMPLAYER_M_TYPEFIND;
-               autoplug_elem = gst_element_factory_make("typefind", "typefinder");
-               if (!autoplug_elem) {
-                       LOGE("failed to create typefind element");
-                       goto ERROR;
+               if (!src_elem) { /* make uridecodebin3 which include src element */
+                       autoplug_elem_id = MMPLAYER_M_AUTOPLUG;
+                       autoplug_elem = __mmplayer_gst_make_uridecodebin(player);
+                       if (!autoplug_elem) {
+                               LOGE("failed to create uridecodebin3 element");
+                               goto ERROR;
+                       }
+               } else {
+                       autoplug_elem_id = MMPLAYER_M_TYPEFIND;
+                       autoplug_elem = gst_element_factory_make("typefind", "typefinder");
+                       if (!autoplug_elem) {
+                               LOGE("failed to create typefind element");
+                               goto ERROR;
+                       }
+                       _mmplayer_add_signal_connection(player, G_OBJECT(autoplug_elem), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "have-type",
+                                                                               G_CALLBACK(_mmplayer_typefind_have_type), (gpointer)player);
                }
-
-               _mmplayer_add_signal_connection(player, G_OBJECT(autoplug_elem), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "have-type",
-                                                                       G_CALLBACK(_mmplayer_typefind_have_type), (gpointer)player);
        } else if (!MMPLAYER_IS_RTSP_STREAMING(player)) {
                autoplug_elem_id = MMPLAYER_M_AUTOPLUG;
                autoplug_elem = _mmplayer_gst_make_decodebin(player);
index d4b2d72..fb552c0 100644 (file)
@@ -133,6 +133,7 @@ mm_player_ini_load(mmplayer_ini_t *ini)
                ini->pcm_buffer_size = iniparser_getint(dict, "general:pcm buffer size", DEFAULT_PCM_BUFFER_SIZE);
                ini->num_of_video_bo = iniparser_getint(dict, "general:video bo max", DEFAULT_NUM_OF_VIDEO_BO);
                ini->video_bo_timeout = iniparser_getint(dict, "general:video bo timeout", DEFAULT_TIMEOUT_OF_VIDEO_BO);
+               ini->use_uridecodebin3 = iniparser_getboolean(dict, "general:use uridecodebin3", DEFAULT_USE_URIDECODEBIN3);
                ini->support_audio_effect = iniparser_getboolean(dict, "general:support audio effect", DEFAULT_SUPPORT_AUDIO_EFFECT);
                ini->support_pcm_exporting = iniparser_getboolean(dict, "general:support pcm exporting", DEFAULT_SUPPORT_PCM_EXPORTING);
                ini->support_pitch_control = iniparser_getboolean(dict, "general:use pitch control", DEFAULT_SUPPORT_PITCH_CONTROL);
@@ -204,6 +205,7 @@ mm_player_ini_load(mmplayer_ini_t *ini)
                ini->pcm_buffer_size = DEFAULT_PCM_BUFFER_SIZE;
                ini->num_of_video_bo = DEFAULT_NUM_OF_VIDEO_BO;
                ini->video_bo_timeout = DEFAULT_TIMEOUT_OF_VIDEO_BO;
+               ini->use_uridecodebin3 = DEFAULT_USE_URIDECODEBIN3;
                ini->support_audio_effect = DEFAULT_SUPPORT_AUDIO_EFFECT;
                ini->support_pcm_exporting = DEFAULT_SUPPORT_PCM_EXPORTING;
                ini->support_pitch_control = DEFAULT_SUPPORT_PITCH_CONTROL;
@@ -286,6 +288,7 @@ mm_player_ini_load(mmplayer_ini_t *ini)
        LOGD("gst param3 : %s", ini->gst_param[2]);
        LOGD("gst param4 : %s", ini->gst_param[3]);
        LOGD("gst param5 : %s", ini->gst_param[4]);
+       LOGD("use uridecodebin3 : %d", ini->use_uridecodebin3);
 
        for (idx = 0; ini->exclude_element_keyword[idx][0] != '\0'; idx++)
                LOGD("exclude_element_keyword [%d] : %s", idx, ini->exclude_element_keyword[idx]);
index 403cf19..7b3d35f 100644 (file)
@@ -141,16 +141,10 @@ static int                __mmplayer_gst_create_video_sink_bin(mmplayer_t *player, GstCaps *ca
 static int             __mmplayer_gst_create_audio_sink_bin(mmplayer_t *player);
 static int             __mmplayer_gst_create_text_sink_bin(mmplayer_t *player);
 
-static void            __mmplayer_gst_decode_no_more_pads(GstElement *elem, gpointer data);
 static void            __mmplayer_gst_create_sinkbin(GstElement *decodebin, GstPad *pad, gpointer data);
-static void            __mmplayer_gst_decode_unknown_type(GstElement *elem,  GstPad *pad, GstCaps *caps, gpointer data);
-static gboolean __mmplayer_gst_decode_autoplug_continue(GstElement *bin,  GstPad *pad, GstCaps *caps,  gpointer data);
-static void __mmplayer_gst_decode_pad_removed(GstElement *elem,  GstPad *new_pad, gpointer data);
-static void __mmplayer_gst_decode_drained(GstElement *bin, gpointer data);
-static void    __mmplayer_pipeline_complete(GstElement *decodebin,  gpointer data);
 static gboolean __mmplayer_is_midi_type(gchar *str_caps);
 static gboolean __mmplayer_is_only_mp3_type(gchar *str_caps);
-static void    __mmplayer_set_audio_attrs(mmplayer_t *player, GstCaps *caps);
+static void            __mmplayer_set_audio_attrs(mmplayer_t *player, GstCaps *caps);
 
 static gboolean        __mmplayer_update_subtitle(GstElement *object, GstBuffer *buffer, GstPad *pad, gpointer data);
 static void            __mmplayer_release_misc(mmplayer_t *player);
@@ -1218,7 +1212,7 @@ _mmplayer_gst_decode_pad_added(GstElement *elem, GstPad *pad, gpointer data)
 
                LOGD("surface type : %d", stype);
 
-               if (MMPLAYER_IS_MS_BUFF_SRC(player)) {
+               if (MMPLAYER_IS_MS_BUFF_SRC(player) || MMPLAYER_USE_URIDECODEBIN3(player)) {
                        __mmplayer_gst_create_sinkbin(elem, pad, player);
                        goto DONE;
                }
@@ -1237,7 +1231,7 @@ _mmplayer_gst_decode_pad_added(GstElement *elem, GstPad *pad, gpointer data)
                gint samplerate = 0;
                gint channels = 0;
 
-               if (MMPLAYER_IS_MS_BUFF_SRC(player) || player->build_audio_offload) {
+               if (MMPLAYER_IS_MS_BUFF_SRC(player) || MMPLAYER_USE_URIDECODEBIN3(player) || player->build_audio_offload) {
                        if (player->build_audio_offload)
                                player->no_more_pad = TRUE; /* remove state holder */
                        __mmplayer_gst_create_sinkbin(elem, pad, player);
@@ -1396,7 +1390,7 @@ __mmplayer_create_audio_sink_path(mmplayer_t *player, GstElement *audio_selector
                }
 
                if (player->num_dynamic_pad == 0) /* FIXME: num_dynamic_pad is only for rtsp? */
-                       __mmplayer_pipeline_complete(NULL, player);
+                       _mmplayer_pipeline_complete(NULL, player);
 
                return TRUE;
        }
@@ -1467,8 +1461,8 @@ __mmplayer_gst_set_queue2_buffering(mmplayer_t *player)
        return TRUE;
 }
 
-static void
-__mmplayer_gst_decode_no_more_pads(GstElement *elem, gpointer data)
+void
+_mmplayer_gst_decode_no_more_pads(GstElement *elem, gpointer data)
 {
        mmplayer_t *player = NULL;
        GstElement *video_selector = NULL;
@@ -1712,7 +1706,7 @@ __mmplayer_gst_create_sinkbin(GstElement *elem, GstPad *pad, gpointer data)
        LOGD("no more pads: %d, stream count dec : %d(num of dynamic pad)", player->no_more_pad, player->num_dynamic_pad);
 
        if ((player->no_more_pad) && (player->num_dynamic_pad == 0))
-               __mmplayer_pipeline_complete(NULL, player);
+               _mmplayer_pipeline_complete(NULL, player);
 
 ERROR:
 
@@ -2492,7 +2486,7 @@ __mmplayer_gst_audio_deinterleave_no_more_pads(GstElement* object, gpointer data
        MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && player->pipeline->mainbin);
 
        player->no_more_pad = TRUE;
-       __mmplayer_pipeline_complete(NULL, player);
+       _mmplayer_pipeline_complete(NULL, player);
 
        MMPLAYER_FLEAVE();
        return;
@@ -5938,21 +5932,20 @@ _mmplayer_typefind_have_type(GstElement *tf, guint probability,
                return;
        }
 
-       if (!_mmplayer_gst_create_decoder(player, pad, caps)) {
-               gboolean async = FALSE;
-               LOGE("failed to autoplug %s", player->type);
+       if (!player->pipeline->mainbin[MMPLAYER_M_AUTOPLUG].gst) {
+               if (!_mmplayer_gst_create_decoder(player, pad, caps)) {
+                       gboolean async = FALSE;
+                       LOGE("failed to autoplug %s", player->type);
 
-               mm_attrs_get_int_by_name(player->attrs, "profile_prepare_async", &async);
-
-               if (async && player->msg_posted == FALSE)
-                       __mmplayer_handle_missed_plugin(player);
+                       mm_attrs_get_int_by_name(player->attrs, "profile_prepare_async", &async);
 
+                       if (async && player->msg_posted == FALSE)
+                               __mmplayer_handle_missed_plugin(player);
+               }
        }
 
        gst_object_unref(GST_OBJECT(pad));
-
        MMPLAYER_FLEAVE();
-
        return;
 }
 
@@ -5977,20 +5970,20 @@ _mmplayer_gst_make_decodebin(mmplayer_t *player)
 
        /* no-more-pad pad handling signal */
        _mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "no-more-pads",
-                                               G_CALLBACK(__mmplayer_gst_decode_no_more_pads), (gpointer)player);
+                                               G_CALLBACK(_mmplayer_gst_decode_no_more_pads), (gpointer)player);
 
        _mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-removed",
-                                               G_CALLBACK(__mmplayer_gst_decode_pad_removed), (gpointer)player);
+                                               G_CALLBACK(_mmplayer_gst_decode_pad_removed), (gpointer)player);
 
        /* This signal is emitted when a pad for which there is no further possible
           decoding is added to the decodebin.*/
        _mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "unknown-type",
-                                               G_CALLBACK(__mmplayer_gst_decode_unknown_type), (gpointer)player);
+                                               G_CALLBACK(_mmplayer_gst_decode_unknown_type), (gpointer)player);
 
        /* This signal is emitted whenever decodebin finds a new stream. It is emitted
           before looking for any elements that can handle that stream.*/
        _mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "autoplug-continue",
-                                               G_CALLBACK(__mmplayer_gst_decode_autoplug_continue), (gpointer)player);
+                                               G_CALLBACK(_mmplayer_gst_decode_autoplug_continue), (gpointer)player);
 
        if (player->need_video_dec_sorting || player->need_audio_dec_sorting)
                _mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "autoplug-sort",
@@ -6003,7 +5996,7 @@ _mmplayer_gst_make_decodebin(mmplayer_t *player)
 
        /* This signal is emitted once decodebin has finished decoding all the data.*/
        _mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "drained",
-                                               G_CALLBACK(__mmplayer_gst_decode_drained), (gpointer)player);
+                                               G_CALLBACK(_mmplayer_gst_decode_drained), (gpointer)player);
 
        /* This signal is emitted when a element is added to the bin.*/
        _mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "element-added",
@@ -6271,8 +6264,8 @@ DONE:
        return MM_ERROR_NONE;
 }
 
-static void
-__mmplayer_pipeline_complete(GstElement *decodebin,  gpointer data)
+void
+_mmplayer_pipeline_complete(GstElement *decodebin, gpointer data)
 {
        mmplayer_t *player = (mmplayer_t *)data;
 
@@ -6283,7 +6276,7 @@ __mmplayer_pipeline_complete(GstElement *decodebin,  gpointer data)
        /* remove fakesink. */
        if (!_mmplayer_gst_remove_fakesink(player,
                                &player->pipeline->mainbin[MMPLAYER_M_SRC_FAKESINK])) {
-               /* NOTE : __mmplayer_pipeline_complete() can be called several time. because
+               /* NOTE : _mmplayer_pipeline_complete() can be called several time. because
                 * signaling mechanism(pad-added, no-more-pad, new-decoded-pad) from various
                 * source element are not same. To overcome this situation, this function will called
                 * several places and several times. Therefore, this is not an error case.
@@ -6699,8 +6692,8 @@ _mmplayer_get_next_uri(MMHandleType hplayer, char **uri)
        return MM_ERROR_NONE;
 }
 
-static void
-__mmplayer_gst_decode_unknown_type(GstElement *elem,  GstPad *pad,
+void
+_mmplayer_gst_decode_unknown_type(GstElement *elem, GstPad *pad,
        GstCaps *caps, gpointer data)
 {
        mmplayer_t *player = (mmplayer_t *)data;
@@ -6721,9 +6714,9 @@ __mmplayer_gst_decode_unknown_type(GstElement *elem,  GstPad *pad,
        __mmplayer_check_not_supported_codec(player, klass, mime);
 }
 
-static gboolean
-__mmplayer_gst_decode_autoplug_continue(GstElement *bin,  GstPad *pad,
-       GstCaps *caps,  gpointer data)
+gboolean
+_mmplayer_gst_decode_autoplug_continue(GstElement *bin, GstPad *pad,
+       GstCaps *caps, gpointer data)
 {
        mmplayer_t *player = (mmplayer_t *)data;
        const char *mime = NULL;
@@ -7312,8 +7305,8 @@ DONE:
        return result;
 }
 
-static void
-__mmplayer_gst_decode_pad_removed(GstElement *elem,  GstPad *new_pad,
+void
+_mmplayer_gst_decode_pad_removed(GstElement *elem, GstPad *new_pad,
        gpointer data)
 {
        //mmplayer_t *player = (mmplayer_t *)data;
@@ -7336,8 +7329,8 @@ __mmplayer_gst_decode_pad_removed(GstElement *elem,  GstPad *new_pad,
        gst_caps_unref(caps);
 }
 
-static void
-__mmplayer_gst_decode_drained(GstElement *bin, gpointer data)
+void
+_mmplayer_gst_decode_drained(GstElement *bin, gpointer data)
 {
        mmplayer_t *player = (mmplayer_t *)data;
        GstIterator *iter = NULL;
@@ -7349,7 +7342,7 @@ __mmplayer_gst_decode_drained(GstElement *bin, gpointer data)
        MMPLAYER_FENTER();
        MMPLAYER_RETURN_IF_FAIL(player);
 
-       LOGD("__mmplayer_gst_decode_drained");
+       LOGD("got drained signal");
 
        if (!MMPLAYER_CMD_TRYLOCK(player)) {
                LOGW("Fail to get cmd lock");
index 04e89cc..07169a1 100644 (file)
@@ -320,7 +320,8 @@ static void __streaming_set_buffer_size(mmplayer_streaming_t *streamer,
                        g_object_set(G_OBJECT(buffer_handle->buffer),
                                                        "max-size-bytes", MAX_BUFFER_SIZE_BYTES,        /* mq size is fixed, control it with high/low watermark value*/
                                                        "max-size-time", (guint64)(buffering_time * GST_MSECOND),
-                                                       "max-size-buffers", 0, NULL);                           /* disable */
+                                                       "max-size-buffers", 0,                      /* disable */
+                                                       "use-interleave", FALSE, NULL);
 
                        GET_CURRENT_BUFFERING_TIME(buffer_handle) = buffering_time;
                        GET_CURRENT_BUFFERING_BYTE(buffer_handle) = MAX_BUFFER_SIZE_BYTES;
index 7665565..493e9db 100644 (file)
@@ -645,3 +645,18 @@ media_format_mimetype_e _mmplayer_convert_audio_pcm_str_to_media_format_mime(con
                return MEDIA_FORMAT_MAX;
        }
 }
+
+gboolean _mmplayer_use_uridecodebin3(mmplayer_t *player) /* MMPLAYER_USE_URIDECODEBIN3(player) */
+{
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
+
+       if (!player->ini.use_uridecodebin3)
+               return FALSE;
+
+       if (MMPLAYER_IS_HTTP_STREAMING(player) ||
+               MMPLAYER_IS_HTTP_LIVE_STREAMING(player) ||
+               MMPLAYER_IS_DASH_STREAMING(player))
+               return TRUE;
+
+       return FALSE;
+}