Add API to get supported transceiver codecs 31/276131/6
authorSangchul Lee <sc11.lee@samsung.com>
Fri, 10 Jun 2022 03:20:29 +0000 (12:20 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Wed, 22 Jun 2022 03:33:05 +0000 (12:33 +0900)
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 <sc11.lee@samsung.com>
include/webrtc.h
include/webrtc_private.h
packaging/capi-media-webrtc.spec
src/webrtc.c
src/webrtc_source.c

index 9863fc341ccd6ef4746b07873279c956198a5941..3c4fe9d5a7cdf47332463305866192111e626f3b 100644 (file)
@@ -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
index 7a487940fc0d6a1d5cab0aeed597267dd6da7c62..a521890035e574ea3841504495edfb0c85b568b4 100644 (file)
@@ -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);
index d1b00ba180103aa07925a1ee47648cb332c7e14e..169d3845182c33ea0c7d9e9f883ad28983d3f577 100644 (file)
@@ -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
index e4161cb14739e3be637754f967c616f740f32e6b..2d6189d07a0c326da3b2187425b24a5f39f3bb48 100644 (file)
@@ -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;
index c4cef647d1c79ead42a30f95308b8434ac74d8b4..8a1a53a4d0f1d0d76cacbc37cf9e8728c0a71a4a 100644 (file)
@@ -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;