Add new audio/video loopback unset APIs 58/265158/10 submit/tizen/20211117.074556
authorbackto.kim <backto.kim@samsung.com>
Tue, 12 Oct 2021 06:25:01 +0000 (15:25 +0900)
committerbackto.kim <backto.kim@samsung.com>
Wed, 17 Nov 2021 07:18:48 +0000 (16:18 +0900)
Functions are added as below.
 - webrtc_media_source_unset_audio_loopback()
 - webrtc_media_source_unset_video_loopback()

[Version] 0.3.9
[Issue Type] API

Change-Id: I78612a39367a56891bed8c7d6c6fa6aeae007098

include/webrtc.h
include/webrtc_private.h
packaging/capi-media-webrtc.spec
src/webrtc.c
src/webrtc_source.c
test/webrtc_test.c

index 72df47e5db9ddf0ea81c938ebf400b4afc05a47b..400d19e5ed805362b10578e23e0a3f518a19b15a 100644 (file)
@@ -1269,6 +1269,21 @@ int webrtc_unset_encoded_video_frame_cb(webrtc_h webrtc);
  */
 int webrtc_media_source_set_audio_loopback(webrtc_h webrtc, unsigned int source_id, sound_stream_info_h stream_info, unsigned int *track_id);
 
+/**
+ * @brief Unsets the audio loopback.
+ * @since_tizen 7.0
+ * @param[in] webrtc      WebRTC handle
+ * @param[in] source_id   The audio source id
+ * @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_audio_loopback()
+ */
+int webrtc_media_source_unset_audio_loopback(webrtc_h webrtc, unsigned int source_id);
+
 /**
  * @brief Sets a video loopback to render the video frames of the media source.
  * @details The following media source types are available for this function:\n
@@ -1296,6 +1311,21 @@ int webrtc_media_source_set_audio_loopback(webrtc_h webrtc, unsigned int source_
  */
 int webrtc_media_source_set_video_loopback(webrtc_h webrtc, unsigned int source_id, webrtc_display_type_e type, webrtc_display_h display, unsigned int *track_id);
 
+/**
+ * @brief Unsets the video loopback.
+ * @since_tizen 7.0
+ * @param[in] webrtc      WebRTC handle
+ * @param[in] source_id   The video source id
+ * @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_video_loopback()
+ */
+int webrtc_media_source_unset_video_loopback(webrtc_h webrtc, unsigned int source_id);
+
 /**
  * @}
  */
