Assign source id with a value of limited range (1-32) 99/244099/7
authorSangchul Lee <sc11.lee@samsung.com>
Tue, 15 Sep 2020 04:12:51 +0000 (13:12 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Thu, 24 Sep 2020 07:11:29 +0000 (07:11 +0000)
Unused value in ascending order is the most priority.

Payload identifier which is set for RTP caps is also
modified to assign it in range of 96-127 dynamically.

Please refer to the link below regarding the dynamic
payload types.
 : https://tools.ietf.org/html/rfc3551

[Version] 0.1.23
[Issue Type] Improvement

Change-Id: I2d028617f621fbaf91f2b76e6dc266f6f2ffa7ae
Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
packaging/capi-media-webrtc.spec
src/webrtc.c
src/webrtc_private.c

index e0a53370effaf045597c792fd9f9dc88901eb966..8cefad04e4f78009171baf01c0c208d56e648968 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-media-webrtc
 Summary:    A WebRTC library in Tizen Native API
-Version:    0.1.22
+Version:    0.1.23
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
index 3d4f54d7583883b39c40c5ef72ed59783509e7b0..8a78d5bd23aa52b717f4eb7920eecc184f02b061 100644 (file)
@@ -234,7 +234,8 @@ int webrtc_add_media_source(webrtc_h webrtc, webrtc_media_source_type_e type, un
 
        g_mutex_unlock(&_webrtc->mutex);
 
-       LOG_INFO("source_id[%d]", *source_id);
+       if (ret == WEBRTC_ERROR_NONE)
+               LOG_INFO("source_id[%d]", *source_id);
 
        return ret;
 }
@@ -250,12 +251,12 @@ int webrtc_remove_media_source(webrtc_h webrtc, unsigned int source_id)
 
        RET_VAL_WITH_UNLOCK_IF(_webrtc->state != WEBRTC_STATE_IDLE, WEBRTC_ERROR_INVALID_STATE, &_webrtc->mutex, "the state should be IDLE");
 
+       LOG_INFO("source_id[%d]", source_id);
+
        ret = _remove_media_source(webrtc, source_id);
 
        g_mutex_unlock(&_webrtc->mutex);
 
-       LOG_INFO("source_id[%d]", source_id);
-
        return ret;
 }
 
index 8e16b46313711807f808d516045a88770c775ad9..53680de588ee9bf7a1277908fb631387f32737e5 100644 (file)
@@ -886,7 +886,7 @@ static codec_type_e __get_codec_type(const gchar *media_type)
                return CODEC_TYPE_NOT_SUPPORTED;
 }
 
-static GstCaps *__make_rtp_caps(const gchar *media_type)
+static GstCaps *__make_rtp_caps(const gchar *media_type, unsigned int id)
 {
        gchar *caps_str;
        GstCaps *caps;
@@ -898,7 +898,7 @@ static GstCaps *__make_rtp_caps(const gchar *media_type)
                                "media", G_TYPE_STRING, g_strrstr(media_type, "video") ? "video" : "audio",
                                "clock-rate", G_TYPE_INT, payload_types[codec_type].clock_rate, /* FIXME: support various clock-rate */
                                "encoding-name", G_TYPE_STRING, payload_types[codec_type].encoding_name,
-                               "payload", G_TYPE_INT, 96, NULL); /* FIXME: payload identifier should be assigned dynamically */
+                               "payload", G_TYPE_INT, id + 95, NULL);
 
        caps_str = gst_caps_to_string(caps);
        LOG_DEBUG("RTP caps is created [%s]", caps_str);
@@ -933,19 +933,23 @@ static int __set_ghost_pad_target(GstPad *ghost_pad, GstElement *target_element,
        return WEBRTC_ERROR_NONE;
 }
 
