Blocking filesrc streaming until the connection with peer is completed 38/266938/11
authorbackto.kim <backto.kim@samsung.com>
Tue, 23 Nov 2021 02:20:53 +0000 (11:20 +0900)
committerbackto.kim <backto.kim@samsung.com>
Thu, 25 Nov 2021 07:43:14 +0000 (16:43 +0900)
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

include/webrtc_private.h
packaging/capi-media-webrtc.spec
src/webrtc_private.c
src/webrtc_source.c

index e2e1e4b66d0b7ac5381b5f8c205df0a9641eb688..0b0ff4d2fc2e397fe9d84a5ddd6db7d5c666c3aa 100644 (file)
@@ -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
 }
index 0aa12413c53d6ee2915fa5a3c5ccda85bbc82c1b..c3f6fd50202436268995b715e62188e2e4309537 100644 (file)
@@ -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
index 619721f4196a643a7504b4b8c74ac257a1ac3a0b..ec20681a88bd69ac09420b9ed9e521b63fd8e19b 100644 (file)
@@ -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]);
 }
index 16c86889fe6ddb41ef8d3d005a6ee6a41dd9edb7..84f4d8c5ba26d08d0bf1e4e8e929a80efbd2245e 100644 (file)
@@ -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