From: hj kim Date: Wed, 13 Jul 2022 06:48:05 +0000 (+0900) Subject: Set a transceiver manually when the source direction is 'recvonly' X-Git-Tag: submit/tizen/20220725.023109~4 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F74%2F277774%2F8;p=platform%2Fcore%2Fapi%2Fwebrtc.git Set a transceiver manually when the source direction is 'recvonly' when offer's source direction is 'recvonly', gstreamer webrtc doesn't add media in offer SDP. then, offerer can't receive media from the peer, so manual setting is needed. plus, change transceiver setting time of null source from webrtc_media_source_set_transceiver_codec() to webrtc_start() like other sources. [Version] 0.3.158 [Issue Type] Bug fix Change-Id: I072084d0888003975a039304d18a6f2d28b4f4ca --- diff --git a/include/webrtc_private.h b/include/webrtc_private.h index 8d71172c..ad8b5c27 100644 --- a/include/webrtc_private.h +++ b/include/webrtc_private.h @@ -227,6 +227,8 @@ do { \ x_webrtc->idle_cb_event_source_ids[x_idx] = 0; \ } while (0) +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + #define GET_AV_IDX(x_is_audio) (x_is_audio) ? AV_IDX_AUDIO : AV_IDX_VIDEO #define GET_MEDIA_TYPE_NAME(x_is_audio) (x_is_audio) ? "audio" : "video" @@ -655,7 +657,7 @@ int _set_transceiver_codec(webrtc_s *webrtc, unsigned int source_id, webrtc_medi int _get_transceiver_codec(webrtc_s *webrtc, unsigned int source_id, webrtc_media_type_e media_type, webrtc_transceiver_codec_e *codec); void _update_transceivers_fec(webrtc_s *webrtc, bool is_offer); int _foreach_supported_transceiver_codec(webrtc_s *webrtc, unsigned int source_id, webrtc_media_type_e media_type, webrtc_media_source_supported_transceiver_codec_cb callback, void *user_data); -bool _check_if_transceiver_is_set_to_null_sources(webrtc_s *webrtc); +bool _check_if_codec_is_set_to_null_sources(webrtc_s *webrtc); int _set_pause(webrtc_s *webrtc, unsigned int source_id, webrtc_media_type_e media_type, bool pause); int _get_pause(webrtc_s *webrtc, unsigned int source_id, webrtc_media_type_e media_type, bool *paused); int _set_audio_mute(webrtc_s *webrtc, unsigned int source_id, bool mute); diff --git a/include/webrtc_source_private.h b/include/webrtc_source_private.h index 0d6eb566..48a60cc0 100644 --- a/include/webrtc_source_private.h +++ b/include/webrtc_source_private.h @@ -78,5 +78,6 @@ GstCaps *_get_caps_from_encoded_audio_media_type(const char *media_type, int cha GstCaps *_get_caps_from_encoded_video_media_type(const char *media_type, int width, int height); unsigned int _get_available_payload_type(webrtc_s *webrtc); GstCaps *_make_rtp_caps(const gchar *media_type, unsigned int payload_type, webrtc_gst_slot_s *source); +int _set_mediapacketsrc_codec_info(webrtc_s *webrtc, webrtc_gst_slot_s *source, media_format_mimetype_e mime_type); #endif /* __TIZEN_MEDIA_WEBRTC_SOURCE_COMMON_H__ */ diff --git a/packaging/capi-media-webrtc.spec b/packaging/capi-media-webrtc.spec index 69c71377..bc591fc3 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.3.157 +Version: 0.3.158 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/webrtc.c b/src/webrtc.c index aef2e7e4..8c7fe23d 100644 --- a/src/webrtc.c +++ b/src/webrtc.c @@ -188,7 +188,7 @@ int webrtc_start(webrtc_h webrtc) RET_VAL_IF(_webrtc->gst.webrtcbin == NULL, WEBRTC_ERROR_INVALID_OPERATION, "webrtcbin is NULL"); RET_VAL_IF(!_check_if_format_is_set_to_packet_sources(_webrtc), WEBRTC_ERROR_INVALID_OPERATION, "the media format should be set"); RET_VAL_IF(!_check_if_path_is_set_to_file_sources(_webrtc), WEBRTC_ERROR_INVALID_OPERATION, "the media path should be set"); - RET_VAL_IF(!_check_if_transceiver_is_set_to_null_sources(_webrtc), WEBRTC_ERROR_INVALID_OPERATION, "transceiver codec is should be set"); + RET_VAL_IF(!_check_if_codec_is_set_to_null_sources(_webrtc), WEBRTC_ERROR_INVALID_OPERATION, "transceiver codec is should be set"); #ifndef TIZEN_TV ret = _acquire_resource_if_needed(_webrtc); diff --git a/src/webrtc_source.c b/src/webrtc_source.c index 731fb230..0d59ff78 100644 --- a/src/webrtc_source.c +++ b/src/webrtc_source.c @@ -242,13 +242,17 @@ static GstCaps *__make_default_encoded_caps(webrtc_gst_slot_s *source, webrtc_in case WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET: if (source->media_types == MEDIA_TYPE_AUDIO) { - _media_type = _get_audio_media_type(ini_source->a_codecs[0]); + _media_type = _get_audio_media_type(source->av[AV_IDX_AUDIO].codec); 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_codecs[0]); + _media_type = _get_video_media_type(source->av[AV_IDX_VIDEO].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); + } else { LOG_ERROR_IF_REACHED("source->media_types(0x%x)", source->media_types); return NULL; @@ -1115,6 +1119,44 @@ static int __add_transceiver(webrtc_gst_slot_s *source, webrtc_media_type_e medi return WEBRTC_ERROR_NONE; } +static rtp_payload_info_s * __get_payload_info(const char *codec) +{ + int i = 0; + size_t n = 0; + + RET_VAL_IF(codec == NULL, NULL, "codec is NULL"); + + n = ARRAY_SIZE(__payload_info); + + for (i = 0; i < (int)n; i++) { + if ((__payload_info[i].encoding_name) && !strcasecmp(__payload_info[i].encoding_name, codec)) + return &__payload_info[i]; + } + + LOG_ERROR("could not find payload_info. codec[%s]", codec); + + return NULL; +} + +static void __check_and_add_recvonly_transceiver(webrtc_gst_slot_s *source) +{ + rtp_payload_info_s *payload_info = NULL; + + RET_IF(source == NULL, "source is NULL"); + + if (source->av[AV_IDX_AUDIO].direction == WEBRTC_TRANSCEIVER_DIRECTION_RECVONLY && source->av[AV_IDX_AUDIO].codec) { + payload_info = __get_payload_info(source->av[AV_IDX_AUDIO].codec); + if (payload_info) + __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) { + payload_info = __get_payload_info(source->av[AV_IDX_VIDEO].codec); + if (payload_info) + __add_transceiver(source, WEBRTC_MEDIA_TYPE_VIDEO, payload_info); + } +} + int _complete_sources(webrtc_s *webrtc) { int i; @@ -1124,17 +1166,24 @@ int _complete_sources(webrtc_s *webrtc) for (i = 0; i < MAX_SOURCE_NUM; i++) { if (!(source = webrtc->gst.sources[i])) continue; - if (source->type == WEBRTC_MEDIA_SOURCE_TYPE_FILE || - source->type == WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET || - source->type == WEBRTC_MEDIA_SOURCE_TYPE_NULL) - continue; LOG_DEBUG("source[id:%u, type:%d, media_types:0x%x]", source->id, source->type, source->media_types); + if (source->type == WEBRTC_MEDIA_SOURCE_TYPE_FILE) + continue; + + if (source->type == WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET || + source->type == WEBRTC_MEDIA_SOURCE_TYPE_NULL) { + goto add_transceiver; + } + if (source->media_types == MEDIA_TYPE_AUDIO) __complete_rest_of_audiosrc(webrtc, source); else __complete_rest_of_videosrc(webrtc, source); + +add_transceiver: + __check_and_add_recvonly_transceiver(source); } return WEBRTC_ERROR_NONE; @@ -1439,6 +1488,8 @@ static GstPadProbeReturn __fakesink_probe_cb(GstPad *pad, GstPadProbeInfo *info, LOG_INFO("setting caps for [%s appsrc] successfully", (av_idx == AV_IDX_AUDIO) ? "audio" : "video"); PRINT_CAPS(caps, "appsrc"); + + source->av[av_idx].codec = gst_structure_get_string(gst_caps_get_structure(caps, 0), "encoding-name"); gst_caps_unref(caps); source->filesrc_av[av_idx].sink_pad = pad; @@ -2143,6 +2194,7 @@ static int __add_null_source(webrtc_s *webrtc, unsigned int *source_id) } *source_id = source->id; + webrtc->gst.sources[*source_id - 1] = source; LOG_INFO("added a source slot[%p, id:%u]", source, source->id); @@ -2457,9 +2509,6 @@ int _set_transceiver_codec(webrtc_s *webrtc, unsigned int source_id, webrtc_medi if((ret = __set_payload_type(webrtc, source, av_idx, payload_info->gst_media_type)) != WEBRTC_ERROR_NONE) return ret; - - if((ret = __add_transceiver(source, media_type, payload_info)) != WEBRTC_ERROR_NONE) - return ret; } /* FIXME: to utilize 'codec-preferences' of trans object, we need to re-create and re-link elements again */ @@ -2798,6 +2847,8 @@ int _set_media_format(webrtc_s *webrtc, unsigned int source_id, media_format_h f media_format_ref(format); source->media_format = format; + if((ret = _set_mediapacketsrc_codec_info(webrtc, source, mime_type)) != WEBRTC_ERROR_NONE) + goto error; if ((mime_type & MEDIA_FORMAT_RAW) && !(mime_type == MEDIA_FORMAT_PCMU || mime_type == MEDIA_FORMAT_PCMA)) /* FIXME: media_format.h defined PCMU/PCMA as a raw format, it's a bug. */ @@ -2850,7 +2901,7 @@ bool _check_if_format_is_set_to_packet_sources(webrtc_s *webrtc) return true; } -static gboolean __check_transceiver_is_not_set_cb(gpointer key, gpointer value, gpointer user_data) +static gboolean __check_codec_is_not_set_cb(gpointer key, gpointer value, gpointer user_data) { const webrtc_gst_slot_s *source = (webrtc_gst_slot_s *)value; int i; @@ -2858,7 +2909,7 @@ static gboolean __check_transceiver_is_not_set_cb(gpointer key, gpointer value, if (source->type == GPOINTER_TO_INT(user_data)) { LOG_INFO("found media null source[%p, id:%u]", source, source->id); for (i = 0; i < AV_IDX_MAX; i++) { - if (source->av[i].transceiver) + if (source->av[i].codec) return FALSE; } return TRUE; @@ -2866,15 +2917,15 @@ static gboolean __check_transceiver_is_not_set_cb(gpointer key, gpointer value, return FALSE; } -bool _check_if_transceiver_is_set_to_null_sources(webrtc_s *webrtc) +bool _check_if_codec_is_set_to_null_sources(webrtc_s *webrtc) { const webrtc_gst_slot_s *source; RET_VAL_IF(webrtc == NULL, false, "webrtc is NULL"); - source = g_hash_table_find(webrtc->gst.source_slots, __check_transceiver_is_not_set_cb, GINT_TO_POINTER(WEBRTC_MEDIA_SOURCE_TYPE_NULL)); + source = g_hash_table_find(webrtc->gst.source_slots, __check_codec_is_not_set_cb, GINT_TO_POINTER(WEBRTC_MEDIA_SOURCE_TYPE_NULL)); if (source) { - LOG_ERROR("transceiver is not set to the media null source[%u]", source->id); + LOG_ERROR("codec is not set to the media null source[%u]", source->id); LOG_ERROR("please use webrtc_media_source_set_transceiver_codec()"); return false; } diff --git a/src/webrtc_source_mediapacket.c b/src/webrtc_source_mediapacket.c index ef094198..79b46038 100644 --- a/src/webrtc_source_mediapacket.c +++ b/src/webrtc_source_mediapacket.c @@ -270,7 +270,7 @@ static GstCaps *__make_encoded_caps_from_media_format(webrtc_gst_slot_s *source, RET_VAL_IF(media_format_get_audio_info(source->media_format, &mime_type, &channels, &samplerate, NULL, NULL) != MEDIA_FORMAT_ERROR_NONE, NULL, "failed to media_format_get_audio_info()"); - _media_type = _get_audio_media_type(_get_audio_format_name(mime_type)); + _media_type = _get_audio_media_type(source->av[AV_IDX_AUDIO].codec); RET_VAL_IF(_media_type == NULL, NULL, "media_type is NULL"); caps = _get_caps_from_encoded_audio_media_type(_media_type, channels, samplerate); @@ -285,7 +285,7 @@ static GstCaps *__make_encoded_caps_from_media_format(webrtc_gst_slot_s *source, RET_VAL_IF(media_format_get_video_frame_rate(source->media_format, &framerate) != MEDIA_FORMAT_ERROR_NONE, NULL, "failed to media_format_get_video_frame_rate()"); - _media_type = _get_video_media_type(_get_video_format_name(mime_type, source->zerocopy_enabled)); + _media_type = _get_video_media_type(source->av[AV_IDX_VIDEO].codec); RET_VAL_IF(_media_type == NULL, NULL, "media_type is NULL"); caps = _get_caps_from_encoded_video_media_type(_media_type, width, height); @@ -636,3 +636,36 @@ exit: return ret; } //LCOV_EXCL_STOP + +int _set_mediapacketsrc_codec_info(webrtc_s *webrtc, webrtc_gst_slot_s *source, media_format_mimetype_e mime_type) +{ + RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL"); + RET_VAL_IF(source == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL"); + RET_VAL_IF(source->media_format == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "media_format is NULL"); + RET_VAL_IF(((source->media_types != MEDIA_TYPE_AUDIO) && (source->media_types != MEDIA_TYPE_VIDEO)), + WEBRTC_ERROR_INVALID_PARAMETER, "invalid media_types [%d]", source->media_types); + + if ((mime_type & MEDIA_FORMAT_RAW) && + !(mime_type == MEDIA_FORMAT_PCMU || mime_type == MEDIA_FORMAT_PCMA)) { /* FIXME: media_format.h defined PCMU/PCMA as a raw format, it's a bug. */ + + const ini_item_media_source_s *ini_source = _ini_get_source_by_type(&webrtc->ini, source->type); + if (ini_source == NULL) + ini_source = &(webrtc->ini.media_source); + + if (source->media_types == MEDIA_TYPE_AUDIO) + source->av[AV_IDX_AUDIO].codec = ini_source->a_codecs[0]; + else + source->av[AV_IDX_VIDEO].codec = ini_source->v_codecs[0]; + + } else { + if (source->media_types == MEDIA_TYPE_AUDIO) + source->av[AV_IDX_AUDIO].codec = _get_audio_format_name(mime_type); + else + source->av[AV_IDX_VIDEO].codec = _get_video_format_name(mime_type, source->zerocopy_enabled); + + } + + LOG_DEBUG("%s codec info [%s]", (source->media_types == MEDIA_TYPE_AUDIO) ? "audio" : "video", source->av[GET_AV_IDX_BY_TYPE(source->media_types)].codec); + + return WEBRTC_ERROR_NONE; +}