-static int __create_rest_of_elements(webrtc_media_source_type_e type, GstElement **capsfilter, GstElement **encoder, GstElement **payloader, GstElement **queue, GstElement **capsfilter2)
+static int __create_rest_of_elements(webrtc_gst_slot_s *source, GstElement **capsfilter, GstElement **encoder, GstElement **payloader, GstElement **queue, GstElement **capsfilter2)
 {
        GstCaps *sink_caps;
+       webrtc_media_source_type_e type;
        element_info_s elem_info;
        const gchar *encoder_klass_name;
        gchar *media_type;
 
+       RET_VAL_IF(source == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL");
        RET_VAL_IF(capsfilter == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "capsfilter is NULL");
        RET_VAL_IF(encoder == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "encoder is NULL");
        RET_VAL_IF(payloader == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "payloader is NULL");
        RET_VAL_IF(queue == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "queue is NULL");
        RET_VAL_IF(capsfilter2 == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "capsfilter2 is NULL");
 
+       type = source->type;
+
        if (!(*capsfilter = __create_element(DEFAULT_ELEMENT_CAPSFILTER, NULL))) {
                LOG_ERROR("failed to create capsfilter");
                return WEBRTC_ERROR_INVALID_OPERATION;
@@ -981,7 +985,7 @@ static int __create_rest_of_elements(webrtc_media_source_type_e type, GstElement
                g_free(media_type);
                return WEBRTC_ERROR_INVALID_OPERATION;
        }
-       if ((sink_caps = __make_rtp_caps(media_type))) {
+       if ((sink_caps = __make_rtp_caps(media_type, source->id))) {
                g_object_set(G_OBJECT(*capsfilter2), "caps", sink_caps, NULL);
                gst_caps_unref(sink_caps);
        }
@@ -991,7 +995,7 @@ static int __create_rest_of_elements(webrtc_media_source_type_e type, GstElement
        return WEBRTC_ERROR_NONE;
 }
 
-static int __build_camerasrc(GstElement *bin, webrtc_media_source_type_e type, GstPad *ghost_src_pad)
+static int __build_camerasrc(webrtc_gst_slot_s *source, GstPad *ghost_src_pad)
 {
        int ret = WEBRTC_ERROR_NONE;
        GstElement *camerasrc;
@@ -1001,8 +1005,9 @@ static int __build_camerasrc(GstElement *bin, webrtc_media_source_type_e type, G
        GstElement *queue;
        GstElement *capsfilter2;
 
-       RET_VAL_IF(bin == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "bin is NULL");
+       RET_VAL_IF(source == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL");
        RET_VAL_IF(ghost_src_pad == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "ghost_src_pad is NULL");
+       RET_VAL_IF(source->bin == NULL, WEBRTC_ERROR_INVALID_OPERATION, "bin is NULL");
 
        /* FIXME: get factory name from ini */
        if (!(camerasrc = __create_element(DEFAULT_ELEMENT_CAMERASRC, NULL))) {
@@ -1011,10 +1016,10 @@ static int __build_camerasrc(GstElement *bin, webrtc_media_source_type_e type, G
        }
        /* FIXME: set camera default setting from ini */
 
-       if ((ret = __create_rest_of_elements(type, &capsfilter, &videoenc, &videopay, &queue, &capsfilter2)) != WEBRTC_ERROR_NONE)
+       if ((ret = __create_rest_of_elements(source, &capsfilter, &videoenc, &videopay, &queue, &capsfilter2)) != WEBRTC_ERROR_NONE)
                return ret;
 
-       gst_bin_add_many(GST_BIN(bin), camerasrc, capsfilter, videoenc, videopay, queue, capsfilter2, NULL);
+       gst_bin_add_many(GST_BIN(source->bin), camerasrc, capsfilter, videoenc, videopay, queue, capsfilter2, NULL);
        if (!gst_element_link_many(camerasrc, capsfilter, videoenc, videopay, queue, capsfilter2, NULL)) {
                LOG_ERROR("failed to gst_element_link_many()");
                return WEBRTC_ERROR_INVALID_OPERATION;
@@ -1023,7 +1028,7 @@ static int __build_camerasrc(GstElement *bin, webrtc_media_source_type_e type, G
        return __set_ghost_pad_target(ghost_src_pad, capsfilter2, TRUE);
 }
 
-static int __build_audiosrc(GstElement *bin, webrtc_media_source_type_e type, GstPad *ghost_src_pad)
+static int __build_audiosrc(webrtc_gst_slot_s *source, GstPad *ghost_src_pad)
 {
        int ret = WEBRTC_ERROR_NONE;
        GstElement *audiosrc;
@@ -1033,18 +1038,19 @@ static int __build_audiosrc(GstElement *bin, webrtc_media_source_type_e type, Gs
        GstElement *queue;
        GstElement *capsfilter2;
 
-       RET_VAL_IF(bin == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "bin is NULL");
+       RET_VAL_IF(source == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL");
        RET_VAL_IF(ghost_src_pad == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "ghost_src_pad is NULL");
+       RET_VAL_IF(source->bin == NULL, WEBRTC_ERROR_INVALID_OPERATION, "bin is NULL");
 
        if (!(audiosrc = __create_element(DEFAULT_ELEMENT_AUDIOSRC, NULL))) {
                LOG_ERROR("failed to create audiosrc");
                return WEBRTC_ERROR_INVALID_OPERATION;
        }
 
-       if ((ret = __create_rest_of_elements(type, &capsfilter, &audioenc, &audiopay, &queue, &capsfilter2)) != WEBRTC_ERROR_NONE)
+       if ((ret = __create_rest_of_elements(source, &capsfilter, &audioenc, &audiopay, &queue, &capsfilter2)) != WEBRTC_ERROR_NONE)
                return ret;
 
-       gst_bin_add_many(GST_BIN(bin), audiosrc, capsfilter, audioenc, audiopay, queue, capsfilter2, NULL);
+       gst_bin_add_many(GST_BIN(source->bin), audiosrc, capsfilter, audioenc, audiopay, queue, capsfilter2, NULL);
        if (!gst_element_link_many(audiosrc, capsfilter, audioenc, audiopay, queue, capsfilter2, NULL)) {
                LOG_ERROR("failed to gst_element_link_many()");
                return WEBRTC_ERROR_INVALID_OPERATION;
@@ -1053,7 +1059,7 @@ static int __build_audiosrc(GstElement *bin, webrtc_media_source_type_e type, Gs
        return __set_ghost_pad_target(ghost_src_pad, capsfilter2, TRUE);
 }
 
-static int __build_videotestsrc(GstElement *bin, webrtc_media_source_type_e type, GstPad *ghost_src_pad)
+static int __build_videotestsrc(webrtc_gst_slot_s *source, GstPad *ghost_src_pad)
 {
        int ret = WEBRTC_ERROR_NONE;
        GstElement *videotestsrc;
@@ -1063,8 +1069,9 @@ static int __build_videotestsrc(GstElement *bin, webrtc_media_source_type_e type
        GstElement *queue;
        GstElement *capsfilter2;
 
-       RET_VAL_IF(bin == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "bin is NULL");
+       RET_VAL_IF(source == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL");
        RET_VAL_IF(ghost_src_pad == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "ghost_src_pad is NULL");
+       RET_VAL_IF(source->bin == NULL, WEBRTC_ERROR_INVALID_OPERATION, "bin is NULL");
 
        if (!(videotestsrc = __create_element(DEFAULT_ELEMENT_VIDEOTESTSRC, NULL))) {
                LOG_ERROR("failed to create videotestsrc");
@@ -1072,10 +1079,10 @@ static int __build_videotestsrc(GstElement *bin, webrtc_media_source_type_e type
        }
        g_object_set(G_OBJECT(videotestsrc), "is-live", TRUE, NULL);
 
-       if ((ret = __create_rest_of_elements(type, &capsfilter, &videoenc, &videopay, &queue, &capsfilter2)) != WEBRTC_ERROR_NONE)
+       if ((ret = __create_rest_of_elements(source, &capsfilter, &videoenc, &videopay, &queue, &capsfilter2)) != WEBRTC_ERROR_NONE)
                return ret;
 
-       gst_bin_add_many(GST_BIN(bin), videotestsrc, capsfilter, videoenc, videopay, queue, capsfilter2, NULL);
+       gst_bin_add_many(GST_BIN(source->bin), videotestsrc, capsfilter, videoenc, videopay, queue, capsfilter2, NULL);
        if (!gst_element_link_many(videotestsrc, capsfilter, videoenc, videopay, queue, capsfilter2, NULL)) {
                LOG_ERROR("failed to gst_element_link_many()");
                return WEBRTC_ERROR_INVALID_OPERATION;
@@ -1084,7 +1091,7 @@ static int __build_videotestsrc(GstElement *bin, webrtc_media_source_type_e type
        return __set_ghost_pad_target(ghost_src_pad, capsfilter2, TRUE);
 }
 
-static int __build_audiotestsrc(GstElement *bin, webrtc_media_source_type_e type, GstPad *ghost_src_pad)
+static int __build_audiotestsrc(webrtc_gst_slot_s *source, GstPad *ghost_src_pad)
 {
        int ret = WEBRTC_ERROR_NONE;
        GstElement *audiotestsrc;
@@ -1094,8 +1101,9 @@ static int __build_audiotestsrc(GstElement *bin, webrtc_media_source_type_e type
        GstElement *queue;
        GstElement *capsfilter2;
 
-       RET_VAL_IF(bin == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "bin is NULL");
+       RET_VAL_IF(source == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL");
        RET_VAL_IF(ghost_src_pad == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "ghost_src_pad is NULL");
+       RET_VAL_IF(source->bin == NULL, WEBRTC_ERROR_INVALID_OPERATION, "bin is NULL");
 
        if (!(audiotestsrc = __create_element(DEFAULT_ELEMENT_AUDIOTESTSRC, NULL))) {
                LOG_ERROR("failed to create audiotestsrc");
@@ -1103,10 +1111,10 @@ static int __build_audiotestsrc(GstElement *bin, webrtc_media_source_type_e type
        }
        g_object_set(G_OBJECT(audiotestsrc), "is-live", TRUE, NULL);
 
-       if ((ret = __create_rest_of_elements(type, &capsfilter, &audioenc, &audiopay, &queue, &capsfilter2)) != WEBRTC_ERROR_NONE)
+       if ((ret = __create_rest_of_elements(source, &capsfilter, &audioenc, &audiopay, &queue, &capsfilter2)) != WEBRTC_ERROR_NONE)
                return ret;
 
-       gst_bin_add_many(GST_BIN(bin), audiotestsrc, capsfilter, audioenc, audiopay, queue, capsfilter2, NULL);
+       gst_bin_add_many(GST_BIN(source->bin), audiotestsrc, capsfilter, audioenc, audiopay, queue, capsfilter2, NULL);
        if (!gst_element_link_many(audiotestsrc, capsfilter, audioenc, audiopay, queue, capsfilter2, NULL)) {
                LOG_ERROR("failed to gst_element_link_many()");
                return WEBRTC_ERROR_INVALID_OPERATION;
@@ -1149,7 +1157,7 @@ static int __build_source_bin(webrtc_gst_slot_s *source)
        gchar *pad_name;
 
        RET_VAL_IF(source == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL");
-       RET_VAL_IF(source->bin == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "bin is NULL");
+       RET_VAL_IF(source->bin == NULL, WEBRTC_ERROR_INVALID_OPERATION, "bin is NULL");
 
        pad_name = g_strdup_printf("src_%u", source->id);
        if (!(src_pad =__add_no_target_ghostpad(source->bin, pad_name))) {
@@ -1161,16 +1169,16 @@ static int __build_source_bin(webrtc_gst_slot_s *source)
 
        switch (source->type) {
        case WEBRTC_MEDIA_SOURCE_TYPE_CAMERA:
-               return __build_camerasrc(source->bin, source->type, src_pad);
+               return __build_camerasrc(source, src_pad);
 
        case WEBRTC_MEDIA_SOURCE_TYPE_MIC:
-               return __build_audiosrc(source->bin, source->type, src_pad);
+               return __build_audiosrc(source, src_pad);
 
        case WEBRTC_MEDIA_SOURCE_TYPE_VIDEOTEST:
-               return __build_videotestsrc(source->bin, source->type, src_pad);
+               return __build_videotestsrc(source, src_pad);
 
        case WEBRTC_MEDIA_SOURCE_TYPE_AUDIOTEST:
-               return __build_audiotestsrc(source->bin, source->type, src_pad);
+               return __build_audiotestsrc(source, src_pad);
 
        default:
                LOG_ERROR_IF_REACHED("type(%d)", source->type);
@@ -1180,10 +1188,34 @@ static int __build_source_bin(webrtc_gst_slot_s *source)
        return WEBRTC_ERROR_NONE;
 }
 
+static unsigned int __get_unoccupied_id(GHashTable *slots)
+{
+       int i;
+       gchar *key;
+
+       RET_VAL_IF(slots == NULL, 0, "slot is NULL");
+
+       /* Payload identifiers 96–127 are used for payloads defined dynamically during a session,
+        * hence the id range is limited here to 1-32. */
+       for (i = 1; i < 33; i++) {
+               key = g_strdup_printf("media_source_%u", i);
+               if (g_hash_table_contains(slots, key)) {
+                       g_free(key);
+                       continue;
+               }
+               g_free(key);
+               return i;
+       }
+
+       LOG_ERROR("all slots are occupied(1-32)");
+
+       return 0;
+}
+
 int _add_media_source(webrtc_s *webrtc, webrtc_media_source_type_e type, unsigned int *source_id)
 {
        int ret = WEBRTC_ERROR_NONE;
-       static unsigned int id = 0;
+       unsigned int id;
        webrtc_gst_slot_s *source = NULL;
        gchar *bin_name = NULL;
        GstPad *webrtc_sinkpad;
@@ -1195,7 +1227,10 @@ int _add_media_source(webrtc_s *webrtc, webrtc_media_source_type_e type, unsigne
        RET_VAL_IF(source_id == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source_id is NULL");
 
        /* bin_name/source will be freed by function which is set to g_hash_table_new_full() */
-       bin_name = g_strdup_printf("media_source_%u", ++id);
+       id = __get_unoccupied_id(webrtc->gst.source_slots);
+       RET_VAL_IF(id == 0, WEBRTC_ERROR_INVALID_OPERATION, "source_slots are full");
+
+       bin_name = g_strdup_printf("media_source_%u", id);
        source = g_new0(webrtc_gst_slot_s, 1);
 
        source->type = type;