From: Sangchul Lee Date: Fri, 25 Jun 2021 09:13:28 +0000 (+0900) Subject: webrtc_source: Improve to get caps for encoded format X-Git-Tag: submit/tizen/20210729.023123~32 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F77%2F260477%2F11;p=platform%2Fcore%2Fapi%2Fwebrtc.git webrtc_source: Improve to get caps for encoded format A bug making invalid caps in __make_default_encoded_caps() is fixed. Tainted array index is also fixed in webrtc_test. [Version] 0.2.28 [Issue Type] Bug fix Change-Id: I49fd509fa04836199baa19b25b36f59e45040222 Signed-off-by: Sangchul Lee --- diff --git a/packaging/capi-media-webrtc.spec b/packaging/capi-media-webrtc.spec index 553858e6..e53d9c74 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.2.27 +Version: 0.2.28 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/webrtc_source.c b/src/webrtc_source.c index 3560b406..3e71a9f9 100644 --- a/src/webrtc_source.c +++ b/src/webrtc_source.c @@ -365,6 +365,48 @@ static GstCaps *__make_raw_caps_from_media_format(webrtc_gst_slot_s *source) return caps; } +static GstCaps *__get_caps_from_encoded_audio_media_type(const char *media_type, int channels, int samplerate) +{ + RET_VAL_IF(media_type == NULL, NULL, "media_type is NULL"); + + if (!strcmp(media_type, MEDIA_TYPE_AUDIO_OPUS) || + !strcmp(media_type, MEDIA_TYPE_AUDIO_VORBIS)) + return gst_caps_new_simple(media_type, NULL, NULL); + + LOG_ERROR_IF_REACHED("invalid media_type(%s)", media_type); + + return NULL; +} + +static GstCaps *__get_caps_from_encoded_video_media_type(const char *media_type, int width, int height) +{ + RET_VAL_IF(media_type == NULL, NULL, "media_type is NULL"); + + if (!strcmp(media_type, MEDIA_TYPE_VIDEO_H264) || + !strcmp(media_type, MEDIA_TYPE_VIDEO_H265)) + return gst_caps_new_simple(media_type, + "stream-format", G_TYPE_STRING, "byte-stream", + "alignment", G_TYPE_STRING, "au", + "width", G_TYPE_INT, width, + "height", G_TYPE_INT, height, + NULL); + + if (!strcmp(media_type, MEDIA_TYPE_VIDEO_VP8) || + !strcmp(media_type, MEDIA_TYPE_VIDEO_VP9) || + !strcmp(media_type, MEDIA_TYPE_VIDEO_THEORA)) + return gst_caps_new_simple(media_type, NULL, NULL); /* NOTE: need to verify these codecs */ + + if (!strcmp(media_type, MEDIA_TYPE_VIDEO_JPEG)) + return gst_caps_new_simple(media_type, + "width", G_TYPE_INT, width, + "height", G_TYPE_INT, height, + NULL); + + LOG_ERROR_IF_REACHED("invalid media_type(%s)", media_type); + + return NULL; +} + /* Use g_free() to free the media_type parameter. */ static GstCaps *__make_default_encoded_caps(webrtc_gst_slot_s *source, webrtc_ini_s *ini, gchar **media_type) { @@ -386,12 +428,8 @@ static GstCaps *__make_default_encoded_caps(webrtc_gst_slot_s *source, webrtc_in case WEBRTC_MEDIA_SOURCE_TYPE_CUSTOM_VIDEO: _media_type = __get_video_media_type(ini_source->v_codec); RET_VAL_IF(_media_type == NULL, NULL, "_media_type is NULL"); + caps = __get_caps_from_encoded_video_media_type(_media_type, ini_source->v_width, ini_source->v_height); - caps = gst_caps_new_simple(_media_type, - "framerate", GST_TYPE_FRACTION, ini_source->v_framerate, 1, - "width", G_TYPE_INT, ini_source->v_width, - "height", G_TYPE_INT, ini_source->v_height, - NULL); source->video_info.width = ini_source->v_width; source->video_info.height = ini_source->v_height; break; @@ -401,35 +439,23 @@ static GstCaps *__make_default_encoded_caps(webrtc_gst_slot_s *source, webrtc_in case WEBRTC_MEDIA_SOURCE_TYPE_CUSTOM_AUDIO: _media_type = __get_audio_media_type(ini_source->a_codec); RET_VAL_IF(_media_type == NULL, NULL, "_media_type is NULL"); - - caps = gst_caps_new_simple(_media_type, - "channels", G_TYPE_INT, ini_source->a_channels, - "rate", G_TYPE_INT, ini_source->a_samplerate, - NULL); + caps = __get_caps_from_encoded_audio_media_type(_media_type, ini_source->a_channels, ini_source->a_samplerate); break; - case WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET: { + case WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET: if (source->media_types == MEDIA_TYPE_AUDIO) { _media_type = __get_audio_media_type(ini_source->a_codec); - caps = gst_caps_new_simple(_media_type, - "channels", G_TYPE_INT, ini_source->a_channels, - "rate", G_TYPE_INT, ini_source->a_samplerate, - NULL); - + RET_VAL_IF(_media_type == NULL, NULL, "_media_type is NULL"); + caps = __get_caps_from_encoded_audio_media_type(_media_type, ini_source->a_channels, ini_source->a_samplerate); } else if (source->media_types == MEDIA_TYPE_VIDEO) { _media_type = __get_video_media_type(ini_source->v_codec); - caps = gst_caps_new_simple(_media_type, - "framerate", GST_TYPE_FRACTION, ini_source->v_framerate, 1, - "width", G_TYPE_INT, ini_source->v_width, - "height", G_TYPE_INT, ini_source->v_height, - NULL); - + RET_VAL_IF(_media_type == NULL, NULL, "_media_type is NULL"); + caps = __get_caps_from_encoded_video_media_type(_media_type, ini_source->v_width, ini_source->v_height); } else { LOG_ERROR_IF_REACHED("source->media_types(0x%x)", source->media_types); return NULL; } break; - } default: LOG_ERROR_IF_REACHED("type(%d)", source->type); @@ -465,10 +491,7 @@ static GstCaps *__make_encoded_caps_from_media_format(webrtc_gst_slot_s *source, _media_type = __get_audio_media_type(__get_format_name(mime_type, source->zerocopy_enabled)); RET_VAL_IF(_media_type == NULL, NULL, "media_type is NULL"); - caps = gst_caps_new_simple(_media_type, - "channels", G_TYPE_INT, channels, - "rate", G_TYPE_INT, samplerate, - NULL); + caps = __get_caps_from_encoded_audio_media_type(_media_type, channels, samplerate); } else if (source->media_types == MEDIA_TYPE_VIDEO) { int width; @@ -483,11 +506,7 @@ static GstCaps *__make_encoded_caps_from_media_format(webrtc_gst_slot_s *source, _media_type = __get_video_media_type(__get_format_name(mime_type, source->zerocopy_enabled)); RET_VAL_IF(_media_type == NULL, NULL, "media_type is NULL"); - caps = gst_caps_new_simple(_media_type, - "framerate", GST_TYPE_FRACTION, framerate, 1, - "width", G_TYPE_INT, width, - "height", G_TYPE_INT, height, - NULL); + caps = __get_caps_from_encoded_video_media_type(_media_type, width, height); } else { LOG_ERROR_IF_REACHED("source->media_types(0x%x)", source->media_types); @@ -663,9 +682,19 @@ static int __create_rest_of_elements(webrtc_s *webrtc, webrtc_gst_slot_s *source RET_VAL_IF(source == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL"); RET_VAL_IF(element_list == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "element_list is NULL"); + if (source->media_types == MEDIA_TYPE_VIDEO) { + encoder_klass_name = GST_KLASS_NAME_ENCODER_VIDEO; + } else if (source->media_types == MEDIA_TYPE_AUDIO) { + encoder_klass_name = GST_KLASS_NAME_ENCODER_AUDIO; + } else { + LOG_ERROR("not ready for this media_types[0x%x]", source->media_types); + return WEBRTC_ERROR_INVALID_OPERATION; + } + if (need_capsfilter) { if (!(capsfilter = _create_element(DEFAULT_ELEMENT_CAPSFILTER, ELEMENT_NAME_FIRST_CAPSFILTER))) return WEBRTC_ERROR_INVALID_OPERATION; + APPEND_ELEMENT(*element_list, capsfilter); if (__is_encoded_format_supported(source->type, &webrtc->ini)) { if ((sink_caps = __make_default_encoded_caps(source, &webrtc->ini, NULL))) { @@ -683,15 +712,6 @@ static int __create_rest_of_elements(webrtc_s *webrtc, webrtc_gst_slot_s *source } } - if (source->media_types == MEDIA_TYPE_VIDEO) { - encoder_klass_name = GST_KLASS_NAME_ENCODER_VIDEO; - } else if (source->media_types == MEDIA_TYPE_AUDIO) { - encoder_klass_name = GST_KLASS_NAME_ENCODER_AUDIO; - } else { - LOG_ERROR("not ready for this media_types[0x%x]", source->media_types); - return WEBRTC_ERROR_INVALID_OPERATION; - } - if (source->zerocopy_enabled) encoder = __get_hw_encoder_element(webrtc, source); else @@ -701,6 +721,7 @@ static int __create_rest_of_elements(webrtc_s *webrtc, webrtc_gst_slot_s *source encoder); if (encoder == NULL) return WEBRTC_ERROR_INVALID_OPERATION; + APPEND_ELEMENT(*element_list, encoder); encoder_name = gst_element_get_name(encoder); if (encoder_name && (!g_strcmp0(encoder_name, "vp8enc") || !g_strcmp0(encoder_name, "vp9enc"))) { @@ -724,16 +745,19 @@ skip_encoder: g_free(media_type); return WEBRTC_ERROR_INVALID_OPERATION; } + APPEND_ELEMENT(*element_list, payloader); if (!(queue = _create_element(DEFAULT_ELEMENT_QUEUE, NULL))) { g_free(media_type); return WEBRTC_ERROR_INVALID_OPERATION; } + APPEND_ELEMENT(*element_list, queue); if (!(capsfilter2 = _create_element(DEFAULT_ELEMENT_CAPSFILTER, ELEMENT_NAME_RTP_CAPSFILTER))) { g_free(media_type); return WEBRTC_ERROR_INVALID_OPERATION; } + APPEND_ELEMENT(*element_list, capsfilter2); payload_id = __get_available_payload_id(webrtc); if (payload_id == 0) { @@ -749,12 +773,6 @@ skip_encoder: g_free(media_type); - APPEND_ELEMENT(*element_list, capsfilter); - APPEND_ELEMENT(*element_list, encoder); - APPEND_ELEMENT(*element_list, payloader); - APPEND_ELEMENT(*element_list, queue); - APPEND_ELEMENT(*element_list, capsfilter2); - return WEBRTC_ERROR_NONE; } @@ -1550,7 +1568,6 @@ exit: static GstCaps *__make_encoded_caps_for_appsrc(webrtc_gst_slot_s *source) { - GstCaps *caps; media_format_mimetype_e mime_type; const char *_media_type; @@ -1562,14 +1579,8 @@ static GstCaps *__make_encoded_caps_for_appsrc(webrtc_gst_slot_s *source) _media_type = __get_video_media_type(__get_format_name(mime_type, source->zerocopy_enabled)); RET_VAL_IF(g_strcmp0(_media_type, MEDIA_TYPE_VIDEO_H264), NULL, "not supported type(%s)", _media_type); - /* FIXME: prepare other types */ - caps = gst_caps_new_simple(_media_type, - "stream-format", G_TYPE_STRING, "byte-stream", - "alignment", G_TYPE_STRING, "au", - NULL); - - return caps; + return __make_encoded_caps_from_media_format(source, NULL); } static int __complete_mediapacketsrc_from_encoded_format(webrtc_s *webrtc, webrtc_gst_slot_s *source) diff --git a/test/webrtc_test.c b/test/webrtc_test.c index 1b0eeef1..949615e2 100644 --- a/test/webrtc_test.c +++ b/test/webrtc_test.c @@ -3282,7 +3282,7 @@ static void displaymenu() g_print("*** input proxy URL.\n"); } else if (g_conns[g_conn_index].menu_state == CURRENT_STATUS_CHANGE_CONNECTION) { - g_print("*** input to connection index.(0 ~ 3)\n"); + g_print("*** input to connection index.(0 ~ 2)\n"); } else if (g_conns[g_conn_index].menu_state == CURRENT_STATUS_REQUEST_SESSION) { g_print("*** input remote peer id.\n"); @@ -3554,7 +3554,7 @@ static void interpret(char *cmd) } case CURRENT_STATUS_CHANGE_CONNECTION: { value = atoi(cmd); - if (value < 0 || value > 3) + if (value < 0 || value >= MAX_CONNECTION_LEN) g_print("invalid value[%d]", value); else g_conn_index = value;