Add API to set/get camera device id 06/277806/10
authorSangchul Lee <sc11.lee@samsung.com>
Wed, 13 Jul 2022 13:52:51 +0000 (22:52 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Tue, 2 Aug 2022 23:20:19 +0000 (08:20 +0900)
Functions are added as below.
 - webrtc_camera_source_set_device_id()
 - webrtc_camera_source_get_device_id()

[Version] 0.3.190
[Issue Type] API

Change-Id: I86a6e87049aaf0d83c3a3dab46c472d8dbe9b27b
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_camera.c [new file with mode: 0644]

index 26bd6f6b5430ca04aba27f1ab785decfb30036ff..18b4cb851751b0252fe32cd1ac45cfff0d34d014 100644 (file)
@@ -1040,6 +1040,9 @@ int webrtc_get_state(webrtc_h webrtc, webrtc_state_e *state);
  * @see webrtc_media_source_get_video_resolution()
  * @see webrtc_media_source_set_video_framerate()
  * @see webrtc_media_source_get_video_framerate()
+ * @see webrtc_mic_source_set_sound_stream_info()
+ * @see webrtc_camera_source_set_device_id()
+ * @see webrtc_camera_source_get_device_id()
  * @see webrtc_media_packet_source_set_buffer_state_changed_cb()
  * @see webrtc_media_packet_source_unset_buffer_state_changed_cb()
  * @see webrtc_media_packet_source_set_format()
@@ -1356,6 +1359,42 @@ int webrtc_media_source_get_video_framerate(webrtc_h webrtc, unsigned int source
  */
 int webrtc_mic_source_set_sound_stream_info(webrtc_h webrtc, unsigned int source_id, sound_stream_info_h stream_info);
 
+/**
+ * @brief Sets a camera device id to the camera source.
+ * @since_tizen 7.0
+ * @param[in] webrtc      WebRTC handle
+ * @param[in] source_id   The camera source id
+ * @param[in] device_id   The camera device 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
+ * @retval #WEBRTC_ERROR_INVALID_STATE Invalid state
+ * @pre Add camera 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_add_media_source()
+ * @see webrtc_camera_source_get_device_id()
+ */
+int webrtc_camera_source_set_device_id(webrtc_h webrtc, unsigned int source_id, unsigned int device_id);
+
+/**
+ * @brief Gets the camera device id of the camera source.
+ * @since_tizen 7.0
+ * @param[in] webrtc      WebRTC handle
+ * @param[in] source_id   The camera source id
+ * @param[out] device_id  The camera device 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 camera source to @a webrtc to get @a source_id by calling webrtc_add_media_source().
+ * @see webrtc_add_media_source()
+ * @see webrtc_camera_source_set_device_id()
+ */
+int webrtc_camera_source_get_device_id(webrtc_h webrtc, unsigned int source_id, unsigned int *device_id);
+
 /**
  * @brief Sets a callback function to be invoked when the buffer state of media packet source is changed.
  * @since_tizen 6.5
index 4253afac969d721558b1aa3e0b045e4a90c1094c..ccba09ffacd9a0f35b0f82ef2408d63f1c0b6727 100644 (file)
@@ -691,6 +691,8 @@ int _set_video_resolution(webrtc_s *webrtc, unsigned int source_id, int width, i
 int _get_video_resolution(webrtc_s *webrtc, unsigned int source_id, int *width, int *height);
 int _set_video_framerate(webrtc_s *webrtc, unsigned int source_id, int framerate);
 int _get_video_framerate(webrtc_s *webrtc, unsigned int source_id, int *framerate);
+int _set_camera_device_id(webrtc_s *webrtc, unsigned int source_id, unsigned int device_id);
+int _get_camera_device_id(webrtc_s *webrtc, unsigned int source_id, unsigned int *device_id);
 int _set_display_mode_to_loopback(webrtc_s *webrtc, unsigned int track_id, webrtc_display_mode_e mode);
 int _get_display_mode_from_loopback(webrtc_s *webrtc, unsigned int track_id, webrtc_display_mode_e *mode);
 int _set_display_visible_to_loopback(webrtc_s *webrtc, unsigned int track_id, bool visible);
index ab67dc81dea93e81bfed9517314e12e67dba1d92..feda5900258cf4241368e1fe5625d5e28b4146b3 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-media-webrtc
 Summary:    A WebRTC library in Tizen Native API
-Version:    0.3.189
+Version:    0.3.190
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
index 768dda6d233c47e7a4993cac0ec5501c274b2d34..828969090f7dc90cf2b3e1254f36264bf9d176a0 100644 (file)
@@ -510,6 +510,33 @@ int webrtc_mic_source_set_sound_stream_info(webrtc_h webrtc, unsigned int source
        return _set_sound_stream_info(webrtc, source_id, stream_info);
 }
 
+int webrtc_camera_source_set_device_id(webrtc_h webrtc, unsigned int source_id, unsigned int device_id)
+{
+       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_camera_device_id(webrtc, source_id, device_id);
+}
+
+int webrtc_camera_source_get_device_id(webrtc_h webrtc, unsigned int source_id, unsigned int *device_id)
+{
+       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(device_id == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "device_id is NULL");
+
+       locker = g_mutex_locker_new(&_webrtc->mutex);
+
+       return _get_camera_device_id(webrtc, source_id, device_id);
+}
+
 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)
 {
        g_autoptr(GMutexLocker) locker = NULL;
diff --git a/src/webrtc_source_camera.c b/src/webrtc_source_camera.c
new file mode 100644 (file)
index 0000000..c0978e1
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "webrtc_private.h"
+#include "webrtc_source_private.h"
+
+typedef enum {
+       CAMERA_DEVICE_TYPE_V4L2,
+       CAMERA_DEVICE_TYPE_TIZEN,
+} camera_device_type_e;
+
+typedef enum {
+       CAMERA_DEVICE_PROP_VAL_TYPE_INT,
+       CAMERA_DEVICE_PROP_VAL_TYPE_STRING,
+} camera_device_prop_value_type_e;
+
+typedef struct {
+       const char *factory_name;
+       const char *device_prop_name;
+       const char *device_prop_value_prefix;
+       camera_device_prop_value_type_e device_prop_value_type;
+} camera_info_s;
+
+static camera_info_s  __camera_infos[] = {
+       [CAMERA_DEVICE_TYPE_V4L2] = { "v4l2src", "device", "/dev/video", CAMERA_DEVICE_PROP_VAL_TYPE_STRING },
+       [CAMERA_DEVICE_TYPE_TIZEN] = { "camerasrc", "camera-id", NULL, CAMERA_DEVICE_PROP_VAL_TYPE_INT },
+};
+
+static int __get_device_type(webrtc_s *webrtc, camera_device_type_e *type)
+{
+       int i;
+       const char *camera_factory_name;
+
+       RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
+       RET_VAL_IF(type == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "type is NULL");
+
+       camera_factory_name = _get_source_element(webrtc, WEBRTC_MEDIA_SOURCE_TYPE_CAMERA);
+       for (i = CAMERA_DEVICE_TYPE_V4L2; i < CAMERA_DEVICE_TYPE_TIZEN + 1; i++) {
+               if (!strcmp(__camera_infos[i].factory_name, camera_factory_name)) {
+                       *type = (camera_device_type_e)i;
+                       return WEBRTC_ERROR_NONE;
+               }
+       }
+
+       LOG_ERROR_IF_REACHED("invalid camera_factory_name(%s)", camera_factory_name);
+       return WEBRTC_ERROR_INVALID_OPERATION;
+}
+
+static gchar *__get_device_prop_value_string(const char *prefix, unsigned int device_id)
+{
+       RET_VAL_IF(prefix == NULL, NULL, "prefix is NULL");
+       return g_strdup_printf("%s%u", prefix, device_id);
+}
+
+static int __validate_source_and_get_camera_device_type(webrtc_s *webrtc, unsigned int source_id, camera_device_type_e *type, GstElement **camerasrc)
+{
+       webrtc_gst_slot_s *source;
+
+       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(type == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "type is NULL");
+       RET_VAL_IF(camerasrc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "camerasrc 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_CAMERA), WEBRTC_ERROR_INVALID_PARAMETER, "it's not camera source, type(%d)", source->type);
+       RET_VAL_IF(__get_device_type(webrtc, type) != WEBRTC_ERROR_NONE, WEBRTC_ERROR_INVALID_OPERATION, "failed to __get_device_type()");
+       RET_VAL_IF(!(*camerasrc = gst_bin_get_by_name(source->bin, ELEMENT_NAME_VIDEO_SRC)), WEBRTC_ERROR_INVALID_OPERATION, "camerasrc is NULL");
+       RET_VAL_IF(!g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(*camerasrc)), __camera_infos[*type].device_prop_name), WEBRTC_ERROR_INVALID_OPERATION,
+               "not supported [%s] property", __camera_infos[*type].device_prop_name);
+
+       return WEBRTC_ERROR_NONE;
+}
+
+int _set_camera_device_id(webrtc_s *webrtc, unsigned int source_id, unsigned int device_id)
+{
+       int ret;
+       GstElement *camerasrc;
+       camera_device_type_e type;
+
+       if ((ret = __validate_source_and_get_camera_device_type(webrtc, source_id, &type, &camerasrc)) != WEBRTC_ERROR_NONE)
+               return ret;
+
+       /* Disable v4l2src tizen feature */
+       if (g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(camerasrc)), "auto-scan-device"))
+               g_object_set(G_OBJECT(camerasrc), "auto-scan-device", FALSE, NULL);
+
+       /* FIXME: check if the device id is valid (e.g. query API or ini) */
+
+       switch (__camera_infos[type].device_prop_value_type) {
+       case CAMERA_DEVICE_PROP_VAL_TYPE_INT:
+               LOG_DEBUG("device prop[name:%s, value:%d]", __camera_infos[type].device_prop_name, (gint)device_id);
+               g_object_set(G_OBJECT(camerasrc), __camera_infos[type].device_prop_name, (gint)device_id, NULL);
+               break;
+       case CAMERA_DEVICE_PROP_VAL_TYPE_STRING: {
+               gchar *device_prop_value = __get_device_prop_value_string(__camera_infos[type].device_prop_value_prefix, device_id);
+               LOG_DEBUG("device prop[name:%s, value:%s]", __camera_infos[type].device_prop_name, device_prop_value);
+               g_object_set(G_OBJECT(camerasrc), __camera_infos[type].device_prop_name, device_prop_value, NULL);
+               g_free(device_prop_value);
+               break;
+       }
+       default:
+               LOG_ERROR_IF_REACHED("invalid device_prop_value_type(%d)", __camera_infos[type].device_prop_value_type);
+               return WEBRTC_ERROR_INVALID_OPERATION;
+       }
+
+       LOG_INFO("source_id[%u], device_id[%u]", source_id, device_id);
+
+       return WEBRTC_ERROR_NONE;
+}
+
+int _get_camera_device_id(webrtc_s *webrtc, unsigned int source_id, unsigned int *device_id)
+{
+       int ret;
+       GstElement *camerasrc;
+       camera_device_type_e type;
+
+       if ((ret = __validate_source_and_get_camera_device_type(webrtc, source_id, &type, &camerasrc)) != WEBRTC_ERROR_NONE)
+               return ret;
+
+       switch (__camera_infos[type].device_prop_value_type) {
+       case CAMERA_DEVICE_PROP_VAL_TYPE_INT: {
+               gint id;
+
+               g_object_get(G_OBJECT(camerasrc), __camera_infos[type].device_prop_name, &id, NULL);
+               *device_id = (unsigned int)id;
+               break;
+       }
+       case CAMERA_DEVICE_PROP_VAL_TYPE_STRING: {
+               g_autofree gchar *id_str = NULL;
+               g_auto(GStrv) tokens = NULL;
+
+               g_object_get(G_OBJECT(camerasrc), __camera_infos[type].device_prop_name, &id_str, NULL);
+               tokens = g_strsplit(id_str, __camera_infos[type].device_prop_value_prefix, 2);
+               *device_id = (unsigned int)atoi(tokens[1]);
+               break;
+       }
+       default:
+               LOG_ERROR_IF_REACHED("invalid device_prop_value_type(%d)", __camera_infos[type].device_prop_value_type);
+               return WEBRTC_ERROR_INVALID_OPERATION;
+       }
+
+       LOG_INFO("source_id[%u], device_id[%u]", source_id, *device_id);
+
+       return WEBRTC_ERROR_NONE;
+}