From: Hyunil Date: Thu, 25 Feb 2021 02:03:37 +0000 (+0900) Subject: Added vpx encoder system configure setting for real-time CBR encoding and streaming X-Git-Tag: submit/tizen/20210729.023123~121 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3caa5742d1b76e0521cd7320b718c814e3bbd403;p=platform%2Fcore%2Fapi%2Fwebrtc.git Added vpx encoder system configure setting for real-time CBR encoding and streaming - 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 --- diff --git a/include/webrtc_private.h b/include/webrtc_private.h index 02d7ccf5..9045a6dc 100644 --- a/include/webrtc_private.h +++ b/include/webrtc_private.h @@ -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; diff --git a/packaging/capi-media-webrtc.spec b/packaging/capi-media-webrtc.spec index 790f51fe..607fbd1f 100644 --- a/packaging/capi-media-webrtc.spec +++ b/packaging/capi-media-webrtc.spec @@ -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 diff --git a/src/webrtc_ini.c b/src/webrtc_ini.c index 575ba39a..a13aa041 100644 --- a/src/webrtc_ini.c +++ b/src/webrtc_ini.c @@ -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" @@ -73,6 +74,27 @@ #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; diff --git a/src/webrtc_source.c b/src/webrtc_source.c index 61906dcd..25a15780 100644 --- a/src/webrtc_source.c +++ b/src/webrtc_source.c @@ -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,