Added vpx encoder system configure setting for real-time CBR encoding and streaming 01/254201/10
authorHyunil <hyunil46.park@samsung.com>
Thu, 25 Feb 2021 02:03:37 +0000 (11:03 +0900)
committerHyunil <hyunil46.park@samsung.com>
Thu, 4 Mar 2021 06:56:50 +0000 (15:56 +0900)
- Referred to https://www.webmproject.org/docs/encoder-parameters and
  https://developers.google.com/media/vp9/the-basics#quality_and_speed_settings

[Version] 0.1.120
[Issue Type] Improvement

Change-Id: Ic3647fa6642a1ff06e3839250838d035add69531
Signed-off-by: Hyunil <hyunil46.park@samsung.com>
include/webrtc_private.h
packaging/capi-media-webrtc.spec
src/webrtc_ini.c
src/webrtc_source.c

index 02d7ccf52368ac665fafe73a5f6ca05d0ae38cd3..9045a6dc110b9c3d3f6115d1cb15b1fb93ecc09a 100644 (file)
@@ -272,11 +272,23 @@ typedef   struct _ini_item_rendering_sink_s {
        gchar **v_hw_decoder_elements;
 } ini_item_rendering_sink_s;
 
+typedef struct _ini_item_vpxenc_params_s {
+       int threads;
+       int end_usage;
+       int cpu_used;
+       int target_bitrate;
+       int keyframe_max_dist;
+       int min_quantizer;
+       int max_quantizer;
+       int undershoot;
+} ini_item_vpxenc_params_s;
+
 typedef struct _webrtc_ini_s {
        dictionary *dict;
        ini_item_general_s general;
        ini_item_media_source_s media_source;
        ini_item_rendering_sink_s rendering_sink;
+       ini_item_vpxenc_params_s vpxenc_params;
        GHashTable *sources;
 } webrtc_ini_s;
 
index 790f51fe03f2d2775fa45df7adc8e8a83d9e98af..607fbd1fb16105333979c15fc6507846f0deca6d 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-media-webrtc
 Summary:    A WebRTC library in Tizen Native API
-Version:    0.1.119
+Version:    0.1.120
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
index 575ba39ac3a5201cb69eda873b062f4f011764a0..a13aa041c495e3faae105d7796c652779175e069 100644 (file)
@@ -33,6 +33,7 @@
 #define INI_CATEGORY_SOURCE_VIDEOTEST     "source videotest"
 #define INI_CATEGORY_SOURCE_MEDIA_PACKET  "source media packet"
 #define INI_CATEGORY_RENDERING_SINK       "rendering sink"
+#define INI_CATEGORY_VPXENC_PARAMS        "vpxenc params"
 
 /* items for general */
 #define INI_ITEM_DOT_PATH                 "dot path"
 #define INI_ITEM_AUDIO_HW_DECODER_ELEMENTS  "audio hw decoder elements"
 #define INI_ITEM_VIDEO_HW_DECODER_ELEMENTS  "video hw decoder elements"
 
+/* items for vpxenc parameters */
+#define INI_ITEM_VPXENC_THREADS             "threads"
+#define INI_ITEM_VPXENC_END_USAGE           "end usage"
+#define INI_ITEM_VPXENC_CPU_USED            "cpu used"
+#define INI_ITEM_VPXENC_TARGET_BITRATE      "target bitrate"
+#define INI_ITEM_VPXENC_KEYFRAME_MAX_DIST   "keyframe max dist"
+#define INI_ITEM_VPXENC_MIN_QUANTIZER       "min quantizer"
+#define INI_ITEM_VPXENC_MAX_QUANTIZER       "max quantizer"
+#define INI_ITEM_VPXENC_UNDERSHOOT          "undershoot"
+
+/* For the values below, refer to 'Real-time CBR Encoding and streaming'
+   of 'https://www.webmproject.org/docs/encoder-parameters'. */
+#define DEFAULT_VPXENC_THREADS              4
+#define DEFAULT_VPXENC_END_USAGE            1
+#define DEFAULT_VPXENC_CPU_USED             5
+#define DEFAULT_VPXENC_TARGET_BITRATE       256000
+#define DEFAULT_VPXENC_KEYFRAME_MAX_DIST    999999
+#define DEFAULT_VPXENC_MIN_QUANTIZER        4
+#define DEFAULT_VPXENC_MAX_QUANTIZER        56
+#define DEFAULT_VPXENC_UNDERSHOOT           95
+
 typedef enum {
        INI_ITEM_TYPE_BOOL,
        INI_ITEM_TYPE_INT,
@@ -149,6 +171,12 @@ static void __dump_items_of_source(ini_item_media_source_s *source)
        __dump_item(INI_ITEM_AUDIO_HW_ENCODER_ELEMENT, INI_ITEM_TYPE_STRING, (void *)source->a_hw_encoder_element);
 }
 