index 3a4343b7bbf4c83b22a9f1f36489dafac8fc26a8..76d67afe9244c20b824deb4bf67ad3a1dd21918c 100644 (file)
@@ -612,7 +612,9 @@ int _get_display_visible_from_sink(webrtc_s *webrtc, unsigned int track_id, bool
 int _set_display_visible_to_loopback(webrtc_s *webrtc, unsigned int track_id, bool visible);
 int _get_display_visible_from_loopback(webrtc_s *webrtc, unsigned int track_id, bool *visible);
 int _set_audio_loopback(webrtc_s *webrtc, unsigned int source_id, sound_stream_info_h stream_info, unsigned int *track_id);
+int _unset_audio_loopback(webrtc_s *webrtc, unsigned int source_id);
 int _set_video_loopback(webrtc_s *webrtc, unsigned int source_id, unsigned int type, void *display, unsigned int *track_id);
+int _unset_video_loopback(webrtc_s *webrtc, unsigned int source_id);
 int _decodebin_autoplug_select_cb(GstElement *decodebin, GstPad *pad, GstCaps *caps, GstElementFactory *factory, gpointer user_data);
 bool _is_owner_of_track_build_context(webrtc_s *webrtc, unsigned int track_id);
 void _track_build_context_destroy_cb(gpointer data);
index fdacaa48fed3621f4c050c0fee67c4e30dee8cc8..6c37f8155dc5e77ce298ab329f15832a59355c5a 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-media-webrtc
 Summary:    A WebRTC library in Tizen Native API
-Version:    0.3.8
+Version:    0.3.9
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
index 540d9f2fb66aa167091827f3f86bd82083b9fb0f..745671da7140ab1e837a96478e3d2ee0f6c246c0 100644 (file)
@@ -822,6 +822,23 @@ int webrtc_media_source_set_audio_loopback(webrtc_h webrtc, unsigned int source_
        return ret;
 }
 
+int webrtc_media_source_unset_audio_loopback(webrtc_h webrtc, unsigned int source_id)
+{
+       int ret = WEBRTC_ERROR_NONE;
+       webrtc_s *_webrtc = (webrtc_s*)webrtc;
+
+       RET_VAL_IF(_webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
+       RET_VAL_IF(source_id == 0, WEBRTC_ERROR_INVALID_PARAMETER, "source_id is 0");
+
+       g_mutex_lock(&_webrtc->mutex);
+
+       ret = _unset_audio_loopback(webrtc, source_id);
+
+       g_mutex_unlock(&_webrtc->mutex);
+
+       return ret;
+}
+
 int webrtc_media_source_set_video_loopback(webrtc_h webrtc, unsigned int source_id, webrtc_display_type_e type, webrtc_display_h display, unsigned int *track_id)
 {
        int ret = WEBRTC_ERROR_NONE;
@@ -841,6 +858,23 @@ int webrtc_media_source_set_video_loopback(webrtc_h webrtc, unsigned int source_
        return ret;
 }
 
+int webrtc_media_source_unset_video_loopback(webrtc_h webrtc, unsigned int source_id)
+{
+       int ret = WEBRTC_ERROR_NONE;
+       webrtc_s *_webrtc = (webrtc_s*)webrtc;
+
+       RET_VAL_IF(_webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
+       RET_VAL_IF(source_id == 0, WEBRTC_ERROR_INVALID_PARAMETER, "source_id is 0");
+
+       g_mutex_lock(&_webrtc->mutex);
+
+       ret = _unset_video_loopback(webrtc, source_id);
+
+       g_mutex_unlock(&_webrtc->mutex);
+
+       return ret;
+}
+
 int webrtc_set_stun_server(webrtc_h webrtc, const char *stun_server)
 {
        g_autoptr(GMutexLocker) locker = NULL;
index ad0baa1fa9646046c416154dccb1a3049af93c02..090be71303e148779f8fe5f5eaf1897ccb0fcf27 100644 (file)
@@ -4154,6 +4154,34 @@ int _set_audio_loopback(webrtc_s *webrtc, unsigned int source_id, sound_stream_i
        return __build_loopback_render_pipeline(webrtc, source, MEDIA_TYPE_AUDIO, track_id);
 }
 
+int _unset_audio_loopback(webrtc_s *webrtc, unsigned int source_id)
+{
+       webrtc_gst_slot_s *source = NULL;
+
+       RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
+       RET_VAL_IF(source_id == 0, WEBRTC_ERROR_INVALID_PARAMETER, "source_id is 0");
+
+       RET_VAL_IF((source = _get_slot_by_id(webrtc->gst.source_slots, source_id)) == NULL,
+               WEBRTC_ERROR_INVALID_PARAMETER, "could not find source");
+       RET_VAL_IF((source->media_types & MEDIA_TYPE_AUDIO) == 0x0, WEBRTC_ERROR_INVALID_PARAMETER,
+               "invalid media_type for source[media_types:0x%x, id:%u]", source->media_types, source_id);
+       RET_VAL_IF((source->type == WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET), WEBRTC_ERROR_INVALID_PARAMETER,
+               "this API does not support the media packet source");
+       RET_VAL_IF(!source->av[AV_IDX_AUDIO].render.pipeline, WEBRTC_ERROR_INVALID_OPERATION, "audio loopback was not set");
+
+       LOG_INFO("source_id[%u]", source_id);
+
+       if (source->sound_stream_info.type) {
+               free(source->sound_stream_info.type);
+               source->sound_stream_info.type = NULL;
+       }
+
+       gst_element_set_state(source->av[AV_IDX_AUDIO].render.pipeline, GST_STATE_NULL);
+       SAFE_GST_OBJECT_UNREF(source->av[AV_IDX_AUDIO].render.pipeline);
+
+       return WEBRTC_ERROR_NONE;
+}
+
 int _set_video_loopback(webrtc_s *webrtc, unsigned int source_id, unsigned int type, void *display, unsigned int *track_id)
 {
        int ret = WEBRTC_ERROR_NONE;
@@ -4195,6 +4223,34 @@ error:
        return ret;
 }
 
+int _unset_video_loopback(webrtc_s *webrtc, unsigned int source_id)
+{
+       webrtc_gst_slot_s *source = NULL;
+
+       RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
+       RET_VAL_IF(source_id == 0, WEBRTC_ERROR_INVALID_PARAMETER, "source_id is 0");
+
+       RET_VAL_IF((source = _get_slot_by_id(webrtc->gst.source_slots, source_id)) == NULL,
+               WEBRTC_ERROR_INVALID_PARAMETER, "could not find source");
+       RET_VAL_IF((source->media_types & MEDIA_TYPE_VIDEO) == 0x0, WEBRTC_ERROR_INVALID_PARAMETER,
+               "invalid media_type for source[media_types:0x%x, id:%u]", source->media_types, source_id);
+       RET_VAL_IF((source->type == WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET), WEBRTC_ERROR_INVALID_PARAMETER,
+               "this API does not support the media packet source");
+       RET_VAL_IF(!source->av[AV_IDX_VIDEO].render.pipeline, WEBRTC_ERROR_INVALID_OPERATION, "video loopback was not set");
+
+       LOG_INFO("source_id[%u]", source_id);
+
+       if (source->display) {
+               _release_display(source->display);
+               source->display = NULL;
+       }
+
+       gst_element_set_state(source->av[AV_IDX_VIDEO].render.pipeline, GST_STATE_NULL);
+       SAFE_GST_OBJECT_UNREF(source->av[AV_IDX_VIDEO].render.pipeline);
+
+       return WEBRTC_ERROR_NONE;
+}
+
 int _set_display_mode_to_loopback(webrtc_s *webrtc, unsigned int track_id, webrtc_display_mode_e mode)
 {
        webrtc_gst_slot_s *source;
index b971fb92d17bb1ed83814e68b1d1311386ba8118..ded8de3e89adc7c04c7812e04f86fa942313ada2 100644 (file)
@@ -80,7 +80,9 @@ enum {
        CURRENT_STATUS_SET_DISPLAY_VISIBLE,
        CURRENT_STATUS_GET_DISPLAY_VISIBLE,
        CURRENT_STATUS_MEDIA_SOURCE_SET_AUDIO_LOOPBACK,
+       CURRENT_STATUS_MEDIA_SOURCE_UNSET_AUDIO_LOOPBACK,
        CURRENT_STATUS_MEDIA_SOURCE_SET_VIDEO_LOOPBACK,
+       CURRENT_STATUS_MEDIA_SOURCE_UNSET_VIDEO_LOOPBACK,
        CURRENT_STATUS_DATA_CHANNEL_SEND_STRING,
        CURRENT_STATUS_DATA_CHANNEL_SEND_STRING_AS_BYTES,
        CURRENT_STATUS_DATA_CHANNEL_SEND_FILE,
@@ -449,6 +451,11 @@ static int app_terminate(void *data)
                }
        }
 
+       if (g_eo_mine) {
+               evas_object_del(g_eo_mine);
+               g_eo_mine = NULL;
+       }
+
        if (g_win_id) {
                evas_object_del(g_win_id);
                g_win_id = NULL;
@@ -1044,6 +1051,16 @@ static void _webrtc_media_source_set_audio_loopback(int index, unsigned int sour
        g_print("webrtc_media_source_set_audio_loopback() success, source_id[%u] track_id[%u]\n", source_id, track_id);
 }
 
+static void _webrtc_media_source_unset_audio_loopback(int index, unsigned int source_id)
+{
+       int ret = WEBRTC_ERROR_NONE;
+
+       ret = webrtc_media_source_unset_audio_loopback(g_conns[index].webrtc, source_id);
+       RET_IF(ret != WEBRTC_ERROR_NONE, "ret[0x%x]", ret);
+
+       g_print("webrtc_media_source_unset_audio_loopback() success, source_id[%u]\n", source_id);
+}
+
 static void _webrtc_media_source_set_video_loopback(int index, unsigned int source_id)
 {
        int ret = WEBRTC_ERROR_NONE;
@@ -1056,6 +1073,18 @@ static void _webrtc_media_source_set_video_loopback(int index, unsigned int sour
        g_conns[index].render.loopback_track_id = track_id;
 }
 
+static void _webrtc_media_source_unset_video_loopback(int index, unsigned int source_id)
+{
+       int ret = WEBRTC_ERROR_NONE;
+
+       ret = webrtc_media_source_unset_video_loopback(g_conns[index].webrtc, source_id);
+       RET_IF(ret != WEBRTC_ERROR_NONE, "ret[0x%x]", ret);
+
+       evas_object_hide(g_eo_mine);
+
+       g_print("webrtc_media_source_unset_video_loopback() success, source_id[%u]\n", source_id);
+}
+
 static int __copy_string_arr(gchar *dest_arr, char *string)
 {
        int len = 0;
@@ -3972,7 +4001,13 @@ void _interpret_main_menu(char *cmd)
                }
 
        } else if (len == 3) {
-               if (strncmp(cmd, "sac", 3) == 0) {
+               if (strncmp(cmd, "ual", 3) == 0) {
+                       g_menu_state = CURRENT_STATUS_MEDIA_SOURCE_UNSET_AUDIO_LOOPBACK;
+
+               } else if (strncmp(cmd, "uvl", 3) == 0) {
+                       g_menu_state = CURRENT_STATUS_MEDIA_SOURCE_UNSET_VIDEO_LOOPBACK;
+
+               } else if (strncmp(cmd, "sac", 3) == 0) {
                        int i;
 
                        _webrtc_set_error_cb(0);
@@ -4139,7 +4174,9 @@ void display_sub_basic()
        g_print("dv. Set display visible\t");
        g_print("gv. Get display visible\n");
        g_print("al. Set audio loopback\t");
-       g_print("vl. Set video loopback\n");
+       g_print("ual. Unset audio loopback\n");
+       g_print("vl. Set video loopback\t");
+       g_print("uvl. Unset video loopback\n");
        g_print("------------------------------------- Data Channel --------------------------------------\n");
        g_print("cd. Create data channel\t");
        g_print("dd. Destroy data channel\n");
@@ -4291,9 +4328,15 @@ static void displaymenu()
        } else if (g_menu_state == CURRENT_STATUS_MEDIA_SOURCE_SET_AUDIO_LOOPBACK) {
                g_print("*** input source id.\n");
 
+       } else if (g_menu_state == CURRENT_STATUS_MEDIA_SOURCE_UNSET_AUDIO_LOOPBACK) {
+               g_print("*** input source id.\n");
+
        } else if (g_menu_state == CURRENT_STATUS_MEDIA_SOURCE_SET_VIDEO_LOOPBACK) {
                g_print("*** input source id.\n");
 
+       } else if (g_menu_state == CURRENT_STATUS_MEDIA_SOURCE_UNSET_VIDEO_LOOPBACK) {
+               g_print("*** input source id.\n");
+
        } else if (g_menu_state == CURRENT_STATUS_MEDIA_SOURCE_SET_FILE_LOOPING) {
                if (g_cnt == 0)
                        g_print("*** input source id.\n");
@@ -4654,12 +4697,24 @@ static void interpret(char *cmd)
                reset_menu_state();
                break;
        }
+       case CURRENT_STATUS_MEDIA_SOURCE_UNSET_AUDIO_LOOPBACK: {
+               value = atoi(cmd);
+               _webrtc_media_source_unset_audio_loopback(0, value);
+               reset_menu_state();
+               break;
+       }
        case CURRENT_STATUS_MEDIA_SOURCE_SET_VIDEO_LOOPBACK: {
                value = atoi(cmd);
                _webrtc_media_source_set_video_loopback(0, value);
                reset_menu_state();
                break;
        }
+       case CURRENT_STATUS_MEDIA_SOURCE_UNSET_VIDEO_LOOPBACK: {
+               value = atoi(cmd);
+               _webrtc_media_source_unset_video_loopback(0, value);
+               reset_menu_state();
+               break;
+       }
        case CURRENT_STATUS_DATA_CHANNEL_SEND_STRING: {
                _webrtc_data_channel_send_string(cmd, false);
                reset_menu_state();