From: Sangchul Lee Date: Thu, 24 Jun 2021 00:29:26 +0000 (+0900) Subject: webrtc_source: Revise assigning payload identifier X-Git-Tag: submit/tizen/20210729.023123~40 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F57%2F260357%2F1;p=platform%2Fcore%2Fapi%2Fwebrtc.git webrtc_source: Revise assigning payload identifier One media source id can have two audio/video streams. e.g.)file source Assigning payload id logic is revised to get it per each stream all over the webrtc handle. [Version] 0.2.22 [Issue Type] Improvement Change-Id: I47aa84e56f58fffc34e2d3735cad0eddc94a8439 Signed-off-by: Sangchul Lee --- diff --git a/include/webrtc_private.h b/include/webrtc_private.h index c4c56a17..9d705b8f 100644 --- a/include/webrtc_private.h +++ b/include/webrtc_private.h @@ -186,14 +186,14 @@ do { \ gst_caps_unref(x_elem_info.src_caps); \ } while (0) -#define MALLOC_AND_INIT_SLOT(x_slot, x_id, x_bin_name, x_webrtcbin) \ +#define MALLOC_AND_INIT_SLOT(x_slot, x_id, x_bin_name, x_webrtc) \ do { \ x_slot = g_new0(webrtc_gst_slot_s, 1); \ x_slot->id = x_id; \ x_slot->bin = GST_BIN(gst_bin_new(x_bin_name)); \ x_slot->av[AV_IDX_AUDIO].mline = -1; \ x_slot->av[AV_IDX_VIDEO].mline = -1; \ - x_slot->webrtcbin = x_webrtcbin; \ + x_slot->webrtc = x_webrtc; \ } while (0) #define GENERATE_DOT(x_webrtc, x_fmt, x_arg...) \ @@ -218,6 +218,7 @@ do { \ #define MEDIA_TYPE_VIDEO_JPEG "image/jpeg" #define WEBRTC_DISPLAY_TYPE_ECORE_WL 2 +#define PAYLOAD_ID_NUM 32 /* 96 ~ 127 */ #define SIGNALING_MESSAGE_PREFIX_CONNECTED "CONNECTED" #define SIGNALING_MESSAGE_PREFIX_REQUEST_SESSION "REQUEST_SESSION" @@ -372,6 +373,7 @@ typedef struct _webrtc_s { GCond desc_cond; webrtc_gst_s gst; + bool payload_ids[PAYLOAD_ID_NUM]; gchar *stun_server_url; GList *turn_server_urls; @@ -416,7 +418,7 @@ typedef struct _webrtc_s { typedef struct _webrtc_gst_slot_s { unsigned int id; GstBin *bin; - GstElement *webrtcbin; + webrtc_s *webrtc; GList *signals; webrtc_media_source_type_e type; @@ -426,6 +428,7 @@ typedef struct _webrtc_gst_slot_s { GstPad *src_pad; gulong src_pad_probe_id; bool pause; + unsigned int payload_id; } av[AV_IDX_MAX]; struct { int width; @@ -436,7 +439,6 @@ typedef struct _webrtc_gst_slot_s { GstAllocator *allocator; webrtc_callbacks_s buffer_state_changed_cb; webrtc_callbacks_s *encoded_frame_cb; - webrtc_s *webrtc; gulong probe_id; bool video_muted; diff --git a/packaging/capi-media-webrtc.spec b/packaging/capi-media-webrtc.spec index f9c9c2e1..58d13445 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.2.21 +Version: 0.2.22 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/webrtc_sink.c b/src/webrtc_sink.c index b8eb8330..2f17068a 100644 --- a/src/webrtc_sink.c +++ b/src/webrtc_sink.c @@ -451,7 +451,7 @@ int _add_rendering_sink_bin(webrtc_s *webrtc, GstPad *src_pad) bin_name = g_strdup_printf("rendering_%u", ++id); track_name = g_strdup_printf("track_%u", id); - MALLOC_AND_INIT_SLOT(sink, id, bin_name, webrtc->gst.webrtcbin); + MALLOC_AND_INIT_SLOT(sink, id, bin_name, webrtc); g_free(bin_name); @@ -777,12 +777,10 @@ int _add_forwarding_sink_bin(webrtc_s *webrtc, GstPad *src_pad, bool is_video) bin_name = g_strdup_printf("forwarding_%u", ++id); track_name = g_strdup_printf("track_%u", id); - MALLOC_AND_INIT_SLOT(sink, id, bin_name, webrtc->gst.webrtcbin); + MALLOC_AND_INIT_SLOT(sink, id, bin_name, webrtc); g_free(bin_name); - sink->webrtc = webrtc; - CREATE_ELEMENT_FROM_REGISTRY(elem_info, GST_KLASS_NAME_DEPAYLOADER_RTP, gst_pad_get_current_caps(src_pad), NULL, depayloader); if (!depayloader) goto error_before_insert; diff --git a/src/webrtc_source.c b/src/webrtc_source.c index 7de1848e..338876a3 100644 --- a/src/webrtc_source.c +++ b/src/webrtc_source.c @@ -503,7 +503,7 @@ static GstCaps *__make_encoded_caps_from_media_format(webrtc_gst_slot_s *source, return caps; } -static GstCaps *__make_rtp_caps(const gchar *media_type, unsigned int id) +static GstCaps *__make_rtp_caps(const gchar *media_type, unsigned int payload_id) { GstCaps *caps; bool is_video; @@ -514,7 +514,7 @@ static GstCaps *__make_rtp_caps(const gchar *media_type, unsigned int id) caps = gst_caps_new_simple("application/x-rtp", "media", G_TYPE_STRING, is_video ? "video" : "audio", - "payload", G_TYPE_INT, id + 95, NULL); + "payload", G_TYPE_INT, payload_id, NULL); PRINT_CAPS(caps, "RTP"); @@ -605,6 +605,31 @@ static bool __is_encoded_format_supported(webrtc_media_source_type_e type, webrt return ini_source->v_encoded_fmt_support; } +static unsigned int __get_available_payload_id(webrtc_s *webrtc) +{ + int i; + + RET_VAL_IF(webrtc == NULL, 0, "webrtc is NULL"); + + for (i = 0; i < PAYLOAD_ID_NUM; i++) { + if (!webrtc->payload_ids[i]) { + webrtc->payload_ids[i] = true; + LOG_DEBUG("found available payload id[%d]", i + 96); + return i + 96; + } + } + LOG_ERROR("could not assign payload id"); + return 0; +} + +static void __return_payload_id(webrtc_s *webrtc, unsigned int payload_id) +{ + RET_IF(webrtc == NULL, "webrtc is NULL"); + RET_IF(payload_id < 96 || payload_id > 127, "invalid payload_id(%u)", payload_id); + + webrtc->payload_ids[payload_id - 96] = false; +} + static int __create_rest_of_elements(webrtc_s *webrtc, webrtc_gst_slot_s *source, bool need_capsfilter, GList **element_list) { GstElement *capsfilter = NULL; @@ -617,16 +642,15 @@ static int __create_rest_of_elements(webrtc_s *webrtc, webrtc_gst_slot_s *source const gchar *encoder_klass_name; gchar *media_type = NULL; gchar *encoder_name = NULL; + unsigned int payload_id; RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL"); RET_VAL_IF(source == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL"); RET_VAL_IF(element_list == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "element_list is NULL"); if (need_capsfilter) { - if (!(capsfilter = _create_element(DEFAULT_ELEMENT_CAPSFILTER, ELEMENT_NAME_FIRST_CAPSFILTER))) { - LOG_ERROR("failed to create capsfilter"); + if (!(capsfilter = _create_element(DEFAULT_ELEMENT_CAPSFILTER, ELEMENT_NAME_FIRST_CAPSFILTER))) return WEBRTC_ERROR_INVALID_OPERATION; - } if (__is_encoded_format_supported(source->type, &webrtc->ini)) { if ((sink_caps = __make_default_encoded_caps(source, &webrtc->ini, NULL))) { @@ -687,17 +711,23 @@ skip_encoder: } if (!(queue = _create_element(DEFAULT_ELEMENT_QUEUE, NULL))) { - LOG_ERROR("failed to create queue"); g_free(media_type); return WEBRTC_ERROR_INVALID_OPERATION; } if (!(capsfilter2 = _create_element(DEFAULT_ELEMENT_CAPSFILTER, ELEMENT_NAME_RTP_CAPSFILTER))) { - LOG_ERROR("failed to create capsfilter"); g_free(media_type); return WEBRTC_ERROR_INVALID_OPERATION; } - if ((sink_caps = __make_rtp_caps(media_type, source->id))) { + + payload_id = __get_available_payload_id(webrtc); + if (payload_id == 0) { + g_free(media_type); + return WEBRTC_ERROR_INVALID_OPERATION; + } + source->av[source->media_types == MEDIA_TYPE_VIDEO ? AV_IDX_VIDEO : AV_IDX_AUDIO].payload_id = payload_id; + + if ((sink_caps = __make_rtp_caps(media_type, payload_id))) { g_object_set(G_OBJECT(capsfilter2), "caps", sink_caps, NULL); gst_caps_unref(sink_caps); } @@ -736,13 +766,11 @@ static int __create_rest_of_elements_for_encoded_format(webrtc_s *webrtc, webrtc } if (!(*queue = _create_element(DEFAULT_ELEMENT_QUEUE, NULL))) { - LOG_ERROR("failed to create queue"); g_free(media_type); return WEBRTC_ERROR_INVALID_OPERATION; } if (!(*capsfilter = _create_element(DEFAULT_ELEMENT_CAPSFILTER, NULL))) { - LOG_ERROR("failed to create capsfilter"); g_free(media_type); return WEBRTC_ERROR_INVALID_OPERATION; } @@ -1294,10 +1322,8 @@ static int __build_mediapacketsrc(webrtc_s *webrtc, webrtc_gst_slot_s *source) RET_VAL_IF(source == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL"); RET_VAL_IF(source->bin == NULL, WEBRTC_ERROR_INVALID_OPERATION, "bin is NULL"); - if (!(appsrc = _create_element(__get_source_element(webrtc, WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET), NULL))) { - LOG_ERROR("failed to create appsrc"); + if (!(appsrc = _create_element(__get_source_element(webrtc, WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET), NULL))) return WEBRTC_ERROR_INVALID_OPERATION; - } g_object_set(G_OBJECT(appsrc), "is-live", TRUE, "do-timestamp", TRUE, "format", GST_FORMAT_TIME, NULL); @@ -1502,11 +1528,12 @@ static gboolean __foreach_src_pad_cb(GstElement *element, GstPad *pad, gpointer GstPad *peer = gst_pad_get_peer(pad); RET_VAL_IF(source == NULL, FALSE, "source is NULL"); + RET_VAL_IF(source->webrtc == NULL, FALSE, "webrtc is NULL"); RET_VAL_IF(peer == NULL, TRUE, "peer pad is NULL"); LOG_DEBUG("about to release request pad[%s]", GST_PAD_NAME(peer)); - gst_element_release_request_pad(source->webrtcbin, peer); + gst_element_release_request_pad(source->webrtc->gst.webrtcbin, peer); /* Two unrefing here, one for getting request pad, another one for getting peer pad */ gst_object_unref(peer); @@ -1532,6 +1559,8 @@ void _source_slot_destroy_cb(gpointer data) gst_pad_remove_probe(source->av[i].src_pad, source->av[i].src_pad_probe_id); source->av[i].src_pad_probe_id = 0; } + if (source->av[i].payload_id > 0) + __return_payload_id(source->webrtc, source->av[i].payload_id); } gst_bin_remove(GST_BIN(gst_element_get_parent(source->bin)), GST_ELEMENT(source->bin)); @@ -1602,7 +1631,7 @@ int _add_media_source(webrtc_s *webrtc, webrtc_media_source_type_e type, unsigne bin_name = g_strdup_printf("media_source_%u", id); - MALLOC_AND_INIT_SLOT(source, id, bin_name, webrtc->gst.webrtcbin); + MALLOC_AND_INIT_SLOT(source, id, bin_name, webrtc); source->type = type; ret = __build_source_bin(webrtc, source);