webrtc_internal: Add API to active transceiver encoding option 74/305374/2
authorSangchul Lee <sc11.lee@samsung.com>
Wed, 17 Jan 2024 07:49:01 +0000 (16:49 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Thu, 1 Feb 2024 09:06:05 +0000 (18:06 +0900)
webrtc_media_source_active_transceiver_encoding() has been added.

This function is to activate or deactivate each rid based stream.

[Version] 0.4.41
[Issue Type] Internal API

Change-Id: I65b4edcb7b171ad7c17b97153047888039a54e9f
Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
include/webrtc_internal.h
include/webrtc_private.h
packaging/capi-media-webrtc.spec
src/webrtc_internal.c
src/webrtc_source_simulcast.c
src/webrtc_transceiver.c

index f59fe525e4844d47477fe79696c0b88327e7b6a0..2ea49a2f72eab31a15a2b360df173fccdfb5e949 100644 (file)
@@ -364,6 +364,27 @@ int webrtc_media_source_add_transceiver_encoding(webrtc_h webrtc, unsigned int s
  */
 int webrtc_media_source_remove_transceiver_encoding(webrtc_h webrtc, unsigned int source_id, webrtc_media_type_e media_type, const char *rid);
 
+/**
+ * @internal
+ * @brief Actives the transceiver encoding option of the media source.
+ * @since_tizen 9.0
+ * @remarks The default value is @c true.
+ * @param[in] webrtc      WebRTC handle
+ * @param[in] source_id   The media source id
+ * @param[in] media_type  The media type
+ * @param[in] rid         The RID (RTP Stream Identifier)
+ * @param[in] active      Active or not (@c true = active, @c false = inactive)
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #WEBRTC_ERROR_NONE    Successful
+ * @retval #WEBRTC_ERROR_INVALID_PARAMETER Invalid parameter
+ * @pre Add media source to @a webrtc to get @a source_id by calling webrtc_add_media_source().
+ * @pre webrtc_media_source_add_transceiver_encoding() must be called before calling this function.
+ * @see webrtc_media_source_add_transceiver_encoding()
+ * @see webrtc_media_source_remove_transceiver_encoding()
+ */
+int webrtc_media_source_active_transceiver_encoding(webrtc_h webrtc, unsigned int source_id, webrtc_media_type_e media_type, const char *rid, bool active);
+
 /**
  * @internal
  * @brief Sets the probability of RTP packet dropping.
index 2443470763aa1c4b5acdc8174d9971e70e83193a..83ba7b50980a047b96ce3cb5712d9f81da52e5e5 100644 (file)
@@ -667,6 +667,7 @@ typedef struct {
        int height;
        bool active;
        GstPad *src_pad;
+       gulong src_pad_probe_id;
        webrtc_gst_slot_s *source;
 } webrtc_transceiver_encoding_s;
 
@@ -747,6 +748,7 @@ int _get_transceiver_codec(webrtc_s *webrtc, unsigned int source_id, webrtc_medi
 int _foreach_supported_transceiver_codec(webrtc_s *webrtc, webrtc_media_source_type_e source_type, webrtc_media_type_e media_type, webrtc_media_source_supported_transceiver_codec_cb callback, void *user_data);
 int _add_transceiver_encoding(webrtc_s *webrtc, unsigned int source_id, webrtc_media_type_e media_type, const char *rid, int target_bitrate, int width, int height);
 int _remove_transceiver_encoding(webrtc_s *webrtc, unsigned int source_id, webrtc_media_type_e media_type, const char *rid);
+int _active_transceiver_encoding(webrtc_s *webrtc, unsigned int source_id, webrtc_media_type_e media_type, const char *rid, bool active);
 GstCaps *_make_rtp_caps_with_encoding(webrtc_gst_slot_s *source, bool is_audio);
 
 /* file source */
index d4dacc53e1f1eeb08daa422d6c5c773687c0eff6..45fcf489be160a39acb6a1da6ee352af7c67111c 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-media-webrtc
 Summary:    A WebRTC library in Tizen Native API
-Version:    0.4.40
+Version:    0.4.41
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
index 0c2158d513ef8d62b5591c571dfc36a91ee4d1ca..b3247ac60b63ddd75f441b0dc73d6f8b322359ae 100644 (file)
@@ -259,6 +259,19 @@ int webrtc_media_source_remove_transceiver_encoding(webrtc_h webrtc, unsigned in
        return _remove_transceiver_encoding(webrtc, source_id, media_type, rid);
 }
 
+int webrtc_media_source_active_transceiver_encoding(webrtc_h webrtc, unsigned int source_id, webrtc_media_type_e media_type, const char *rid, bool active)
+{
+       g_autoptr(GMutexLocker) locker = NULL;
+       webrtc_s *_webrtc = (webrtc_s *)webrtc;
+
+       RET_VAL_IF(_webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
+       RET_VAL_IF(rid == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "rid is NULL");
+
+       locker = g_mutex_locker_new(&_webrtc->mutex);
+
+       return _active_transceiver_encoding(webrtc, source_id, media_type, rid, active);
+}
+
 int webrtc_set_rtp_packet_drop_probability(webrtc_h webrtc, bool sender, float probability)
 {
        webrtc_s *_webrtc = (webrtc_s *)webrtc;
index 6591127a0fd93f7894d92d7ef5c3cf00891f990b..cf690dbba941fa45bef3c3f2a6606143973425fe 100644 (file)
@@ -108,6 +108,53 @@ exit:
        return ret;
 }
 
+static GstPadProbeReturn __encoding_stream_probe_cb(GstPad *pad, GstPadProbeInfo *info, gpointer user_data)
+{
+       webrtc_transceiver_encoding_s *encoding = (webrtc_transceiver_encoding_s *)user_data;
+       GstBuffer *buffer;
+
+       ASSERT(info);
+       ASSERT(info->data);
+       ASSERT(encoding);
+
+       buffer = gst_pad_probe_info_get_buffer(info);
+
+       if (!encoding->active) {
+               LOG_DEBUG("inactive, drop buffer[%p] of encoding[ssrc:%d, pad:%p, probe_id:%lu]",
+                       buffer, encoding->ssrc, encoding->src_pad, encoding->src_pad_probe_id);
+               return GST_PAD_PROBE_DROP;
+       }
+
+       return GST_PAD_PROBE_OK;
+}
+
+static void __add_probe_to_pad_for_active(webrtc_transceiver_encoding_s *encoding, void *probe_cb)
+{
+       ASSERT(encoding);
+       ASSERT(probe_cb);
+
+       encoding->src_pad_probe_id = gst_pad_add_probe(encoding->src_pad, GST_PAD_PROBE_TYPE_BUFFER,
+                       probe_cb, encoding, NULL);
+
+       LOG_DEBUG("encoding[ssrc:%d, pad:%p, probe_id:%lu]",
+               encoding->ssrc, encoding->src_pad, encoding->src_pad_probe_id);
+}
+
+static void __remove_probe_from_pad_for_active(webrtc_transceiver_encoding_s *encoding)
+{
+       ASSERT(encoding);
+
+       if (encoding->src_pad_probe_id == 0)
+               return;
+
+       LOG_DEBUG("encoding[ssrc:%d, pad:%p, probe_id:%lu]",
+               encoding->ssrc, encoding->src_pad, encoding->src_pad_probe_id);
+
+       gst_pad_remove_probe(encoding->src_pad, encoding->src_pad_probe_id);
+
+       encoding->src_pad_probe_id = 0;
+}
+
 static void __create_and_link_elements_foreach_cb(gpointer key, gpointer value, gpointer user_data)
 {
        webrtc_transceiver_encoding_s *encoding = (webrtc_transceiver_encoding_s *)value;
@@ -128,7 +175,7 @@ static void __create_and_link_elements_foreach_cb(gpointer key, gpointer value,
        source = userdata->source;
        av_idx = userdata->is_audio ? AV_IDX_AUDIO : AV_IDX_VIDEO;
 
-       LOG_INFO("key[%s] encoding[%p, ssrc:%d, active:%d] userdata[is_audio:%d, source;%p]",
+       LOG_INFO("rid[%s] encoding[%p, ssrc:%d, active:%d] userdata[is_audio:%d, source:%p]",
                rid, encoding, encoding->ssrc, encoding->active, userdata->is_audio, userdata->source);
 
        if (!encoding->active) {
@@ -194,6 +241,8 @@ static void __create_and_link_elements_foreach_cb(gpointer key, gpointer value,
        if (__link_encoding_bin_with_funnel(encoding, userdata->funnel) != WEBRTC_ERROR_NONE)
                goto exit_with_remove_from_bin;
 
+       __add_probe_to_pad_for_active(encoding, __encoding_stream_probe_cb);
+
        SAFE_G_LIST_FREE(element_list);
        return;
 
@@ -223,7 +272,7 @@ static void __add_rtp_header_extensions_foreach_cb(gpointer key, gpointer value,
        source = userdata->source;
        av_idx = userdata->is_audio ? AV_IDX_AUDIO : AV_IDX_VIDEO;
 
-       LOG_INFO("key[%s] encoding[%p, ssrc:%d, active:%d] userdata[is_audio:%d, source:%p]",
+       LOG_INFO("rid[%s] encoding[%p, ssrc:%d, active:%d] userdata[is_audio:%d, source:%p]",
                rid, encoding, encoding->ssrc, encoding->active, userdata->is_audio, userdata->source);
 
        if (!encoding->active) {
@@ -257,6 +306,7 @@ int _add_no_target_ghostpad_to_encoding(webrtc_transceiver_encoding_s *encoding,
 void _encoding_slot_destroy_cb(gpointer data)
 {
        webrtc_transceiver_encoding_s *encoding = (webrtc_transceiver_encoding_s *)data;
+       GstElement *parent;
 
        ASSERT(encoding);
        ASSERT(encoding->source);
@@ -264,8 +314,9 @@ void _encoding_slot_destroy_cb(gpointer data)
        LOG_DEBUG("encoding[%p, ssrc:%d, source:%s, soource_id:%u] is removed", encoding, encoding->ssrc,
                encoding->source->bin ? GST_ELEMENT_NAME(encoding->source->bin) : "null", encoding->source->id);
 
-       GstElement *parent = GST_ELEMENT(gst_element_get_parent(encoding->bin));
-       if (parent)
+       __remove_probe_from_pad_for_active(encoding);
+
+       if ((parent = GST_ELEMENT(gst_element_get_parent(encoding->bin))))
                gst_bin_remove(GST_BIN(parent), GST_ELEMENT(encoding->bin));
 
        g_free(encoding);
@@ -419,6 +470,7 @@ GstCaps *_create_simulcast_caps(webrtc_gst_slot_s *source, bool is_send, bool is
        GHashTableIter iter;
        gpointer key, value;
        int count = 0;
+       webrtc_transceiver_encoding_s *encoding;
 
        RET_VAL_IF(source == NULL, NULL, "source is NULL");
 
@@ -437,6 +489,11 @@ GstCaps *_create_simulcast_caps(webrtc_gst_slot_s *source, bool is_send, bool is
 
        g_hash_table_iter_init(&iter, source->av[av_idx].encodings);
        while (g_hash_table_iter_next(&iter, &key, &value)) {
+               encoding = (webrtc_transceiver_encoding_s *)value;
+               if (!encoding->active) {
+                       LOG_WARNING("skip this inactive encoding option");
+                       continue;
+               }
                rid_key = g_strdup_printf("rid-%s", (gchar *)key);
                gst_structure_set(s, rid_key, G_TYPE_STRING, is_send ? "send" : "recv", NULL);
                if (count++ > 0)
index 40d49c7bc8cf389e573495d28c3cad1a9d393c6a..e30db3c5cf3944a7a37362453a534e4e7424c681 100644 (file)
@@ -838,3 +838,42 @@ int _remove_transceiver_encoding(webrtc_s *webrtc, unsigned int source_id, webrt
 
        return _remove_source_encoding(source, av_idx, rid);
 }
+
+static int __active_encoding(webrtc_gst_slot_s *source, int av_idx, const char *rid, bool active)
+{
+       webrtc_transceiver_encoding_s *encoding;
+
+       ASSERT(source);
+       ASSERT(rid);
+
+       if (!g_hash_table_contains(source->av[av_idx].encodings, rid)) {
+               LOG_ERROR("rid[%s] does not exist of the source[id:%u, av_idx:%d]", rid, source->id, av_idx);
+               return WEBRTC_ERROR_INVALID_PARAMETER;
+       }
+
+       encoding = g_hash_table_lookup(source->av[av_idx].encodings, rid);
+       ASSERT(encoding);
+
+       if (encoding->active == active) {
+               LOG_INFO("it is already the active[%d]", active);
+               return WEBRTC_ERROR_NONE;
+       }
+
+       encoding->active = active;
+       LOG_INFO("source_id[%u], av_idx[%d], rid[%s], encoding[ssrc:%d, target_bitrate:%d, width:%d, height:%d, active:%d]",
+               source->id, av_idx, rid, encoding->ssrc, encoding->target_bitrate, encoding->width, encoding->height, encoding->active);
+
+       return WEBRTC_ERROR_NONE;
+}
+
+int _active_transceiver_encoding(webrtc_s *webrtc, unsigned int source_id, webrtc_media_type_e media_type, const char *rid, bool active)
+{
+       webrtc_gst_slot_s *source;
+       int av_idx = (media_type == WEBRTC_MEDIA_TYPE_AUDIO) ? AV_IDX_AUDIO : AV_IDX_VIDEO;
+
+       RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
+       RET_VAL_IF((source = _get_slot_by_id(webrtc->gst.source_slots, source_id)) == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL");
+       RET_VAL_IF(rid == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "rid is NULL");
+
+       return __active_encoding(source, av_idx, rid, active);
+}