webrtc_transceiver: Apply simulcast info to null source type 73/305373/1
authorSangchul Lee <sc11.lee@samsung.com>
Wed, 10 Jan 2024 05:40:12 +0000 (14:40 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Thu, 1 Feb 2024 03:17:14 +0000 (12:17 +0900)
In case of answerer, null source type(recvonly) is used to select
codec information for receiving suggested streams from offer description.
If the offer description suggests RID based simulcast, this patch enables
to choose some of RIDs in the answer description to receive them.

[Version] 0.4.40
[Issue Type] New feature

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

index bbe7611f9c34d6f8e99f93ecc44d513fc17fbef9..f59fe525e4844d47477fe79696c0b88327e7b6a0 100644 (file)
@@ -325,8 +325,10 @@ int webrtc_media_source_get_payload_type(webrtc_h webrtc, unsigned int source_id
  * @internal
  * @brief Adds the transceiver encoding option to the media source.
  * @since_tizen 9.0
- * @remarks If @a source_id should be a media source of #WEBRTC_MEDIA_SOURCE_TYPE_AUDIOTEST or #WEBRTC_MEDIA_SOURCE_TYPE_MIC or #WEBRTC_MEDIA_SOURCE_TYPE_VIDEOTEST,
+ * @remarks If @a source_id should be a media source of #WEBRTC_MEDIA_SOURCE_TYPE_AUDIOTEST or #WEBRTC_MEDIA_SOURCE_TYPE_MIC or #WEBRTC_MEDIA_SOURCE_TYPE_VIDEOTEST or #WEBRTC_MEDIA_SOURCE_TYPE_NULL,
  *          otherwise this function will return #WEBRTC_ERROR_INVALID_PARAMETER.\n
+ *          If @a source_id is a media source of #WEBRTC_MEDIA_SOURCE_TYPE_NULL, @a target_bitrate, @a width, and @a height will be ignored.\n
+ *          If @a source_id is a media source of #WEBRTC_MEDIA_SOURCE_TYPE_NULL, webrtc_media_source_set_transceiver_codec() must be called before calling this function.\n
  *          If @a media_type is for #WEBRTC_MEDIA_TYPE_AUDIO, @a width and @a height will be ignored.
  * @param[in] webrtc      WebRTC handle
  * @param[in] source_id   The media source id
index 4eb04cecab9272e092b9e33752844ef2c1297645..d4dacc53e1f1eeb08daa422d6c5c773687c0eff6 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-media-webrtc
 Summary:    A WebRTC library in Tizen Native API
-Version:    0.4.39
+Version:    0.4.40
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
index 2b9ac9f58b6ef86bcb61c71c3efd8a2ff381458b..40d49c7bc8cf389e573495d28c3cad1a9d393c6a 100644 (file)
@@ -409,6 +409,37 @@ int _set_manual_payload_type(webrtc_s *webrtc, unsigned int payload_type)
        return 0;
 }
 
+static int __add_transceiver_for_simulcast(webrtc_gst_slot_s *source, webrtc_media_type_e media_type)
+{
+       GstWebRTCRTPTransceiver *trans;
+       g_autoptr(GstCaps) caps = NULL;
+       int av_idx = (media_type == WEBRTC_MEDIA_TYPE_AUDIO) ? AV_IDX_AUDIO : AV_IDX_VIDEO;
+       rtp_payload_info_s *payload_info;
+
+       RET_VAL_IF(source == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL");
+
+       if (!source->av[av_idx].transceiver) {
+               if (source->av[av_idx].pt >= MIN_DYNAMIC_PAYLOAD_TYPE && !source->av[av_idx].pt_set_by_api)
+                       _return_payload_type(source->webrtc, source->av[av_idx].pt);
+               payload_info = __get_payload_info_by_encoding_name(source->av[av_idx].codec);
+               ASSERT(payload_info);
+               if ((_set_payload_type(source->webrtc, source, av_idx, payload_info->gst_media_type)) != WEBRTC_ERROR_NONE)
+                       return WEBRTC_ERROR_INVALID_OPERATION;
+
+               g_signal_emit_by_name(source->webrtc->gst.webrtcbin, "add-transceiver",
+                       GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_RECVONLY, NULL, &trans, NULL);
+               caps = _create_simulcast_caps(source, false, media_type == WEBRTC_MEDIA_TYPE_AUDIO);
+               PRINT_CAPS(caps, "transceiver");
+               g_object_set(G_OBJECT(trans), "codec-preferences", caps, NULL);
+               gst_object_unref(trans);
+       }
+
+       LOG_DEBUG("webrtc[%p] source_id[%u] transceiver[%p]",
+               source->webrtc, source->id, source->av[av_idx].transceiver );
+
+       return WEBRTC_ERROR_NONE;
+}
+
 void _check_and_add_recvonly_transceiver(webrtc_gst_slot_s *source)
 {
        rtp_payload_info_s *payload_info = NULL;
@@ -416,12 +447,16 @@ void _check_and_add_recvonly_transceiver(webrtc_gst_slot_s *source)
        RET_IF(source == NULL, "source is NULL");
 
        if (source->av[AV_IDX_AUDIO].direction == WEBRTC_TRANSCEIVER_DIRECTION_RECVONLY && source->av[AV_IDX_AUDIO].codec) {
-               if ((payload_info = __get_payload_info_by_encoding_name(source->av[AV_IDX_AUDIO].codec)))
+               if (g_hash_table_size(source->av[AV_IDX_AUDIO].encodings) > 0)
+                       __add_transceiver_for_simulcast(source, WEBRTC_MEDIA_TYPE_AUDIO);
+               else if ((payload_info = __get_payload_info_by_encoding_name(source->av[AV_IDX_AUDIO].codec)))
                        _add_transceiver(source, WEBRTC_MEDIA_TYPE_AUDIO, payload_info);
        }
 
        if (source->av[AV_IDX_VIDEO].direction == WEBRTC_TRANSCEIVER_DIRECTION_RECVONLY && source->av[AV_IDX_VIDEO].codec) {
-               if ((payload_info = __get_payload_info_by_encoding_name(source->av[AV_IDX_VIDEO].codec)))
+               if (g_hash_table_size(source->av[AV_IDX_VIDEO].encodings) > 0)
+                       __add_transceiver_for_simulcast(source, WEBRTC_MEDIA_TYPE_VIDEO);
+               else if ((payload_info = __get_payload_info_by_encoding_name(source->av[AV_IDX_VIDEO].codec)))
                        _add_transceiver(source, WEBRTC_MEDIA_TYPE_VIDEO, payload_info);
        }
 }
@@ -748,8 +783,9 @@ int _add_transceiver_encoding(webrtc_s *webrtc, unsigned int source_id, webrtc_m
 
        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((source->type > WEBRTC_MEDIA_SOURCE_TYPE_MIC), WEBRTC_ERROR_INVALID_PARAMETER, "not supported media source type[%d]", source->type);
+       RET_VAL_IF((source->type > WEBRTC_MEDIA_SOURCE_TYPE_MIC && source->type != WEBRTC_MEDIA_SOURCE_TYPE_NULL), WEBRTC_ERROR_INVALID_PARAMETER, "not supported media source type[%d]", source->type);
        RET_VAL_IF(rid == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "rid is NULL");
+       RET_VAL_IF(source->media_types == 0, WEBRTC_ERROR_INVALID_OPERATION, "source->media_types is 0");
 
        if ((media_type == WEBRTC_MEDIA_TYPE_AUDIO && !(source->media_types & MEDIA_TYPE_AUDIO)) ||
                (media_type == WEBRTC_MEDIA_TYPE_VIDEO && !(source->media_types & MEDIA_TYPE_VIDEO))) {
@@ -759,6 +795,8 @@ int _add_transceiver_encoding(webrtc_s *webrtc, unsigned int source_id, webrtc_m
 
        if (media_type == WEBRTC_MEDIA_TYPE_AUDIO)
                LOG_DEBUG("media_type is AUDIO, skip width[%d] height[%d] parameters", width, height);
+       if (source->type == WEBRTC_MEDIA_SOURCE_TYPE_NULL)
+               LOG_DEBUG("NULL source type, skip target_bitrate[%d] width[%d] height[%d] parameters", target_bitrate, width, height);
 
        ret = _add_source_encoding(source, av_idx, rid, target_bitrate, width, height, &ssrc);
        if (ret != WEBRTC_ERROR_NONE)
@@ -772,6 +810,8 @@ int _add_transceiver_encoding(webrtc_s *webrtc, unsigned int source_id, webrtc_m
        case WEBRTC_MEDIA_SOURCE_TYPE_VIDEOTEST:
                ret = _build_videotestsrc(webrtc, source, ssrc);
                break;
+       case WEBRTC_MEDIA_SOURCE_TYPE_NULL:
+               return WEBRTC_ERROR_NONE;
        default:
                /* TODO: support other types */
                LOG_ERROR_IF_REACHED("type(%d)", source->type);