From: backto.kim Date: Tue, 23 Nov 2021 02:20:53 +0000 (+0900) Subject: Blocking filesrc streaming until the connection with peer is completed X-Git-Tag: submit/tizen/20211208.120003~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d78665ff946efa3aef0fa6f6df6cd0d496717f8f;p=platform%2Fcore%2Fapi%2Fwebrtc.git Blocking filesrc streaming until the connection with peer is completed Common streaming sending is blocked while connecting with peer. but until now, filesrc has not been blocked because filesrc constructs it's own pipeline. [Version] 0.3.12 [Issue Type] Improvement Change-Id: I18c45e075b5b1db6e78822d7af2ee6a0148a8d8b --- diff --git a/include/webrtc_private.h b/include/webrtc_private.h index e2e1e4b6..0b0ff4d2 100644 --- a/include/webrtc_private.h +++ b/include/webrtc_private.h @@ -494,6 +494,10 @@ typedef struct _webrtc_gst_slot_s { GstBus *filesrc_bus; guint filesrc_bus_watcher; bool filesrc_loop; + struct { + GstPad *sink_pad; + gulong sink_pad_probe_id; + } filesrc_av[AV_IDX_MAX]; webrtc_display_s *display; } webrtc_gst_slot_s; @@ -683,6 +687,7 @@ int _check_feature(const char *feature); int _gst_filesrc_pipeline_set_state(webrtc_s *webrtc, GstState state); int _set_filesrc_looping(webrtc_s *webrtc, unsigned int source_id, bool looping); int _get_filesrc_looping(webrtc_s *webrtc, unsigned int source_id, bool *looping); +int _remove_filesrc_pad_block_probe(webrtc_s *webrtc); #ifdef __cplusplus } diff --git a/packaging/capi-media-webrtc.spec b/packaging/capi-media-webrtc.spec index 0aa12413..c3f6fd50 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.11 +Version: 0.3.12 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/webrtc_private.c b/src/webrtc_private.c index 619721f4..ec20681a 100644 --- a/src/webrtc_private.c +++ b/src/webrtc_private.c @@ -228,8 +228,10 @@ void _invoke_state_changed_cb(webrtc_s *webrtc, webrtc_state_e old, webrtc_state LOG_DEBUG("<<< end of the callback"); } - if (new == WEBRTC_STATE_PLAYING) + if (new == WEBRTC_STATE_PLAYING) { _set_stats_timer(webrtc); + _remove_filesrc_pad_block_probe(webrtc); + } GENERATE_DOT(webrtc, webrtc->gst.pipeline, "%s.state_%s", GST_ELEMENT_NAME(webrtc->gst.pipeline), __state_str[webrtc->state]); } diff --git a/src/webrtc_source.c b/src/webrtc_source.c index 16c86889..84f4d8c5 100644 --- a/src/webrtc_source.c +++ b/src/webrtc_source.c @@ -1850,20 +1850,36 @@ static void __filesrc_pipeline_video_stream_handoff_cb(GstElement *object, GstBu LOG_ERROR("failed to 'push-buffer', gst_ret[0x%x]", gst_ret); } +static GstPadProbeReturn __fakesink_block_probe_cb(GstPad *pad, GstPadProbeInfo *info, gpointer u_data) +{ + webrtc_gst_slot_s *source = u_data; + gchar *media = NULL; + + gst_structure_get(gst_caps_get_structure(gst_pad_get_current_caps(pad), 0), "media", G_TYPE_STRING, &media, NULL); + + LOG_DEBUG("source[%p, id:%u] fakesink pad[%p] for [%s] is blocked", source, source->id, pad, media); + + return GST_PAD_PROBE_OK; +} + static GstPadProbeReturn __fakesink_probe_cb(GstPad *pad, GstPadProbeInfo *info, gpointer u_data) { webrtc_gst_slot_s *source = u_data; GstCaps *new_cap = NULL; GstElement *appsrc = NULL; gchar *media = NULL; + int av_idx; gst_structure_get(gst_caps_get_structure(gst_pad_get_current_caps(pad), 0), "media", G_TYPE_STRING, &media, NULL); - if (g_strrstr(media, "audio")) - appsrc = gst_bin_get_by_name(source->bin, ELEMENT_NAME_AUDIO_APPSRC); - else - appsrc = gst_bin_get_by_name(source->bin, ELEMENT_NAME_VIDEO_APPSRC); + if (!g_strrstr(media, "audio") && !g_strrstr(media, "video")) { + LOG_ERROR("not supported media type [%s]", media); + return GST_PAD_PROBE_OK; + } + av_idx = GET_AV_IDX(g_strrstr(media, "audio")); + + appsrc = gst_bin_get_by_name(source->bin, _av_tbl[av_idx].appsrc_name); RET_VAL_IF(appsrc == NULL, GST_PAD_PROBE_OK, "There is no appsrc for [%s]", media); new_cap = gst_caps_copy(gst_pad_get_current_caps(pad)); @@ -1872,6 +1888,10 @@ static GstPadProbeReturn __fakesink_probe_cb(GstPad *pad, GstPadProbeInfo *info LOG_INFO("setting caps for [%s appsrc] successfully", media); PRINT_CAPS(new_cap, "appsrc"); + source->filesrc_av[av_idx].sink_pad = pad; + source->filesrc_av[av_idx].sink_pad_probe_id = gst_pad_add_probe(pad, GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_BLOCK, + __fakesink_block_probe_cb, source, NULL); + return GST_PAD_PROBE_REMOVE; } @@ -2062,7 +2082,7 @@ static void __filesrc_pipeline_decodebin_pad_added_cb(GstElement *element, GstPa LOG_INFO("[%s] new_pad[%s] media_type[%s]", GST_ELEMENT_NAME(element), GST_PAD_NAME(pad), media_type); if (!g_strrstr(media_type, "audio") && !g_strrstr(media_type, "video")) { - LOG_ERROR("invalid media type [%s]", media_type); + LOG_ERROR("not supported media type [%s]", media_type); return; } @@ -4554,4 +4574,33 @@ int _get_rtp_packet_drop_probability(webrtc_s *webrtc, unsigned int source_id, f return WEBRTC_ERROR_NONE; } + +static void __remove_filesrc_pad_block_foreach_cb(gpointer key, gpointer value, gpointer user_data) +{ + webrtc_gst_slot_s *source = (webrtc_gst_slot_s *)value; + int av_idx; + + if (source->type != WEBRTC_MEDIA_SOURCE_TYPE_FILE) + return; + + for (av_idx = 0; av_idx < AV_IDX_MAX; av_idx++) { + if (source->filesrc_av[av_idx].sink_pad_probe_id == 0) + continue; + + LOG_DEBUG("source[%p, id:%u] fakesink pad[%p] for [%s] is unblocked", + source, source->id, source->filesrc_av[av_idx].sink_pad, GET_MEDIA_TYPE_NAME(av_idx == AV_IDX_AUDIO)); + gst_pad_remove_probe(source->filesrc_av[av_idx].sink_pad, source->filesrc_av[av_idx].sink_pad_probe_id); + source->filesrc_av[av_idx].sink_pad = NULL; + source->filesrc_av[av_idx].sink_pad_probe_id = 0; + } +} + +int _remove_filesrc_pad_block_probe(webrtc_s *webrtc) +{ + RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL"); + + g_hash_table_foreach(webrtc->gst.source_slots, __remove_filesrc_pad_block_foreach_cb, NULL); + + return WEBRTC_ERROR_NONE; +} //LCOV_EXCL_STOP