From: Sangchul Lee Date: Wed, 13 Jul 2022 13:52:51 +0000 (+0900) Subject: Add API to set/get camera device id X-Git-Tag: submit/tizen/20220805.110513~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=48c6ee229540c3b01b8c33fa06b8a2bcaaf01150;p=platform%2Fcore%2Fapi%2Fwebrtc.git Add API to set/get camera device id 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 --- diff --git a/include/webrtc.h b/include/webrtc.h index 26bd6f6b..18b4cb85 100644 --- a/include/webrtc.h +++ b/include/webrtc.h @@ -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 diff --git a/include/webrtc_private.h b/include/webrtc_private.h index 4253afac..ccba09ff 100644 --- a/include/webrtc_private.h +++ b/include/webrtc_private.h @@ -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); diff --git a/packaging/capi-media-webrtc.spec b/packaging/capi-media-webrtc.spec index ab67dc81..feda5900 100644 --- a/packaging/capi-media-webrtc.spec +++ b/packaging/capi-media-webrtc.spec @@ -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 diff --git a/src/webrtc.c b/src/webrtc.c index 768dda6d..82896909 100644 --- a/src/webrtc.c +++ b/src/webrtc.c @@ -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 index 00000000..c0978e1d --- /dev/null +++ b/src/webrtc_source_camera.c @@ -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; +}