From: Sangchul Lee Date: Tue, 14 Dec 2021 06:42:48 +0000 (+0900) Subject: webrtc_sink: Enable in-band FEC of OPUS decoder X-Git-Tag: submit/tizen/20211229.072812~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0c7d98a98bca829fd45890c7621aef0a3c892003;p=platform%2Fcore%2Fapi%2Fwebrtc.git webrtc_sink: Enable in-band FEC of OPUS decoder [Version] 0.3.33 [Issue Type] New feature Change-Id: I48d271615a1f742e15c2ba2d10e4de023d4430cc Signed-off-by: Sangchul Lee --- diff --git a/include/webrtc_private.h b/include/webrtc_private.h index d5a960c6..b408a5fe 100644 --- a/include/webrtc_private.h +++ b/include/webrtc_private.h @@ -212,6 +212,7 @@ do { \ g_free(dot_name); \ } while (0) +#define GET_AV_IDX(x_is_audio) (x_is_audio) ? AV_IDX_AUDIO : AV_IDX_VIDEO #define GET_MEDIA_TYPE_NAME(x_is_audio) (x_is_audio) ? "audio" : "video" #define DEFAULT_ELEMENT_FAKESINK "fakesink" @@ -623,7 +624,7 @@ GstElement *_create_element_from_registry(element_info_s *elem_info); webrtc_gst_slot_s* _get_slot_by_id(GHashTable *slots, unsigned int id); int _add_no_target_ghostpad_to_slot(webrtc_gst_slot_s *slot, bool is_src, GstPad **new_pad); int _set_ghost_pad_target(GstPad *ghost_pad, GstElement *target_element, bool is_src); -int _add_rendering_sink_bin(webrtc_s *webrtc, GstPad *src_pad); +int _add_rendering_sink_bin(webrtc_s *webrtc, GstPad *src_pad, bool is_audio); int _add_forwarding_sink_bin(webrtc_s *webrtc, GstPad *src_pad, bool is_audio); int _set_stream_info_to_sink(webrtc_s *webrtc, unsigned int track_id, sound_stream_info_h stream_info); int _set_display_to_sink(webrtc_s *webrtc, unsigned int track_id, unsigned int type, void *display); @@ -707,6 +708,7 @@ int _remove_filesrc_pad_block_probe(webrtc_s *webrtc); gchar * _get_media_type_from_pad(GstPad *pad); gchar * _get_mime_type_from_pad(GstPad *pad); +int _get_payload_id_from_pad(GstPad *pad); bool _is_supported_media_type(const char *media_type); bool _is_audio_media_type(const char *media_type); diff --git a/packaging/capi-media-webrtc.spec b/packaging/capi-media-webrtc.spec index 05943ab4..db6a6313 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.3.32 +Version: 0.3.33 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/webrtc_private.c b/src/webrtc_private.c index d18f38d8..c49e9745 100644 --- a/src/webrtc_private.c +++ b/src/webrtc_private.c @@ -1271,6 +1271,25 @@ gchar * _get_mime_type_from_pad(GstPad *pad) return mime_type; } +int _get_payload_id_from_pad(GstPad *pad) +{ + GstCaps *caps = NULL; + gint id = -1; + + RET_VAL_IF(pad == NULL, -1, "pad is NULL"); + + caps = gst_pad_get_current_caps(pad); + RET_VAL_IF(caps == NULL, -1, "caps is NULL"); + + if (!gst_structure_get_int(gst_caps_get_structure(caps, 0), "payload", &id)) + LOG_ERROR("failed to gst_structure_get_int()"); + else + LOG_DEBUG("payload id[%d]", id); + + gst_caps_unref(caps); + + return id; +} //LCOV_EXCL_STOP bool _is_supported_media_type(const char *media_type) @@ -1324,7 +1343,7 @@ static void __webrtcbin_pad_added_cb(GstElement *webrtcbin, GstPad *new_pad, gpo ret = _add_forwarding_sink_bin(webrtc, new_pad, is_audio); RET_IF(ret != WEBRTC_ERROR_NONE, "failed to _add_forwarding_sink_bin()"); } else { - ret = _add_rendering_sink_bin(webrtc, new_pad); + ret = _add_rendering_sink_bin(webrtc, new_pad, is_audio); RET_IF(ret != WEBRTC_ERROR_NONE, "failed to _add_rendering_sink_bin()"); } diff --git a/src/webrtc_sink.c b/src/webrtc_sink.c index cacd7f96..ab131a61 100644 --- a/src/webrtc_sink.c +++ b/src/webrtc_sink.c @@ -342,18 +342,38 @@ static void __invoke_track_added_cb(webrtc_s *webrtc, const gchar *name, bool is static void __decodebin_element_added_cb(GstElement *decodebin, GstElement *element, gpointer user_data) { + webrtc_gst_slot_s *sink = (webrtc_gst_slot_s *)user_data; gchar *factory_name = NULL; RET_IF(decodebin == NULL, "decodebin is NULL"); RET_IF(element == NULL, "element is NULL"); + RET_IF(sink == NULL, "sink is NULL"); factory_name = GST_OBJECT_NAME(gst_element_get_factory(element)); LOG_INFO("element[name: %s] was added to decodebin", GST_ELEMENT_NAME(element)); if (g_strrstr(factory_name, "rtpvp8depay")) { - LOG_INFO("set wait-for-keyframe to rtpvp8depay"); + LOG_INFO("set wait-for-keyframe to %s", factory_name); g_object_set(G_OBJECT(element), "wait-for-keyframe", TRUE, NULL); + + } else if (g_strrstr(factory_name, "opusdec")) { + int i; + for (i = 0; i < MAX_MLINE_NUM; i ++) { /* FIXME: we don't know mline in this situation, so retrieve the array here. */ + if (!sink->webrtc->data_recovery_types[i].inbandfec.use) + continue; + if (sink->webrtc->data_recovery_types[i].inbandfec.pt != (int)sink->av[AV_IDX_AUDIO].payload_id) + continue; + if (!g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(element)), "use-inband-fec")) { + LOG_WARNING("could not find 'use-inband-fec' property"); + break; + } + LOG_INFO("set plc and use-inband-fec to %s", factory_name); + g_object_set(G_OBJECT(element), + "plc", TRUE, + "use-inband-fec", TRUE, + NULL); + } } } @@ -431,7 +451,7 @@ int _decodebin_autoplug_select_cb(GstElement *decodebin, GstPad *pad, GstCaps *c factory_name = GST_OBJECT_NAME(factory); klass = gst_element_factory_get_metadata(factory, GST_ELEMENT_METADATA_KLASS); - LOG_INFO("decodebin[%p] factory[name:%s, klass:%s]", decodebin, factory_name, klass); + LOG_DEBUG("decodebin[%p] factory[name:%s, klass:%s]", decodebin, factory_name, klass); str_arr = webrtc->ini.general.gst_excluded_elements; while (str_arr && *str_arr) { @@ -504,7 +524,7 @@ void _sink_slot_destroy_cb(gpointer data) g_free(sink); } -int _add_rendering_sink_bin(webrtc_s *webrtc, GstPad *src_pad) +int _add_rendering_sink_bin(webrtc_s *webrtc, GstPad *src_pad, bool is_audio) { int ret = WEBRTC_ERROR_NONE; unsigned int id; @@ -530,11 +550,13 @@ int _add_rendering_sink_bin(webrtc_s *webrtc, GstPad *src_pad) if (!decodebin) goto error_before_insert; + sink->av[GET_AV_IDX(is_audio)].payload_id = _get_payload_id_from_pad(src_pad); + gst_bin_add(sink->bin, decodebin); g_signal_connect(decodebin, "pad-added", G_CALLBACK(__decodebin_pad_added_cb), webrtc); g_signal_connect(decodebin, "autoplug-select", G_CALLBACK(_decodebin_autoplug_select_cb), webrtc); - g_signal_connect(decodebin, "element-added", G_CALLBACK(__decodebin_element_added_cb), NULL); + g_signal_connect(decodebin, "element-added", G_CALLBACK(__decodebin_element_added_cb), sink); ret = _add_no_target_ghostpad_to_slot(sink, false, &sink_pad); if (ret != WEBRTC_ERROR_NONE) diff --git a/src/webrtc_source.c b/src/webrtc_source.c index 334cd1de..927c2735 100644 --- a/src/webrtc_source.c +++ b/src/webrtc_source.c @@ -77,7 +77,6 @@ do { \ LOG_DEBUG("%s is prepended", GST_ELEMENT_NAME(x_element)); \ } while (0) -#define GET_AV_IDX(x_is_audio) (x_is_audio) ? AV_IDX_AUDIO : AV_IDX_VIDEO #define GET_AV_IDX_BY_TYPE(x_media_type) GET_AV_IDX(x_media_type == MEDIA_TYPE_AUDIO) typedef struct {