From b79012ad96b65afc7f54debd6e5fb6ce1788b43a Mon Sep 17 00:00:00 2001 From: Volodymyr Brynza Date: Thu, 8 Dec 2016 13:48:09 +0200 Subject: [PATCH 01/16] Implement DPM requests for camera and mic Change-Id: Ic1e57ca37017a0aac694a457e5b62b00ba0cf55b Signed-off-by: Volodymyr Brynza --- CMakeLists.txt | 4 +- include/media_streamer_node.h | 1 + include/media_streamer_node_policy.h | 40 +++++++ include/media_streamer_priv.h | 3 + packaging/capi-media-streamer.spec | 1 + src/media_streamer_node.c | 41 +++++++ src/media_streamer_node_policy.c | 204 +++++++++++++++++++++++++++++++++++ src/media_streamer_node_resources.c | 2 +- src/media_streamer_priv.c | 47 ++++++++ 9 files changed, 340 insertions(+), 3 deletions(-) create mode 100644 include/media_streamer_node_policy.h create mode 100644 src/media_streamer_node_policy.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 0c7e7c5..04a307d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,8 +10,8 @@ SET(PREFIX ${CMAKE_INSTALL_PREFIX}) SET(INC_DIR include) INCLUDE_DIRECTORIES(${INC_DIR}) -SET(dependents "dlog glib-2.0 mm-common capi-media-tool iniparser bundle libtbm gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-app-1.0 gstreamer-video-1.0 cynara-client capi-system-info ecore elementary murphy-resource murphy-glib") -SET(pc_dependents "capi-base-common capi-media-tool gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-app-1.0 gstreamer-video-1.0 cynara-client capi-system-info ecore evas elementary murphy-resource murphy-glib") +SET(dependents "dlog glib-2.0 mm-common capi-media-tool iniparser bundle libtbm gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-app-1.0 gstreamer-video-1.0 cynara-client capi-system-info ecore elementary murphy-resource murphy-glib dpm") +SET(pc_dependents "capi-base-common capi-media-tool gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-app-1.0 gstreamer-video-1.0 cynara-client capi-system-info ecore evas elementary murphy-resource murphy-glib dpm") INCLUDE(FindPkgConfig) pkg_check_modules(${fw_name} REQUIRED ${dependents}) diff --git a/include/media_streamer_node.h b/include/media_streamer_node.h index f79f9e5..add8a37 100644 --- a/include/media_streamer_node.h +++ b/include/media_streamer_node.h @@ -131,3 +131,4 @@ int __ms_node_set_pad_format(media_streamer_node_s *node, const char *pad_name, gboolean _ms_node_resouces_acquire_iter(const GValue *item, GValue *ret, gpointer user_data); gboolean _ms_node_resouces_release_iter(const GValue *item, GValue *ret, gpointer user_data); +gboolean _ms_node_policy_check_iter(const GValue *item, GValue *ret, gpointer user_data); diff --git a/include/media_streamer_node_policy.h b/include/media_streamer_node_policy.h new file mode 100644 index 0000000..5f9adef --- /dev/null +++ b/include/media_streamer_node_policy.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2015-2016 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. + */ + +#ifndef __MEDIA_STREAMER_NODE_POLICY_H__ +#define __MEDIA_STREAMER_NODE_POLICY_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + POLICY_TYPE_NONE, + POLICY_TYPE_CAMERA, + POLICY_TYPE_MIC, +} media_streamer_policy_type_e; + +int __ms_node_policy_init(media_streamer_node_s *node); +int __ms_node_policy_deinit(media_streamer_node_s *node); +int _ms_node_policy_check(media_streamer_node_s *node); + +#ifdef __cplusplus +} +#endif + +#endif /* __MEDIA_STREAMER_NODE_POLICY_H__ */ diff --git a/include/media_streamer_priv.h b/include/media_streamer_priv.h index 14a45f7..bbfd37b 100755 --- a/include/media_streamer_priv.h +++ b/include/media_streamer_priv.h @@ -24,6 +24,7 @@ extern "C" { #include #include +#include #include #include @@ -137,6 +138,8 @@ typedef struct { void *callbacks_structure; media_streamer_resource_manager_s resource_manager; + device_policy_manager_h dpm_handle; + int policy_changed_cb_id; } media_streamer_node_s; typedef struct _media_streamer_wl_info_s { diff --git a/packaging/capi-media-streamer.spec b/packaging/capi-media-streamer.spec index 7443f3b..317b737 100644 --- a/packaging/capi-media-streamer.spec +++ b/packaging/capi-media-streamer.spec @@ -31,6 +31,7 @@ BuildRequires: pkgconfig(ecore-wayland) BuildRequires: pkgconfig(appcore-efl) BuildRequires: pkgconfig(murphy-resource) BuildRequires: pkgconfig(murphy-glib) +BuildRequires: pkgconfig(dpm) %description A MediaStreamer library in Tizen Native API. diff --git a/src/media_streamer_node.c b/src/media_streamer_node.c index a87724f..ced5323 100644 --- a/src/media_streamer_node.c +++ b/src/media_streamer_node.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -579,6 +580,12 @@ int __ms_src_node_create(media_streamer_node_s *node) return ret; } + ret = __ms_node_policy_init(node); + if (MEDIA_STREAMER_ERROR_NONE != ret) { + ms_error("Failed to init policy for node [%s]", node->name); + return ret; + } + return ret; } @@ -702,6 +709,10 @@ void __ms_node_destroy(media_streamer_node_s *node) /* Disconnects and clean all node signals */ g_list_free_full(node->sig_list, __ms_signal_destroy); + /* Deinitialize policy manager */ + if (MEDIA_STREAMER_ERROR_NONE != __ms_node_policy_deinit(node)) + ms_error("Failed to deinitialize policy manager"); + /* Deinitialize resource manager */ if (MEDIA_STREAMER_ERROR_NONE != __ms_node_resouces_deinit(node)) ms_error("Failed to deinitialize resource manager"); @@ -1598,3 +1609,33 @@ gboolean _ms_node_resouces_release_iter(const GValue *item, GValue *ret, gpointe return TRUE; } + +gboolean _ms_node_policy_check_iter(const GValue *item, GValue *ret, gpointer user_data) +{ + media_streamer_s *ms_streamer = (media_streamer_s *) user_data; + media_streamer_node_s *node = NULL; + GstElement *element = NULL; + g_value_set_boolean(ret, FALSE); + + element = GST_ELEMENT(g_value_get_object(item)); + g_object_ref(element); + + node = (media_streamer_node_s *) g_hash_table_lookup(ms_streamer->nodes_table, + GST_ELEMENT_NAME(element)); + if (!node) { + /* If we fail to found corresonding node inside streamer + then apprently this element doesn't require resources */ + ms_info("Failed to found corresonding node [%s] inside streamer", GST_ELEMENT_NAME(element)); + g_value_set_boolean(ret, TRUE); + return TRUE; + } + + if (MEDIA_STREAMER_ERROR_NONE != _ms_node_policy_check(node)) { + ms_error("Failed to check policy for node [%s]", node->name); + return FALSE; + } + + g_value_set_boolean(ret, TRUE); + + return TRUE; +} diff --git a/src/media_streamer_node_policy.c b/src/media_streamer_node_policy.c new file mode 100644 index 0000000..90628b9 --- /dev/null +++ b/src/media_streamer_node_policy.c @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2016 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 +#include + +#include +#include +#include +#include + +#define DPM_ALLOWED 1 +#define DPM_DISALLOWED 0 + +enum { + DPM_POLICY_FOR_CAMERA, + DPM_POLICY_FOR_MIC, + DPM_POLICY_MAX, +}; +const char* policy_str[DPM_POLICY_MAX] = { + "camera", + "microphone", +}; + +static void __ms_node_get_dpm_check_needed(media_streamer_node_s *node, + media_streamer_policy_type_e *policy) { + int subtype = node->subtype; + + ms_debug("Checking policy for node type %d, subtype %d", node->type, subtype); + + /* Check for node types */ + switch (subtype) { + case MEDIA_STREAMER_NODE_SRC_TYPE_CAMERA: + case MEDIA_STREAMER_NODE_SRC_TYPE_VIDEO_CAPTURE: + *policy = POLICY_TYPE_CAMERA; + break; + case MEDIA_STREAMER_NODE_SRC_TYPE_AUDIO_CAPTURE: + *policy = POLICY_TYPE_MIC; + break; + default: + break; + } +} + +static void __ms_node_policy_changed_cb(const char *name, const char *value, void *user_data) +{ + if (user_data == NULL) + return; + + media_streamer_node_s *node = (media_streamer_node_s *) user_data; + media_streamer_s *streamer = (media_streamer_s *) node->parent_streamer; + ms_info("Received policy_changed_cb from node [%s]", node->name); + + /* Here we perform action to release resources relases that + were previoursly acquired. Basically what we need to do is + to unprepare media streamer.*/ + g_mutex_lock(&streamer->mutex_lock); + streamer->is_interrupted = TRUE; + if (MEDIA_STREAMER_ERROR_NONE != + __ms_pipeline_unprepare(streamer)) { + ms_error("Failed to unprepare streamer"); + streamer->is_interrupted = FALSE; + g_mutex_unlock(&streamer->mutex_lock); + return; + } + streamer->is_interrupted = FALSE; + + /* Call interrupted_cb with appropriate code */ + media_streamer_interrupted_cb interrupted_cb = + (media_streamer_interrupted_cb) streamer->interrupted_cb.callback; + if (interrupted_cb) { + interrupted_cb(MEDIA_STREAMER_INTERRUPTED_BY_SECURITY, + streamer->interrupted_cb.user_data); + } else { + ms_info("Interuption will not be handled because interrupted_cb is NULL"); + } + g_mutex_unlock(&streamer->mutex_lock); +} + +int __ms_node_policy_init(media_streamer_node_s *node) +{ + media_streamer_policy_type_e policy = POLICY_TYPE_NONE; + int ret = MEDIA_STREAMER_ERROR_NONE; + const char *policy_name = NULL; + + /* Check if node require policy manager */ + __ms_node_get_dpm_check_needed(node, &policy); + if (POLICY_TYPE_NONE == policy) { + ms_info("No policy is needed for %p node type [%d] subtype [%d]", + node, node->type, node->subtype); + return MEDIA_STREAMER_ERROR_NONE; + } + + switch (policy) { + case POLICY_TYPE_CAMERA: + policy_name = policy_str[DPM_POLICY_FOR_CAMERA]; + break; + case POLICY_TYPE_MIC: + policy_name = policy_str[DPM_POLICY_FOR_MIC]; + break; + default: + break; + } + /* Initialize policy manager */ + node->dpm_handle = dpm_manager_create(); + if (node->dpm_handle) { + int dpm_ret = DPM_ERROR_NONE; + dpm_ret = dpm_add_policy_changed_cb(node->dpm_handle, policy_name, + __ms_node_policy_changed_cb, (void *)node, &node->policy_changed_cb_id); + + if (dpm_ret != DPM_ERROR_NONE) { + ms_error("add DPM changed cb failed, keep going"); + node->policy_changed_cb_id = 0; + } + ms_debug("DPM initialized"); + } + + return ret; +} + +int __ms_node_policy_deinit(media_streamer_node_s *node) +{ + media_streamer_policy_type_e policy = POLICY_TYPE_NONE; + int ret = MEDIA_STREAMER_ERROR_NONE; + + /* Check if node require policy manager */ + __ms_node_get_dpm_check_needed(node, &policy); + if (POLICY_TYPE_NONE == policy) { + ms_info("No policy is needed for %p node type [%d] subtype [%d]", + node, node->type, node->subtype); + return MEDIA_STREAMER_ERROR_NONE; + } + + if (node->dpm_handle) { + if (node->policy_changed_cb_id > 0) { + dpm_remove_policy_changed_cb(node->dpm_handle, node->policy_changed_cb_id); + } else { + ms_info("invalid dpm cb id"); + } + ms_debug("DPM released"); + } + + dpm_manager_destroy(node->dpm_handle); + node->dpm_handle = NULL; + + return ret; +} + +int _ms_node_policy_check(media_streamer_node_s *node) +{ + media_streamer_policy_type_e policy = POLICY_TYPE_NONE; + int ret = MEDIA_STREAMER_ERROR_NONE; + int dpm_state = DPM_ALLOWED; + int dpm_ret = DPM_ERROR_NONE; + + /* Check if node require policy manager */ + __ms_node_get_dpm_check_needed(node, &policy); + if (POLICY_TYPE_NONE == policy) { + ms_info("No policy is needed for %p node type [%d] subtype [%d]", + node, node->type, node->subtype); + return MEDIA_STREAMER_ERROR_NONE; + } + + if (node->dpm_handle == NULL) { + ms_error("DPM manager handle is NULL"); + return MEDIA_STREAMER_ERROR_INVALID_OPERATION; + } + + switch (policy) { + case POLICY_TYPE_CAMERA: + dpm_ret = dpm_restriction_get_camera_state(node->dpm_handle, &dpm_state); + break; + case POLICY_TYPE_MIC: + dpm_ret = dpm_restriction_get_microphone_state(node->dpm_handle, &dpm_state); + break; + default: + break; + } + + if (dpm_ret == DPM_ERROR_NONE) { + ms_info("DPM state - %d", dpm_state); + if (dpm_state == DPM_DISALLOWED) { + ms_error("Policy disallowed by DPM"); + return MEDIA_STREAMER_ERROR_INVALID_OPERATION; + } + } else { + ms_info("get DPM state failed, continue too work"); + } + + return ret; +} diff --git a/src/media_streamer_node_resources.c b/src/media_streamer_node_resources.c index 5dabe15..3c1545a 100644 --- a/src/media_streamer_node_resources.c +++ b/src/media_streamer_node_resources.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2016 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. diff --git a/src/media_streamer_priv.c b/src/media_streamer_priv.c index 3fe8485..a6b995d 100644 --- a/src/media_streamer_priv.c +++ b/src/media_streamer_priv.c @@ -23,6 +23,7 @@ #define GST_TIME_TO_MSEC(t) (t == GST_CLOCK_TIME_NONE ? t : (int)(((GstClockTime)(t)) / GST_MSECOND)) int __ms_change_resources_state(media_streamer_s *ms_streamer, media_streamer_state_e state); +int __ms_change_policy_state(media_streamer_s *ms_streamer, media_streamer_state_e state); static gboolean media_streamer_resource_relese_cb(media_streamer_resource_manager_s *resource_manager, void *user_data); int __ms_state_change(media_streamer_s *ms_streamer, media_streamer_state_e state) @@ -33,6 +34,11 @@ int __ms_state_change(media_streamer_s *ms_streamer, media_streamer_state_e stat ms_retvm_if(ms_streamer->state == state, MEDIA_STREAMER_ERROR_NONE, "Media streamer already in this state"); if (!ms_streamer->is_interrupted) { + ret = __ms_change_policy_state(ms_streamer, state); + if (MEDIA_STREAMER_ERROR_NONE != ret) { + ms_error("Failed to change policy state for streamer %p", ms_streamer); + return MEDIA_STREAMER_ERROR_INVALID_OPERATION; + } ret = __ms_change_resources_state(ms_streamer, state); if (MEDIA_STREAMER_ERROR_NONE != ret) { ms_error("Failed to change resources state for streamer %p", ms_streamer); @@ -338,3 +344,44 @@ static gboolean media_streamer_resource_relese_cb( return TRUE; } + +int __ms_check_policy(media_streamer_s *ms_streamer) +{ + int ret = MEDIA_STREAMER_ERROR_NONE; + + /* Acquire resources for src bin */ + ret = __ms_bin_foreach_elements(GST_BIN(ms_streamer->src_bin), + _ms_node_policy_check_iter, ms_streamer); + if (MEDIA_STREAMER_ERROR_NONE != ret) { + ms_error("Failed to check policies for src bin"); + return ret; + } + + return MEDIA_STREAMER_ERROR_NONE; +} + +int __ms_change_policy_state(media_streamer_s *ms_streamer, media_streamer_state_e state) +{ + int ret = MEDIA_STREAMER_ERROR_NONE; + + /* According to state graph we need to handle only this state + * and different transotions into them */ + if (state == MEDIA_STREAMER_STATE_READY) { + switch (ms_streamer->pend_state) { + case MEDIA_STREAMER_STATE_IDLE: + /* After prepare function */ + ret = __ms_check_policy(ms_streamer); + break; + case MEDIA_STREAMER_STATE_PAUSED: + case MEDIA_STREAMER_STATE_PLAYING: + case MEDIA_STREAMER_STATE_NONE: + case MEDIA_STREAMER_STATE_SEEKING: + default: + break; + } + } else { + ms_debug("Ignoring state for policy managements"); + } + + return ret; +} -- 2.7.4 From 73a6be599b809791ca3f094cc2902a789c168751 Mon Sep 17 00:00:00 2001 From: Volodymyr Brynza Date: Thu, 8 Dec 2016 13:48:09 +0200 Subject: [PATCH 02/16] Implement DPM requests for camera and mic Change-Id: Ic1e57ca37017a0aac694a457e5b62b00ba0cf55b Signed-off-by: Volodymyr Brynza (cherry picked from commit b79012ad96b65afc7f54debd6e5fb6ce1788b43a) --- CMakeLists.txt | 4 +- include/media_streamer_node.h | 1 + include/media_streamer_node_policy.h | 40 +++++++ include/media_streamer_priv.h | 3 + packaging/capi-media-streamer.spec | 1 + src/media_streamer_node.c | 41 +++++++ src/media_streamer_node_policy.c | 204 +++++++++++++++++++++++++++++++++++ src/media_streamer_node_resources.c | 2 +- src/media_streamer_priv.c | 47 ++++++++ 9 files changed, 340 insertions(+), 3 deletions(-) create mode 100644 include/media_streamer_node_policy.h create mode 100644 src/media_streamer_node_policy.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 0c7e7c5..04a307d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,8 +10,8 @@ SET(PREFIX ${CMAKE_INSTALL_PREFIX}) SET(INC_DIR include) INCLUDE_DIRECTORIES(${INC_DIR}) -SET(dependents "dlog glib-2.0 mm-common capi-media-tool iniparser bundle libtbm gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-app-1.0 gstreamer-video-1.0 cynara-client capi-system-info ecore elementary murphy-resource murphy-glib") -SET(pc_dependents "capi-base-common capi-media-tool gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-app-1.0 gstreamer-video-1.0 cynara-client capi-system-info ecore evas elementary murphy-resource murphy-glib") +SET(dependents "dlog glib-2.0 mm-common capi-media-tool iniparser bundle libtbm gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-app-1.0 gstreamer-video-1.0 cynara-client capi-system-info ecore elementary murphy-resource murphy-glib dpm") +SET(pc_dependents "capi-base-common capi-media-tool gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-app-1.0 gstreamer-video-1.0 cynara-client capi-system-info ecore evas elementary murphy-resource murphy-glib dpm") INCLUDE(FindPkgConfig) pkg_check_modules(${fw_name} REQUIRED ${dependents}) diff --git a/include/media_streamer_node.h b/include/media_streamer_node.h index f79f9e5..add8a37 100644 --- a/include/media_streamer_node.h +++ b/include/media_streamer_node.h @@ -131,3 +131,4 @@ int __ms_node_set_pad_format(media_streamer_node_s *node, const char *pad_name, gboolean _ms_node_resouces_acquire_iter(const GValue *item, GValue *ret, gpointer user_data); gboolean _ms_node_resouces_release_iter(const GValue *item, GValue *ret, gpointer user_data); +gboolean _ms_node_policy_check_iter(const GValue *item, GValue *ret, gpointer user_data); diff --git a/include/media_streamer_node_policy.h b/include/media_streamer_node_policy.h new file mode 100644 index 0000000..5f9adef --- /dev/null +++ b/include/media_streamer_node_policy.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2015-2016 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. + */ + +#ifndef __MEDIA_STREAMER_NODE_POLICY_H__ +#define __MEDIA_STREAMER_NODE_POLICY_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + POLICY_TYPE_NONE, + POLICY_TYPE_CAMERA, + POLICY_TYPE_MIC, +} media_streamer_policy_type_e; + +int __ms_node_policy_init(media_streamer_node_s *node); +int __ms_node_policy_deinit(media_streamer_node_s *node); +int _ms_node_policy_check(media_streamer_node_s *node); + +#ifdef __cplusplus +} +#endif + +#endif /* __MEDIA_STREAMER_NODE_POLICY_H__ */ diff --git a/include/media_streamer_priv.h b/include/media_streamer_priv.h index 14a45f7..bbfd37b 100755 --- a/include/media_streamer_priv.h +++ b/include/media_streamer_priv.h @@ -24,6 +24,7 @@ extern "C" { #include #include +#include #include #include @@ -137,6 +138,8 @@ typedef struct { void *callbacks_structure; media_streamer_resource_manager_s resource_manager; + device_policy_manager_h dpm_handle; + int policy_changed_cb_id; } media_streamer_node_s; typedef struct _media_streamer_wl_info_s { diff --git a/packaging/capi-media-streamer.spec b/packaging/capi-media-streamer.spec index 7443f3b..317b737 100644 --- a/packaging/capi-media-streamer.spec +++ b/packaging/capi-media-streamer.spec @@ -31,6 +31,7 @@ BuildRequires: pkgconfig(ecore-wayland) BuildRequires: pkgconfig(appcore-efl) BuildRequires: pkgconfig(murphy-resource) BuildRequires: pkgconfig(murphy-glib) +BuildRequires: pkgconfig(dpm) %description A MediaStreamer library in Tizen Native API. diff --git a/src/media_streamer_node.c b/src/media_streamer_node.c index a87724f..ced5323 100644 --- a/src/media_streamer_node.c +++ b/src/media_streamer_node.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -579,6 +580,12 @@ int __ms_src_node_create(media_streamer_node_s *node) return ret; } + ret = __ms_node_policy_init(node); + if (MEDIA_STREAMER_ERROR_NONE != ret) { + ms_error("Failed to init policy for node [%s]", node->name); + return ret; + } + return ret; } @@ -702,6 +709,10 @@ void __ms_node_destroy(media_streamer_node_s *node) /* Disconnects and clean all node signals */ g_list_free_full(node->sig_list, __ms_signal_destroy); + /* Deinitialize policy manager */ + if (MEDIA_STREAMER_ERROR_NONE != __ms_node_policy_deinit(node)) + ms_error("Failed to deinitialize policy manager"); + /* Deinitialize resource manager */ if (MEDIA_STREAMER_ERROR_NONE != __ms_node_resouces_deinit(node)) ms_error("Failed to deinitialize resource manager"); @@ -1598,3 +1609,33 @@ gboolean _ms_node_resouces_release_iter(const GValue *item, GValue *ret, gpointe return TRUE; } + +gboolean _ms_node_policy_check_iter(const GValue *item, GValue *ret, gpointer user_data) +{ + media_streamer_s *ms_streamer = (media_streamer_s *) user_data; + media_streamer_node_s *node = NULL; + GstElement *element = NULL; + g_value_set_boolean(ret, FALSE); + + element = GST_ELEMENT(g_value_get_object(item)); + g_object_ref(element); + + node = (media_streamer_node_s *) g_hash_table_lookup(ms_streamer->nodes_table, + GST_ELEMENT_NAME(element)); + if (!node) { + /* If we fail to found corresonding node inside streamer + then apprently this element doesn't require resources */ + ms_info("Failed to found corresonding node [%s] inside streamer", GST_ELEMENT_NAME(element)); + g_value_set_boolean(ret, TRUE); + return TRUE; + } + + if (MEDIA_STREAMER_ERROR_NONE != _ms_node_policy_check(node)) { + ms_error("Failed to check policy for node [%s]", node->name); + return FALSE; + } + + g_value_set_boolean(ret, TRUE); + + return TRUE; +} diff --git a/src/media_streamer_node_policy.c b/src/media_streamer_node_policy.c new file mode 100644 index 0000000..90628b9 --- /dev/null +++ b/src/media_streamer_node_policy.c @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2016 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 +#include + +#include +#include +#include +#include + +#define DPM_ALLOWED 1 +#define DPM_DISALLOWED 0 + +enum { + DPM_POLICY_FOR_CAMERA, + DPM_POLICY_FOR_MIC, + DPM_POLICY_MAX, +}; +const char* policy_str[DPM_POLICY_MAX] = { + "camera", + "microphone", +}; + +static void __ms_node_get_dpm_check_needed(media_streamer_node_s *node, + media_streamer_policy_type_e *policy) { + int subtype = node->subtype; + + ms_debug("Checking policy for node type %d, subtype %d", node->type, subtype); + + /* Check for node types */ + switch (subtype) { + case MEDIA_STREAMER_NODE_SRC_TYPE_CAMERA: + case MEDIA_STREAMER_NODE_SRC_TYPE_VIDEO_CAPTURE: + *policy = POLICY_TYPE_CAMERA; + break; + case MEDIA_STREAMER_NODE_SRC_TYPE_AUDIO_CAPTURE: + *policy = POLICY_TYPE_MIC; + break; + default: + break; + } +} + +static void __ms_node_policy_changed_cb(const char *name, const char *value, void *user_data) +{ + if (user_data == NULL) + return; + + media_streamer_node_s *node = (media_streamer_node_s *) user_data; + media_streamer_s *streamer = (media_streamer_s *) node->parent_streamer; + ms_info("Received policy_changed_cb from node [%s]", node->name); + + /* Here we perform action to release resources relases that + were previoursly acquired. Basically what we need to do is + to unprepare media streamer.*/ + g_mutex_lock(&streamer->mutex_lock); + streamer->is_interrupted = TRUE; + if (MEDIA_STREAMER_ERROR_NONE != + __ms_pipeline_unprepare(streamer)) { + ms_error("Failed to unprepare streamer"); + streamer->is_interrupted = FALSE; + g_mutex_unlock(&streamer->mutex_lock); + return; + } + streamer->is_interrupted = FALSE; + + /* Call interrupted_cb with appropriate code */ + media_streamer_interrupted_cb interrupted_cb = + (media_streamer_interrupted_cb) streamer->interrupted_cb.callback; + if (interrupted_cb) { + interrupted_cb(MEDIA_STREAMER_INTERRUPTED_BY_SECURITY, + streamer->interrupted_cb.user_data); + } else { + ms_info("Interuption will not be handled because interrupted_cb is NULL"); + } + g_mutex_unlock(&streamer->mutex_lock); +} + +int __ms_node_policy_init(media_streamer_node_s *node) +{ + media_streamer_policy_type_e policy = POLICY_TYPE_NONE; + int ret = MEDIA_STREAMER_ERROR_NONE; + const char *policy_name = NULL; + + /* Check if node require policy manager */ + __ms_node_get_dpm_check_needed(node, &policy); + if (POLICY_TYPE_NONE == policy) { + ms_info("No policy is needed for %p node type [%d] subtype [%d]", + node, node->type, node->subtype); + return MEDIA_STREAMER_ERROR_NONE; + } + + switch (policy) { + case POLICY_TYPE_CAMERA: + policy_name = policy_str[DPM_POLICY_FOR_CAMERA]; + break; + case POLICY_TYPE_MIC: + policy_name = policy_str[DPM_POLICY_FOR_MIC]; + break; + default: + break; + } + /* Initialize policy manager */ + node->dpm_handle = dpm_manager_create(); + if (node->dpm_handle) { + int dpm_ret = DPM_ERROR_NONE; + dpm_ret = dpm_add_policy_changed_cb(node->dpm_handle, policy_name, + __ms_node_policy_changed_cb, (void *)node, &node->policy_changed_cb_id); + + if (dpm_ret != DPM_ERROR_NONE) { + ms_error("add DPM changed cb failed, keep going"); + node->policy_changed_cb_id = 0; + } + ms_debug("DPM initialized"); + } + + return ret; +} + +int __ms_node_policy_deinit(media_streamer_node_s *node) +{ + media_streamer_policy_type_e policy = POLICY_TYPE_NONE; + int ret = MEDIA_STREAMER_ERROR_NONE; + + /* Check if node require policy manager */ + __ms_node_get_dpm_check_needed(node, &policy); + if (POLICY_TYPE_NONE == policy) { + ms_info("No policy is needed for %p node type [%d] subtype [%d]", + node, node->type, node->subtype); + return MEDIA_STREAMER_ERROR_NONE; + } + + if (node->dpm_handle) { + if (node->policy_changed_cb_id > 0) { + dpm_remove_policy_changed_cb(node->dpm_handle, node->policy_changed_cb_id); + } else { + ms_info("invalid dpm cb id"); + } + ms_debug("DPM released"); + } + + dpm_manager_destroy(node->dpm_handle); + node->dpm_handle = NULL; + + return ret; +} + +int _ms_node_policy_check(media_streamer_node_s *node) +{ + media_streamer_policy_type_e policy = POLICY_TYPE_NONE; + int ret = MEDIA_STREAMER_ERROR_NONE; + int dpm_state = DPM_ALLOWED; + int dpm_ret = DPM_ERROR_NONE; + + /* Check if node require policy manager */ + __ms_node_get_dpm_check_needed(node, &policy); + if (POLICY_TYPE_NONE == policy) { + ms_info("No policy is needed for %p node type [%d] subtype [%d]", + node, node->type, node->subtype); + return MEDIA_STREAMER_ERROR_NONE; + } + + if (node->dpm_handle == NULL) { + ms_error("DPM manager handle is NULL"); + return MEDIA_STREAMER_ERROR_INVALID_OPERATION; + } + + switch (policy) { + case POLICY_TYPE_CAMERA: + dpm_ret = dpm_restriction_get_camera_state(node->dpm_handle, &dpm_state); + break; + case POLICY_TYPE_MIC: + dpm_ret = dpm_restriction_get_microphone_state(node->dpm_handle, &dpm_state); + break; + default: + break; + } + + if (dpm_ret == DPM_ERROR_NONE) { + ms_info("DPM state - %d", dpm_state); + if (dpm_state == DPM_DISALLOWED) { + ms_error("Policy disallowed by DPM"); + return MEDIA_STREAMER_ERROR_INVALID_OPERATION; + } + } else { + ms_info("get DPM state failed, continue too work"); + } + + return ret; +} diff --git a/src/media_streamer_node_resources.c b/src/media_streamer_node_resources.c index 5dabe15..3c1545a 100644 --- a/src/media_streamer_node_resources.c +++ b/src/media_streamer_node_resources.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2016 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. diff --git a/src/media_streamer_priv.c b/src/media_streamer_priv.c index 3fe8485..a6b995d 100644 --- a/src/media_streamer_priv.c +++ b/src/media_streamer_priv.c @@ -23,6 +23,7 @@ #define GST_TIME_TO_MSEC(t) (t == GST_CLOCK_TIME_NONE ? t : (int)(((GstClockTime)(t)) / GST_MSECOND)) int __ms_change_resources_state(media_streamer_s *ms_streamer, media_streamer_state_e state); +int __ms_change_policy_state(media_streamer_s *ms_streamer, media_streamer_state_e state); static gboolean media_streamer_resource_relese_cb(media_streamer_resource_manager_s *resource_manager, void *user_data); int __ms_state_change(media_streamer_s *ms_streamer, media_streamer_state_e state) @@ -33,6 +34,11 @@ int __ms_state_change(media_streamer_s *ms_streamer, media_streamer_state_e stat ms_retvm_if(ms_streamer->state == state, MEDIA_STREAMER_ERROR_NONE, "Media streamer already in this state"); if (!ms_streamer->is_interrupted) { + ret = __ms_change_policy_state(ms_streamer, state); + if (MEDIA_STREAMER_ERROR_NONE != ret) { + ms_error("Failed to change policy state for streamer %p", ms_streamer); + return MEDIA_STREAMER_ERROR_INVALID_OPERATION; + } ret = __ms_change_resources_state(ms_streamer, state); if (MEDIA_STREAMER_ERROR_NONE != ret) { ms_error("Failed to change resources state for streamer %p", ms_streamer); @@ -338,3 +344,44 @@ static gboolean media_streamer_resource_relese_cb( return TRUE; } + +int __ms_check_policy(media_streamer_s *ms_streamer) +{ + int ret = MEDIA_STREAMER_ERROR_NONE; + + /* Acquire resources for src bin */ + ret = __ms_bin_foreach_elements(GST_BIN(ms_streamer->src_bin), + _ms_node_policy_check_iter, ms_streamer); + if (MEDIA_STREAMER_ERROR_NONE != ret) { + ms_error("Failed to check policies for src bin"); + return ret; + } + + return MEDIA_STREAMER_ERROR_NONE; +} + +int __ms_change_policy_state(media_streamer_s *ms_streamer, media_streamer_state_e state) +{ + int ret = MEDIA_STREAMER_ERROR_NONE; + + /* According to state graph we need to handle only this state + * and different transotions into them */ + if (state == MEDIA_STREAMER_STATE_READY) { + switch (ms_streamer->pend_state) { + case MEDIA_STREAMER_STATE_IDLE: + /* After prepare function */ + ret = __ms_check_policy(ms_streamer); + break; + case MEDIA_STREAMER_STATE_PAUSED: + case MEDIA_STREAMER_STATE_PLAYING: + case MEDIA_STREAMER_STATE_NONE: + case MEDIA_STREAMER_STATE_SEEKING: + default: + break; + } + } else { + ms_debug("Ignoring state for policy managements"); + } + + return ret; +} -- 2.7.4 From 7c16b0bd37214f99f2bb3dd1a46d67bd87961484 Mon Sep 17 00:00:00 2001 From: Volodymyr Brynza Date: Mon, 19 Dec 2016 22:31:44 +0200 Subject: [PATCH 03/16] Add Murphy loop quit to prevent polling after destroy Change-Id: I789b032fced4b95a767b4efcda92c54fb5c2cd12 Signed-off-by: Volodymyr Brynza --- src/media_streamer_resource.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/media_streamer_resource.c b/src/media_streamer_resource.c index 4d84082..6f99048 100644 --- a/src/media_streamer_resource.c +++ b/src/media_streamer_resource.c @@ -520,6 +520,7 @@ int _ms_resource_manager_deinit(media_streamer_resource_manager_s *resource_mana } if (resource_manager->mloop) { + mrp_mainloop_quit(resource_manager->mloop, 0); mrp_mainloop_destroy(resource_manager->mloop); resource_manager->mloop = NULL; } -- 2.7.4 From 526c4fde1380d5fcdfa70a0a8c320c10af3094c8 Mon Sep 17 00:00:00 2001 From: Volodymyr Brynza Date: Mon, 19 Dec 2016 22:31:44 +0200 Subject: [PATCH 04/16] Add Murphy loop quit to prevent polling after destroy Change-Id: I789b032fced4b95a767b4efcda92c54fb5c2cd12 Signed-off-by: Volodymyr Brynza (cherry picked from commit 7c16b0bd37214f99f2bb3dd1a46d67bd87961484) --- src/media_streamer_resource.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/media_streamer_resource.c b/src/media_streamer_resource.c index 4d84082..6f99048 100644 --- a/src/media_streamer_resource.c +++ b/src/media_streamer_resource.c @@ -520,6 +520,7 @@ int _ms_resource_manager_deinit(media_streamer_resource_manager_s *resource_mana } if (resource_manager->mloop) { + mrp_mainloop_quit(resource_manager->mloop, 0); mrp_mainloop_destroy(resource_manager->mloop); resource_manager->mloop = NULL; } -- 2.7.4 From 6fceb7b1aa3d798c22ffc7b1cb13403976b1c034 Mon Sep 17 00:00:00 2001 From: Oleksandr Popov Date: Tue, 27 Dec 2016 19:00:21 +0200 Subject: [PATCH 05/16] Add platform check before resource manager initialization Change-Id: I001fbd14fe4589db030a69e6fd985a32460ac6da Signed-off-by: Oleksandr Popov --- include/media_streamer_resource.h | 2 +- src/media_streamer_node_resources.c | 58 +++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/include/media_streamer_resource.h b/include/media_streamer_resource.h index 27da5ca..2cefdc8 100644 --- a/include/media_streamer_resource.h +++ b/include/media_streamer_resource.h @@ -52,7 +52,7 @@ typedef enum { } media_streamer_resource_state_e; typedef struct _media_streamer_resource_manager_s media_streamer_resource_manager_s; -typedef gboolean (*resource_relese_cb) (media_streamer_resource_manager_s *resource_manager, void *user_data); +typedef gboolean (*resource_relese_cb)(media_streamer_resource_manager_s *resource_manager, void *user_data); struct _media_streamer_resource_manager_s { mrp_mainloop_t *mloop; diff --git a/src/media_streamer_node_resources.c b/src/media_streamer_node_resources.c index 3c1545a..5e96813 100644 --- a/src/media_streamer_node_resources.c +++ b/src/media_streamer_node_resources.c @@ -16,6 +16,8 @@ #include +#include + #include #include #include @@ -61,6 +63,41 @@ static gboolean __ms_resource_relese_cb( return TRUE; } +static gboolean __ms_node_resources_is_needed_by_platform(media_streamer_node_s *node) +{ + media_streamer_node_type_e type = node->type; + int subtype = node->subtype; + char *model_name, *platform_processor; + gboolean ret = FALSE; + + /* Checking for model_name and processor because some resources + are platform dependent */ + system_info_get_platform_string("http://tizen.org/system/model_name", &model_name); + system_info_get_platform_string("http://tizen.org/system/platform.processor", &platform_processor); + ms_info("Check for resources for model_name %s, platform.processor %s", model_name, platform_processor); + + switch (type) { + case MEDIA_STREAMER_NODE_TYPE_VIDEO_ENCODER: + case MEDIA_STREAMER_NODE_TYPE_VIDEO_DECODER: + if (!g_strcmp0(model_name, "Emulator") || + !g_strcmp0(platform_processor, "Emulator")) + ret = FALSE; + break; + case MEDIA_STREAMER_NODE_TYPE_SRC: + if (MEDIA_STREAMER_NODE_SRC_TYPE_CAMERA == subtype) + ret = TRUE; + break; + case MEDIA_STREAMER_NODE_TYPE_SINK: + if (MEDIA_STREAMER_NODE_SINK_TYPE_OVERLAY == subtype) + ret = TRUE; + break; + default: + break; + } + + return ret; +} + static void __ms_node_get_resources_needed(media_streamer_node_s *node, media_streamer_resource_type_e *resource) { media_streamer_node_type_e type = node->type; @@ -101,6 +138,13 @@ int __ms_node_resouces_init(media_streamer_node_s *node) return MEDIA_STREAMER_ERROR_NONE; } + /* Check if platform requires resource (e.g. Emulator) */ + if (!__ms_node_resources_is_needed_by_platform(node)) { + ms_info("Platform doesn't require resource for %p node type [%d] subtype [%d]", + node, node->type, node->subtype); + return MEDIA_STREAMER_ERROR_NONE; + } + /* Initialize resource manager */ ret = _ms_resource_manager_init(&node->resource_manager, __ms_resource_relese_cb, node); @@ -125,6 +169,13 @@ int __ms_node_resouces_deinit(media_streamer_node_s *node) return MEDIA_STREAMER_ERROR_NONE; } + /* Check if platform requires resource (e.g. Emulator) */ + if (!__ms_node_resources_is_needed_by_platform(node)) { + ms_info("Platform doesn't require resource for %p node type [%d] subtype [%d]", + node, node->type, node->subtype); + return MEDIA_STREAMER_ERROR_NONE; + } + /* Deinitialize resource manager */ ret = _ms_resource_manager_deinit(&node->resource_manager); if (ret != MEDIA_STREAMER_ERROR_NONE) { @@ -196,6 +247,13 @@ int _ms_node_resource_aquire(media_streamer_node_s *node) return MEDIA_STREAMER_ERROR_NONE; } + /* Check if platform requires resource (e.g. Emulator) */ + if (!__ms_node_resources_is_needed_by_platform(node)) { + ms_info("Platform doesn't require resource for %p node type [%d] subtype [%d]", + node, node->type, node->subtype); + return MEDIA_STREAMER_ERROR_NONE; + } + if (MEDIA_STREAMER_ERROR_NONE != __ms_node_resouces_prepare(node, resource)) { ms_error("Failed to prepare resources for Node [%p]", node); return MEDIA_STREAMER_ERROR_INVALID_OPERATION; -- 2.7.4 From 81d4e447b82db4346069405ecfcfaeaf1fc0b388 Mon Sep 17 00:00:00 2001 From: Oleksandr Popov Date: Tue, 27 Dec 2016 19:00:21 +0200 Subject: [PATCH 06/16] Add platform check before resource manager initialization Change-Id: I001fbd14fe4589db030a69e6fd985a32460ac6da Signed-off-by: Oleksandr Popov --- include/media_streamer_resource.h | 2 +- src/media_streamer_node_resources.c | 58 +++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/include/media_streamer_resource.h b/include/media_streamer_resource.h index 27da5ca..2cefdc8 100644 --- a/include/media_streamer_resource.h +++ b/include/media_streamer_resource.h @@ -52,7 +52,7 @@ typedef enum { } media_streamer_resource_state_e; typedef struct _media_streamer_resource_manager_s media_streamer_resource_manager_s; -typedef gboolean (*resource_relese_cb) (media_streamer_resource_manager_s *resource_manager, void *user_data); +typedef gboolean (*resource_relese_cb)(media_streamer_resource_manager_s *resource_manager, void *user_data); struct _media_streamer_resource_manager_s { mrp_mainloop_t *mloop; diff --git a/src/media_streamer_node_resources.c b/src/media_streamer_node_resources.c index 3c1545a..5e96813 100644 --- a/src/media_streamer_node_resources.c +++ b/src/media_streamer_node_resources.c @@ -16,6 +16,8 @@ #include +#include + #include #include #include @@ -61,6 +63,41 @@ static gboolean __ms_resource_relese_cb( return TRUE; } +static gboolean __ms_node_resources_is_needed_by_platform(media_streamer_node_s *node) +{ + media_streamer_node_type_e type = node->type; + int subtype = node->subtype; + char *model_name, *platform_processor; + gboolean ret = FALSE; + + /* Checking for model_name and processor because some resources + are platform dependent */ + system_info_get_platform_string("http://tizen.org/system/model_name", &model_name); + system_info_get_platform_string("http://tizen.org/system/platform.processor", &platform_processor); + ms_info("Check for resources for model_name %s, platform.processor %s", model_name, platform_processor); + + switch (type) { + case MEDIA_STREAMER_NODE_TYPE_VIDEO_ENCODER: + case MEDIA_STREAMER_NODE_TYPE_VIDEO_DECODER: + if (!g_strcmp0(model_name, "Emulator") || + !g_strcmp0(platform_processor, "Emulator")) + ret = FALSE; + break; + case MEDIA_STREAMER_NODE_TYPE_SRC: + if (MEDIA_STREAMER_NODE_SRC_TYPE_CAMERA == subtype) + ret = TRUE; + break; + case MEDIA_STREAMER_NODE_TYPE_SINK: + if (MEDIA_STREAMER_NODE_SINK_TYPE_OVERLAY == subtype) + ret = TRUE; + break; + default: + break; + } + + return ret; +} + static void __ms_node_get_resources_needed(media_streamer_node_s *node, media_streamer_resource_type_e *resource) { media_streamer_node_type_e type = node->type; @@ -101,6 +138,13 @@ int __ms_node_resouces_init(media_streamer_node_s *node) return MEDIA_STREAMER_ERROR_NONE; } + /* Check if platform requires resource (e.g. Emulator) */ + if (!__ms_node_resources_is_needed_by_platform(node)) { + ms_info("Platform doesn't require resource for %p node type [%d] subtype [%d]", + node, node->type, node->subtype); + return MEDIA_STREAMER_ERROR_NONE; + } + /* Initialize resource manager */ ret = _ms_resource_manager_init(&node->resource_manager, __ms_resource_relese_cb, node); @@ -125,6 +169,13 @@ int __ms_node_resouces_deinit(media_streamer_node_s *node) return MEDIA_STREAMER_ERROR_NONE; } + /* Check if platform requires resource (e.g. Emulator) */ + if (!__ms_node_resources_is_needed_by_platform(node)) { + ms_info("Platform doesn't require resource for %p node type [%d] subtype [%d]", + node, node->type, node->subtype); + return MEDIA_STREAMER_ERROR_NONE; + } + /* Deinitialize resource manager */ ret = _ms_resource_manager_deinit(&node->resource_manager); if (ret != MEDIA_STREAMER_ERROR_NONE) { @@ -196,6 +247,13 @@ int _ms_node_resource_aquire(media_streamer_node_s *node) return MEDIA_STREAMER_ERROR_NONE; } + /* Check if platform requires resource (e.g. Emulator) */ + if (!__ms_node_resources_is_needed_by_platform(node)) { + ms_info("Platform doesn't require resource for %p node type [%d] subtype [%d]", + node, node->type, node->subtype); + return MEDIA_STREAMER_ERROR_NONE; + } + if (MEDIA_STREAMER_ERROR_NONE != __ms_node_resouces_prepare(node, resource)) { ms_error("Failed to prepare resources for Node [%p]", node); return MEDIA_STREAMER_ERROR_INVALID_OPERATION; -- 2.7.4 From 0a187c0051812dbe8e6c2f12c189cac7c2b239ae Mon Sep 17 00:00:00 2001 From: Oleksandr Popov Date: Tue, 27 Dec 2016 19:39:48 +0200 Subject: [PATCH 07/16] Added missing condition for resource management check Signed-off-by: Oleksandr Popov Change-Id: I700bad3752224583d04762081689b48188a5ec74 --- src/media_streamer_node_resources.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/media_streamer_node_resources.c b/src/media_streamer_node_resources.c index 5e96813..2f69001 100644 --- a/src/media_streamer_node_resources.c +++ b/src/media_streamer_node_resources.c @@ -82,6 +82,8 @@ static gboolean __ms_node_resources_is_needed_by_platform(media_streamer_node_s if (!g_strcmp0(model_name, "Emulator") || !g_strcmp0(platform_processor, "Emulator")) ret = FALSE; + else + ret = TRUE; break; case MEDIA_STREAMER_NODE_TYPE_SRC: if (MEDIA_STREAMER_NODE_SRC_TYPE_CAMERA == subtype) -- 2.7.4 From 4b988c903016df04335ca09a98ed9ddf9cf544a1 Mon Sep 17 00:00:00 2001 From: Eunhae Choi Date: Mon, 9 Jan 2017 21:52:24 +0900 Subject: [PATCH 08/16] [v0.1.12] init mrp after create pipeline and add missed unlock Change-Id: Icd662f3ce720ed2863a05dc0045b52459ff90717 (cherry picked from commit 1603f61104ec15d3adb42edfc4a694c21e1788d7) --- packaging/capi-media-streamer.spec | 2 +- src/media_streamer.c | 1 + src/media_streamer_gst.c | 10 +++++----- src/media_streamer_node_policy.c | 16 ++++++++-------- src/media_streamer_priv.c | 6 +++++- src/media_streamer_resource.c | 34 ++++++++++++++++++++-------------- 6 files changed, 40 insertions(+), 29 deletions(-) diff --git a/packaging/capi-media-streamer.spec b/packaging/capi-media-streamer.spec index 317b737..89c0c35 100644 --- a/packaging/capi-media-streamer.spec +++ b/packaging/capi-media-streamer.spec @@ -1,6 +1,6 @@ Name: capi-media-streamer Summary: A Media Streamer API -Version: 0.1.11 +Version: 0.1.12 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/media_streamer.c b/src/media_streamer.c index 73ba7dc..a17c699 100644 --- a/src/media_streamer.c +++ b/src/media_streamer.c @@ -256,6 +256,7 @@ int media_streamer_create(media_streamer_h *streamer) ret = __ms_create(ms_streamer); if (ret != MEDIA_STREAMER_ERROR_NONE) { ms_error("Error creating Media Streamer"); + g_mutex_unlock(&ms_streamer->mutex_lock); __ms_streamer_destroy(ms_streamer); return ret; diff --git a/src/media_streamer_gst.c b/src/media_streamer_gst.c index f3961d4..c592087 100644 --- a/src/media_streamer_gst.c +++ b/src/media_streamer_gst.c @@ -2068,15 +2068,15 @@ static void __demux_nomore_pads_combine(GstPad *src_pad, media_streamer_s *ms_st { GstElement *found_element = gst_pad_get_parent_element(src_pad); const gchar *new_pad_type = __ms_get_pad_type(src_pad); - if (MS_ELEMENT_IS_VIDEO(new_pad_type)) { + if (MS_ELEMENT_IS_VIDEO(new_pad_type)) found_element = __ms_combine_next_element(found_element, src_pad, ms_streamer->topology_bin, MEDIA_STREAMER_NODE_TYPE_VIDEO_DECODER); - } else if (MS_ELEMENT_IS_AUDIO(new_pad_type)) { + else if (MS_ELEMENT_IS_AUDIO(new_pad_type)) found_element = __ms_combine_next_element(found_element, src_pad, ms_streamer->topology_bin, MEDIA_STREAMER_NODE_TYPE_AUDIO_DECODER); - } else if (MS_ELEMENT_IS_TEXT(new_pad_type)) { + else if (MS_ELEMENT_IS_TEXT(new_pad_type)) found_element = __ms_combine_next_element(found_element, src_pad, ms_streamer->topology_bin, MEDIA_STREAMER_NODE_TYPE_TEXT_OVERLAY); - } else { + else ms_error("Unsupported pad type [%s]!", new_pad_type); - } + __ms_generate_dots(ms_streamer->pipeline, "after_demux_linked"); gst_object_unref(found_element); } diff --git a/src/media_streamer_node_policy.c b/src/media_streamer_node_policy.c index 90628b9..3c4f6ec 100644 --- a/src/media_streamer_node_policy.c +++ b/src/media_streamer_node_policy.c @@ -145,11 +145,11 @@ int __ms_node_policy_deinit(media_streamer_node_s *node) } if (node->dpm_handle) { - if (node->policy_changed_cb_id > 0) { + if (node->policy_changed_cb_id > 0) dpm_remove_policy_changed_cb(node->dpm_handle, node->policy_changed_cb_id); - } else { + else ms_info("invalid dpm cb id"); - } + ms_debug("DPM released"); } @@ -191,11 +191,11 @@ int _ms_node_policy_check(media_streamer_node_s *node) } if (dpm_ret == DPM_ERROR_NONE) { - ms_info("DPM state - %d", dpm_state); - if (dpm_state == DPM_DISALLOWED) { - ms_error("Policy disallowed by DPM"); - return MEDIA_STREAMER_ERROR_INVALID_OPERATION; - } + ms_info("DPM state - %d", dpm_state); + if (dpm_state == DPM_DISALLOWED) { + ms_error("Policy disallowed by DPM"); + return MEDIA_STREAMER_ERROR_INVALID_OPERATION; + } } else { ms_info("get DPM state failed, continue too work"); } diff --git a/src/media_streamer_priv.c b/src/media_streamer_priv.c index a6b995d..c3825dc 100644 --- a/src/media_streamer_priv.c +++ b/src/media_streamer_priv.c @@ -91,11 +91,14 @@ int __ms_state_change(media_streamer_s *ms_streamer, media_streamer_state_e stat int __ms_create(media_streamer_s *ms_streamer) { + int ret = MEDIA_STREAMER_ERROR_NONE; __ms_load_ini_settings(&ms_streamer->ini); ms_streamer->nodes_table = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, __ms_node_remove_from_table); ms_retvm_if(ms_streamer->nodes_table == NULL, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Error creating hash table"); + ret = __ms_pipeline_create(ms_streamer); + if (MEDIA_STREAMER_ERROR_NONE != _ms_resource_manager_init( &ms_streamer->resource_manager, media_streamer_resource_relese_cb, @@ -104,7 +107,7 @@ int __ms_create(media_streamer_s *ms_streamer) return MEDIA_STREAMER_ERROR_INVALID_OPERATION; } - return __ms_pipeline_create(ms_streamer); + return ret; } int __ms_get_position(media_streamer_s *ms_streamer, int *time) @@ -189,6 +192,7 @@ int __ms_streamer_destroy(media_streamer_s *ms_streamer) if (MEDIA_STREAMER_ERROR_NONE != _ms_resource_manager_deinit(&ms_streamer->resource_manager)) { ms_error("Failed to deinit resource manager for media streamer"); + g_mutex_unlock(&ms_streamer->mutex_lock); return MEDIA_STREAMER_ERROR_INVALID_OPERATION; } diff --git a/src/media_streamer_resource.c b/src/media_streamer_resource.c index 6f99048..bce054d 100644 --- a/src/media_streamer_resource.c +++ b/src/media_streamer_resource.c @@ -64,9 +64,9 @@ static int __ms_resource_manager_wait_connection(media_streamer_resource_manager MEDIA_STREAMER_RESOURCE_UNLOCK(resource_manager); return MEDIA_STREAMER_ERROR_INVALID_OPERATION; } else { - if (resource_manager->is_connected) + if (resource_manager->is_connected) { ms_debug("Successfully connected to resource server!"); - else { + } else { ms_error("Failed to connect to resource server"); MEDIA_STREAMER_RESOURCE_UNLOCK(resource_manager); return MEDIA_STREAMER_ERROR_INVALID_OPERATION; @@ -119,7 +119,7 @@ static void mrp_state_callback(mrp_res_context_t *context, mrp_res_error_t err, if (err != MRP_RES_ERROR_NONE) { ms_error(" - error message received from Murphy, err(0x%x)", err); g_cond_signal(&resource_manager->cond); - MEDIA_STREAMER_RESOURCE_LOCK(resource_manager); + MEDIA_STREAMER_RESOURCE_UNLOCK(resource_manager); return; } @@ -131,6 +131,7 @@ static void mrp_state_callback(mrp_res_context_t *context, mrp_res_error_t err, resource_names = mrp_res_list_resource_names(rset); if (!resource_names) { ms_error(" - no resources available"); + MEDIA_STREAMER_RESOURCE_UNLOCK(resource_manager); return; } for (i = 0; i < resource_names->num_strings; i++) { @@ -219,6 +220,7 @@ static void mrp_resource_release_cb(mrp_res_context_t *cx, const mrp_res_resourc if (!mrp_res_equal_resource_set(rs, resource_manager->rset)) { ms_info("- resource set(%p) is not same as this resource_manager handle's(%p)", rs, resource_manager->rset); + MEDIA_STREAMER_RESOURCE_UNLOCK(resource_manager); return; } @@ -234,11 +236,10 @@ static void mrp_resource_release_cb(mrp_res_context_t *cx, const mrp_res_resourc } if (resource_manager->release_cb) { - if (!resource_manager->release_cb(resource_manager, resource_manager->user_data)) { + if (!resource_manager->release_cb(resource_manager, resource_manager->user_data)) ms_error("release_cb failed"); - } else { + else ms_info("release_cb is fine"); - } } else { ms_error("release cb is NULL. Something wrong happens..."); } @@ -316,6 +317,7 @@ static int set_resource_release_cb(media_streamer_resource_manager_s *resource_m int _ms_resource_manager_init(media_streamer_resource_manager_s *resource_manager, resource_relese_cb release_cb, void *user_data) { + int ret = MEDIA_STREAMER_ERROR_NONE; MEDIA_STREAMER_CHECK_RESOURCE_MANAGER_INSTANCE(resource_manager); ms_retvm_if(release_cb == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "release_cb is NULL"); @@ -328,14 +330,16 @@ int _ms_resource_manager_init(media_streamer_resource_manager_s *resource_manage GMainContext *mrp_ctx = g_main_context_new(); if (!mrp_ctx) { ms_error("- could not create main context for resource manager"); - return MEDIA_STREAMER_ERROR_INVALID_OPERATION; + ret = MEDIA_STREAMER_ERROR_INVALID_OPERATION; + goto EXIT; } GMainLoop *mrp_loop = g_main_loop_new(mrp_ctx, TRUE); g_main_context_unref(mrp_ctx); if (!mrp_loop) { ms_error("- could not create glib mainloop for resource manager"); - return MEDIA_STREAMER_ERROR_INVALID_OPERATION; + ret = MEDIA_STREAMER_ERROR_INVALID_OPERATION; + goto EXIT; } resource_manager->mloop = mrp_mainloop_glib_get(mrp_loop); @@ -348,20 +352,23 @@ int _ms_resource_manager_init(media_streamer_resource_manager_s *resource_manage ms_error(" - could not get context for resource manager"); mrp_mainloop_destroy(resource_manager->mloop); resource_manager->mloop = NULL; - return MEDIA_STREAMER_ERROR_INVALID_OPERATION; + ret = MEDIA_STREAMER_ERROR_INVALID_OPERATION; + goto EXIT; } resource_manager->user_data = user_data; } else { ms_error("- could not get mainloop for resource manager"); - return MEDIA_STREAMER_ERROR_INVALID_OPERATION; + ret = MEDIA_STREAMER_ERROR_INVALID_OPERATION; + goto EXIT; } resource_manager->release_cb = release_cb; resource_manager->state = RESOURCE_STATE_INITIALIZED; +EXIT: MEDIA_STREAMER_RESOURCE_UNLOCK(resource_manager); - return MEDIA_STREAMER_ERROR_NONE; + return ret; } int _ms_resource_manager_prepare(media_streamer_resource_manager_s *resource_manager, media_streamer_resource_type_e resource_type) @@ -392,11 +399,10 @@ int _ms_resource_manager_prepare(media_streamer_resource_manager_s *resource_man } } - if (MEDIA_STREAMER_ERROR_NONE == ret) { + if (MEDIA_STREAMER_ERROR_NONE == ret) resource_manager->state = RESOURCE_STATE_PREPARED; - } else { + else resource_manager->state = RESOURCE_STATE_ERROR; - } return ret; } -- 2.7.4 From f0f288ba44517a92a4a27603e708ff01203d8b96 Mon Sep 17 00:00:00 2001 From: Volodymyr Brynza Date: Thu, 2 Feb 2017 13:26:20 +0200 Subject: [PATCH 09/16] fix memory leak Change-Id: I4687b9f4949ecaac16e44bdd210a5ed4d1964b6a Signed-off-by: Volodymyr Brynza --- packaging/capi-media-streamer.spec | 2 +- src/media_streamer_gst.c | 5 ++++- src/media_streamer_node.c | 13 +++++++++++++ src/media_streamer_node_resources.c | 9 +++++++++ 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/packaging/capi-media-streamer.spec b/packaging/capi-media-streamer.spec index 89c0c35..646ff93 100644 --- a/packaging/capi-media-streamer.spec +++ b/packaging/capi-media-streamer.spec @@ -1,6 +1,6 @@ Name: capi-media-streamer Summary: A Media Streamer API -Version: 0.1.12 +Version: 0.1.13 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/media_streamer_gst.c b/src/media_streamer_gst.c index c592087..3ac83fc 100644 --- a/src/media_streamer_gst.c +++ b/src/media_streamer_gst.c @@ -1172,6 +1172,7 @@ GstElement *__ms_video_decoder_element_create(node_plug_s *plug_info, media_stre GstElement *__ms_audio_encoder_element_create(node_plug_s *plug_info, media_streamer_node_type_e type) { GstCaps *enc_caps = plug_info->src_caps; + gchar *encoder_name = NULL; if (!enc_caps) { enc_caps = gst_caps_from_string(MEDIA_STREAMER_DEFAULT_AUDIO_FORMAT); ms_debug("No Audio encoding format is set! Deafault will be: [%s]", MEDIA_STREAMER_DEFAULT_AUDIO_FORMAT); @@ -1192,8 +1193,10 @@ GstElement *__ms_audio_encoder_element_create(node_plug_s *plug_info, media_stre if (!audio_encoder) audio_encoder = __ms_element_create_by_registry(&plug_info_encoder, type); - if (g_strrstr(gst_element_get_name(audio_encoder), "aac")) + encoder_name = gst_element_get_name(audio_encoder); + if (encoder_name && g_strrstr(encoder_name, "aac")) g_object_set(audio_encoder, "compliance", -2, NULL); + MS_SAFE_GFREE(encoder_name); /* Creating bin - Audio Encoder */ GstElement *audio_enc_bin = gst_bin_new("audio_encoder"); diff --git a/src/media_streamer_node.c b/src/media_streamer_node.c index ced5323..0f69deb 100644 --- a/src/media_streamer_node.c +++ b/src/media_streamer_node.c @@ -657,6 +657,7 @@ int __ms_sink_node_create(media_streamer_node_s *node) case MEDIA_STREAMER_NODE_SINK_TYPE_OVERLAY: plugin_name = __ms_ini_get_string("node type 2:overlay", DEFAULT_VIDEO_SINK); node->gst_element = __ms_element_create(plugin_name, NULL); + g_object_set(node->gst_element, "use-tbm", FALSE, NULL); break; case MEDIA_STREAMER_NODE_SINK_TYPE_FAKE: plugin_name = __ms_ini_get_string("node type 2:fake", DEFAULT_FAKE_SINK); @@ -1567,16 +1568,20 @@ gboolean _ms_node_resouces_acquire_iter(const GValue *item, GValue *ret, gpointe then apprently this element doesn't require resources */ ms_info("Failed to found corresonding node [%s] inside streamer", GST_ELEMENT_NAME(element)); g_value_set_boolean(ret, TRUE); + g_object_unref(element); return TRUE; } if (MEDIA_STREAMER_ERROR_NONE != _ms_node_resource_aquire(node)) { ms_error("Failed to acquire resource for node [%s]", node->name); + g_object_unref(element); return FALSE; } g_value_set_boolean(ret, TRUE); + g_object_unref(element); + return TRUE; } @@ -1597,16 +1602,20 @@ gboolean _ms_node_resouces_release_iter(const GValue *item, GValue *ret, gpointe then apprently this element doesn't require resources. */ ms_debug("Failed to found corresonding node [%s] inside streamer", GST_ELEMENT_NAME(element)); g_value_set_boolean(ret, TRUE); + g_object_unref(element); return TRUE; } if (MEDIA_STREAMER_ERROR_NONE != _ms_node_resource_release(node)) { ms_error("Failed to release resource for node [%s]", node->name); + g_object_unref(element); return FALSE; } g_value_set_boolean(ret, TRUE); + g_object_unref(element); + return TRUE; } @@ -1627,15 +1636,19 @@ gboolean _ms_node_policy_check_iter(const GValue *item, GValue *ret, gpointer us then apprently this element doesn't require resources */ ms_info("Failed to found corresonding node [%s] inside streamer", GST_ELEMENT_NAME(element)); g_value_set_boolean(ret, TRUE); + g_object_unref(element); return TRUE; } if (MEDIA_STREAMER_ERROR_NONE != _ms_node_policy_check(node)) { ms_error("Failed to check policy for node [%s]", node->name); + g_object_unref(element); return FALSE; } g_value_set_boolean(ret, TRUE); + g_object_unref(element); + return TRUE; } diff --git a/src/media_streamer_node_resources.c b/src/media_streamer_node_resources.c index 2f69001..dbf8c54 100644 --- a/src/media_streamer_node_resources.c +++ b/src/media_streamer_node_resources.c @@ -74,6 +74,12 @@ static gboolean __ms_node_resources_is_needed_by_platform(media_streamer_node_s are platform dependent */ system_info_get_platform_string("http://tizen.org/system/model_name", &model_name); system_info_get_platform_string("http://tizen.org/system/platform.processor", &platform_processor); + if (!model_name || ! platform_processor) { + ms_error("Failed to get information about platform check resources"); + MS_SAFE_FREE(model_name); + MS_SAFE_FREE(platform_processor); + return TRUE; + } ms_info("Check for resources for model_name %s, platform.processor %s", model_name, platform_processor); switch (type) { @@ -97,6 +103,9 @@ static gboolean __ms_node_resources_is_needed_by_platform(media_streamer_node_s break; } + MS_SAFE_FREE(model_name); + MS_SAFE_FREE(platform_processor); + return ret; } -- 2.7.4 From 9094f0c3465c389223ddc8f930ea296fb46e3a9a Mon Sep 17 00:00:00 2001 From: Eunhae Choi Date: Thu, 16 Feb 2017 19:45:43 +0900 Subject: [PATCH 10/16] [0.1.14] fix svace issue Change-Id: I7e05d5b5cb6dab7fb21bda14b2988ef0f9b7db9d (cherry picked from commit 74dc3e6ba4dade3c52216587d31c3e984dac3f7a) --- packaging/capi-media-streamer.spec | 2 +- src/media_streamer_gst.c | 22 +++++++++++++++++----- src/media_streamer_node.c | 2 +- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/packaging/capi-media-streamer.spec b/packaging/capi-media-streamer.spec index 646ff93..cab5a44 100644 --- a/packaging/capi-media-streamer.spec +++ b/packaging/capi-media-streamer.spec @@ -1,6 +1,6 @@ Name: capi-media-streamer Summary: A Media Streamer API -Version: 0.1.13 +Version: 0.1.14 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/media_streamer_gst.c b/src/media_streamer_gst.c index 3ac83fc..d10c954 100644 --- a/src/media_streamer_gst.c +++ b/src/media_streamer_gst.c @@ -817,11 +817,22 @@ static GstElement *__ms_manifest_src_create(media_streamer_node_s *ms_node) } } g_free(protocol); - ms_retvm_if(manifest_src_name == NULL, NULL, - "Error empty manifest source name for adaprive source"); + + if (manifest_src_name == NULL) { + LOGE("Error empty manifest source name for adaptive source"); + g_free(location); + return NULL; + } + manifest_src = gst_element_factory_make(manifest_src_name, NULL); - ms_retvm_if(manifest_src == NULL, NULL, - "Error creating manifest source for adaptive source"); + g_free(manifest_src_name); + + if (manifest_src == NULL) { + LOGE("Error creating manifest source for adaptive source"); + g_free(location); + return NULL; + } + g_object_set(manifest_src, "location", location, NULL); g_free(location); @@ -843,8 +854,9 @@ int __ms_adaptive_element_prepare(media_streamer_node_s *ms_node, bool auto_plug ms_retvm_if(plugin_name == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Error empty plugin name for adaprive source"); ms_info("Creating [%s] element", plugin_name); plugin_elem = gst_element_factory_make(plugin_name, NULL); + g_free(plugin_name); ms_retvm_if(plugin_elem == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, - "Error creating element [%s] for adaptive source", plugin_name); + "Error creating element for adaptive source"); res = gst_bin_add(GST_BIN(ms_node->gst_element), plugin_elem); ms_retvm_if(res == FALSE, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, diff --git a/src/media_streamer_node.c b/src/media_streamer_node.c index 0f69deb..ddc60e5 100644 --- a/src/media_streamer_node.c +++ b/src/media_streamer_node.c @@ -343,7 +343,7 @@ static int __ms_node_check_priveleges(media_streamer_node_s *node) char smackLabel[SMACK_LABEL_LEN + 1]; char uid[10]; - cynara *cynara_h; + cynara *cynara_h = NULL; if (CYNARA_API_SUCCESS != cynara_initialize(&cynara_h, NULL)) { ms_error("Failed to initialize cynara structure\n"); -- 2.7.4 From 340e505a7c067e5c68ecc5324856e874348ea0a9 Mon Sep 17 00:00:00 2001 From: Oleksandr Popov Date: Mon, 20 Feb 2017 18:08:39 +0000 Subject: [PATCH 11/16] Added http server feature Change-Id: I286acf360eae667868d1ee17372e4930f82e719f Signed-off-by: Oleksandr Popov --- CMakeLists.txt | 4 +- include/media_streamer_http_server.h | 42 ++++++ include/media_streamer_net_util.h | 31 +++++ include/media_streamer_priv.h | 3 + include/media_streamer_util.h | 2 +- packaging/capi-media-streamer.spec | 7 +- src/media_streamer.c | 4 + src/media_streamer_gst.c | 4 +- src/media_streamer_http_server.c | 262 +++++++++++++++++++++++++++++++++++ src/media_streamer_net_util.c | 49 +++++++ src/media_streamer_node.c | 40 +++++- src/media_streamer_util.c | 4 +- test/media_streamer_test.c | 2 +- 13 files changed, 443 insertions(+), 11 deletions(-) create mode 100644 include/media_streamer_http_server.h create mode 100644 include/media_streamer_net_util.h mode change 100755 => 100644 include/media_streamer_priv.h create mode 100644 src/media_streamer_http_server.c create mode 100644 src/media_streamer_net_util.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 04a307d..2a05d39 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,8 +10,8 @@ SET(PREFIX ${CMAKE_INSTALL_PREFIX}) SET(INC_DIR include) INCLUDE_DIRECTORIES(${INC_DIR}) -SET(dependents "dlog glib-2.0 mm-common capi-media-tool iniparser bundle libtbm gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-app-1.0 gstreamer-video-1.0 cynara-client capi-system-info ecore elementary murphy-resource murphy-glib dpm") -SET(pc_dependents "capi-base-common capi-media-tool gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-app-1.0 gstreamer-video-1.0 cynara-client capi-system-info ecore evas elementary murphy-resource murphy-glib dpm") +SET(dependents "dlog glib-2.0 mm-common capi-media-tool iniparser bundle libtbm gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-app-1.0 gstreamer-video-1.0 cynara-client capi-system-info ecore elementary murphy-resource murphy-glib dpm capi-network-connection capi-content-mime-type libsoup-2.4") +SET(pc_dependents "capi-base-common capi-media-tool gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-app-1.0 gstreamer-video-1.0 cynara-client capi-system-info ecore evas elementary murphy-resource murphy-glib dpm capi-system-info capi-network-connection capi-content-mime-type libsoup-2.4") INCLUDE(FindPkgConfig) pkg_check_modules(${fw_name} REQUIRED ${dependents}) diff --git a/include/media_streamer_http_server.h b/include/media_streamer_http_server.h new file mode 100644 index 0000000..29c565c --- /dev/null +++ b/include/media_streamer_http_server.h @@ -0,0 +1,42 @@ + +/* + * Copyright (c) 2015 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. + */ + +#ifndef __MEDIA_STREAMER_HTTP_H__ +#define __MEDIA_STREAMER_HTTP_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void *media_streamer_http_server_h; + +int __ms_http_server_create(media_streamer_http_server_h *server, char *ip_address, char *port); +int __ms_http_server_destroy(media_streamer_http_server_h server); + +int __ms_http_server_start(media_streamer_http_server_h server); +int __ms_http_server_stop(media_streamer_http_server_h server); + +int __ms_http_server_register_uri(media_streamer_http_server_h server, char *uri, char *file_path); +int __ms_http_server_unregister_uri(media_streamer_http_server_h server, char *uri); + +#ifdef __cplusplus +} +#endif + +#endif /* __MEDIA_STREAMER_HTTP_H__ */ diff --git a/include/media_streamer_net_util.h b/include/media_streamer_net_util.h new file mode 100644 index 0000000..76f72e9 --- /dev/null +++ b/include/media_streamer_net_util.h @@ -0,0 +1,31 @@ + +/* + * Copyright (c) 2015 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. + */ + +#ifndef __MEDIA_STREAMER_NET_UTIL_H__ +#define __MEDIA_STREAMER_NET_UTIL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +int __ms_get_local_network_address(char **ip_address); + +#ifdef __cplusplus +} +#endif + +#endif /* __MEDIA_STREAMER_NET_UTIL_H__ */ diff --git a/include/media_streamer_priv.h b/include/media_streamer_priv.h old mode 100755 new mode 100644 index bbfd37b..9ba66a0 --- a/include/media_streamer_priv.h +++ b/include/media_streamer_priv.h @@ -29,6 +29,7 @@ extern "C" { #include #include #include +#include struct media_streamer_node_s; @@ -116,6 +117,8 @@ typedef struct { gboolean is_interrupted; media_streamer_resource_manager_s resource_manager; + + media_streamer_http_server_h http_server; } media_streamer_s; /** diff --git a/include/media_streamer_util.h b/include/media_streamer_util.h index 2b44cdf..5c85853 100644 --- a/include/media_streamer_util.h +++ b/include/media_streamer_util.h @@ -332,7 +332,7 @@ void __ms_param_value_destroy(gpointer data); * * @since_tizen 3.0 */ -int __ms_node_uri_path_check(const char *file_uri); +int __ms_util_uri_path_check(const char *file_uri); /** * @brief Iterates func over all elements contained within a bin. diff --git a/packaging/capi-media-streamer.spec b/packaging/capi-media-streamer.spec index cab5a44..d413ffb 100644 --- a/packaging/capi-media-streamer.spec +++ b/packaging/capi-media-streamer.spec @@ -1,6 +1,6 @@ Name: capi-media-streamer Summary: A Media Streamer API -Version: 0.1.14 +Version: 0.1.15 Release: 0 Group: Multimedia/API License: Apache-2.0 @@ -32,6 +32,9 @@ BuildRequires: pkgconfig(appcore-efl) BuildRequires: pkgconfig(murphy-resource) BuildRequires: pkgconfig(murphy-glib) BuildRequires: pkgconfig(dpm) +BuildRequires: pkgconfig(capi-network-connection) +BuildRequires: pkgconfig(libsoup-2.4) +BuildRequires: pkgconfig(capi-content-mime-type) %description A MediaStreamer library in Tizen Native API. @@ -51,7 +54,7 @@ cp %{SOURCE1001} . %define ini_path %{_sysconfdir}/multimedia/mmfw_media_streamer.ini %build -flags="-DMEDIA_STREAMER_INI_PATH=\\\"%{ini_path}\\\"" +flags="-DMEDIA_STREAMER_INI_PATH=\\\"%{ini_path}\\\" -D_FILE_OFFSET_BITS=64" %if 0%{?sec_build_binary_debug_enable} flags="$flags -DTIZEN_DEBUG_ENABLE" diff --git a/src/media_streamer.c b/src/media_streamer.c index a17c699..a2eb3ff 100644 --- a/src/media_streamer.c +++ b/src/media_streamer.c @@ -213,6 +213,8 @@ int media_streamer_unprepare(media_streamer_h streamer) ret = __ms_pipeline_unprepare(ms_streamer); + __ms_http_server_destroy(ms_streamer->http_server); + __ms_generate_dots(ms_streamer->pipeline, "after_unprepare"); g_mutex_unlock(&ms_streamer->mutex_lock); @@ -477,6 +479,8 @@ int media_streamer_stop(media_streamer_h streamer) else ret = __ms_state_change(ms_streamer, MEDIA_STREAMER_STATE_PAUSED); + __ms_http_server_stop(ms_streamer->http_server); + g_mutex_unlock(&ms_streamer->mutex_lock); __ms_get_state(ms_streamer); diff --git a/src/media_streamer_gst.c b/src/media_streamer_gst.c index d10c954..5171d3d 100644 --- a/src/media_streamer_gst.c +++ b/src/media_streamer_gst.c @@ -752,7 +752,7 @@ static int __ms_adaptive_sink_prepare(media_streamer_s * ms_streamer) {"Codec/Muxer", "mpegtsmux"}, /* MEDIA_STREAMER_NODE_TYPE_MUXER */ }; - GstCaps *video_enc_src_caps = gst_caps_new_empty_simple("video/mpeg"); + GstCaps *video_enc_src_caps = gst_caps_new_simple("video/mpeg", "mpegversion", G_TYPE_INT, 4, NULL); GstCaps *video_enc_sink_caps = gst_caps_new_empty_simple("video/x-raw"); node_plug_s video_enc_plug_info = {&(nodes_info[0]), video_enc_src_caps, video_enc_sink_caps, NULL}; GstElement *video_enc = __ms_node_element_create(&video_enc_plug_info, MEDIA_STREAMER_NODE_TYPE_VIDEO_ENCODER); @@ -807,7 +807,7 @@ static GstElement *__ms_manifest_src_create(media_streamer_node_s *ms_node) location = gst_uri_get_location(uri); } else { ms_error("Unsupported URI protocol... Check URI is file path"); - if (__ms_node_uri_path_check(uri) == MEDIA_STREAMER_ERROR_NONE) { + if (__ms_util_uri_path_check(uri) == MEDIA_STREAMER_ERROR_NONE) { manifest_src_name = __ms_ini_get_string("node type 1:file", DEFAULT_FILE_SOURCE); location = g_strdup(uri); } else { diff --git a/src/media_streamer_http_server.c b/src/media_streamer_http_server.c new file mode 100644 index 0000000..0179559 --- /dev/null +++ b/src/media_streamer_http_server.c @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2015 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 +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include + +#define HTTP_SERVER_LOG_LEVEL AD_LOG_DEBUG + +typedef struct { + SoupServer *server; /* Soup HTTP server */ + + GHashTable *uri_table; +} _ms_http_server_s; + +static int __ms_http_server_file_read_contents(const char *file_path, char **content, gsize *size); +static void __ms_http_server_connection_handle_cb(SoupServer *server, SoupMessage *msg, + const char *path, GHashTable *query, SoupClientContext *client, gpointer user_data); + +int __ms_http_server_create(media_streamer_http_server_h *server, char *ip_address, char *port) +{ + ms_retvm_if(server == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL"); + //ms_retvm_if(ip_address == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "IP address is NULL"); + ms_retvm_if(port == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Port is NULL"); + + _ms_http_server_s *ms_server = (_ms_http_server_s *) calloc(1, sizeof(_ms_http_server_s)); + ms_retvm_if(ms_server == NULL, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Error allocation memory"); + + const int iport = atoi(port); + ms_server->server = soup_server_new(SOUP_SERVER_PORT, iport, NULL); + + if (!ms_server->server) { + ms_error("Failed to create http server"); + __ms_http_server_destroy(ms_server); + return MEDIA_STREAMER_ERROR_INVALID_OPERATION; + } + + /* Create hash table for URIs */ + ms_server->uri_table = g_hash_table_new(g_str_hash, g_str_equal); + if (!ms_server->uri_table) { + ms_error("Failed to URIs hash table"); + __ms_http_server_destroy(ms_server); + return MEDIA_STREAMER_ERROR_INVALID_OPERATION; + } + + *server = ms_server; + + ms_info("http server created successfully"); + + return MEDIA_STREAMER_ERROR_NONE; +} + +int __ms_http_server_destroy(media_streamer_http_server_h server) +{ + ms_retvm_if(server == NULL, MEDIA_STREAMER_ERROR_NONE, "Handle is NULL"); + _ms_http_server_s *hserver = (_ms_http_server_s *) server; + + /* Stop server first */ + __ms_http_server_stop(server); + + /* Destroy URIs hash table */ + g_hash_table_destroy(hserver->uri_table); + + if (hserver->server) + g_object_unref(hserver->server); + + MS_SAFE_GFREE(hserver); + + return MEDIA_STREAMER_ERROR_NONE; +} + +int __ms_http_server_start(media_streamer_http_server_h server) +{ + ms_retvm_if(server == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL"); + + _ms_http_server_s *hserver = (_ms_http_server_s *) server; + + soup_server_add_handler(hserver->server, NULL, + __ms_http_server_connection_handle_cb, hserver, NULL); + + soup_server_run_async(hserver->server); + + return MEDIA_STREAMER_ERROR_NONE; +} + +int __ms_http_server_stop(media_streamer_http_server_h server) +{ + ms_retvm_if(server == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL"); + _ms_http_server_s *hserver = (_ms_http_server_s *) server; + + soup_server_disconnect(hserver->server); + + return MEDIA_STREAMER_ERROR_NONE; +} + +int __ms_http_server_register_uri(media_streamer_http_server_h server, char *uri, char *file_path) +{ + ms_retvm_if(server == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL"); + ms_retvm_if(uri == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "URI address is NULL"); + ms_retvm_if(file_path == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "File path is NULL"); + + _ms_http_server_s *hserver = (_ms_http_server_s *) server; + + if (!hserver->uri_table) { + ms_error("Failed to register URI. Table is NULL"); + return MEDIA_STREAMER_ERROR_INVALID_OPERATION; + } + + g_hash_table_insert(hserver->uri_table, uri, file_path); + + return MEDIA_STREAMER_ERROR_NONE; +} + +int __ms_http_server_unregister_uri(media_streamer_http_server_h server, char *uri) +{ + ms_retvm_if(server == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL"); + ms_retvm_if(uri == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "URI address is NULL"); + + _ms_http_server_s *hserver = (_ms_http_server_s *) server; + + if (!hserver->uri_table) { + ms_error("Failed to unregister URI. Table is NULL"); + return MEDIA_STREAMER_ERROR_INVALID_OPERATION; + } + + /* Return if URI is not registered */ + if (!g_hash_table_contains(hserver->uri_table, uri)) + return MEDIA_STREAMER_ERROR_NONE; + + if (!g_hash_table_remove(hserver->uri_table, uri)) { + ms_error("Failed to remove URI %s from table", uri); + return MEDIA_STREAMER_ERROR_INVALID_OPERATION; + } + + return MEDIA_STREAMER_ERROR_NONE; +} + +static const char *get_filename_ext(const char *file_path) +{ + const char *dot = strrchr(file_path, '.'); + + if (!dot || dot == file_path) return ""; + return dot + 1; +} + +static int __ms_http_server_file_read_contents(const char *file_path, char **content, gsize *size) +{ + int ret = MEDIA_STREAMER_ERROR_NONE; + struct stat stat_results = {0, }; + int file_open = 0; + + if (!file_path || !strlen(file_path)) + return MEDIA_STREAMER_ERROR_INVALID_PARAMETER; + + ret = __ms_util_uri_path_check(file_path); + if (MEDIA_STREAMER_ERROR_NONE != ret) + return ret; + + file_open = open(file_path, O_RDONLY); + if (file_open < 0) { + char mes_error[256]; + strerror_r(errno, mes_error, sizeof(mes_error)); + ms_error("Couldn`t open file [%s] according to [%s]. Error N [%d]", file_path, mes_error, errno); + + return MEDIA_STREAMER_ERROR_INVALID_PARAMETER; + } + + if (fstat(file_open, &stat_results) < 0) { + ms_error("Couldn`t get status of the file [%s]", file_path); + } else if (stat_results.st_size == 0) { + ms_error("The size of file is 0"); + close(file_open); + return MEDIA_STREAMER_ERROR_INVALID_PARAMETER; + } else { + ms_debug("Size of file [%lld] bytes", (long long)stat_results.st_size); + } + + *content = malloc((size_t)stat_results.st_size); + if (read(file_open, *content, (size_t)stat_results.st_size) < (size_t)stat_results.st_size) + return MEDIA_STREAMER_ERROR_INVALID_OPERATION; + *size = (gsize)stat_results.st_size; + + close(file_open); + + return MEDIA_STREAMER_ERROR_NONE; +} + +static void __ms_http_server_connection_handle_cb(SoupServer *server, SoupMessage *msg, + const char *path, GHashTable *query, SoupClientContext *client, gpointer user_data) +{ + _ms_http_server_s *hserver = (_ms_http_server_s *) user_data; + + /* Close connetion if handle is NULL */ + ms_retm_if(hserver == NULL, "Handle is NULL"); + + SoupMessageHeadersIter iter; + const char *name, *value; + + ms_debug("%s %s HTTP/1.%d", msg->method, path, + soup_message_get_http_version(msg)); + soup_message_headers_iter_init(&iter, msg->request_headers); + while (soup_message_headers_iter_next(&iter, &name, &value)) + ms_debug("%s: %s", name, value); + if (msg->request_body->length) + ms_debug("%s", msg->request_body->data); + + if (msg->method == SOUP_METHOD_GET || msg->method == SOUP_METHOD_HEAD) { + ms_info("Received read event"); + + /* Extract file path with URI. First symbol is '/' */ + char *fs_dir = (char *)g_hash_table_lookup(hserver->uri_table, "adaptive_path"); + char *file_path = g_strjoin(NULL, fs_dir, path+1, NULL); + const char *extension = get_filename_ext(path+1); + char *content = NULL; + gsize size = 0; + char *mime_type = NULL; + + mime_type_get_mime_type(extension, &mime_type); + + ms_info("Recieved URI %s", path + 1); + ms_info("mime-type: %s", mime_type); + + if (MEDIA_STREAMER_ERROR_NONE != + __ms_http_server_file_read_contents(file_path, &content, &size)) { + + soup_message_set_status(msg, SOUP_STATUS_BAD_REQUEST); + } else { + ms_info("Sending response"); + soup_message_set_response(msg, mime_type, SOUP_MEMORY_TAKE, content, size); + soup_message_set_status(msg, SOUP_STATUS_OK); + } + + g_free(file_path); + g_free(mime_type); + } else { + soup_message_set_status(msg, SOUP_STATUS_NOT_IMPLEMENTED); + soup_message_set_status(msg, SOUP_STATUS_OK); + } +} diff --git a/src/media_streamer_net_util.c b/src/media_streamer_net_util.c new file mode 100644 index 0000000..71a92e0 --- /dev/null +++ b/src/media_streamer_net_util.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2015 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 +#include +#include + +#include + +int __ms_get_local_network_address(char **ip_address) +{ + connection_h conn = NULL; + connection_type_e conn_type = CONNECTION_TYPE_DISCONNECTED; + + if (CONNECTION_ERROR_NONE != connection_create(&conn)) { + ms_error("Failed to create connection"); + return MEDIA_STREAMER_ERROR_INVALID_OPERATION; + } + + if (CONNECTION_ERROR_NONE != connection_get_type(conn, &conn_type)) { + ms_error("Failed to acquire connection type"); + return MEDIA_STREAMER_ERROR_INVALID_OPERATION; + } + + if (conn_type != CONNECTION_TYPE_WIFI) { + ms_error("Wrong connection type"); + return MEDIA_STREAMER_ERROR_INVALID_OPERATION; + } + + if (CONNECTION_ERROR_NONE != connection_get_ip_address(conn, CONNECTION_ADDRESS_FAMILY_IPV4, ip_address)) { + ms_error("Failed to acquire connection ip address"); + return MEDIA_STREAMER_ERROR_INVALID_OPERATION; + } + + return MEDIA_STREAMER_ERROR_NONE; +} diff --git a/src/media_streamer_node.c b/src/media_streamer_node.c index ddc60e5..5bd70c1 100644 --- a/src/media_streamer_node.c +++ b/src/media_streamer_node.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -29,6 +30,7 @@ #define SMACK_LABEL_LEN 255 #define DEFAULT_URI_SCHEME_LENGTH 10 +#define DEFAULT_HTTP_PORT "8888" param_s param_table[] = { {MEDIA_STREAMER_PARAM_CAMERA_ID, "camera-id"}, @@ -855,6 +857,38 @@ static gboolean demux_find(gpointer key, gpointer value, gpointer user_data) return g_strrstr((char *)key, "demux") != NULL; } +static int __ms_adaptive_sink_http_server_prepare(media_streamer_s * ms_streamer, media_streamer_node_s *node) +{ + int err_code = MEDIA_STREAMER_ERROR_NONE; + char *playlist_location = NULL; + char *playlist_dir = NULL; + char *split = NULL; + + /* Create and start http server */ + err_code = __ms_http_server_create(&ms_streamer->http_server, NULL, DEFAULT_HTTP_PORT); + if (MEDIA_STREAMER_ERROR_NONE != err_code) { + ms_error("Failed to create http server during prepare"); + } else { + ms_info("Starting http server"); + /* FIXME: find out how to set default port */ + err_code = __ms_http_server_start(ms_streamer->http_server); + if (MEDIA_STREAMER_ERROR_NONE != err_code) { + ms_error("Failed to start http server during prepare. Destroying http server"); + __ms_http_server_destroy(ms_streamer->http_server); + } + } + + g_object_get(node->gst_element, MEDIA_STREAMER_PARAM_PLAYLIST_LOCATION, &playlist_location, NULL); + split = strrchr(playlist_location, '/'); + playlist_dir = g_strndup(playlist_location, split - playlist_location + 1); + + __ms_http_server_register_uri(ms_streamer->http_server, "adaptive_path", playlist_dir); + + MS_SAFE_GFREE(playlist_location); + + return err_code; +} + int __ms_pipeline_prepare(media_streamer_s *ms_streamer) { ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL"); @@ -863,6 +897,7 @@ int __ms_pipeline_prepare(media_streamer_s *ms_streamer) media_streamer_node_s *rtp_node = (media_streamer_node_s *)g_hash_table_lookup(ms_streamer->nodes_table, "rtp_container"); media_streamer_node_s *demux = (media_streamer_node_s *)g_hash_table_find(ms_streamer->nodes_table, (GHRFunc)demux_find, NULL); media_streamer_node_s *adaptive_src = (media_streamer_node_s *)g_hash_table_lookup(ms_streamer->nodes_table, "adaptive_src"); + media_streamer_node_s *adaptive_sink = (media_streamer_node_s *)g_hash_table_lookup(ms_streamer->nodes_table, "adaptive_sink"); if (rtp_node) { ret = __ms_rtp_element_prepare(rtp_node) ? MEDIA_STREAMER_ERROR_NONE : MEDIA_STREAMER_ERROR_INVALID_PARAMETER; } else if (demux) { @@ -889,6 +924,9 @@ int __ms_pipeline_prepare(media_streamer_s *ms_streamer) ret = __ms_adaptive_element_prepare(adaptive_src, false); } + if (adaptive_sink) + __ms_adaptive_sink_http_server_prepare(ms_streamer, adaptive_sink); + if (ret != MEDIA_STREAMER_ERROR_NONE) goto prepare_fail; @@ -1477,7 +1515,7 @@ int __ms_node_set_param_value(media_streamer_node_s *ms_node, param_s *param, co else if (!g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_IS_LIVE_STREAM)) g_object_set(ms_node->gst_element, param->origin_name, !g_ascii_strcasecmp(param_value, "true"), NULL); else if (!g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_URI)) { - ret = __ms_node_uri_path_check(param_value); + ret = __ms_util_uri_path_check(param_value); if (ret == MEDIA_STREAMER_ERROR_NONE) g_object_set(ms_node->gst_element, param->origin_name, param_value, NULL); } else if (!g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_USER_AGENT)) diff --git a/src/media_streamer_util.c b/src/media_streamer_util.c index 4ea599f..7f55672 100644 --- a/src/media_streamer_util.c +++ b/src/media_streamer_util.c @@ -296,7 +296,7 @@ void __ms_param_value_destroy(gpointer data) MS_SAFE_GFREE(val); } -int __ms_node_uri_path_check(const char *file_uri) +int __ms_util_uri_path_check(const char *file_uri) { struct stat stat_results = {0, }; int file_open = 0; @@ -308,7 +308,7 @@ int __ms_node_uri_path_check(const char *file_uri) if (file_open < 0) { char mes_error[256]; strerror_r(errno, mes_error, sizeof(mes_error)); - ms_error("Couldn`t open file according to [%s]. Error N [%d]", mes_error, errno); + ms_error("Couldn`t open file [%s] according to [%s]. Error N [%d]", file_uri, mes_error, errno); if (EACCES == errno) return MEDIA_STREAMER_ERROR_PERMISSION_DENIED; diff --git a/test/media_streamer_test.c b/test/media_streamer_test.c index 3c8d834..11eafcc 100644 --- a/test/media_streamer_test.c +++ b/test/media_streamer_test.c @@ -1557,7 +1557,7 @@ void _interpret_getting_uri_menu(char *cmd) return; } - g_print("_interpret_getting_uri_menu %d %d %d\n", g_menu_state, g_sub_menu_state, g_scenario_mode); + g_print("_interpret_getting_uri_menu %d %d %d", g_menu_state, g_sub_menu_state, g_scenario_mode); if (g_menu_state == MENU_STATE_PLAYING_MENU) { if (g_scenario_mode == SCENARIO_MODE_FILE_SUBTITLE_VIDEO_AUDIO) { g_sub_menu_state = SUBMENU_STATE_GETTING_SUBFILE_URI; -- 2.7.4 From 7fcbd1e606a124ae6ee1c24e4f88a52b5bc1bb49 Mon Sep 17 00:00:00 2001 From: Eunhae Choi Date: Wed, 22 Mar 2017 19:21:06 +0900 Subject: [PATCH 12/16] [0.1.15] Use %license macro to copy license Change-Id: I292746121fab2da101ba4a2f9c226565c368ecc7 --- packaging/capi-media-streamer.spec | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/packaging/capi-media-streamer.spec b/packaging/capi-media-streamer.spec index d413ffb..e30cddc 100644 --- a/packaging/capi-media-streamer.spec +++ b/packaging/capi-media-streamer.spec @@ -71,10 +71,8 @@ make %{?jobs:-j%jobs} %install rm -rf %{buildroot} -mkdir -p %{buildroot}%{_datadir}/license -mkdir -p %{buildroot}/usr/bin -cp LICENSE.APLv2 %{buildroot}%{_datadir}/license/%{name} -cp test/media_streamer_test %{buildroot}/usr/bin +mkdir -p %{buildroot}%{_bindir} +cp test/media_streamer_test %{buildroot}%{_bindir} mkdir -p %{buildroot}/usr/etc @@ -90,7 +88,7 @@ mkdir -p %{buildroot}/usr/etc %manifest %{name}.manifest %license LICENSE.APLv2 %{_libdir}/lib%{name}.so.* -%{_datadir}/license/%{name} +%license LICENSE.APLv2 %{_bindir}/* %files devel -- 2.7.4 From a8fe84c312f9607a87ec2fb38593465b2d38d2e4 Mon Sep 17 00:00:00 2001 From: Eunhae Choi Date: Wed, 5 Apr 2017 16:41:03 +0900 Subject: [PATCH 13/16] doc: update featuring doc path Change-Id: Icb0a69d20fe0f71b9dc8dc9b8da62d889b48a1e1 (cherry picked from commit 5431cd6d88366f21e0b44c8748f4edf923bc5930) --- doc/mediastreamer_doc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/mediastreamer_doc.h b/doc/mediastreamer_doc.h index 117e05b..289d684 100755 --- a/doc/mediastreamer_doc.h +++ b/doc/mediastreamer_doc.h @@ -53,7 +53,7 @@ * It is recommended to design feature related codes in your application for reliability.\n * You can check if a device supports the related features for this API by using @ref CAPI_SYSTEM_SYSTEM_INFO_MODULE, thereby controlling the procedure of your application.\n * To ensure your application is only running on the device with specific features, please define the features in your manifest file using the manifest editor in the SDK.\n - * More details on featuring your application can be found from Feature Element. + * More details on featuring your application can be found from Feature List. * */ -- 2.7.4 From 56c3360271da3de3478d3968b4aca3112c75e847 Mon Sep 17 00:00:00 2001 From: Eunhae Choi Date: Mon, 17 Apr 2017 16:46:40 +0900 Subject: [PATCH 14/16] [0.1.16] fix svace issue Change-Id: I71289af8dae084733fd99b98429adc75da1bc211 --- LICENSE.APLv2 => LICENSE.Apache-2.0 | 0 packaging/capi-media-streamer.spec | 5 ++--- src/media_streamer_http_server.c | 4 +++- src/media_streamer_node.c | 27 +++++++++++++++++++-------- 4 files changed, 24 insertions(+), 12 deletions(-) rename LICENSE.APLv2 => LICENSE.Apache-2.0 (100%) mode change 100755 => 100644 diff --git a/LICENSE.APLv2 b/LICENSE.Apache-2.0 old mode 100755 new mode 100644 similarity index 100% rename from LICENSE.APLv2 rename to LICENSE.Apache-2.0 diff --git a/packaging/capi-media-streamer.spec b/packaging/capi-media-streamer.spec index e30cddc..9e8832c 100644 --- a/packaging/capi-media-streamer.spec +++ b/packaging/capi-media-streamer.spec @@ -1,6 +1,6 @@ Name: capi-media-streamer Summary: A Media Streamer API -Version: 0.1.15 +Version: 0.1.16 Release: 0 Group: Multimedia/API License: Apache-2.0 @@ -86,9 +86,8 @@ mkdir -p %{buildroot}/usr/etc %files %manifest %{name}.manifest -%license LICENSE.APLv2 +%license LICENSE.Apache-2.0 %{_libdir}/lib%{name}.so.* -%license LICENSE.APLv2 %{_bindir}/* %files devel diff --git a/src/media_streamer_http_server.c b/src/media_streamer_http_server.c index 0179559..5d35bc2 100644 --- a/src/media_streamer_http_server.c +++ b/src/media_streamer_http_server.c @@ -199,8 +199,10 @@ static int __ms_http_server_file_read_contents(const char *file_path, char **con } *content = malloc((size_t)stat_results.st_size); - if (read(file_open, *content, (size_t)stat_results.st_size) < (size_t)stat_results.st_size) + if (read(file_open, *content, (size_t)stat_results.st_size) < (size_t)stat_results.st_size) { + close(file_open); return MEDIA_STREAMER_ERROR_INVALID_OPERATION; + } *size = (gsize)stat_results.st_size; close(file_open); diff --git a/src/media_streamer_node.c b/src/media_streamer_node.c index 5bd70c1..33afa5b 100644 --- a/src/media_streamer_node.c +++ b/src/media_streamer_node.c @@ -868,17 +868,26 @@ static int __ms_adaptive_sink_http_server_prepare(media_streamer_s * ms_streamer err_code = __ms_http_server_create(&ms_streamer->http_server, NULL, DEFAULT_HTTP_PORT); if (MEDIA_STREAMER_ERROR_NONE != err_code) { ms_error("Failed to create http server during prepare"); - } else { - ms_info("Starting http server"); - /* FIXME: find out how to set default port */ - err_code = __ms_http_server_start(ms_streamer->http_server); - if (MEDIA_STREAMER_ERROR_NONE != err_code) { - ms_error("Failed to start http server during prepare. Destroying http server"); - __ms_http_server_destroy(ms_streamer->http_server); - } + goto _DONE; + } + + ms_info("Starting http server"); + /* FIXME: find out how to set default port */ + err_code = __ms_http_server_start(ms_streamer->http_server); + if (MEDIA_STREAMER_ERROR_NONE != err_code) { + ms_error("Failed to start http server during prepare. Destroying http server"); + __ms_http_server_destroy(ms_streamer->http_server); + goto _DONE; } g_object_get(node->gst_element, MEDIA_STREAMER_PARAM_PLAYLIST_LOCATION, &playlist_location, NULL); + if (!playlist_location) { + err_code = MEDIA_STREAMER_ERROR_INVALID_OPERATION; + ms_error("Failed to get playlist location"); + __ms_http_server_destroy(ms_streamer->http_server); + goto _DONE; + } + split = strrchr(playlist_location, '/'); playlist_dir = g_strndup(playlist_location, split - playlist_location + 1); @@ -886,6 +895,8 @@ static int __ms_adaptive_sink_http_server_prepare(media_streamer_s * ms_streamer MS_SAFE_GFREE(playlist_location); +_DONE: + return err_code; } -- 2.7.4 From c41e5f861f18cd4c844e7a73fef331764b70649b Mon Sep 17 00:00:00 2001 From: Eunhae Choi Date: Mon, 22 May 2017 20:01:53 +0900 Subject: [PATCH 15/16] [0.1.16] modify doc Change-Id: I53bd6ea1e8714432ff1f721444a3b31a8d4231ef --- doc/mediastreamer_doc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/mediastreamer_doc.h b/doc/mediastreamer_doc.h index 289d684..e97184c 100755 --- a/doc/mediastreamer_doc.h +++ b/doc/mediastreamer_doc.h @@ -53,7 +53,7 @@ * It is recommended to design feature related codes in your application for reliability.\n * You can check if a device supports the related features for this API by using @ref CAPI_SYSTEM_SYSTEM_INFO_MODULE, thereby controlling the procedure of your application.\n * To ensure your application is only running on the device with specific features, please define the features in your manifest file using the manifest editor in the SDK.\n - * More details on featuring your application can be found from Feature List. + * More details on featuring your application can be found from Feature Element. * */ -- 2.7.4 From 1fedfbdeeb432a1b204c8cea8f6e4cf03ca96dcf Mon Sep 17 00:00:00 2001 From: Eunhae Choi Date: Wed, 14 Jun 2017 21:47:56 +0900 Subject: [PATCH 16/16] [0.1.17] fix svace issue Change-Id: Ie1572cedafa46e69b129467f57b58e790d36357a --- packaging/capi-media-streamer.spec | 2 +- src/media_streamer_node.c | 21 ++++++++++++++------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/packaging/capi-media-streamer.spec b/packaging/capi-media-streamer.spec index 9e8832c..b72d961 100644 --- a/packaging/capi-media-streamer.spec +++ b/packaging/capi-media-streamer.spec @@ -1,6 +1,6 @@ Name: capi-media-streamer Summary: A Media Streamer API -Version: 0.1.16 +Version: 0.1.17 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/media_streamer_node.c b/src/media_streamer_node.c index 33afa5b..8c57112 100644 --- a/src/media_streamer_node.c +++ b/src/media_streamer_node.c @@ -149,8 +149,10 @@ static int __ms_rtp_node_set_property(media_streamer_node_s *ms_node, param_s *p int ret = MEDIA_STREAMER_ERROR_NONE; GValue *val = (GValue *)g_object_get_data(G_OBJECT(ms_node->gst_element), param->param_name); - if (!val) - ret = MEDIA_STREAMER_ERROR_INVALID_PARAMETER; + if (!val) { + ms_error("fail to get [%s] val from [%s]", param->param_name, GST_ELEMENT_NAME(ms_node->gst_element)); + return MEDIA_STREAMER_ERROR_INVALID_PARAMETER; + } if (!strcmp(param->param_name, MEDIA_STREAMER_PARAM_VIDEO_IN_PORT) || !strcmp(param->param_name, MEDIA_STREAMER_PARAM_AUDIO_IN_PORT) || @@ -170,10 +172,12 @@ static int __ms_rtp_node_set_property(media_streamer_node_s *ms_node, param_s *p g_value_unset(val); g_value_init(val, GST_TYPE_CAPS); gst_value_set_caps(val, caps); - } else + } else { ret = MEDIA_STREAMER_ERROR_INVALID_PARAMETER; - } else + } + } else { ret = MEDIA_STREAMER_ERROR_INVALID_PARAMETER; + } return ret; } @@ -221,15 +225,18 @@ static int __ms_adaptive_src_node_set_property(media_streamer_node_s *ms_node, p int ret = MEDIA_STREAMER_ERROR_NONE; GValue *val = (GValue *)g_object_get_data(G_OBJECT(ms_node->gst_element), param->param_name); - if (!val) - ret = MEDIA_STREAMER_ERROR_INVALID_PARAMETER; + if (!val) { + ms_error("fail to get [%s] val from [%s]", param->param_name, GST_ELEMENT_NAME(ms_node->gst_element)); + return MEDIA_STREAMER_ERROR_INVALID_PARAMETER; + } if (!strcmp(param->param_name, MEDIA_STREAMER_PARAM_URI)) { g_value_unset(val); g_value_init(val, G_TYPE_STRING); g_value_set_string(val, param_value); - } else + } else { ret = MEDIA_STREAMER_ERROR_INVALID_PARAMETER; + } return ret; } -- 2.7.4