From: Hyunil Date: Mon, 11 Jan 2021 10:26:44 +0000 (+0900) Subject: Apply h/w resource management X-Git-Tag: submit/tizen/20210729.023123~152 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3d449f88fdbb1d6d1029fff6b468af02db63dca5;p=platform%2Fcore%2Fapi%2Fwebrtc.git Apply h/w resource management - In case of TV profile, functions are disabled. [Version] 0.1.89 [Issue Type] New feature Change-Id: Ida0e5049b667c2cb14756d03dae25d9d757178bf Signed-off-by: Hyunil --- diff --git a/CMakeLists.txt b/CMakeLists.txt index d20c1dd3..2e07c522 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,10 @@ 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 \ json-glib-1.0 iniparser mm-common mm-display-interface capi-media-tool libtbm libwebsockets \ cynara-client libsmack") +IF(TIZEN_FEATURE_RESOURCE_MANAGER) +SET(dependents "${dependents} mm-resource-manager") +ADD_DEFINITIONS("-DTIZEN_FEATURE_RES_MGR") +ENDIF() SET(pc_dependents "capi-base-common" ) @@ -39,6 +43,9 @@ AUX_SOURCE_DIRECTORY (src MAIN_SRC) LIST (APPEND SOURCES ${MAIN_SRC} ) +IF(NOT TIZEN_FEATURE_RESOURCE_MANAGER) +LIST (REMOVE_ITEM SOURCES src/webrtc_resource.c) +ENDIF() ADD_LIBRARY(${fw_name} SHARED ${SOURCES}) diff --git a/include/webrtc_private.h b/include/webrtc_private.h index 1a72b1fc..6eea4f9b 100644 --- a/include/webrtc_private.h +++ b/include/webrtc_private.h @@ -26,6 +26,9 @@ #endif #include #include +#ifdef TIZEN_FEATURE_RES_MGR +#include +#endif #include #include @@ -176,6 +179,17 @@ typedef enum { #define MLINES_IDX_AUDIO 0 #define MLINES_IDX_VIDEO 1 +#ifdef TIZEN_FEATURE_RES_MGR +#define RESOURCE_TYPE_MAX MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_ENCODER + 1 + +typedef struct _webrtc_resource_s { + mm_resource_manager_h mgr; + mm_resource_manager_res_h res[RESOURCE_TYPE_MAX]; + gboolean need_to_acquire[RESOURCE_TYPE_MAX]; + gboolean release_cb_is_calling; +} webrtc_resource_s; +#endif + typedef struct _ini_item_general_s { bool generate_dot; const char *dot_path; @@ -305,6 +319,9 @@ typedef struct _webrtc_s { const gchar *ice_connection_state; const gchar *ice_gathering_state; } internal_states; +#ifdef TIZEN_FEATURE_RES_MGR + webrtc_resource_s resource; +#endif } webrtc_s; typedef struct _webrtc_data_channel_s { @@ -345,6 +362,7 @@ int _load_ini(webrtc_s *webrtc); void _unload_ini(webrtc_s *webrtc); ini_item_media_source_s* _ini_get_source_by_type(webrtc_ini_s *ini, webrtc_media_source_type_e type); +int _webrtc_stop(webrtc_s *webrtc); int _gst_init(webrtc_s *webrtc); int _gst_build_pipeline(webrtc_s *webrtc); void _gst_destroy_pipeline(webrtc_s *webrtc); @@ -379,6 +397,14 @@ void _release_display(webrtc_display_s *display); int _apply_display(webrtc_display_s *display); void _video_stream_decoded_cb(GstElement *object, GstBuffer *buffer, GstPad *pad, gpointer data); +#ifdef TIZEN_FEATURE_RES_MGR +int _acquire_resource_if_needed(webrtc_s *webrtc); +int _create_resource_manager(webrtc_s *webrtc); +int _destroy_resource_manager(webrtc_s *webrtc); +int _acquire_resource_for_type(webrtc_s *webrtc, mm_resource_manager_res_type_e type); +int _release_all_resources(webrtc_s *webrtc); +#endif + webrtc_tbm_s *_alloc_tbm(void); void _release_tbm(webrtc_tbm_s *tbm); void _create_tbm_bo_list(webrtc_tbm_s *tbm, int bo_size, int list_length); diff --git a/packaging/capi-media-webrtc.spec b/packaging/capi-media-webrtc.spec index db961930..c8a08d32 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.1.88 +Version: 0.1.89 Release: 0 Group: Multimedia/API License: Apache-2.0 @@ -27,6 +27,9 @@ BuildRequires: pkgconfig(libtbm) BuildRequires: pkgconfig(libwebsockets) BuildRequires: pkgconfig(cynara-client) BuildRequires: pkgconfig(libsmack) +%if "%{tizen_profile_name}" != "tv" +BuildRequires: pkgconfig(mm-resource-manager) +%endif %description A WebRTC library in Tizen Native API. @@ -45,7 +48,12 @@ cp %{SOURCE1001} . %build MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'` -cmake . -DCMAKE_INSTALL_PREFIX=/usr -DFULLVER=%{version} -DMAJORVER=${MAJORVER} +cmake . -DCMAKE_INSTALL_PREFIX=/usr -DFULLVER=%{version} -DMAJORVER=${MAJORVER} \ +%if "%{tizen_profile_name}" != "tv" +-DTIZEN_FEATURE_RESOURCE_MANAGER=on +%else +-DTIZEN_FEATURE_RESOURCE_MANAGER=off +%endif make %{?jobs:-j%jobs} diff --git a/src/webrtc.c b/src/webrtc.c index 0f87047e..8b7607bf 100644 --- a/src/webrtc.c +++ b/src/webrtc.c @@ -115,6 +115,14 @@ int webrtc_create(webrtc_h *webrtc) _webrtc = g_new0(webrtc_s, 1); +#ifdef TIZEN_FEATURE_RES_MGR + ret = _create_resource_manager(_webrtc); + if (ret != WEBRTC_ERROR_NONE) { + LOG_ERROR("failed to create resource manager"); + g_free(_webrtc); + return ret; + } +#endif g_mutex_init(&_webrtc->mutex); g_mutex_lock(&_webrtc->mutex); @@ -148,6 +156,10 @@ int webrtc_destroy(webrtc_h webrtc) _gst_pipeline_set_state(webrtc, GST_STATE_NULL); +#ifdef TIZEN_FEATURE_RES_MGR + if (_destroy_resource_manager(_webrtc) != WEBRTC_ERROR_NONE) + LOG_ERROR("failed to destroy webrtc[%p]", webrtc); +#endif _webrtc->pend_state = WEBRTC_STATE_IDLE; _webrtc->state = _webrtc->pend_state; @@ -170,6 +182,7 @@ int webrtc_destroy(webrtc_h webrtc) int webrtc_start(webrtc_h webrtc) { + int ret = WEBRTC_ERROR_NONE; webrtc_s *_webrtc = (webrtc_s*)webrtc; RET_VAL_IF(_webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL"); @@ -181,6 +194,14 @@ int webrtc_start(webrtc_h webrtc) RET_VAL_WITH_UNLOCK_IF(_webrtc->gst.webrtcbin == NULL, WEBRTC_ERROR_INVALID_OPERATION, &_webrtc->mutex, "webrtcbin is NULL"); RET_VAL_WITH_UNLOCK_IF(!_check_if_format_is_set_to_packet_sources(_webrtc), WEBRTC_ERROR_INVALID_OPERATION, &_webrtc->mutex, "the media format should be set"); +#ifdef TIZEN_FEATURE_RES_MGR + ret = _acquire_resource_if_needed(_webrtc); + if (ret != WEBRTC_ERROR_NONE) { + LOG_ERROR("failed to acquire resource, webrtc[%p]", _webrtc); + g_mutex_unlock(&_webrtc->mutex); + return ret; + } +#endif _gst_pipeline_set_state(webrtc, GST_STATE_PLAYING); _webrtc->pend_state = WEBRTC_STATE_NEGOTIATING; @@ -188,7 +209,7 @@ int webrtc_start(webrtc_h webrtc) g_mutex_unlock(&_webrtc->mutex); - return WEBRTC_ERROR_NONE; + return ret; } int webrtc_stop(webrtc_h webrtc) @@ -197,22 +218,7 @@ int webrtc_stop(webrtc_h webrtc) RET_VAL_IF(_webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc 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 NOT be IDLE"); - - _gst_pipeline_set_state(_webrtc, GST_STATE_NULL); - - _post_state_in_idle(_webrtc, WEBRTC_STATE_IDLE); - - LOG_INFO("webrtc[%p] is stopping", webrtc); - - g_hash_table_remove_all(_webrtc->gst.sink_slots); - g_hash_table_remove_all(_webrtc->data_channels); - - g_mutex_unlock(&_webrtc->mutex); - - return WEBRTC_ERROR_NONE; + return _webrtc_stop(_webrtc); } int webrtc_get_state(webrtc_h webrtc, webrtc_state_e *state) @@ -1001,4 +1007,4 @@ int webrtc_get_data(webrtc_bytes_data_h bytes, const char **data, unsigned int * LOG_INFO("data[%p] size[%u]", *data, *size); return WEBRTC_ERROR_NONE; -} \ No newline at end of file +} diff --git a/src/webrtc_private.c b/src/webrtc_private.c index 4f00b584..ac42e228 100644 --- a/src/webrtc_private.c +++ b/src/webrtc_private.c @@ -1441,3 +1441,28 @@ bool _webrtcbin_have_remote_offer(webrtc_s *webrtc) return (signaling_state == GST_WEBRTC_SIGNALING_STATE_HAVE_REMOTE_OFFER); } + +int _webrtc_stop(webrtc_s *webrtc) +{ + int ret = WEBRTC_ERROR_NONE; + + RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc 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 not be IDLE"); + + _gst_pipeline_set_state(webrtc, GST_STATE_NULL); + +#ifdef TIZEN_FEATURE_RES_MGR + ret = _release_all_resources(webrtc); + RET_VAL_WITH_UNLOCK_IF(ret != WEBRTC_ERROR_NONE, ret, &webrtc->mutex, "failed to release all resources"); +#endif + _post_state_in_idle(webrtc, WEBRTC_STATE_IDLE); + + LOG_INFO("webrtc[%p] is stopping", webrtc); + + g_mutex_unlock(&webrtc->mutex); + + return ret; +} diff --git a/src/webrtc_resource.c b/src/webrtc_resource.c new file mode 100644 index 00000000..f7d68434 --- /dev/null +++ b/src/webrtc_resource.c @@ -0,0 +1,172 @@ + +/* + * Copyright (c) 2021 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.h" +#include "webrtc_private.h" + +int _acquire_resource_if_needed(webrtc_s *webrtc) +{ + int i; + int ret = WEBRTC_ERROR_NONE; + + RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL"); + + for (i = 0; i < RESOURCE_TYPE_MAX; i++) { + if (webrtc->resource.need_to_acquire[i] == true) { + ret = _acquire_resource_for_type(webrtc, i); + if (ret != WEBRTC_ERROR_NONE) + return ret; + webrtc->resource.need_to_acquire[i] = false; + } + } + + return ret; +} + +static int __resource_release_cb(mm_resource_manager_h mgr, + mm_resource_manager_res_h res, void *user_data) +{ + int i; + int ret = true; + webrtc_s *webrtc = (webrtc_s *)user_data; + + RET_VAL_IF(webrtc == NULL, false, "webrtc is NULL"); + + webrtc->resource.release_cb_is_calling = true; + + for (i = 0; i < RESOURCE_TYPE_MAX; i++) { + if (webrtc->resource.res[i] == res) { + LOG_INFO("type[%d] resource was released by resource manager", i); + webrtc->resource.res[i] = NULL; + } + } + + if (_webrtc_stop(webrtc) != WEBRTC_ERROR_NONE) + ret = false; + + webrtc->resource.release_cb_is_calling = false; + + return ret; +} + +int _create_resource_manager(webrtc_s *webrtc) +{ + RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL"); + + if (mm_resource_manager_create(MM_RESOURCE_MANAGER_APP_CLASS_MEDIA, + __resource_release_cb, webrtc, + &webrtc->resource.mgr) != MM_RESOURCE_MANAGER_ERROR_NONE) { + LOG_ERROR("Failed to init resource manager for media"); + return WEBRTC_ERROR_RESOURCE_FAILED; + } + + return WEBRTC_ERROR_NONE; +} + +static bool __is_valid_resource_type(mm_resource_manager_res_type_e type) +{ + if (type < MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_DECODER || type >= RESOURCE_TYPE_MAX) { + LOG_ERROR("Type[%d] is a invalid resource type", type); + return false; + } + return true; +} + +int _acquire_resource_for_type(webrtc_s *webrtc, mm_resource_manager_res_type_e type) +{ + int ret = MM_RESOURCE_MANAGER_ERROR_NONE; + + RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL"); + RET_VAL_IF(webrtc->resource.mgr == NULL, WEBRTC_ERROR_INVALID_PARAMETER, + "resource manager is NULL"); + RET_VAL_IF(!__is_valid_resource_type(type), WEBRTC_ERROR_INVALID_PARAMETER, + "type is wrong"); + + if (webrtc->resource.res[type] != NULL) { + LOG_ERROR("type[%d] resource was already acquired", type); + return WEBRTC_ERROR_RESOURCE_FAILED; + } + + LOG_DEBUG("mark for acquire type[%d] resource", type); + ret = mm_resource_manager_mark_for_acquire(webrtc->resource.mgr, type, + MM_RESOURCE_MANAGER_RES_VOLUME_FULL, &webrtc->resource.res[type]); + if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) { + LOG_ERROR("failed to mark resource for acquire, ret[0x%x]", ret); + return WEBRTC_ERROR_RESOURCE_FAILED; + } + + LOG_DEBUG("commit type[%d] resource", type); + ret = mm_resource_manager_commit(webrtc->resource.mgr); + if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) { + LOG_ERROR("failed to commit of resource, ret([0x%x]", ret); + return WEBRTC_ERROR_RESOURCE_FAILED; + } + + return WEBRTC_ERROR_NONE; +} + +int _release_all_resources(webrtc_s *webrtc) +{ + int i; + int ret = MM_RESOURCE_MANAGER_ERROR_NONE; + + RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL"); + RET_VAL_IF(webrtc->resource.mgr == NULL, WEBRTC_ERROR_INVALID_PARAMETER, + "resource manager is NULL"); + + if(webrtc->resource.release_cb_is_calling) { + LOG_INFO("__resource_release_cb is calling, so skip"); + return WEBRTC_ERROR_NONE; + } + + ret = mm_resource_manager_mark_all_for_release(webrtc->resource.mgr); + if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) { + LOG_ERROR("failed to mark all for release, ret[0x%x]", ret); + return WEBRTC_ERROR_RESOURCE_FAILED; + } + ret = mm_resource_manager_commit(webrtc->resource.mgr); + if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) { + LOG_ERROR("failed to commit resource, ret[0x%x]", ret); + return WEBRTC_ERROR_RESOURCE_FAILED; + } + LOG_DEBUG("all resources were released by resource manager"); + + for (i = 0; i < RESOURCE_TYPE_MAX; i++) { + webrtc->resource.need_to_acquire[i] = false; + webrtc->resource.res[i] = NULL; + } + + return WEBRTC_ERROR_NONE; +} + +int _destroy_resource_manager(webrtc_s *webrtc) +{ + int ret = MM_RESOURCE_MANAGER_ERROR_NONE; + + RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL"); + RET_VAL_IF(webrtc->resource.mgr == NULL, WEBRTC_ERROR_INVALID_PARAMETER, + "resource manager is NULL"); + + ret = mm_resource_manager_destroy(webrtc->resource.mgr); + if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) { + LOG_ERROR("failed to destroy resource manager, ret[0x%x]", ret); + return WEBRTC_ERROR_RESOURCE_FAILED; + } + webrtc->resource.mgr = NULL; + LOG_DEBUG("destroyed resource manager"); + + return WEBRTC_ERROR_NONE; +} diff --git a/src/webrtc_sink.c b/src/webrtc_sink.c index 94087c02..eae69900 100644 --- a/src/webrtc_sink.c +++ b/src/webrtc_sink.c @@ -114,6 +114,7 @@ static int __build_videosink(webrtc_s *webrtc, GstElement *decodebin, GstPad *sr GstElement *videosink; const char *videosink_factory_name; bool display_is_set = false; + int ret = WEBRTC_ERROR_NONE; RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL"); RET_VAL_IF(decodebin == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "decodebin is NULL"); @@ -125,13 +126,14 @@ static int __build_videosink(webrtc_s *webrtc, GstElement *decodebin, GstPad *sr sink->media_types |= MEDIA_TYPE_VIDEO; - if (!(videoconvert = _create_element(DEFAULT_ELEMENT_VIDEOCONVERT, NULL))) { - LOG_ERROR("failed to create videoconvert"); - return WEBRTC_ERROR_INVALID_OPERATION; - } - videosink_factory_name = __get_videosink_factory_name(sink->display, DEFAULT_ELEMENT_VIDEOSINK, &display_is_set); - +#ifdef TIZEN_FEATURE_RES_MGR + if (!g_strcmp0(videosink_factory_name, DEFAULT_ELEMENT_VIDEOSINK)) { + webrtc->resource.need_to_acquire[MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_OVERLAY] = true; + if ((ret =_acquire_resource_for_type(webrtc, MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_OVERLAY))) + return ret; + } +#endif if (!(videosink = _create_element(videosink_factory_name, NULL))) { LOG_ERROR("failed to create videosink[%s]", videosink_factory_name); return WEBRTC_ERROR_INVALID_OPERATION; @@ -148,6 +150,11 @@ static int __build_videosink(webrtc_s *webrtc, GstElement *decodebin, GstPad *sr } } + if (!(videoconvert = _create_element(DEFAULT_ELEMENT_VIDEOCONVERT, NULL))) { + LOG_ERROR("failed to create videoconvert"); + return WEBRTC_ERROR_INVALID_OPERATION; + } + gst_bin_add_many(GST_BIN(sink->bin), videoconvert, videosink, NULL); if (!gst_element_sync_state_with_parent(videoconvert)) { @@ -164,7 +171,7 @@ static int __build_videosink(webrtc_s *webrtc, GstElement *decodebin, GstPad *sr return WEBRTC_ERROR_INVALID_OPERATION; } - return WEBRTC_ERROR_NONE; + return ret; } static int __build_audiosink(webrtc_s *webrtc, GstElement *decodebin, GstPad *src_pad) @@ -371,6 +378,12 @@ static int __decodebin_autoplug_select_cb(GstElement *decodebin, GstPad *pad, Gs if (str_arr == NULL || !g_strv_contains((const gchar * const *)str_arr, factory_name)) { LOG_WARNING("this video hw decoder element[%s] is not specified in ini file, skip it", factory_name); return GST_AUTOPLUG_SELECT_SKIP; +#ifdef TIZEN_FEATURE_RES_MGR + } else { + webrtc->resource.need_to_acquire[MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_DECODER] = true; + if (_acquire_resource_for_type(webrtc, MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_DECODER) != WEBRTC_ERROR_NONE) + return GST_AUTOPLUG_SELECT_SKIP; +#endif } } @@ -514,4 +527,4 @@ int _set_display_to_sink(webrtc_s *webrtc, unsigned int track_id, unsigned int t sink->display->object = display; return _apply_display(sink->display); -} \ No newline at end of file +} diff --git a/src/webrtc_source.c b/src/webrtc_source.c index 2a7a54ca..93a7ded6 100644 --- a/src/webrtc_source.c +++ b/src/webrtc_source.c @@ -507,6 +507,7 @@ static GstCaps *__make_rtp_caps(const gchar *media_type, unsigned int id) static GstElement *__get_hw_encoder_element(webrtc_s *webrtc, webrtc_media_source_type_e type) { ini_item_media_source_s *source; + GstElement *encoder = NULL; RET_VAL_IF(webrtc == NULL, NULL, "webrtc is NULL"); @@ -514,10 +515,14 @@ static GstElement *__get_hw_encoder_element(webrtc_s *webrtc, webrtc_media_sourc if (type == WEBRTC_MEDIA_SOURCE_TYPE_CAMERA || type == WEBRTC_MEDIA_SOURCE_TYPE_VIDEOTEST) { if (source && source->v_hw_encoder_element) - return _create_element(source->v_hw_encoder_element, NULL); - if (webrtc->ini.media_source.v_hw_encoder_element) - return _create_element(webrtc->ini.media_source.v_hw_encoder_element, NULL); - + encoder = _create_element(source->v_hw_encoder_element, NULL); + else if (webrtc->ini.media_source.v_hw_encoder_element) + encoder = _create_element(webrtc->ini.media_source.v_hw_encoder_element, NULL); +#ifdef TIZEN_FEATURE_RES_MGR + if (encoder) + webrtc->resource.need_to_acquire[MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_ENCODER] = true; +#endif + return encoder; } else if (type == WEBRTC_MEDIA_SOURCE_TYPE_MIC || type == WEBRTC_MEDIA_SOURCE_TYPE_AUDIOTEST) { if (source && source->a_hw_encoder_element) return _create_element(source->a_hw_encoder_element, NULL); @@ -702,7 +707,9 @@ static int __build_camerasrc(webrtc_s *webrtc, webrtc_gst_slot_s *source) RET_VAL_IF(source->src_pad == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "src_pad is NULL"); source->media_types = MEDIA_TYPE_VIDEO; - +#ifdef TIZEN_FEATURE_RES_MGR + webrtc->resource.need_to_acquire[MM_RESOURCE_MANAGER_RES_TYPE_CAMERA] = true; +#endif if (!(camerasrc = _create_element(__get_source_element(webrtc, WEBRTC_MEDIA_SOURCE_TYPE_CAMERA), NULL))) { LOG_ERROR("failed to create camerasrc"); return WEBRTC_ERROR_INVALID_OPERATION; @@ -1425,4 +1432,4 @@ int _push_media_packet(webrtc_s *webrtc, unsigned int source_id, media_packet_h } return WEBRTC_ERROR_NONE; -} \ No newline at end of file +}