webrtc_source: Enable in-band FEC of OPUS encoder 45/266545/7
authorSangchul Lee <sc11.lee@samsung.com>
Fri, 12 Nov 2021 08:15:11 +0000 (17:15 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Tue, 28 Dec 2021 07:37:02 +0000 (16:37 +0900)
Revise caller of g_object_set()/get() to use multiple lines.

[Version] 0.3.34
[Issue Type] New feature

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

index b408a5fee3dbf2723d05318601b92f68114c1a92..0b783b737afdfa7f26bb77f86adf72dc80ae6ddf 100644 (file)
@@ -479,6 +479,7 @@ typedef struct _webrtc_gst_slot_s {
                GstPad *src_pad;
                gulong src_pad_probe_id;
                bool pause;
+               bool inbandfec;
                unsigned int payload_id;
                struct {
                        unsigned int track_id;
index db6a63134f28269bb52a1f31b26e84f562eddb95..ccc2294e2eee1f30a8251738236f3311f25d9368 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-media-webrtc
 Summary:    A WebRTC library in Tizen Native API
-Version:    0.3.33
+Version:    0.3.34
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
index 927c2735655df11f05e98144430363bd11ac9a23..4ac01d3bb7e357d3729fb1cfe012af2dec480d3e 100644 (file)
@@ -616,7 +616,7 @@ static GstCaps *__make_encoded_caps_from_media_format(webrtc_gst_slot_s *source,
 }
 //LCOV_EXCL_STOP
 
-static GstCaps *__make_rtp_caps(const gchar *media_type, unsigned int payload_id)
+static GstCaps *__make_rtp_caps(const gchar *media_type, unsigned int payload_id, webrtc_gst_slot_s *source)
 {
        GstCaps *caps;
        bool is_audio;
@@ -627,7 +627,12 @@ static GstCaps *__make_rtp_caps(const gchar *media_type, unsigned int payload_id
 
        caps = gst_caps_new_simple("application/x-rtp",
                                "media", G_TYPE_STRING, GET_MEDIA_TYPE_NAME(is_audio),
-                               "payload", G_TYPE_INT, payload_id, NULL);
+                               "payload", G_TYPE_INT, payload_id,
+                               NULL);
+
+       if (is_audio && source->av[AV_IDX_AUDIO].inbandfec)
+               /* NOTE: set it with string type due to the parsing logic in gstwebrtcbin.c */
+               gst_structure_set(gst_caps_get_structure(caps, 0), "useinbandfec", G_TYPE_STRING, "1", NULL);
 
        PRINT_CAPS(caps, "RTP");
 
@@ -880,9 +885,21 @@ static GstElement * __prepare_encoder(webrtc_s *webrtc, webrtc_gst_slot_s *sourc
                        "min-quantizer", webrtc->ini.vpxenc_params.min_quantizer,
                        "undershoot", webrtc->ini.vpxenc_params.undershoot,
                        NULL);
+
+               LOG_DEBUG("[%s] end-usage(%d) cpu-used(%d) target-bitrate(%d) keyframe-max-dist(%d) max-quantizer(%d) min-quantizer(%d) undershoot(%d)",
+                       encoder_name, webrtc->ini.vpxenc_params.end_usage, webrtc->ini.vpxenc_params.cpu_used, webrtc->ini.vpxenc_params.target_bitrate,
+                       webrtc->ini.vpxenc_params.keyframe_max_dist, webrtc->ini.vpxenc_params.max_quantizer, webrtc->ini.vpxenc_params.min_quantizer,
+                       webrtc->ini.vpxenc_params.undershoot);
+
+       } else if (g_strrstr(encoder_name, "opusenc")) {
+               if (source->av[AV_IDX_AUDIO].inbandfec) {
+                       g_object_set(G_OBJECT(encoder), "inband-fec", TRUE, NULL);
+                       g_object_set(G_OBJECT(encoder), "packet-loss-percentage", 10, NULL); /* TODO: set this value from ini or API */
+                       LOG_DEBUG("[%s] inband-fec(%d)", encoder_name, TRUE);
+               }
        }
-       g_free(encoder_name);
 
+       g_free(encoder_name);
        return encoder;
 }
 
@@ -972,7 +989,7 @@ skip_encoder:
 
        source->av[idx].payload_id = payload_id;
 
-       if ((sink_caps = __make_rtp_caps(media_type, payload_id))) {
+       if ((sink_caps = __make_rtp_caps(media_type, payload_id, source))) {
                g_object_set(G_OBJECT(capsfilter2), "caps", sink_caps, NULL);
                gst_caps_unref(sink_caps);
        }
@@ -1027,7 +1044,7 @@ static int __create_rest_of_elements_for_encoded_format(webrtc_s *webrtc, webrtc
 
        source->av[GET_AV_IDX_BY_TYPE(source->media_types)].payload_id = payload_id;
 
-       if ((sink_caps = __make_rtp_caps(media_type, payload_id))) {
+       if ((sink_caps = __make_rtp_caps(media_type, payload_id, source))) {
                g_object_set(G_OBJECT(capsfilter), "caps", sink_caps, NULL);
                gst_caps_unref(sink_caps);
        }
@@ -1764,9 +1781,9 @@ static int __build_filesrc_bin(webrtc_gst_slot_s *source, media_type_e media_typ
        APPEND_ELEMENT(element_list, appsrc);
 
        g_object_set(G_OBJECT(appsrc),
-                       "is-live", TRUE,
-                       "format", GST_FORMAT_TIME,
-                       NULL);
+               "is-live", TRUE,
+               "format", GST_FORMAT_TIME,
+               NULL);
 
        if (!(queue = _create_element(DEFAULT_ELEMENT_QUEUE, _av_tbl[av_idx].queue_name)))
                goto exit;
@@ -1955,7 +1972,7 @@ static GstElement * __prepare_capsfilter_for_filesrc_pipeline(webrtc_gst_slot_s
 
        source->av[GET_AV_IDX(is_audio)].payload_id = payload_id;
 
-       if ((sink_caps = __make_rtp_caps(GET_MEDIA_TYPE_NAME(is_audio), payload_id))) {
+       if ((sink_caps = __make_rtp_caps(GET_MEDIA_TYPE_NAME(is_audio), payload_id, source))) {
                g_object_set(G_OBJECT(capsfilter), "caps", sink_caps, NULL);
                gst_caps_unref(sink_caps);
        }
@@ -4396,15 +4413,15 @@ int _set_screen_source_crop(webrtc_s *webrtc, unsigned int source_id, int x, int
        LOG_INFO("set source crop x:%d, y:%d, width:%d, height:%d, mode:%s", x, y, w, h, (portrait_mode) ? "portrait" : "landscape");
 
        g_object_get(G_OBJECT(screen_source),
-                       portrait_mode ? "mirroring-v-src-width" : "mirroring-h-src-width", &src_width,
-                       portrait_mode ? "mirroring-v-src-height" : "mirroring-h-src-height", &src_height,
-                       portrait_mode ? "mirroring-v-x" : "mirroring-h-x", &mirroring_x,
-                       portrait_mode ? "mirroring-v-y" : "mirroring-h-y", &mirroring_y,
-                       portrait_mode ? "mirroring-v-width" : "mirroring-h-width", &mirroring_width,
-                       portrait_mode ? "mirroring-v-height" : "mirroring-h-height", &mirroring_height,
-                       "output-width", &output_width,
-                       "output-height", &output_height,
-                       NULL);
+               portrait_mode ? "mirroring-v-src-width" : "mirroring-h-src-width", &src_width,
+               portrait_mode ? "mirroring-v-src-height" : "mirroring-h-src-height", &src_height,
+               portrait_mode ? "mirroring-v-x" : "mirroring-h-x", &mirroring_x,
+               portrait_mode ? "mirroring-v-y" : "mirroring-h-y", &mirroring_y,
+               portrait_mode ? "mirroring-v-width" : "mirroring-h-width", &mirroring_width,
+               portrait_mode ? "mirroring-v-height" : "mirroring-h-height", &mirroring_height,
+               "output-width", &output_width,
+               "output-height", &output_height,
+               NULL);
 
        rw = (float)src_width / mirroring_width;
        rh = (float)src_height / mirroring_height;
@@ -4417,8 +4434,12 @@ int _set_screen_source_crop(webrtc_s *webrtc, unsigned int source_id, int x, int
                "mirroring[x:%d y:%d width:%d, height:%d", src_width, src_height, output_width,
                output_height, mirroring_x, mirroring_y, mirroring_width, mirroring_height);
 
-       g_object_set(G_OBJECT(videocrop), "left", left, "right", right, "top", top,
-                       "bottom", bottom, NULL);
+       g_object_set(G_OBJECT(videocrop),
+               "left", left,
+               "right", right,
+               "top", top,
+               "bottom", bottom,
+               NULL);
 
        LOG_INFO("cropped: left:%d, right:%d, top:%d, bottom:%d", left, right, top, bottom);
 
@@ -4448,10 +4469,20 @@ int _unset_screen_source_crop(webrtc_s *webrtc, unsigned int source_id)
        videocrop =  gst_bin_get_by_name(source->bin, ELEMENT_NAME_VIDEOCROP);
        RET_VAL_IF(videocrop == NULL, WEBRTC_ERROR_INVALID_OPERATION, "videocrop is NULL");
 
-       g_object_get(G_OBJECT(videocrop), "left", &left, "right", &right, "top", &top, "bottom", &bottom, NULL);
+       g_object_get(G_OBJECT(videocrop),
+               "left", &left,
+               "right", &right,
+               "top", &top,
+               "bottom", &bottom,
+               NULL);
        RET_VAL_IF(left == 0 && right == 0 && top == 0 && bottom == 0, WEBRTC_ERROR_INVALID_OPERATION, "webrtc_screen_source_set_crop was not set");
 
-       g_object_set(G_OBJECT(videocrop), "left", 0, "right", 0, "top", 0, "bottom", 0, NULL);
+       g_object_set(G_OBJECT(videocrop),
+               "left", 0,
+               "right", 0,
+               "top", 0,
+               "bottom", 0,
+               NULL);
 
        return WEBRTC_ERROR_NONE;
 }