From: Sangchul Lee Date: Fri, 10 Jun 2022 03:20:29 +0000 (+0900) Subject: Add API to get supported transceiver codecs X-Git-Tag: submit/tizen/20220627.062515~6 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=46e23d819d2943913d5ec904e6b32ef8c4b5719d;p=platform%2Fcore%2Fapi%2Fwebrtc.git Add API to get supported transceiver codecs Functions are added as below. - webrtc_media_source_foreach_supported_transceiver_codec() - webrtc_media_source_supported_transceiver_codec_cb() Enums are added as below. - WEBRTC_TRANSCEIVER_CODEC_PCMU - WEBRTC_TRANSCEIVER_CODEC_PCMA - WEBRTC_TRANSCEIVER_CODEC_OPUS - WEBRTC_TRANSCEIVER_CODEC_VP8 - WEBRTC_TRANSCEIVER_CODEC_VP9 - WEBRTC_TRANSCEIVER_CODEC_H264 [Version] 0.3.127 [Issue Type] API Change-Id: Ibc839734570d406fc006d9ef88554fd2db84c036 Signed-off-by: Sangchul Lee --- diff --git a/include/webrtc.h b/include/webrtc.h index 9863fc34..3c4fe9d5 100644 --- a/include/webrtc.h +++ b/include/webrtc.h @@ -196,6 +196,19 @@ typedef enum { WEBRTC_TRANSCEIVER_DIRECTION_SENDRECV, /**< Send and receive */ } webrtc_transceiver_direction_e; +/** + * @brief Enumeration for WebRTC transceiver codec. + * @since_tizen 7.0 + */ +typedef enum { + WEBRTC_TRANSCEIVER_CODEC_PCMU = 0x00000100 | 0x01, /**< PCMU audio codec */ + WEBRTC_TRANSCEIVER_CODEC_PCMA = 0x00000100 | 0x02, /**< PCMA audio codec */ + WEBRTC_TRANSCEIVER_CODEC_OPUS = 0x00000100 | 0x03, /**< OPUS audio codec */ + WEBRTC_TRANSCEIVER_CODEC_VP8 = 0x00000200 | 0x01, /**< VP8 video codec */ + WEBRTC_TRANSCEIVER_CODEC_VP9 = 0x00000200 | 0x02, /**< VP9 video codec */ + WEBRTC_TRANSCEIVER_CODEC_H264 = 0x00000200 | 0x03, /**< H264 video codec */ +} webrtc_transceiver_codec_e; + /** * @} */ @@ -626,6 +639,18 @@ typedef void (*webrtc_track_added_cb)(webrtc_h webrtc, webrtc_media_type_e type, */ typedef void (*webrtc_media_packet_source_buffer_state_changed_cb)(unsigned int source_id, webrtc_media_packet_source_buffer_state_e state, void *user_data); + +/** + * @brief Called iteratively to report all the supported transceiver codecs. + * @since_tizen 7.0 + * @param[in] codec The supported codec + * @param[in] user_data The user data passed from the callback registration function + * @return @c true to continue with the next iteration of the loop, + * otherwise @c false to break out of the loop + * @see webrtc_media_source_foreach_supported_transceiver_codec() + */ +typedef bool (*webrtc_media_source_supported_transceiver_codec_cb)(webrtc_transceiver_codec_e codec, void *user_data); + /** * @} */ @@ -1076,6 +1101,25 @@ int webrtc_media_source_set_transceiver_direction(webrtc_h webrtc, unsigned int */ int webrtc_media_source_get_transceiver_direction(webrtc_h webrtc, unsigned int source_id, webrtc_media_type_e media_type, webrtc_transceiver_direction_e *direction); +/** + * @brief Retrieves all the supported transceiver codecs. + * @since_tizen 7.0 + * @remarks If @a source_id is a media source of #WEBRTC_MEDIA_SOURCE_TYPE_FILE or #WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET, + * this function will return #WEBRTC_ERROR_INVALID_PARAMETER. + * @param[in] webrtc WebRTC handle + * @param[in] source_id The media source id + * @param[in] media_type The media type + * @param[in] callback Callback function pointer + * @param[in] user_data The user data to be passed to the callback function + * @return @c 0 on success, + * otherwise a negative error value + * @retval #WEBRTC_ERROR_NONE Successful + * @retval #WEBRTC_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #WEBRTC_ERROR_INVALID_OPERATION Invalid operation + * @see webrtc_media_source_supported_transceiver_codec_cb() + */ +int webrtc_media_source_foreach_supported_transceiver_codec(webrtc_h webrtc, unsigned int source_id, webrtc_media_type_e media_type, webrtc_media_source_supported_transceiver_codec_cb callback, void *user_data); + /** * @brief Sets pause to the media source. * @since_tizen 6.5 diff --git a/include/webrtc_private.h b/include/webrtc_private.h index 7a487940..a5218900 100644 --- a/include/webrtc_private.h +++ b/include/webrtc_private.h @@ -624,6 +624,7 @@ int _set_transceiver_direction(webrtc_s *webrtc, unsigned int source_id, webrtc_ int _get_transceiver_direction(webrtc_s *webrtc, unsigned int source_id, webrtc_media_type_e media_type, webrtc_transceiver_direction_e *direction); direction_info_s *_convert_transceiver_direction(webrtc_transceiver_direction_e direction); 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); 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/packaging/capi-media-webrtc.spec b/packaging/capi-media-webrtc.spec index d1b00ba1..169d3845 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.126 +Version: 0.3.127 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/webrtc.c b/src/webrtc.c index e4161cb1..2d6189d0 100644 --- a/src/webrtc.c +++ b/src/webrtc.c @@ -342,6 +342,19 @@ int webrtc_media_source_get_transceiver_direction(webrtc_h webrtc, unsigned int return _get_transceiver_direction(webrtc, source_id, media_type, direction); } +int webrtc_media_source_foreach_supported_transceiver_codec(webrtc_h webrtc, unsigned int source_id, webrtc_media_type_e media_type, webrtc_media_source_supported_transceiver_codec_cb callback, void *user_data) +{ + g_autoptr(GMutexLocker) locker = NULL; + webrtc_s *_webrtc = (webrtc_s *)webrtc; + + RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL"); + RET_VAL_IF(callback == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "callback is NULL"); + + locker = g_mutex_locker_new(&_webrtc->mutex); + + return _foreach_supported_transceiver_codec(_webrtc, source_id, media_type, callback, user_data); +} + int webrtc_media_source_set_pause(webrtc_h webrtc, unsigned int source_id, webrtc_media_type_e media_type, bool pause) { g_autoptr(GMutexLocker) locker = NULL; diff --git a/src/webrtc_source.c b/src/webrtc_source.c index c4cef647..8a1a53a4 100644 --- a/src/webrtc_source.c +++ b/src/webrtc_source.c @@ -2990,6 +2990,105 @@ int _get_transceiver_direction(webrtc_s *webrtc, unsigned int source_id, webrtc_ return WEBRTC_ERROR_NONE; } +static int __convert_audio_codec(const char *codec_name, webrtc_transceiver_codec_e *codec) +{ + RET_VAL_IF(codec_name == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "codec_name is NULL"); + RET_VAL_IF(codec == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "codec is NULL"); + + if (!strcmp(codec_name, "pcmu") || !strcmp(codec_name, "PCMU")) { + *codec = WEBRTC_TRANSCEIVER_CODEC_PCMU; + return WEBRTC_ERROR_NONE; + } + if (!strcmp(codec_name, "pcma") || !strcmp(codec_name, "PCMA")) { + *codec = WEBRTC_TRANSCEIVER_CODEC_PCMA; + return WEBRTC_ERROR_NONE; + } + if (!strcmp(codec_name, "opus") || !strcmp(codec_name, "OPUS")) { + *codec = WEBRTC_TRANSCEIVER_CODEC_OPUS; + return WEBRTC_ERROR_NONE; + } + + LOG_ERROR("not supported audio codec_name[%s]", codec_name); + + return WEBRTC_ERROR_INVALID_PARAMETER; +} + +static int __convert_video_codec(const char *codec_name, webrtc_transceiver_codec_e *codec) +{ + RET_VAL_IF(codec_name == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "codec_name is NULL"); + RET_VAL_IF(codec == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "codec is NULL"); + + if (!strcmp(codec_name, "vp8") || !strcmp(codec_name, "VP8")) { + *codec = WEBRTC_TRANSCEIVER_CODEC_VP8; + return WEBRTC_ERROR_NONE; + } + if (!strcmp(codec_name, "vp9") || !strcmp(codec_name, "VP9")) { + *codec = WEBRTC_TRANSCEIVER_CODEC_VP9; + return WEBRTC_ERROR_NONE; + } + if (!strcmp(codec_name, "h264") || !strcmp(codec_name, "H264")) { + *codec = WEBRTC_TRANSCEIVER_CODEC_H264; + return WEBRTC_ERROR_NONE; + } + + LOG_ERROR("not supported video codec_name[%s]", codec_name); + + return WEBRTC_ERROR_INVALID_PARAMETER; +} + +typedef int (*convert_codec_func)(const char *codec_name, webrtc_transceiver_codec_e *codec); + +static convert_codec_func convert_codec_funcs[] = { + [WEBRTC_MEDIA_TYPE_AUDIO] = __convert_audio_codec, + [WEBRTC_MEDIA_TYPE_VIDEO] = __convert_video_codec, +}; + +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) +{ + int ret; + webrtc_gst_slot_s *source; + const ini_item_media_source_s *ini_source; + webrtc_transceiver_codec_e codec; + GStrv codecs; + guint i; + + RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL"); + RET_VAL_IF(callback == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "callback is NULL"); + RET_VAL_IF(webrtc->gst.webrtcbin == NULL, WEBRTC_ERROR_INVALID_OPERATION, "webrtcbin is NULL"); + RET_VAL_IF(webrtc->gst.source_slots == NULL, WEBRTC_ERROR_INVALID_OPERATION, "source_slots is NULL"); + RET_VAL_IF((source = _get_slot_by_id(webrtc->gst.source_slots, source_id)) == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL"); + RET_VAL_IF((source->type == WEBRTC_MEDIA_SOURCE_TYPE_FILE), WEBRTC_ERROR_INVALID_PARAMETER, "this API does not support the file source"); + RET_VAL_IF((source->type == WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET), WEBRTC_ERROR_INVALID_PARAMETER, "this API does not support the media packet source"); + + ini_source = _ini_get_source_by_type(&webrtc->ini, source->type); + RET_VAL_IF(ini_source == NULL, WEBRTC_ERROR_INVALID_OPERATION, "ini_source is NULL"); + + if (media_type == WEBRTC_MEDIA_TYPE_AUDIO && source->media_types & MEDIA_TYPE_AUDIO) { + codecs = ini_source->a_codecs; + + } else if (media_type == WEBRTC_MEDIA_TYPE_VIDEO && source->media_types & MEDIA_TYPE_VIDEO) { + codecs = ini_source->v_codecs; + + } else { + LOG_ERROR("invalid media_type[%d] for source[media_types:0x%x, id:%u]", media_type, source->media_types, source_id); + return WEBRTC_ERROR_INVALID_PARAMETER; + } + + LOG_INFO("webrtc[%p] source_id[%u] media_type[%d] callback[%p] user_data[%p]", webrtc, source_id, media_type, callback, user_data); + + for (i = 0; i < g_strv_length(codecs); i++) { + if ((ret = convert_codec_funcs[media_type](codecs[i], &codec)) != WEBRTC_ERROR_NONE) + return ret; + LOG_INFO(" - supported %s codec: %s", media_type == WEBRTC_MEDIA_TYPE_AUDIO ? "audio" : "video", codecs[i]); + if (!callback(codec, user_data)) { + LOG_DEBUG("stop foreach callback"); + break; + } + } + + return WEBRTC_ERROR_NONE; +} + int _set_pause(webrtc_s *webrtc, unsigned int source_id, webrtc_media_type_e media_type, bool pause) { webrtc_gst_slot_s *source;