+static bool __is_vpx(const char *v_codec)
+{
+       return (!g_strcmp0(v_codec, "vp8") || !g_strcmp0(v_codec, "vp9") ||
+                       !g_strcmp0(v_codec, "VP8") || !g_strcmp0(v_codec, "VP9"));
+}
+
 static void __dump_ini(webrtc_ini_s *ini)
 {
        int i = 0;
@@ -177,6 +205,18 @@ static void __dump_ini(webrtc_ini_s *ini)
                }
        }
 
+       if (__is_vpx(ini->media_source.v_codec)) {
+               LOG_INFO("[%s]", INI_CATEGORY_VPXENC_PARAMS);
+               __dump_item(INI_ITEM_VPXENC_THREADS, INI_ITEM_TYPE_INT, &ini->vpxenc_params.threads);
+               __dump_item(INI_ITEM_VPXENC_END_USAGE, INI_ITEM_TYPE_INT, &ini->vpxenc_params.end_usage);
+               __dump_item(INI_ITEM_VPXENC_CPU_USED, INI_ITEM_TYPE_INT, &ini->vpxenc_params.cpu_used);
+               __dump_item(INI_ITEM_VPXENC_TARGET_BITRATE, INI_ITEM_TYPE_INT, &ini->vpxenc_params.target_bitrate);
+               __dump_item(INI_ITEM_VPXENC_KEYFRAME_MAX_DIST, INI_ITEM_TYPE_INT, &ini->vpxenc_params.keyframe_max_dist);
+               __dump_item(INI_ITEM_VPXENC_MIN_QUANTIZER, INI_ITEM_TYPE_INT, &ini->vpxenc_params.min_quantizer);
+               __dump_item(INI_ITEM_VPXENC_MAX_QUANTIZER, INI_ITEM_TYPE_INT, &ini->vpxenc_params.max_quantizer);
+               __dump_item(INI_ITEM_VPXENC_UNDERSHOOT, INI_ITEM_TYPE_INT, &ini->vpxenc_params.undershoot);
+       }
+
        __dump_item(INI_ITEM_AUDIO_HW_DECODER_ELEMENTS, INI_ITEM_TYPE_STRINGS, ini->rendering_sink.a_hw_decoder_elements);
        __dump_item(INI_ITEM_VIDEO_HW_DECODER_ELEMENTS, INI_ITEM_TYPE_STRINGS, ini->rendering_sink.v_hw_decoder_elements);
 }
@@ -284,6 +324,25 @@ static void __ini_source_destroy_cb(gpointer data)
        g_free(source);
 }
 
