From: Sangchul Lee Date: Tue, 15 Sep 2020 04:12:51 +0000 (+0900) Subject: Assign source id with a value of limited range (1-32) X-Git-Tag: submit/tizen/20210729.023123~219 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F99%2F244099%2F7;p=platform%2Fcore%2Fapi%2Fwebrtc.git Assign source id with a value of limited range (1-32) 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 --- diff --git a/packaging/capi-media-webrtc.spec b/packaging/capi-media-webrtc.spec index e0a53370..8cefad04 100644 --- a/packaging/capi-media-webrtc.spec +++ b/packaging/capi-media-webrtc.spec @@ -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 diff --git a/src/webrtc.c b/src/webrtc.c index 3d4f54d7..8a78d5bd 100644 --- a/src/webrtc.c +++ b/src/webrtc.c @@ -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; } diff --git a/src/webrtc_private.c b/src/webrtc_private.c index 8e16b463..53680de5 100644 --- a/src/webrtc_private.c +++ b/src/webrtc_private.c @@ -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;