Add API to set sound stream info. to the MIC source 14/260714/8
authorSangchul Lee <sc11.lee@samsung.com>
Thu, 1 Jul 2021 12:04:51 +0000 (21:04 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Mon, 5 Jul 2021 05:14:32 +0000 (14:14 +0900)
webrtc_mic_source_set_sound_stream_info() is added.

For example, audio device(e.g. USB) can be set by the stream info
handle of capi-media-sound-manager. By passing this handle to the
new function, the MIC source will be read data from the device.

[Version] 0.2.29
[Issue Type] API

Change-Id: I0027109ae5ee3b546e40aadef1740551ad6a2e40
Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
CMakeLists.txt
include/webrtc.h
include/webrtc_private.h
packaging/capi-media-webrtc.spec
src/webrtc.c
src/webrtc_source.c
test/webrtc_test.c

index 514ed676a43fd1002be89ceaa9a348e75fbc133f..951af7f7c870bd718187f83e2a884bb0e57946c8 100644 (file)
@@ -13,7 +13,7 @@ INCLUDE_DIRECTORIES(${INC_DIR})
 
 SET(dependents "dlog glib-2.0 gstreamer-1.0 gstreamer-webrtc-1.0 gstreamer-video-1.0 gstreamer-audio-1.0 \
                 gstreamer-allocators-1.0 json-glib-1.0 iniparser mm-common mm-display-interface capi-media-tool \
-                libtbm libwebsockets cynara-client libsmack capi-system-info libsoup-2.4 bundle")
+                libtbm libwebsockets cynara-client libsmack capi-system-info libsoup-2.4 bundle capi-media-sound-manager")
 IF(NOT TIZEN_PROFILE_TV)
     SET(dependents "${dependents} mm-resource-manager")
 ELSE()
index 7bb769e3305327c3aef09d265398ce1c9eead72b..83b308135c3cb8efecb08c22409a71b1e6add38a 100644 (file)
@@ -20,6 +20,7 @@
 #include <tizen.h>
 #include <media_format.h>
 #include <media_packet.h>
+#include <sound_manager.h>
 #include <bundle.h>
 
 #ifdef __cplusplus
@@ -788,7 +789,7 @@ int webrtc_media_source_set_mute(webrtc_h webrtc, unsigned int source_id, webrtc
 
  /**
  * @brief Gets the mute of the media source.
- * @details if @a source_id is a media source of #WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET, this function will return #WEBRTC_ERROR_INVALID_PARAMETER.
+ * @details If @a source_id is a media source of #WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET, this function will return #WEBRTC_ERROR_INVALID_PARAMETER.
  * @since_tizen 6.5
  * @remarks The default value is @c false.
  * @param[in] webrtc      WebRTC handle
@@ -848,6 +849,32 @@ int webrtc_media_source_set_video_resolution(webrtc_h webrtc, unsigned int sourc
  */
 int webrtc_media_source_get_video_resolution(webrtc_h webrtc, unsigned int source_id, int *width, int *height);
 
+/**
+ * @brief Sets the mic source's sound manager stream information.
+ * @details If @a source_id is not a media source of #WEBRTC_MEDIA_SOURCE_TYPE_MIC, this function will return #WEBRTC_ERROR_INVALID_PARAMETER.
+ * @since_tizen 6.5
+ * @remarks You can set sound stream information including audio routing.\n
+ *          The following sound stream types can be used for the @a stream_info:\n
+ *          #SOUND_STREAM_TYPE_MEDIA\n
+ *          #SOUND_STREAM_TYPE_VOICE_RECOGNITION\n
+ *          #SOUND_STREAM_TYPE_VOIP\n
+ *          #SOUND_STREAM_TYPE_MEDIA_EXTERNAL_ONLY\n
+ *          For more details, please refer to @ref CAPI_MEDIA_SOUND_MANAGER_MODULE.
+ * @param[in] webrtc      WebRTC handle
+ * @param[in] source_id   The mic source id
+ * @param[in] stream_info The sound stream information
+ * @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 @a webrtc state must be set to #WEBRTC_STATE_IDLE.
+ * @see #sound_stream_info_h
+ * @see sound_manager_create_stream_information()
+ * @see sound_manager_destroy_stream_information()
+ */
+int webrtc_mic_source_set_sound_stream_info(webrtc_h webrtc, unsigned int source_id, sound_stream_info_h stream_info);
+
 /**
  * @brief Sets a callback function to be invoked when the buffer state of media packet source is changed.
  * @since_tizen 6.5
index ad8a0bedb51ed0c201a7d5bdfe363eb215d7608d..d0e1e41dcd586dcd2cfd8933d9df408e8a3d4277 100644 (file)
@@ -29,6 +29,7 @@
 #ifndef TIZEN_TV
 #include <mm_resource_manager.h>
 #endif
+#include <sound_manager_internal.h>
 #include <tbm_bufmgr.h>
 #include <libwebsockets.h>
 #include <libsoup/soup.h>
@@ -525,6 +526,7 @@ int _set_video_mute(webrtc_s *webrtc, unsigned int source_id, bool mute);
 int _get_video_mute(webrtc_s *webrtc, unsigned int source_id, bool *muted);
 int _set_video_resolution(webrtc_s *webrtc, unsigned int source_id, int width, int height);
 int _get_video_resolution(webrtc_s *webrtc, unsigned int source_id, int *width, int *height);
+int _set_sound_stream_info(webrtc_s *webrtc, unsigned int source_id, sound_stream_info_h stream_info);
 int _set_media_format(webrtc_s *webrtc, unsigned int source_id, media_format_h format);
 bool _check_if_format_is_set_to_packet_sources(webrtc_s *webrtc);
 int _push_media_packet(webrtc_s *webrtc, unsigned int source_id, media_packet_h packet);
index e53d9c74cf114dc33659faa8795c88269b718bad..f00ffad4d17ebe258a4ca7aa2dc4359fdd907034 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-media-webrtc
 Summary:    A WebRTC library in Tizen Native API
-Version:    0.2.28
+Version:    0.2.29
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
@@ -29,6 +29,7 @@ BuildRequires:  pkgconfig(libwebsockets)
 BuildRequires:  pkgconfig(cynara-client)
 BuildRequires:  pkgconfig(libsmack)
 BuildRequires:  pkgconfig(capi-system-info)
+BuildRequires:  pkgconfig(capi-media-sound-manager)
 BuildRequires:  pkgconfig(bundle)
 %if "%{tizen_profile_name}" != "tv"
 BuildRequires:  pkgconfig(mm-resource-manager)
index 62d7110bbfa668c0772f06971ecbce5cac0f3003..42f499b084993f0d282a7e83842d24bf2429c5fe 100644 (file)
@@ -473,6 +473,25 @@ int webrtc_media_source_get_video_resolution(webrtc_h webrtc, unsigned int sourc
        return ret;
 }
 
+int webrtc_mic_source_set_sound_stream_info(webrtc_h webrtc, unsigned int source_id, sound_stream_info_h stream_info)
+{
+       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(stream_info == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "stream_info is NULL");
+
+       g_mutex_lock(&_webrtc->mutex);
+
+       RET_VAL_WITH_UNLOCK_IF(_webrtc->state != WEBRTC_STATE_IDLE, WEBRTC_ERROR_INVALID_STATE, &_webrtc->mutex, "the state should be IDLE");
+
+       ret = _set_sound_stream_info(webrtc, source_id, stream_info);
+
+       g_mutex_unlock(&_webrtc->mutex);
+
+       return ret;
+}
+
 int webrtc_media_packet_source_set_buffer_state_changed_cb(webrtc_h webrtc, unsigned int source_id, webrtc_media_packet_source_buffer_state_changed_cb callback, void *user_data)
 {
        webrtc_s *_webrtc = (webrtc_s*)webrtc;
index 3e71a9f945a655cdf53ae7f22af1957c156b36c6..0935ac9c3564cc56e43cf7531cd0d1628bc6e12d 100644 (file)
@@ -47,6 +47,7 @@
 #define ELEMENT_NAME_VIDEO_SWITCH     "videoSwitch"
 #define ELEMENT_NAME_VIDEO_MUTE_SRC   "videoMuteSrc"
 #define ELEMENT_NAME_VOLUME           "volume"
+#define ELEMENT_NAME_MIC_SRC          "micSrc"
 
 #define APPEND_ELEMENT(x_list, x_element) \
 do { \
@@ -1214,7 +1215,7 @@ static int __build_audiosrc(webrtc_s *webrtc, webrtc_gst_slot_s *source, bool us
        source->zerocopy_enabled = __is_hw_encoder_used(webrtc, source->type, source->media_types);
 
        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, NULL)))
+       if (!(audiosrc = _create_element(source_factory_name, use_mic ? ELEMENT_NAME_MIC_SRC: NULL)))
                return WEBRTC_ERROR_INVALID_OPERATION;
        APPEND_ELEMENT(element_list, audiosrc);
 
@@ -2112,6 +2113,55 @@ int _get_video_resolution(webrtc_s *webrtc, unsigned int source_id, int *width,
        return WEBRTC_ERROR_NONE;
 }
 
+int _set_sound_stream_info(webrtc_s *webrtc, unsigned int source_id, sound_stream_info_h stream_info)
+{
+       webrtc_gst_slot_s *source;
+       GstElement *element;
+       int ret = SOUND_MANAGER_ERROR_NONE;
+       bool available = false;
+       char *stream_type;
+       int stream_index;
+       GstStructure *structure;
+       char values[64] = {'\0',};
+
+       RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
+       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->type != WEBRTC_MEDIA_SOURCE_TYPE_MIC), WEBRTC_ERROR_INVALID_PARAMETER, "this API only support the mic source");
+       RET_VAL_IF(stream_info == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "stream_info is NULL");
+       RET_VAL_IF(!(element = gst_bin_get_by_name(source->bin, ELEMENT_NAME_MIC_SRC)), WEBRTC_ERROR_INVALID_OPERATION, "could not find element for mic");
+       RET_VAL_IF(!g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(element)), "stream-properties"),
+               WEBRTC_ERROR_INVALID_OPERATION, "mic source element does not have 'stream-properties");
+
+       sound_manager_get_type_from_stream_information(stream_info, &stream_type);
+       sound_manager_get_index_from_stream_information(stream_info, &stream_index);
+
+       ret = sound_manager_is_available_stream_information(stream_info, NATIVE_API_WEBRTC, &available);
+       if (ret != SOUND_MANAGER_ERROR_NONE) {
+               LOG_ERROR("failed to sound_manager_is_available_stream_information()");
+               return WEBRTC_ERROR_INVALID_OPERATION;
+       }
+
+       if (!available) {
+               LOG_ERROR("this stream info[%p, type:%s, index:%d] is not allowed to this framework", stream_info, stream_type, stream_index);
+               return WEBRTC_ERROR_INVALID_PARAMETER;
+       }
+
+       LOG_INFO("source_id[%u], stream_info[%p, type:%s, index:%d]", source_id, stream_info, stream_type, stream_index);
+
+       snprintf(values, sizeof(values) - 1, "props,media.role=%s, media.parent_id=%d", stream_type, stream_index);
+       structure = gst_structure_from_string(values, NULL);
+       if (!structure) {
+               LOG_ERROR("failed to gst_structure_from_string(), [%s]", values);
+               return WEBRTC_ERROR_INVALID_OPERATION;
+       }
+
+       LOG_INFO("stream-properties[%s]", values);
+       g_object_set(G_OBJECT(element), "stream-properties", structure, NULL);
+       gst_structure_free(structure);
+
+       return WEBRTC_ERROR_NONE;
+}
+
 int _set_media_format(webrtc_s *webrtc, unsigned int source_id, media_format_h format)
 {
        int ret;
index 949615e2736f02f4fbce00bbb1a5dc511aad66d6..fd9fa91883dc83d4edecf9536045e37cdf760349 100644 (file)
@@ -17,6 +17,7 @@
 #include <webrtc_internal.h>
 #include <media_format.h>
 #include <media_packet_internal.h>
+#include <sound_manager.h>
 #include <appcore-efl.h>
 #include <Elementary.h>
 #include <tbm_surface_internal.h>
@@ -501,37 +502,54 @@ static void _webrtc_add_media_source(int index, int value)
        unsigned int source_id = 0;
        int i;
 
-       switch (value) {
-       case 1: /* WEBRTC_MEDIA_SOURCE_TYPE_AUDIOTEST */
-       case 2: /* WEBRTC_MEDIA_SOURCE_TYPE_VIDEOTEST */
-       case 3: /* WEBRTC_MEDIA_SOURCE_TYPE_MIC */
-       case 4: /* WEBRTC_MEDIA_SOURCE_TYPE_CAMERA */
-       case 5: /* WEBRTC_MEDIA_SOURCE_TYPE_SCREEN */
-       case 6: /* WEBRTC_MEDIA_SOURCE_TYPE_FILE */
-       case 7: /* WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET */
-               if ((value - 1) == WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET) {
-                       i = _get_empty_packet_sources_index(index);
-                       RET_IF(i == -1, "media packet source can be added up to %d", MAX_MEDIA_PACKET_SOURCE_LEN);
+       if (value - 1 <= WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET) {
+               webrtc_media_source_type_e type = value - 1;
+               switch (type) {
+               case WEBRTC_MEDIA_SOURCE_TYPE_AUDIOTEST ... WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET:
+                       if (type == WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET) {
+                               i = _get_empty_packet_sources_index(index);
+                               RET_IF(i == -1, "media packet source can be added up to %d", MAX_MEDIA_PACKET_SOURCE_LEN);
+                       }
+                       ret = webrtc_add_media_source(g_conns[index].webrtc, type, &source_id);
+                       RET_IF(ret != WEBRTC_ERROR_NONE, "ret[0x%x]", ret);
+
+                       if (type == WEBRTC_MEDIA_SOURCE_TYPE_MIC) {
+                               sound_stream_info_h stream_info;
+                               ret = sound_manager_create_stream_information(SOUND_STREAM_TYPE_MEDIA, NULL, NULL, &stream_info);
+                               RET_IF(ret != SOUND_MANAGER_ERROR_NONE, "failed to sound_manager_create_stream_information(), ret[0x%x]", ret);
+
+                               ret = webrtc_mic_source_set_sound_stream_info(g_conns[index].webrtc, source_id, stream_info);
+                               if (ret != WEBRTC_ERROR_NONE)
+                                       g_printerr("failed to webrtc_mic_source_set_sound_stream_info(), ret[0x%x]\n", ret);
+
+                               sound_manager_destroy_stream_information(stream_info);
+                       }
+                       break;
+               default:
+                       g_printerr("failed to _webrtc_add_media_source(), invalid type(%d)\n", type);
+                       return;
+               }
+               if (type == WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET) {
+                       g_conns[index].packet_sources[i].source_id = source_id;
+                       g_mutex_init(&g_conns[index].packet_sources[i].mutex);
+                       g_cond_init(&g_conns[index].packet_sources[i].cond);
                }
-               ret = webrtc_add_media_source(g_conns[index].webrtc, (webrtc_media_source_type_e)(value - 1), &source_id);
-               RET_IF(ret != WEBRTC_ERROR_NONE, "ret[0x%x]", ret);
-               break;
-       case 8: /* WEBRTC_MEDIA_SOURCE_TYPE_CUSTOM_AUDIO */
-       case 9: /* WEBRTC_MEDIA_SOURCE_TYPE_CUSTOM_VIDEO */
-               ret = webrtc_add_media_source_internal(g_conns[index].webrtc, (webrtc_media_source_type_internal_e)(value - 1), &source_id);
-               RET_IF(ret != WEBRTC_ERROR_NONE, "ret[0x%x]", ret);
-               break;
-       default:
-               break;
-       }
 
-       if ((value - 1) == WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET) {
-               g_conns[index].packet_sources[i].source_id = source_id;
-               g_mutex_init(&g_conns[index].packet_sources[i].mutex);
-               g_cond_init(&g_conns[index].packet_sources[i].cond);
+       } else {
+               webrtc_media_source_type_internal_e type = value - 1;
+               switch (type) {
+               case WEBRTC_MEDIA_SOURCE_TYPE_CUSTOM_AUDIO:
+               case WEBRTC_MEDIA_SOURCE_TYPE_CUSTOM_VIDEO:
+                       ret = webrtc_add_media_source_internal(g_conns[index].webrtc, type, &source_id);
+                       RET_IF(ret != WEBRTC_ERROR_NONE, "ret[0x%x]", ret);
+                       break;
+               default:
+                       g_printerr("failed to _webrtc_add_media_source(), invalid type(%d)\n", type);
+                       return;
+               }
        }
 
-       g_print("webrtc_add_media_source() success, source_id[%u]\n", source_id);
+       g_print("_webrtc_add_media_source() success, source_id[%u]\n", source_id);
 }
 
 static void _webrtc_remove_media_source(int index, unsigned int source_id)