+static void __apply_vpxenc_params_setting(webrtc_ini_s *ini, ini_item_vpxenc_params_s *vpxenc_params, const char *category)
+{
+       RET_IF(ini == NULL, "ini is NULL");
+       RET_IF(vpxenc_params == NULL, "vpxenc_params is NULL");
+       RET_IF(category == NULL, "category is NULL");
+
+       if (g_strcmp0(category, INI_CATEGORY_VPXENC_PARAMS) != 0)
+               return;
+
+       vpxenc_params->threads = __ini_get_int(ini->dict, category, INI_ITEM_VPXENC_THREADS, DEFAULT_VPXENC_THREADS);
+       vpxenc_params->end_usage = __ini_get_int(ini->dict, category, INI_ITEM_VPXENC_END_USAGE, DEFAULT_VPXENC_END_USAGE);
+       vpxenc_params->cpu_used = __ini_get_int(ini->dict, category, INI_ITEM_VPXENC_CPU_USED, DEFAULT_VPXENC_CPU_USED);
+       vpxenc_params->target_bitrate = __ini_get_int(ini->dict, category, INI_ITEM_VPXENC_TARGET_BITRATE, DEFAULT_VPXENC_TARGET_BITRATE);
+       vpxenc_params->keyframe_max_dist = __ini_get_int(ini->dict, category, INI_ITEM_VPXENC_KEYFRAME_MAX_DIST, DEFAULT_VPXENC_KEYFRAME_MAX_DIST);
+       vpxenc_params->min_quantizer = __ini_get_int(ini->dict, category, INI_ITEM_VPXENC_MIN_QUANTIZER, DEFAULT_VPXENC_MIN_QUANTIZER);
+       vpxenc_params->max_quantizer = __ini_get_int(ini->dict, category, INI_ITEM_VPXENC_MAX_QUANTIZER, DEFAULT_VPXENC_MAX_QUANTIZER);
+       vpxenc_params->undershoot = __ini_get_int(ini->dict, category, INI_ITEM_VPXENC_UNDERSHOOT, DEFAULT_VPXENC_UNDERSHOOT);
+}
+
 static void __apply_media_source_setting(webrtc_ini_s *ini, ini_item_media_source_s *source, const char *category)
 {
        bool is_default = false;
@@ -303,7 +362,7 @@ static void __apply_media_source_setting(webrtc_ini_s *ini, ini_item_media_sourc
        source->v_width = __ini_get_int(ini->dict, category, INI_ITEM_VIDEO_WIDTH,
                        is_default ? DEFAULT_VIDEO_WIDTH : ini->media_source.v_width);
        source->v_height = __ini_get_int(ini->dict, category, INI_ITEM_VIDEO_HEIGHT,
-                       is_default? DEFAULT_VIDEO_HEIGHT : ini->media_source.v_height);
+                       is_default ? DEFAULT_VIDEO_HEIGHT : ini->media_source.v_height);
        source->v_framerate = __ini_get_int(ini->dict, category, INI_ITEM_VIDEO_FRAMERATE,
                        is_default ? DEFAULT_VIDEO_FRAMERATE : ini->media_source.v_framerate);
        source->v_codec = __ini_get_string(ini->dict, category, INI_ITEM_VIDEO_CODEC,
@@ -371,6 +430,9 @@ int _load_ini(webrtc_s *webrtc)
        __ini_read_list(ini->dict, INI_CATEGORY_RENDERING_SINK, INI_ITEM_AUDIO_HW_DECODER_ELEMENTS, &ini->rendering_sink.a_hw_decoder_elements);
        __ini_read_list(ini->dict, INI_CATEGORY_RENDERING_SINK, INI_ITEM_VIDEO_HW_DECODER_ELEMENTS, &ini->rendering_sink.v_hw_decoder_elements);
 
+       if (__is_vpx(ini->media_source.v_codec))
+               __apply_vpxenc_params_setting(ini, &ini->vpxenc_params, INI_CATEGORY_VPXENC_PARAMS);
+
        __dump_ini(ini);
 
        return WEBRTC_ERROR_NONE;
index 61906dcdbaf4af20705b1cb569f309817df14fdd..25a157804555ebccd1741796c785389962763bf1 100644 (file)
@@ -528,6 +528,7 @@ static int __create_rest_of_elements(webrtc_s *webrtc, webrtc_gst_slot_s *source
        element_info_s elem_info;
        const gchar *encoder_klass_name;
        gchar *media_type = NULL;
+       gchar *encoder_name = NULL;
 
        RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
        RET_VAL_IF(source == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL");
@@ -570,6 +571,19 @@ static int __create_rest_of_elements(webrtc_s *webrtc, webrtc_gst_slot_s *source
                        return WEBRTC_ERROR_INVALID_OPERATION;
        }
 
+       encoder_name = gst_element_get_name(*encoder);
+       if (encoder_name && (!g_strcmp0(encoder_name, "vp8enc") || !g_strcmp0(encoder_name, "vp9enc"))) {
+               g_object_set(G_OBJECT(*encoder), "threads", webrtc->ini.vpxenc_params.threads,
+                                               "end-usage", webrtc->ini.vpxenc_params.end_usage,
+                                               "cpu-used", webrtc->ini.vpxenc_params.cpu_used,
+                                               "target-bitrate", webrtc->ini.vpxenc_params.target_bitrate,
+                                               "keyframe-max-dist", webrtc->ini.vpxenc_params.keyframe_max_dist,
+                                               "max-quantizer", webrtc->ini.vpxenc_params.max_quantizer,
+                                               "min-quantizer", webrtc->ini.vpxenc_params.min_quantizer,
+                                               "undershoot", webrtc->ini.vpxenc_params.undershoot, NULL);
+       }
+       g_free(encoder_name);
+
        CREATE_ELEMENT_FROM_REGISTRY(elem_info, GST_KLASS_NAME_PAYLOADER_RTP,
                                                __make_default_encoded_caps(source, &webrtc->ini, &media_type),
                                                NULL,