Add API to set/get transceiver codec 18/275818/11
authorSangchul Lee <sc11.lee@samsung.com>
Thu, 2 Jun 2022 07:12:22 +0000 (16:12 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Wed, 22 Jun 2022 08:53:51 +0000 (17:53 +0900)
Functions are added as below.
 - webrtc_media_source_set_transceiver_codec()
 - webrtc_media_source_get_transceiver_codec()

[Version] 0.3.128
[Issue Type] API

Change-Id: Ieed7d8dedfc32036a45f2a6e7a242b0a0fc416c8
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 3c4fe9d5a7cdf47332463305866192111e626f3b..e614dcc3a4ddb681bb1e0e070b65e576a483ce1a 100644 (file)
@@ -1117,9 +1117,53 @@ int webrtc_media_source_get_transceiver_direction(webrtc_h webrtc, unsigned int
  * @retval #WEBRTC_ERROR_INVALID_PARAMETER Invalid parameter
  * @retval #WEBRTC_ERROR_INVALID_OPERATION Invalid operation
  * @see webrtc_media_source_supported_transceiver_codec_cb()
+ * @see webrtc_media_source_set_transceiver_codec()
+ * @see webrtc_media_source_get_transceiver_codec()
  */
 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 the transceiver codec to the media source.
+ * @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] codec       The transceiver codec to set
+ * @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
+ * @retval #WEBRTC_ERROR_INVALID_STATE Invalid state
+ * @pre Add media source to @a webrtc to get @a source_id by calling webrtc_add_media_source().
+ * @pre @a webrtc state must be set to #WEBRTC_STATE_IDLE.
+ * @see webrtc_media_source_get_transceiver_codec()
+ * @see webrtc_media_source_foreach_supported_transceiver_codec()
+ */
+int webrtc_media_source_set_transceiver_codec(webrtc_h webrtc, unsigned int source_id, webrtc_media_type_e media_type, webrtc_transceiver_codec_e codec);
+
+/**
+ * @brief Gets the transceiver codec of the media source.
+ * @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[out] codec      Current transceiver codec
+ * @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
+ * @pre Add media source to @a webrtc to get @a source_id by calling webrtc_add_media_source().
+ * @see webrtc_media_source_set_transceiver_codec()
+ * @see webrtc_media_source_foreach_supported_transceiver_codec()
+ */
+int webrtc_media_source_get_transceiver_codec(webrtc_h webrtc, unsigned int source_id, webrtc_media_type_e media_type, webrtc_transceiver_codec_e *codec);
+
 /**
  * @brief Sets pause to the media source.
  * @since_tizen 6.5
index a521890035e574ea3841504495edfb0c85b568b4..41013176a6205ebf9bd0d35ef523b17f662dda61 100644 (file)
@@ -243,6 +243,10 @@ do { \
 #define TRACK_ID_THRESHOLD_OF_LOOPBACK  100
 #define MAX_MLINE_NUM                   16
 
+/* See webrtc_transceiver_codec_e */
+#define CODEC_TYPE_AUDIO                0x00000100
+#define CODEC_TYPE_VIDEO                0x00000200
+
 /* NOTE : GstAutoplugSelectResult is defined in gstplay-enum.h but not exposed
  We are defining our own and will be removed when it actually exposed */
 typedef enum {
@@ -493,6 +497,7 @@ typedef struct _webrtc_gst_slot_s {
        struct {
                GstWebRTCRTPTransceiver *transceiver;
                webrtc_transceiver_direction_e direction;
+               const char *codec;
                GstPad *src_pad;
                gulong src_pad_probe_id;
                gchar *raw_format;
@@ -623,6 +628,8 @@ int _remove_media_source(webrtc_s *webrtc, unsigned int source_id);
 int _set_transceiver_direction(webrtc_s *webrtc, unsigned int source_id, webrtc_media_type_e media_type, webrtc_transceiver_direction_e direction);
 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);
+int _set_transceiver_codec(webrtc_s *webrtc, unsigned int source_id, webrtc_media_type_e media_type, webrtc_transceiver_codec_e codec);
+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);
 int _set_pause(webrtc_s *webrtc, unsigned int source_id, webrtc_media_type_e media_type, bool pause);
index 169d3845182c33ea0c7d9e9f883ad28983d3f577..22ee528f94bed93532436987ad81cb80331859cb 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-media-webrtc
 Summary:    A WebRTC library in Tizen Native API
-Version:    0.3.127
+Version:    0.3.128
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
index 2d6189d07a0c326da3b2187425b24a5f39f3bb48..72578730f7c01922ffa907632f95670f00c6cd72 100644 (file)
@@ -355,6 +355,33 @@ int webrtc_media_source_foreach_supported_transceiver_codec(webrtc_h webrtc, uns
        return _foreach_supported_transceiver_codec(_webrtc, source_id, media_type, callback, user_data);
 }
 
+int webrtc_media_source_set_transceiver_codec(webrtc_h webrtc, unsigned int source_id, webrtc_media_type_e media_type, webrtc_transceiver_codec_e codec)
+{
+       g_autoptr(GMutexLocker) locker = NULL;
+       webrtc_s *_webrtc = (webrtc_s *)webrtc;
+
+       RET_VAL_IF(_webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
+
+       locker = g_mutex_locker_new(&_webrtc->mutex);
+
+       RET_VAL_IF(_webrtc->state != WEBRTC_STATE_IDLE, WEBRTC_ERROR_INVALID_STATE, "the state should be IDLE");
+
+       return _set_transceiver_codec(webrtc, source_id, media_type, codec);
+}
+
+int webrtc_media_source_get_transceiver_codec(webrtc_h webrtc, unsigned int source_id, webrtc_media_type_e media_type, webrtc_transceiver_codec_e *codec)
+{
+       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(codec == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "codec is NULL");
+
+       locker = g_mutex_locker_new(&_webrtc->mutex);
+
+       return _get_transceiver_codec(webrtc, source_id, media_type, codec);
+}
+
 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 8a1a53a4d0f1d0d76cacbc37cf9e8728c0a71a4a..13598a5e466ecd5d5fcab05a2d2471933b79b55c 100644 (file)
@@ -96,6 +96,15 @@ static direction_info_s __direction_info[] = {
        [WEBRTC_TRANSCEIVER_DIRECTION_SENDRECV] = { "SENDRECV", GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_SENDRECV }
 };
 
+static const char *__codec_str[] = {
+       [WEBRTC_TRANSCEIVER_CODEC_PCMU] = "PCMU",
+       [WEBRTC_TRANSCEIVER_CODEC_PCMA] = "PCMA",
+       [WEBRTC_TRANSCEIVER_CODEC_OPUS] = "OPUS",
+       [WEBRTC_TRANSCEIVER_CODEC_VP8] = "VP8",
+       [WEBRTC_TRANSCEIVER_CODEC_VP9] = "VP9",
+       [WEBRTC_TRANSCEIVER_CODEC_H264] = "H264"
+};
+
 typedef struct {
        const char *appsrc_name;
        const char *queue_name;
@@ -517,7 +526,7 @@ static GstCaps *__make_default_encoded_caps(webrtc_gst_slot_s *source, webrtc_in
        case WEBRTC_MEDIA_SOURCE_TYPE_CAMERA:
        case WEBRTC_MEDIA_SOURCE_TYPE_SCREEN:
        case WEBRTC_MEDIA_SOURCE_TYPE_CUSTOM_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");
 
                source->video_info.width = source->video_info.width > 0 ? source->video_info.width : ini_source->v_width;
@@ -530,8 +539,9 @@ static GstCaps *__make_default_encoded_caps(webrtc_gst_slot_s *source, webrtc_in
        case WEBRTC_MEDIA_SOURCE_TYPE_AUDIOTEST:
        case WEBRTC_MEDIA_SOURCE_TYPE_MIC:
        case WEBRTC_MEDIA_SOURCE_TYPE_CUSTOM_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);
                break;
 
@@ -1347,6 +1357,7 @@ static int __build_screensrc(webrtc_s *webrtc, webrtc_gst_slot_s *source)
        source->media_types = MEDIA_TYPE_VIDEO;
        source->zerocopy_enabled = __is_hw_encoder_used(webrtc, source->type, source->media_types);
        source->av[AV_IDX_VIDEO].raw_format = g_strdup(ini_source->v_raw_format);
+       source->av[AV_IDX_VIDEO].codec = ini_source->v_codecs[0];
 
        if (!(screensrc = _create_element(__get_source_element(webrtc, WEBRTC_MEDIA_SOURCE_TYPE_SCREEN), ELEMENT_NAME_SCREENSRC)))
                return WEBRTC_ERROR_INVALID_OPERATION;
@@ -1575,6 +1586,7 @@ static int __build_camerasrc(webrtc_s *webrtc, webrtc_gst_slot_s *source)
        source->media_types = MEDIA_TYPE_VIDEO;
        source->zerocopy_enabled = __is_hw_encoder_used(webrtc, source->type, source->media_types);
        source->av[AV_IDX_VIDEO].raw_format = g_strdup(ini_source->v_raw_format);
+       source->av[AV_IDX_VIDEO].codec = ini_source->v_codecs[0];
 
 #ifndef TIZEN_TV
        if (webrtc->ini.resource_acquisition.camera)
@@ -1723,6 +1735,7 @@ static int __build_audiosrc(webrtc_s *webrtc, webrtc_gst_slot_s *source, bool us
        source->media_types = MEDIA_TYPE_AUDIO;
        source->zerocopy_enabled = __is_hw_encoder_used(webrtc, source->type, source->media_types);
        source->av[AV_IDX_AUDIO].raw_format = g_strdup(ini_source->a_raw_format);
+       source->av[AV_IDX_AUDIO].codec = ini_source->a_codecs[0];
 
        source_factory_name = __get_source_element(webrtc, use_mic ? WEBRTC_MEDIA_SOURCE_TYPE_MIC : WEBRTC_MEDIA_SOURCE_TYPE_AUDIOTEST);
        if (!(audiosrc = _create_element(source_factory_name, use_mic ? ELEMENT_NAME_MIC_SRC : ELEMENT_NAME_AUDIO_SRC)))
@@ -1760,6 +1773,7 @@ static int __build_videotestsrc(webrtc_s *webrtc, webrtc_gst_slot_s *source)
        source->media_types = MEDIA_TYPE_VIDEO;
        source->zerocopy_enabled = __is_hw_encoder_used(webrtc, source->type, source->media_types);
        source->av[AV_IDX_VIDEO].raw_format = g_strdup(ini_source->v_raw_format);
+       source->av[AV_IDX_VIDEO].codec = ini_source->v_codecs[0];
 
        if (!(videotestsrc = _create_element(__get_source_element(webrtc, WEBRTC_MEDIA_SOURCE_TYPE_VIDEOTEST), ELEMENT_NAME_VIDEO_SRC)))
                return WEBRTC_ERROR_INVALID_OPERATION;
@@ -1796,6 +1810,7 @@ static int __build_custom_videosrc(webrtc_s *webrtc, webrtc_gst_slot_s *source)
 
        source->media_types = MEDIA_TYPE_VIDEO;
        source->zerocopy_enabled = __is_hw_encoder_used(webrtc, source->type, source->media_types);
+       source->av[AV_IDX_VIDEO].codec = ini_source->v_codecs[0];
 
        if (!(custom_videosrc = _create_element(__get_source_element(webrtc, WEBRTC_MEDIA_SOURCE_TYPE_CUSTOM_VIDEO), ELEMENT_NAME_VIDEO_SRC)))
                return WEBRTC_ERROR_INVALID_OPERATION;
@@ -1832,6 +1847,7 @@ static int __build_custom_audiosrc(webrtc_s *webrtc, webrtc_gst_slot_s *source)
 
        source->media_types = MEDIA_TYPE_AUDIO;
        source->zerocopy_enabled = __is_hw_encoder_used(webrtc, source->type, source->media_types);
+       source->av[AV_IDX_AUDIO].codec = ini_source->a_codecs[0];
 
        source_factory_name = __get_source_element(webrtc, WEBRTC_MEDIA_SOURCE_TYPE_CUSTOM_AUDIO);
        if (!(custom_audiosrc = _create_element(source_factory_name, NULL)))
@@ -2973,6 +2989,12 @@ int _get_transceiver_direction(webrtc_s *webrtc, unsigned int source_id, webrtc_
        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");
 
+       if (source->type == WEBRTC_MEDIA_SOURCE_TYPE_FILE ||
+               source->type == WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET) {
+               LOG_ERROR("invalid type(%d)", source->type);
+               return WEBRTC_ERROR_INVALID_PARAMETER;
+       }
+
        if (media_type == WEBRTC_MEDIA_TYPE_AUDIO && source->media_types & MEDIA_TYPE_AUDIO) {
                *direction = source->av[AV_IDX_AUDIO].direction;
 
@@ -3089,6 +3111,107 @@ int _foreach_supported_transceiver_codec(webrtc_s *webrtc, unsigned int source_i
        return WEBRTC_ERROR_NONE;
 }
 
+static int __validate_codec(webrtc_s *webrtc, webrtc_gst_slot_s *source, webrtc_media_type_e media_type, webrtc_transceiver_codec_e codec)
+{
+       int ret;
+       const ini_item_media_source_s *ini_source;
+       GStrv codecs;
+       webrtc_transceiver_codec_e _codec;
+       guint i;
+
+       RET_VAL_IF(webrtc == NULL, FALSE, "webrtc is NULL");
+       RET_VAL_IF(source == NULL, FALSE, "source is NULL");
+
+       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 &&
+               codec & CODEC_TYPE_AUDIO) {
+               codecs = ini_source->a_codecs;
+
+       } else if (media_type == WEBRTC_MEDIA_TYPE_VIDEO &&
+               source->media_types & MEDIA_TYPE_VIDEO &&
+               codec & CODEC_TYPE_VIDEO) {
+               codecs = ini_source->v_codecs;
+
+       } else {
+               LOG_ERROR("invalid media_type[%d], codec[0x%x] for source[media_types:0x%x, id:%u]",
+                       media_type, codec, source->media_types, source->id);
+               return WEBRTC_ERROR_INVALID_PARAMETER;
+       }
+
+       for (i = 0; i < g_strv_length(codecs); i++) {
+               if ((ret = convert_codec_funcs[media_type](codecs[i], &_codec)) != WEBRTC_ERROR_NONE)
+                       return ret;
+               if (_codec == codec) {
+                       LOG_DEBUG("codec[0x%x] is supported", codec);
+                       return WEBRTC_ERROR_NONE;
+               }
+       }
+
+       LOG_ERROR("webrtc[%p] codec[0x%x] is not supported for this source type[%d]", webrtc, codec, source->type);
+
+       return WEBRTC_ERROR_INVALID_PARAMETER;
+}
+
+int _set_transceiver_codec(webrtc_s *webrtc, unsigned int source_id, webrtc_media_type_e media_type, webrtc_transceiver_codec_e codec)
+{
+       int ret;
+       webrtc_gst_slot_s *source;
+
+       RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc 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");
+
+       if ((ret = __validate_codec(webrtc, source, media_type, codec)) != WEBRTC_ERROR_NONE)
+               return ret;
+
+       source->av[GET_AV_IDX_BY_TYPE(source->media_types)].codec = __codec_str[codec];
+
+       /* FIXME: to utilize 'codec-preferences' of trans object, we need to re-create and re-link elements again */
+       LOG_INFO("webrtc[%p] source_id[%u] media_type[%d] codec[%s]", webrtc, source_id, media_type, __codec_str[codec]);
+
+       return WEBRTC_ERROR_NONE;
+}
+
+int _get_transceiver_codec(webrtc_s *webrtc, unsigned int source_id, webrtc_media_type_e media_type, webrtc_transceiver_codec_e *codec)
+{
+       int ret;
+       webrtc_gst_slot_s *source;
+       const char *codec_str;
+       webrtc_transceiver_codec_e _codec;
+
+       RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
+       RET_VAL_IF(codec == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "codec 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");
+
+       if (media_type == WEBRTC_MEDIA_TYPE_AUDIO && source->media_types & MEDIA_TYPE_AUDIO) {
+               codec_str = source->av[AV_IDX_AUDIO].codec;
+
+       } else if (media_type == WEBRTC_MEDIA_TYPE_VIDEO && source->media_types & MEDIA_TYPE_VIDEO) {
+               codec_str = source->av[AV_IDX_VIDEO].codec;
+
+       } 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;
+       }
+
+       if ((ret = convert_codec_funcs[media_type](codec_str, &_codec)) != WEBRTC_ERROR_NONE)
+               return ret;
+
+       *codec = _codec;
+
+       LOG_INFO("webrtc[%p] source_id[%u] media_type[%d] codec[%s]", webrtc, source_id, media_type, codec_str);
+
+       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;
@@ -3953,7 +4076,7 @@ static int __validate_video_source_for_mute(webrtc_s *webrtc, unsigned int sourc
        if (_source->type != WEBRTC_MEDIA_SOURCE_TYPE_VIDEOTEST &&
                _source->type != WEBRTC_MEDIA_SOURCE_TYPE_CAMERA &&
                _source->type != WEBRTC_MEDIA_SOURCE_TYPE_SCREEN) {
-               LOG_ERROR_IF_REACHED("type(%d)", _source->type);
+               LOG_ERROR("invalid type(%d)", _source->type);
                return WEBRTC_ERROR_INVALID_PARAMETER;
        }
 
@@ -4002,7 +4125,7 @@ static int __validate_audio_source_for_mute(webrtc_s *webrtc, unsigned int sourc
 
        if (_source->type != WEBRTC_MEDIA_SOURCE_TYPE_AUDIOTEST &&
                _source->type != WEBRTC_MEDIA_SOURCE_TYPE_MIC) {
-               LOG_ERROR_IF_REACHED("type(%d)", _source->type);
+               LOG_ERROR("invalid type(%d)", _source->type);
                return WEBRTC_ERROR_INVALID_PARAMETER;
        }