[0.6.292] Fix Svace issue (DEREF_OF_NULL.RET.ALLOC)
[platform/core/multimedia/libmm-player.git] / src / mm_player_gst.c
index 27498b7..8747a9b 100644 (file)
@@ -766,6 +766,11 @@ __mmplayer_gst_extract_tag_from_msg(mmplayer_t *player, GstMessage *msg)
                if (gst_tag_list_get_date(tag_list, gsttag, &date)) {\
                        if (date != NULL) {\
                                string = g_strdup_printf("%d", g_date_get_year(date));\
+                               if (string == NULL) {\
+                                       LOGD("failed to get date/time from tag");\
+                                       g_date_free(date);\
+                                       break;\
+                               } \
                                mm_player_set_attribute((MMHandleType)player, NULL,\
                                                playertag, string, strlen(string), NULL); \
                                SECURE_LOGD("metainfo year : %s", string);\
@@ -872,6 +877,23 @@ __mmplayer_gst_extract_tag_from_msg(mmplayer_t *player, GstMessage *msg)
        return TRUE;
 }
 
+
+static mmplayer_track_type_e
+__mmplayer_convert_gst_stream_type_to_track_type (GstStreamType stype)
+{
+       switch (stype) {
+       case GST_STREAM_TYPE_AUDIO:
+               return MM_PLAYER_TRACK_TYPE_AUDIO;
+       case GST_STREAM_TYPE_VIDEO:
+               return MM_PLAYER_TRACK_TYPE_VIDEO;
+       case GST_STREAM_TYPE_TEXT:
+               return MM_PLAYER_TRACK_TYPE_TEXT;
+       default:
+               LOGD("not supported stream stype");
+               return MM_PLAYER_TRACK_TYPE_MAX;
+       }
+}
+
 /* if retval is FALSE, it will be dropped for performance. */
 static gboolean
 __mmplayer_gst_check_useful_message(mmplayer_t *player, GstMessage *message)
@@ -899,10 +921,12 @@ __mmplayer_gst_check_useful_message(mmplayer_t *player, GstMessage *message)
        case GST_MESSAGE_ASYNC_DONE:
        case GST_MESSAGE_STATE_CHANGED:
                /* we only handle messages from pipeline */
+               MMPLAYER_RECONFIGURE_LOCK(player);
                if ((message->src == (GstObject *)player->pipeline->mainbin[MMPLAYER_M_PIPE].gst) && (!player->gapless.reconfigure))
                        retval = TRUE;
                else
                        retval = FALSE;
+               MMPLAYER_RECONFIGURE_UNLOCK(player);
                break;
        case GST_MESSAGE_BUFFERING:
        {
@@ -933,11 +957,6 @@ __mmplayer_gst_check_useful_message(mmplayer_t *player, GstMessage *message)
        {
                if (MMPLAYER_USE_DECODEBIN(player))
                        break; /* drop msg */
-               if (message->src == (GstObject *)player->pipeline->mainbin[MMPLAYER_M_ADAPTIVE_DEMUX].gst) {
-                       LOGD("pipeline is still under construction for adaptive streaming");
-                       retval = TRUE;
-                       break;
-               }
 
                if ((MMPLAYER_IS_HTTP_STREAMING(player)) &&
                        (!player->pipeline->mainbin[MMPLAYER_M_DEMUXED_S_BUFFER].gst) &&
@@ -960,7 +979,8 @@ __mmplayer_gst_check_useful_message(mmplayer_t *player, GstMessage *message)
                LOGD("GST_MESSAGE_STREAMS_SELECTED");
                player->no_more_pad = TRUE;
                _mmplayer_set_reconfigure_state(player, FALSE);
-               _mmplayer_pipeline_complete(NULL, player);
+               if (!MMPLAYER_IS_ADAPTIVE_STREAMING(player))
+                       _mmplayer_pipeline_complete(NULL, player);
                retval = TRUE;
                break;
        }
@@ -1556,7 +1576,6 @@ static void
 __mmplayer_gst_handle_state_message(mmplayer_t *player, GstMessage *msg)
 {
        mmplayer_gst_element_t *mainbin;
-       const GValue *voldstate, *vnewstate, *vpending;
        GstState oldstate = GST_STATE_NULL;
        GstState newstate = GST_STATE_NULL;
        GstState pending = GST_STATE_NULL;
@@ -1570,20 +1589,7 @@ __mmplayer_gst_handle_state_message(mmplayer_t *player, GstMessage *msg)
        if (msg->src != (GstObject *)mainbin[MMPLAYER_M_PIPE].gst)
                return;
 
-       /* get state info from msg */
-       voldstate = gst_structure_get_value(gst_message_get_structure(msg), "old-state");
-       vnewstate = gst_structure_get_value(gst_message_get_structure(msg), "new-state");
-       vpending = gst_structure_get_value(gst_message_get_structure(msg), "pending-state");
-
-       if (!voldstate || !vnewstate) {
-               LOGE("received msg has wrong format.");
-               return;
-       }
-
-       oldstate = (GstState)voldstate->data[0].v_int;
-       newstate = (GstState)vnewstate->data[0].v_int;
-       if (vpending)
-               pending = (GstState)vpending->data[0].v_int;
+       gst_message_parse_state_changed(msg, &oldstate, &newstate, &pending);
 
        LOGD("state changed [%s] : %s ---> %s     final : %s",
                GST_OBJECT_NAME(GST_MESSAGE_SRC(msg)),
@@ -1819,6 +1825,9 @@ __mmplayer_gst_handle_async_done_message(mmplayer_t *player, GstMessage *msg)
                return;
 
        if (player->seek_state == MMPLAYER_SEEK_IN_PROGRESS) {
+               if (player->is_external_subtitle_present)
+                       _mmplayer_sync_subtitle_pipeline(player);
+
                if (MMPLAYER_TARGET_STATE(player) == MM_PLAYER_STATE_PAUSED) {
                        player->seek_state = MMPLAYER_SEEK_NONE;
                        MMPLAYER_POST_MSG(player, MM_MESSAGE_SEEK_COMPLETED, NULL);
@@ -2076,14 +2085,28 @@ __mmplayer_gst_bus_msg_callback(GstMessage *msg, gpointer data)
 
                gst_message_parse_streams_selected(msg, &collection);
                if (collection) {
-                       guint i = 0, len = 0;
-                       len = gst_message_streams_selected_get_size(msg);
-                       for (i = 0; i < len; i++) {
+                       guint len = gst_message_streams_selected_get_size(msg);
+                       for (guint i = 0; i < len; i++) {
                                GstStream *stream = gst_message_streams_selected_get_stream(msg, i);
+                               mmplayer_track_type_e type = __mmplayer_convert_gst_stream_type_to_track_type(
+                                                       gst_stream_get_stream_type(stream));
+                               if (type == MM_PLAYER_TRACK_TYPE_MAX) {
+                                       LOGD("not supported track type");
+                                       gst_object_unref(stream);
+                                       break;
+                               }
                                LOGD ("  Stream #%d : %s\n", i, gst_stream_get_stream_id(stream));
+                               if (player->track[type].active_track_index == INVALID_TRACK_INDEX) {
+                                       int stream_index = INVALID_TRACK_INDEX;
+                                       if (_mmplayer_get_track_index(player, type, stream, &stream_index) == MM_ERROR_NONE) {
+                                               player->track[type].active_track_index = stream_index;
+                                               LOGD("selected this stream, update active idx : %d",
+                                                               player->track[type].active_track_index);
+                                       }
+                               }
                                gst_object_unref(stream);
                        }
-                       gst_object_unref (collection);
+                       gst_object_unref(collection);
                }
        } break;
 
@@ -2881,62 +2904,29 @@ __mmplayer_gst_found_source(GObject *object, GObject *orig, GParamSpec *pspec, g
        MMPLAYER_FLEAVE();
 }
 
-static gboolean
-__mmplayer_stream_equal(gconstpointer stream1, gconstpointer stream2)
-{
-       const gchar *stream1_id = gst_stream_get_stream_id((GstStream *)stream1);
-       const gchar *stream2_id = gst_stream_get_stream_id((GstStream *)stream2);
-
-       return (g_strcmp0(stream1_id, stream2_id) == 0);
-}
-
-static gboolean
-__mmplayer_has_duplicated_stream(mmplayer_t *player, GstStreamType stype, GstStream *stream)
-{
-       mmplayer_track_type_e type = MM_PLAYER_TRACK_TYPE_MAX;
-       MMPLAYER_FENTER();
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
-
-       switch (stype) {
-       case GST_STREAM_TYPE_AUDIO:
-               type = MM_PLAYER_TRACK_TYPE_AUDIO;
-               break;
-       case GST_STREAM_TYPE_VIDEO:
-               type = MM_PLAYER_TRACK_TYPE_VIDEO;
-               break;
-       case GST_STREAM_TYPE_TEXT:
-               type = MM_PLAYER_TRACK_TYPE_TEXT;
-               break;
-       default:
-               LOGD("Skip not supported stream stype");
-               return FALSE;
-       }
-
-       return g_ptr_array_find_with_equal_func(player->track[type].streams, stream, __mmplayer_stream_equal, NULL);
-}
-
 static gint
 __mmplayer_gst_select_stream (GstElement * uridecodebin, GstStreamCollection * collection,
     GstStream * stream, gpointer data)
 {
-       gint ret = 0; /* 1: select, 0: skip, -1: depends on decodebin */
+#define RET_SELECT 1
+#define RET_SKIP 0
+#define RET_DEPENDS_ON_DECODEBIN -1
+
        GstStreamType stype = gst_stream_get_stream_type(stream);
        mmplayer_t *player = (mmplayer_t *)data;
        mmplayer_track_type_e type = MM_PLAYER_TRACK_TYPE_MAX;
-       GstCaps *caps = gst_stream_get_caps(stream);
+       g_autoptr(GstCaps) caps = gst_stream_get_caps(stream);
+       g_autofree gchar *caps_str = NULL;
        GstStructure *caps_structure = NULL;
-       gchar *caps_str = NULL;
+       int stream_index = INVALID_TRACK_INDEX;
+       int ret = MM_ERROR_NONE;
 
        LOGD("Stream type %s flags 0x%x",
                        gst_stream_type_get_name(stype),
                        gst_stream_get_stream_flags(stream));
        LOGD("  ID: %s", gst_stream_get_stream_id(stream));
 
-       if (__mmplayer_has_duplicated_stream(player, stype, stream)) {
-               LOGD("Already added stream, skip it");
-               ret = 0;
-               goto EXIT;
-       }
+       type = __mmplayer_convert_gst_stream_type_to_track_type(stype);
 
        if (caps) {
                caps_str = gst_caps_to_string(caps);
@@ -2951,27 +2941,32 @@ __mmplayer_gst_select_stream (GstElement * uridecodebin, GstStreamCollection * c
                                                mime, player->ini.unsupported_codec_keyword[idx]);
 
                                _mmplayer_update_not_supported_codec_info(player, NULL, mime);
-                               ret = 0;
-                               goto EXIT;
+                               return RET_SKIP;
                        }
                }
+       } else if (type == MM_PLAYER_TRACK_TYPE_AUDIO || type == MM_PLAYER_TRACK_TYPE_VIDEO) {
+               if (MMPLAYER_IS_HTTP_LIVE_STREAMING(player) || MMPLAYER_IS_DASH_STREAMING(player)) {
+                       LOGD("No caps info, depends on decodebin");
+                       _mmplayer_track_update_stream(player, type, stream);
+                       return RET_DEPENDS_ON_DECODEBIN;
+               }
+
+               LOGD("No caps info, skip it");
+               return RET_SKIP;
        }
 
        switch (stype) {
        case GST_STREAM_TYPE_AUDIO:
        {
-               gint samplerate = 0;
-               gint channels = 0;
-
-               type = MM_PLAYER_TRACK_TYPE_AUDIO;
-
                if (caps_structure) {
+                       gint samplerate = 0;
+                       gint channels = 0;
+
                        gst_structure_get_int(caps_structure, "rate", &samplerate);
                        gst_structure_get_int(caps_structure, "channels", &channels);
-
-                       if (channels > 0 && samplerate == 0) {
+                       if (samplerate == 0 && channels > 0) {
                                LOGW("Skip corrupted audio stream");
-                               goto EXIT;
+                               return RET_SKIP;
                        }
 
                        if (g_strrstr(caps_str, "mobile-xmf"))
@@ -2982,30 +2977,28 @@ __mmplayer_gst_select_stream (GstElement * uridecodebin, GstStreamCollection * c
        }
        case GST_STREAM_TYPE_VIDEO:
        {
-               gint stype = 0;
-               gint width = 0;
-
-               type = MM_PLAYER_TRACK_TYPE_VIDEO;
-
-               /* do not support multi track video */
-               if (player->track[MM_PLAYER_TRACK_TYPE_VIDEO].total_track_num >= 1)
-                       goto EXIT;
+               if (player->track[MM_PLAYER_TRACK_TYPE_VIDEO].total_track_num >= 1) {
+                       LOGD("do not support muti track video");
+                       break;
+               }
 
                // FIXME: it cause block during preparing
                if ((!MMPLAYER_IS_HTTP_LIVE_STREAMING(player)) && (!MMPLAYER_IS_DASH_STREAMING(player))) {
-                       mm_attrs_get_int_by_name(player->attrs, "display_surface_type", &stype);
+                       gint stype = 0;
 
+                       mm_attrs_get_int_by_name(player->attrs, "display_surface_type", &stype);
                        /* don't make video because of not required */
                        if ((stype == MM_DISPLAY_SURFACE_NULL) &&
                                (!player->set_mode.video_export)) {
                                LOGD("no need video decoding, skip video stream");
-                               goto EXIT;
+                               return RET_SKIP;
                        }
                }
 
                if (caps_structure) {
-                       gst_structure_get_int(caps_structure, "width", &width);
+                       gint width = 0;
 
+                       gst_structure_get_int(caps_structure, "width", &width);
                        if (width != 0) {
                                if (player->v_stream_caps) {
                                        gst_caps_unref(player->v_stream_caps);
@@ -3019,29 +3012,32 @@ __mmplayer_gst_select_stream (GstElement * uridecodebin, GstStreamCollection * c
                break;
        }
        case GST_STREAM_TYPE_TEXT:
-               type = MM_PLAYER_TRACK_TYPE_TEXT;
                break;
        default:
                LOGW("Skip not supported stream type");
-               goto EXIT;
+               return RET_SKIP;
        }
 
        _mmplayer_track_update_stream(player, type, stream);
 
-       if (player->track[type].active_track_index == (player->track[type].total_track_num - 1)) {
-               LOGD("select this stream, active idx : %d", player->track[type].active_track_index);
+       ret = _mmplayer_get_track_index(player, type, stream, &stream_index);
+
+       if ((player->track[type].active_track_index == INVALID_TRACK_INDEX) &&
+               (ret == MM_ERROR_NONE)) {
+               player->track[type].active_track_index = stream_index;
+               LOGD("select this stream, active track idx : %d", player->track[type].active_track_index);
                if (type == MM_PLAYER_TRACK_TYPE_AUDIO)
                        _mmplayer_set_audio_attrs(player, caps);
-               ret = 1;
+               return RET_SELECT;
        }
 
-EXIT:
-       g_free(caps_str);
-       if (caps)
-               gst_caps_unref(caps);
+       if (player->track[type].active_track_index == stream_index) {
+               LOGD("already activate track idx : %d", player->track[type].active_track_index);
+               return RET_SELECT;
+       }
 
-       LOGD("ret %d", ret);
-       return ret;
+       LOGD("Skip stream");
+       return RET_SKIP;
 }
 
 static gboolean
@@ -4207,7 +4203,7 @@ _mmplayer_gst_get_buffer_position(mmplayer_t *player, int *start_pos, int *end_p
                                g_object_get(G_OBJECT(mainbin[MMPLAYER_M_DEMUXED_S_BUFFER].gst),
                                        "curr-size-bytes", &curr_size_bytes, NULL);
                                LOGD("curr_size_bytes of multiqueue = %d", curr_size_bytes);
-                               buffered_total += curr_size_bytes;
+                               buffered_total += (gint64)curr_size_bytes;
                        }
 
                        if (avg_byterate > 0)