From: Sangchul Lee Date: Thu, 7 May 2020 06:10:53 +0000 (+0900) Subject: Revise and move functions X-Git-Tag: submit/tizen/20200714.065000~56 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=39c9a301add2c0a96e26c99aa7097a1ecbec77f5;p=platform%2Fcore%2Fapi%2Fmediastreamer.git Revise and move functions Move internal functions to the proper file. Revise function signatures to clarify its meaning. [Version] 0.1.38 [Issue Type] Refactory Change-Id: I0b796c9ccdbcfd68e81ecd09475d4fd22217692c Signed-off-by: Sangchul Lee --- diff --git a/include/media_streamer_gst.h b/include/media_streamer_gst.h index cc93efb..9bafa7c 100644 --- a/include/media_streamer_gst.h +++ b/include/media_streamer_gst.h @@ -65,13 +65,6 @@ GstElement *__ms_element_create(const char *plugin_name, const char *name); */ GstElement *__ms_adaptive_element_create(void); -/** - * @brief Prepares GstBin for adaptive streaming. - * - * @since_tizen 3.0 - */ -int __ms_adaptive_element_prepare(media_streamer_node_s *ms_node, bool auto_plug); - /** * @brief Creates GstElement from specified node_plug_s structure. * @@ -86,18 +79,12 @@ GstElement *__ms_node_element_create(node_plug_s *plug_info, media_streamer_node */ GstElement *__ms_rtp_element_create(void); -/** - * @brief Prepares rtp container according to parameters data. - * @since_tizen 3.0 - */ -gboolean __ms_rtp_element_prepare(media_streamer_node_s *ms_node); - /** * @brief Unlink all pads into GstElement. * * @since_tizen 3.0 */ -gboolean __ms_element_unlink(GstElement *src_element); +gboolean __ms_element_unlink(GstElement *element); /** * @brief Remove GstElement from bin. @@ -124,7 +111,7 @@ const gchar *__ms_get_pad_type(GstPad *element_pad); * * @since_tizen 3.0 */ -GstElement *__ms_decodebin_create(media_streamer_s *ms_streamer, char * name); +GstElement *__ms_decodebin_create(media_streamer_s *ms_streamer, char *name); /** * @brief Creates next element by klass or by properties and links with the previous one. @@ -176,40 +163,33 @@ int __ms_pipeline_prepare(media_streamer_s *ms_streamer); */ int __ms_pipeline_unprepare(media_streamer_s *ms_streamer); -/** - * @brief Adds node to bin - * - * @since_tizen 3.0 - */ -int __ms_add_node_into_bin(media_streamer_s *ms_streamer, media_streamer_node_s *ms_node); - /** * @brief Sets GstElement into state. * * @since_tizen 3.0 */ -int __ms_element_set_state(GstElement *gst_element, GstState gst_state); +int __ms_element_set_state(GstElement *element, GstState state); /** * @brief Iterates pas inside gst element. * * @since_tizen 3.0 */ -int __ms_element_pad_names(GstElement *gst_element, GstPadDirection pad_type, char ***pad_name_array, int *pads_count); +int __ms_element_pad_names(GstElement *element, GstPadDirection pad_type, char ***pad_name_array, int *pads_count); /** * @brief Gets mediaformat from the GstElement's pad by pad name. * * @since_tizen 3.0 */ -int __ms_element_get_pad_fmt(GstElement *gst_element, const char *pad_name, media_format_h *fmt); +int __ms_element_get_pad_fmt(GstElement *element, const char *pad_name, media_format_h *fmt); /** - * @brief Sets mediaformat into Node's pad. + * @brief Sets mediaformat to the GstElement's pad. * * @since_tizen 3.0 */ -int __ms_element_set_fmt(media_streamer_node_s *node, const char *pad_name, media_format_h fmt); +int __ms_element_set_fmt(GstElement *element, const char *pad_name, media_format_h fmt); /** * @brief Creates GstCap's from mediaformat. @@ -239,22 +219,24 @@ int __ms_element_push_packet(GstElement *src_element, media_packet_h packet); */ int __ms_element_pull_packet(GstElement *sink_element, media_packet_h *packet); -/** - * @brief Prepare demuxer element for playing. - * - * @since_tizen 3.0 - */ -int __ms_demux_element_prepare(media_streamer_s *ms_streamer, media_streamer_node_s *demux_node); - /** * @brief Finds type of media * * @since_tizen 3.0 */ -int __ms_find_type(media_streamer_s *ms_streamer, GstElement *src_element); +int __ms_find_type(media_streamer_s *ms_streamer, GstElement *element); + +void __ms_rtpbin_pad_added_cb(GstElement *element, GstPad *new_pad, gpointer user_data); + +void __ms_demux_pad_added_cb(GstElement *element, GstPad *new_pad, gpointer user_data); + +void __ms_hlsdemux_pad_added_cb(GstElement *element, GstPad *new_pad, gpointer user_data); + +void __ms_demux_nomore_pads_cb(GstElement *element, gpointer user_data); + #ifdef __cplusplus } #endif -#endif /* __TIZEN_MEDIA_STREAMER_GST_H__ */ \ No newline at end of file +#endif /* __TIZEN_MEDIA_STREAMER_GST_H__ */ diff --git a/include/media_streamer_http_server.h b/include/media_streamer_http_server.h index 0308138..667c8c5 100644 --- a/include/media_streamer_http_server.h +++ b/include/media_streamer_http_server.h @@ -23,6 +23,8 @@ extern "C" { #endif +#define DEFAULT_HTTP_PORT 8888 + typedef void *media_streamer_http_server_h; int __ms_http_server_create(media_streamer_http_server_h *server); diff --git a/include/media_streamer_node.h b/include/media_streamer_node.h index b3bfbe4..7f1cced 100644 --- a/include/media_streamer_node.h +++ b/include/media_streamer_node.h @@ -58,12 +58,47 @@ int __ms_sink_node_create(media_streamer_node_s *node); */ void __ms_node_destroy(media_streamer_node_s *node); +/** + * @brief Adds node to bin + * + * @since_tizen 3.0 + */ +int __ms_add_node_into_bin(media_streamer_s *ms_streamer, media_streamer_node_s *node); + +/** + * @brief Prepares source node for adaptive streaming. + * + * @since_tizen 3.0 + */ +int __ms_adaptive_src_node_prepare(media_streamer_node_s *node, bool auto_plug); + +/** + * @brief Prepares sink node for adaptive streaming. + * + * @since_tizen 3.0 + */ +int __ms_adaptive_sink_node_prepare(media_streamer_s *ms_streamer, media_streamer_node_s *node); + +/** + * @brief Prepares rtp node. + * + * @since_tizen 3.0 + */ +gboolean __ms_rtp_node_prepare(media_streamer_node_s *node); + +/** + * @brief Prepares demux node. + * + * @since_tizen 3.0 + */ +int __ms_demux_node_prepare(media_streamer_s *ms_streamer, media_streamer_node_s *node); + /** * @brief Inserts media streamer node into nodes table. * * @since_tizen 3.0 */ -int __ms_node_insert_into_table(GHashTable *nodes_table, media_streamer_node_s *ms_node); +int __ms_node_insert_into_table(GHashTable *nodes_table, media_streamer_node_s *node); /** * @brief Removes media streamer node from nodes table. @@ -112,7 +147,7 @@ int __ms_node_get_param_value(media_streamer_node_s *node, param_s *param, char * * @since_tizen 3.0 */ -int __ms_node_set_param_value(media_streamer_node_s *ms_node, param_s *param, const gchar *param_value); +int __ms_node_set_param_value(media_streamer_node_s *node, param_s *param, const gchar *param_value); /** * @brief Sets media format value into node's pad. @@ -121,12 +156,14 @@ int __ms_node_set_param_value(media_streamer_node_s *ms_node, param_s *param, co */ int __ms_node_set_pad_format(media_streamer_node_s *node, const char *pad_name, media_format_h fmt); +gboolean _ms_sink_node_prepare_iter(const GValue *item, GValue *g_ret, gpointer user_data); +gboolean _ms_src_node_prepare_iter(const GValue *item, GValue *g_ret, gpointer user_data); gboolean _ms_node_resources_acquire_iter(const GValue *item, GValue *ret, gpointer user_data); -gboolean _ms_node_resources_release_iter(const GValue *item, GValue *ret, gpointer user_data); +gboolean _ms_node_resources_release_iter(const GValue *item, GValue *ret, gpointer user_data); gboolean _ms_node_policy_check_iter(const GValue *item, GValue *ret, gpointer user_data); #ifdef __cplusplus } #endif -#endif /* __TIZEN_MEDIA_STREAMER_NODE_H__ */ \ No newline at end of file +#endif /* __TIZEN_MEDIA_STREAMER_NODE_H__ */ diff --git a/include/media_streamer_util.h b/include/media_streamer_util.h index 9b75895..9829bf6 100644 --- a/include/media_streamer_util.h +++ b/include/media_streamer_util.h @@ -221,11 +221,6 @@ typedef struct { #define MEDIA_STREAMER_DEFAULT_DOT_DIR "/tmp" -#define MS_BIN_UNPREPARE(bin) \ - if (!__ms_bin_remove_elements(ms_streamer, bin)) {\ - ms_debug("Got a few errors during unprepare [%s] bin.", GST_ELEMENT_NAME(bin));\ - } - #define MS_SET_INT_PARAM(obj, key, value) \ do { \ GValue *val = g_malloc0(sizeof(GValue)); \ diff --git a/packaging/capi-media-streamer.spec b/packaging/capi-media-streamer.spec index 56657cd..f410d5a 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.37 +Version: 0.1.38 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/media_streamer_gst.c b/src/media_streamer_gst.c index 1890a23..d9fb8fa 100644 --- a/src/media_streamer_gst.c +++ b/src/media_streamer_gst.c @@ -32,7 +32,7 @@ typedef enum { MEDIA_STREAMER_SINK_BIN_ADAPTIVE, } media_streamer_sink_bin_type_e; -static int __ms_adaptive_sink_prepare(media_streamer_s * ms_streamer); +static int __ms_adaptive_sink_prepare(media_streamer_s *ms_streamer); void __ms_generate_dots(GstElement *bin, gchar *name_tag) { @@ -553,7 +553,7 @@ GstElement *__ms_combine_next_element(GstElement *previous_element, GstPad *prev return found_element; } -static gint __decodebin_autoplug_select_cb(GstElement * bin, GstPad * pad, GstCaps * caps, GstElementFactory * factory, gpointer data) +static gint __decodebin_autoplug_select_cb(GstElement *bin, GstPad *pad, GstCaps *caps, GstElementFactory *factory, gpointer data) { /* NOTE : GstAutoplugSelectResult is defined in gstplay-enum.h but not exposed */ typedef enum { @@ -655,7 +655,7 @@ static gint __pad_type_compare(gconstpointer a, gconstpointer b) return 0; } -static void __decodebin_newpad_cb(GstElement * decodebin, GstPad * new_pad, gpointer user_data) +static void __decodebin_pad_added_cb(GstElement *element, GstPad *new_pad, gpointer user_data) { media_streamer_s *ms_streamer = (media_streamer_s *) user_data; @@ -795,7 +795,7 @@ static void __decodebin_nomore_pads_cb(GstElement *decodebin, gpointer user_data ms_debug_fleave(); } -GstElement *__ms_decodebin_create(media_streamer_s * ms_streamer, char * name) +GstElement *__ms_decodebin_create(media_streamer_s *ms_streamer, char *name) { GstElement *decodebin = NULL; @@ -807,7 +807,7 @@ GstElement *__ms_decodebin_create(media_streamer_s * ms_streamer, char * name) __ms_bin_add_element(ms_streamer->transform_bin, decodebin, TRUE); gst_element_sync_state_with_parent(decodebin); - __ms_signal_create(&ms_streamer->autoplug_sig_list, decodebin, "pad-added", G_CALLBACK(__decodebin_newpad_cb), ms_streamer); + __ms_signal_create(&ms_streamer->autoplug_sig_list, decodebin, "pad-added", G_CALLBACK(__decodebin_pad_added_cb), ms_streamer); __ms_signal_create(&ms_streamer->autoplug_sig_list, decodebin, "autoplug-select", G_CALLBACK(__decodebin_autoplug_select_cb), ms_streamer); __ms_signal_create(&ms_streamer->autoplug_sig_list, decodebin, "no-more-pads", G_CALLBACK(__decodebin_nomore_pads_cb), ms_streamer); @@ -817,7 +817,7 @@ GstElement *__ms_decodebin_create(media_streamer_s * ms_streamer, char * name) } //LCOV_EXCL_START -static gboolean __ms_sink_bin_prepare(media_streamer_s * ms_streamer, GstPad * source_pad, const gchar * src_pad_type) +static gboolean __ms_sink_bin_prepare(media_streamer_s *ms_streamer, GstPad *src_pad, const gchar *src_pad_type) { GstElement *decoder_element = NULL; GstElement *found_element = NULL; @@ -826,14 +826,14 @@ static gboolean __ms_sink_bin_prepare(media_streamer_s * ms_streamer, GstPad * s ms_debug_fenter(); ms_retvm_if(!ms_streamer, FALSE, "ms_streamer is NULL"); - ms_retvm_if(!source_pad, FALSE, "source_pad is NULL"); + ms_retvm_if(!src_pad, FALSE, "src_pad is NULL"); /* Getting Depayloader */ - parent_rtp_element = gst_pad_get_parent_element(source_pad); + parent_rtp_element = gst_pad_get_parent_element(src_pad); if (MS_ELEMENT_IS_VIDEO(src_pad_type)) { gst_object_ref(parent_rtp_element); - found_element = __ms_combine_next_element(parent_rtp_element, source_pad, ms_streamer->transform_bin, MEDIA_STREAMER_NODE_TYPE_VIDEO_DEPAY); + found_element = __ms_combine_next_element(parent_rtp_element, src_pad, ms_streamer->transform_bin, MEDIA_STREAMER_NODE_TYPE_VIDEO_DEPAY); decoder_element = __ms_bin_find_element_by_type(found_element, NULL, ms_streamer->transform_bin, __ms_node_get_klass_by_its_type(MEDIA_STREAMER_NODE_TYPE_VIDEO_DECODER)); if (!decoder_element) { @@ -857,7 +857,7 @@ static gboolean __ms_sink_bin_prepare(media_streamer_s * ms_streamer, GstPad * s } } else if (MS_ELEMENT_IS_AUDIO(src_pad_type)) { gst_object_ref(parent_rtp_element); - found_element = __ms_combine_next_element(parent_rtp_element, source_pad, ms_streamer->transform_bin, MEDIA_STREAMER_NODE_TYPE_AUDIO_DEPAY); + found_element = __ms_combine_next_element(parent_rtp_element, src_pad, ms_streamer->transform_bin, MEDIA_STREAMER_NODE_TYPE_AUDIO_DEPAY); found_element = __ms_combine_next_element(found_element, NULL, ms_streamer->transform_bin, MEDIA_STREAMER_NODE_TYPE_AUDIO_DECODER); found_element = __ms_combine_next_element(found_element, NULL, ms_streamer->sink_bin, MEDIA_STREAMER_NODE_TYPE_SINK); } else { @@ -871,15 +871,15 @@ static gboolean __ms_sink_bin_prepare(media_streamer_s * ms_streamer, GstPad * s return TRUE; } -static void __ms_rtpbin_pad_added_cb(GstElement * src, GstPad * new_pad, gpointer user_data) +void __ms_rtpbin_pad_added_cb(GstElement *src, GstPad *new_pad, gpointer user_data) { media_streamer_s *ms_streamer = NULL; GstPad *target_pad = NULL; GstCaps *src_pad_caps = NULL; - gchar *source_pad_name = NULL; + gchar *src_pad_name = NULL; GstStructure *src_pad_struct = NULL; const gchar *src_pad_type = NULL; - GstPad *source_pad = NULL; + GstPad *src_pad = NULL; media_streamer_node_s *ms_node = (media_streamer_node_s *) user_data; ms_debug_fenter(); @@ -900,25 +900,25 @@ static void __ms_rtpbin_pad_added_cb(GstElement * src, GstPad * new_pad, gpointe ms_debug("type is [%s]", src_pad_type); if (MS_ELEMENT_IS_VIDEO(src_pad_type)) - source_pad_name = g_strdup_printf("%s_out", "video"); + src_pad_name = g_strdup_printf("%s_out", "video"); else if (MS_ELEMENT_IS_AUDIO(src_pad_type)) - source_pad_name = g_strdup_printf("%s_out", "audio"); + src_pad_name = g_strdup_printf("%s_out", "audio"); - if (source_pad_name != NULL) { + if (src_pad_name != NULL) { - source_pad = gst_element_get_static_pad(ms_node->gst_element, source_pad_name); + src_pad = gst_element_get_static_pad(ms_node->gst_element, src_pad_name); - if (source_pad) - gst_ghost_pad_set_target(GST_GHOST_PAD(source_pad), new_pad); + if (src_pad) + gst_ghost_pad_set_target(GST_GHOST_PAD(src_pad), new_pad); - if (source_pad && __ms_sink_bin_prepare(ms_streamer, source_pad, src_pad_type)) { + if (src_pad && __ms_sink_bin_prepare(ms_streamer, src_pad, src_pad_type)) { __ms_element_set_state(ms_node->gst_element, GST_STATE_PLAYING); __ms_generate_dots(ms_streamer->pipeline, "rtpbin_playing"); } else { ms_error("Failed to prepare sink_bin for pad type [%s]", src_pad_type); } - MS_SAFE_GFREE(source_pad_name); + MS_SAFE_GFREE(src_pad_name); } g_mutex_unlock(&ms_node->parent_streamer->mutex_lock); @@ -930,18 +930,98 @@ static void __ms_rtpbin_pad_added_cb(GstElement * src, GstPad * new_pad, gpointe } //LCOV_EXCL_STOP -int __ms_element_set_state(GstElement * gst_element, GstState gst_state) +void __ms_demux_pad_added_cb(GstElement *element, GstPad *new_pad, gpointer user_data) +{ + media_streamer_s *ms_streamer = (media_streamer_s *) user_data; + + ms_debug_fenter(); + + ms_retm_if(ms_streamer == NULL, "user_data is NULL"); + ms_retm_if(new_pad == NULL, "new_pad is NULL"); + + g_mutex_lock(&ms_streamer->mutex_lock); + + g_object_ref(new_pad); + + ms_streamer->pads_types_list = g_list_insert_sorted(ms_streamer->pads_types_list, new_pad, __pad_type_compare); + + g_mutex_unlock(&ms_streamer->mutex_lock); + + ms_debug_fleave(); +} + +void __ms_hlsdemux_pad_added_cb(GstElement *element, GstPad *new_pad, gpointer user_data) +{ + GstPad *gp = NULL; + + ms_debug_fenter(); + + gp = GST_PAD(user_data); + gst_ghost_pad_set_target(GST_GHOST_PAD(gp), new_pad); + + ms_debug_fleave(); +} + +static void __demux_nomore_pads_combine(GstPad *src_pad, media_streamer_s *ms_streamer) +{ + GstElement *found_element = NULL; + const gchar *new_pad_type = NULL; + + ms_debug_fenter(); + + found_element = gst_pad_get_parent_element(src_pad); + new_pad_type = __ms_get_pad_type(src_pad); + + if (MS_ELEMENT_IS_VIDEO(new_pad_type)) + found_element = __ms_combine_next_element(found_element, src_pad, ms_streamer->transform_bin, MEDIA_STREAMER_NODE_TYPE_VIDEO_DECODER); + else if (MS_ELEMENT_IS_AUDIO(new_pad_type)) + found_element = __ms_combine_next_element(found_element, src_pad, ms_streamer->transform_bin, MEDIA_STREAMER_NODE_TYPE_AUDIO_DECODER); + else if (MS_ELEMENT_IS_TEXT(new_pad_type)) + found_element = __ms_combine_next_element(found_element, src_pad, ms_streamer->transform_bin, MEDIA_STREAMER_NODE_TYPE_TEXT_OVERLAY); + else + ms_error("Unsupported pad type [%s]!", new_pad_type); + + __ms_generate_dots(ms_streamer->pipeline, "after_demux_linked"); + gst_object_unref(found_element); + + ms_debug_fleave(); +} + +void __ms_demux_nomore_pads_cb(GstElement *element, gpointer user_data) +{ + media_streamer_s *ms_streamer = (media_streamer_s *) user_data; + GList *iterator = NULL; + GList *list = NULL; + + ms_debug_fenter(); + + ms_retm_if(ms_streamer == NULL, "Handle is NULL"); + + g_mutex_lock(&ms_streamer->mutex_lock); + + list = ms_streamer->pads_types_list; + for (iterator = list; iterator; iterator = iterator->next) { + GstPad *src_pad = GST_PAD(iterator->data); + __demux_nomore_pads_combine(src_pad, ms_streamer); + } + + g_mutex_unlock(&ms_streamer->mutex_lock); + + ms_debug_fleave(); +} + +int __ms_element_set_state(GstElement *element, GstState state) { GstStateChangeReturn ret_state; ms_debug_fenter(); - ms_retvm_if(gst_element == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "gst_element is NULL"); + ms_retvm_if(element == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "element is NULL"); - ret_state = gst_element_set_state(gst_element, gst_state); + ret_state = gst_element_set_state(element, state); if (ret_state == GST_STATE_CHANGE_FAILURE) { - ms_error("Failed to set element [%s] into %s state", GST_ELEMENT_NAME(gst_element), gst_element_state_get_name(gst_state)); + ms_error("Failed to set element [%s] into %s state", GST_ELEMENT_NAME(element), gst_element_state_get_name(state)); return MEDIA_STREAMER_ERROR_INVALID_OPERATION; } @@ -968,19 +1048,7 @@ GstElement *__ms_element_create(const char *plugin_name, const char *name) return plugin_elem; } -static void __hlsdemux_pad_added_cb(GstElement *demux, GstPad *pad, gpointer data) -{ - GstPad *gp = NULL; - - ms_debug_fenter(); - - gp = GST_PAD(data); - gst_ghost_pad_set_target(GST_GHOST_PAD(gp), pad); - - ms_debug_fleave(); -} - -static int __ms_adaptive_sink_prepare(media_streamer_s * ms_streamer) +static int __ms_adaptive_sink_prepare(media_streamer_s *ms_streamer) { static node_info_s nodes_info[] = { {"Codec/Encoder/Video", "video_encoder"}, /* MEDIA_STREAMER_NODE_TYPE_VIDEO_ENCODER */ @@ -1054,121 +1122,6 @@ GstElement *__ms_adaptive_element_create(void) return adaptive_bin; } -static GstElement *__ms_manifest_src_create(media_streamer_node_s *ms_node) -{ - char *manifest_src_name = NULL; - gchar *location = NULL; - GstElement *manifest_src = NULL; - GValue *val = NULL; - const char *uri = NULL; - gchar *protocol = NULL; - - ms_debug_fenter(); - - ms_retvm_if(!ms_node, NULL, "ms_node is NULL"); - - val = (GValue *)g_object_get_data(G_OBJECT(ms_node->gst_element), MEDIA_STREAMER_PARAM_URI); - uri = g_value_get_string(val); - protocol = gst_uri_is_valid(uri) ? gst_uri_get_protocol(uri) : NULL; - - if (protocol && g_strrstr(protocol, "http")) { - manifest_src_name = __ms_ini_get_string("node type 1:http", DEFAULT_HTTP_SOURCE); - location = g_strdup(uri); - } else if (protocol && g_strrstr(protocol, "file")) { - manifest_src_name = __ms_ini_get_string("node type 1:file", DEFAULT_FILE_SOURCE); - location = gst_uri_get_location(uri); - } else { - ms_error("Unsupported URI protocol... Check URI is file path"); - 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 { - g_free(protocol); - ms_error("URI is not valid file path"); - return NULL; - } - } - g_free(protocol); - - 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); - 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); - - ms_debug_fleave(); - - return manifest_src; -} - -int __ms_adaptive_element_prepare(media_streamer_node_s *ms_node, bool auto_plug) -{ - char *plugin_name = NULL; - GstElement *manifest_src = NULL; - GstElement *plugin_elem = NULL; - gboolean res = FALSE; - GstPad *gp = NULL; - - ms_debug_fenter(); - - ms_retvm_if(ms_node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "ms_node is NULL"); - - if (!auto_plug) { - plugin_name = __ms_ini_get_string("node type 1:adaptive", DEFAULT_ADAPTIVE_SOURCE); - ms_retvm_if(plugin_name == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Error empty plugin name for adaptive 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 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, - "Error adding adaptive element to bin for adaptive source"); - } - - manifest_src = __ms_manifest_src_create(ms_node); - ms_retvm_if(manifest_src == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, - "Error creating manifest source for adaptive source"); - - res = gst_bin_add(GST_BIN(ms_node->gst_element), manifest_src); - ms_retvm_if(res == FALSE, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, - "Error adding manifest source to bin for adaptive source"); - - if (!auto_plug) { - res = gst_element_link(manifest_src, plugin_elem); - ms_retvm_if(res == FALSE, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, - "Error linking manifest source and element for adaptive source"); - } - - gp = gst_element_get_static_pad(ms_node->gst_element, "src"); - ms_retvm_if(gp == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, - "Error getting source pad for adaptive source"); - - if (!auto_plug) { - g_signal_connect_object(plugin_elem, "pad-added", - G_CALLBACK(__hlsdemux_pad_added_cb), gp, 0); - } else { - GstPad *manifest_src_pad = gst_element_get_static_pad(manifest_src, "src"); - gst_ghost_pad_set_target(GST_GHOST_PAD(gp), manifest_src_pad); - } - - ms_debug_fleave(); - - return MEDIA_STREAMER_ERROR_NONE; -} static gboolean __ms_feature_node_filter(GstPluginFeature *feature, gpointer data) { @@ -1719,7 +1672,7 @@ GstElement *__ms_node_element_create(node_plug_s *plug_info, media_streamer_node /* 1. Main priority: * If Node klass defined as MEDIA_STREAMER_STRICT or ENCODER/DECODER or CONVERTER types, - * element will be created immediately by format ot name */ + * element will be created immediately by format or name */ if (type == MEDIA_STREAMER_NODE_TYPE_AUDIO_ENCODER) gst_element = __ms_audio_encoder_element_create(plug_info); else if (type == MEDIA_STREAMER_NODE_TYPE_AUDIO_DECODER) @@ -1793,184 +1746,6 @@ GstElement *__ms_rtp_element_create(void) return rtp_container; } -//LCOV_EXCL_START -gboolean __ms_rtp_element_prepare(media_streamer_node_s *ms_node) -{ - GstElement *rtpbin = NULL; - gboolean ret = TRUE; - GstElement *rtp_el = NULL; - GstElement *rtcp_el = NULL; - GValue *val = NULL; - const char *host = NULL; - GstElement *video_filter = NULL; - GstCaps *video_caps = NULL; - GstGhostPad *ghost_pad = NULL; - GstElement *audio_filter = NULL; - GstCaps *audio_caps = NULL; - - ms_debug_fenter(); - - ms_retvm_if(!ms_node, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "ms_node is NULL"); - - rtpbin = __ms_element_create("rtpbin", "rtpbin"); - ms_retvm_if(!rtpbin, FALSE, "Error: creating elements for rtp container"); - - if (!__ms_bin_add_element(ms_node->gst_element, rtpbin, FALSE)) { - MS_SAFE_UNREF(rtpbin); - return FALSE; - } - - __ms_signal_create(&ms_node->sig_list, rtpbin, "pad-added", G_CALLBACK(__ms_rtpbin_pad_added_cb), ms_node); - - val = (GValue *)g_object_get_data(G_OBJECT(ms_node->gst_element), MEDIA_STREAMER_PARAM_HOST); - host = g_value_get_string(val); - - val = (GValue *)g_object_get_data(G_OBJECT(ms_node->gst_element), MEDIA_STREAMER_PARAM_VIDEO_IN_PORT); - if (g_value_get_int(val) > RTP_STREAM_DISABLED) { - rtp_el = __ms_element_create("udpsrc", MS_RTP_PAD_VIDEO_IN"_rtp"); - __ms_bin_add_element(ms_node->gst_element, rtp_el, FALSE); - - rtcp_el = __ms_element_create("udpsrc", MS_RTP_PAD_VIDEO_IN"_rctp"); - __ms_bin_add_element(ms_node->gst_element, rtcp_el, FALSE); - - ret = ret && gst_element_link_pads(rtp_el, "src", rtpbin, "recv_rtp_sink_0"); - ret = ret && gst_element_link_pads(rtcp_el, "src", rtpbin, "recv_rtcp_sink_0"); - - g_object_set_property(G_OBJECT(rtp_el), MEDIA_STREAMER_PARAM_PORT, val); - g_object_set(G_OBJECT(rtcp_el), MEDIA_STREAMER_PARAM_PORT, (g_value_get_int(val) + 1), NULL); - - val = (GValue *)g_object_get_data(G_OBJECT(ms_node->gst_element), MEDIA_STREAMER_PARAM_VIDEO_IN_FORMAT); - g_object_set_property(G_OBJECT(rtp_el), "caps", val); - } - - val = (GValue *)g_object_get_data(G_OBJECT(ms_node->gst_element), MEDIA_STREAMER_PARAM_AUDIO_IN_PORT); - if (g_value_get_int(val) > RTP_STREAM_DISABLED) { - rtp_el = __ms_element_create("udpsrc", MS_RTP_PAD_AUDIO_IN"_rtp"); - __ms_bin_add_element(ms_node->gst_element, rtp_el, FALSE); - - rtcp_el = __ms_element_create("udpsrc", MS_RTP_PAD_AUDIO_IN"_rctp"); - __ms_bin_add_element(ms_node->gst_element, rtcp_el, FALSE); - - ret = ret && gst_element_link_pads(rtp_el, "src", rtpbin, "recv_rtp_sink_1"); - ret = ret && gst_element_link_pads(rtcp_el, "src", rtpbin, "recv_rtcp_sink_1"); - - g_object_set_property(G_OBJECT(rtp_el), MEDIA_STREAMER_PARAM_PORT, val); - g_object_set(G_OBJECT(rtcp_el), MEDIA_STREAMER_PARAM_PORT, (g_value_get_int(val) + 1), NULL); - - val = (GValue *)g_object_get_data(G_OBJECT(ms_node->gst_element), MEDIA_STREAMER_PARAM_AUDIO_IN_FORMAT); - g_object_set_property(G_OBJECT(rtp_el), "caps", val); - } - - val = (GValue *)g_object_get_data(G_OBJECT(ms_node->gst_element), MEDIA_STREAMER_PARAM_VIDEO_OUT_PORT); - if (g_value_get_int(val) > RTP_STREAM_DISABLED) { - rtp_el = __ms_element_create("udpsink", MS_RTP_PAD_VIDEO_OUT"_rtp"); - __ms_bin_add_element(ms_node->gst_element, rtp_el, FALSE); - - rtcp_el = __ms_element_create("udpsink", MS_RTP_PAD_VIDEO_OUT"_rctp"); - __ms_bin_add_element(ms_node->gst_element, rtcp_el, FALSE); - - video_filter = __ms_element_create("capsfilter", NULL); - __ms_bin_add_element(ms_node->gst_element, video_filter, FALSE); - - video_caps = gst_caps_from_string(MEDIA_STREAMER_DEFAULT_VIDEO_RTP_FORMAT); - g_object_set(G_OBJECT(video_filter), "caps", video_caps, NULL); - gst_caps_unref(video_caps); - - gst_element_link_pads(video_filter, "src", rtpbin, "send_rtp_sink_0"); - - ghost_pad = (GstGhostPad *)gst_element_get_static_pad(ms_node->gst_element, MS_RTP_PAD_VIDEO_IN); - if (ghost_pad) { - if (gst_ghost_pad_set_target(ghost_pad, gst_element_get_static_pad(video_filter, "sink"))) - ms_info(" Capsfilter for [%s] in RTP is set and linked", MS_RTP_PAD_VIDEO_IN); - } - - ret = ret && gst_element_link_pads(rtpbin, "send_rtp_src_0", rtp_el, "sink"); - ret = ret && gst_element_link_pads(rtpbin, "send_rtcp_src_0", rtcp_el, "sink"); - - g_object_set_property(G_OBJECT(rtp_el), MEDIA_STREAMER_PARAM_PORT, val); - g_object_set(GST_OBJECT(rtp_el), MEDIA_STREAMER_PARAM_HOST, host, NULL); - g_object_set(G_OBJECT(rtcp_el), MEDIA_STREAMER_PARAM_PORT, (g_value_get_int(val) + 1), NULL); - g_object_set(GST_OBJECT(rtcp_el), "sync", FALSE, NULL); - g_object_set(GST_OBJECT(rtcp_el), "async", FALSE, NULL); - g_object_set(GST_OBJECT(rtcp_el), MEDIA_STREAMER_PARAM_HOST, host, NULL); - } - - val = (GValue *)g_object_get_data(G_OBJECT(ms_node->gst_element), MEDIA_STREAMER_PARAM_AUDIO_OUT_PORT); - if (g_value_get_int(val) > RTP_STREAM_DISABLED) { - rtp_el = __ms_element_create("udpsink", MS_RTP_PAD_AUDIO_OUT"_rtp"); - __ms_bin_add_element(ms_node->gst_element, rtp_el, FALSE); - - rtcp_el = __ms_element_create("udpsink", MS_RTP_PAD_AUDIO_OUT"_rctp"); - __ms_bin_add_element(ms_node->gst_element, rtcp_el, FALSE); - - audio_filter = __ms_element_create("capsfilter", NULL); - __ms_bin_add_element(ms_node->gst_element, audio_filter, FALSE); - - audio_caps = gst_caps_from_string(MEDIA_STREAMER_DEFAULT_AUDIO_RTP_FORMAT); - g_object_set(G_OBJECT(audio_filter), "caps", audio_caps, NULL); - - gst_element_link_pads(audio_filter, "src", rtpbin, "send_rtp_sink_1"); - - ghost_pad = (GstGhostPad *)gst_element_get_static_pad(ms_node->gst_element, MS_RTP_PAD_AUDIO_IN); - if (ghost_pad) { - if (gst_ghost_pad_set_target(ghost_pad, gst_element_get_static_pad(audio_filter, "sink"))) - ms_info(" Capsfilter for [%s] in RTP is set and linked", MS_RTP_PAD_AUDIO_IN); - } - - ret = ret && gst_element_link_pads(rtpbin, "send_rtp_src_1", rtp_el, "sink"); - ret = ret && gst_element_link_pads(rtpbin, "send_rtcp_src_1", rtcp_el, "sink"); - - g_object_set_property(G_OBJECT(rtp_el), MEDIA_STREAMER_PARAM_PORT, val); - g_object_set(GST_OBJECT(rtp_el), MEDIA_STREAMER_PARAM_HOST, host, NULL); - g_object_set(G_OBJECT(rtcp_el), MEDIA_STREAMER_PARAM_PORT, (g_value_get_int(val) + 1), NULL); - g_object_set(GST_OBJECT(rtcp_el), "sync", FALSE, NULL); - g_object_set(GST_OBJECT(rtcp_el), "async", FALSE, NULL); - g_object_set(GST_OBJECT(rtcp_el), MEDIA_STREAMER_PARAM_HOST, host, NULL); - } - - __ms_generate_dots(ms_node->gst_element, "rtp_prepared"); - - ms_debug_fleave(); - - return ret; -} -//LCOV_EXCL_STOP - -int __ms_add_node_into_bin(media_streamer_s *ms_streamer, media_streamer_node_s *ms_node) -{ - int ret = MEDIA_STREAMER_ERROR_NONE; - GstElement *bin = NULL; - - ms_debug_fenter(); - - ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Handle is NULL"); - ms_retvm_if(ms_node == NULL, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Handle is NULL"); - - ms_info("Try to add [%s] node into streamer, node type/subtype [%d/%d]", ms_node->name, ms_node->type, ms_node->subtype); - - switch (ms_node->type) { - case MEDIA_STREAMER_NODE_TYPE_SRC: - bin = ms_streamer->src_bin; - break; - case MEDIA_STREAMER_NODE_TYPE_SINK: - bin = ms_streamer->sink_bin; - break; - default: - /* Another elements will be add into transform bin */ - bin = ms_streamer->transform_bin; - break; - } - - if (!__ms_bin_add_element(bin, ms_node->gst_element, TRUE)) { - ms_error("Failed to add Element [%s] into [%s] bin.", ms_node->name, GST_ELEMENT_NAME(bin)); - ret = MEDIA_STREAMER_ERROR_INVALID_OPERATION; - } - - ms_debug_fleave(); - - return ret; -} - //LCOV_EXCL_START static gboolean __ms_parse_gst_error(media_streamer_s *ms_streamer, GstMessage *message, GError *error) { @@ -2308,6 +2083,207 @@ int __ms_pipeline_create(media_streamer_s *ms_streamer) return ret; } +static gboolean demux_find(gpointer key, gpointer value, gpointer user_data) +{ + return g_strrstr((char *)key, "demux") != NULL; +} + +static void __ms_pending_pads_remove(void *data) +{ + GstPad *pad = NULL; + + ms_debug_fenter(); + + ms_retm_if(data == NULL, "data is NULL"); + + pad = GST_PAD(data); + MS_SAFE_UNREF(pad); + + ms_debug_fleave(); +} + +static gboolean __ms_bin_unprepare(media_streamer_s *ms_streamer, GstElement *bin) +{ + GValue element = G_VALUE_INIT; + GstIterator *bin_iterator = NULL; + gboolean ret = TRUE; /* If the bin doesn't have any elements, it returns TRUE */ + GstElement *found_element = NULL; + GstIteratorResult it_res = GST_ITERATOR_ERROR; + media_streamer_node_s *found_node = NULL; + + ms_debug_fenter(); + + ms_retvm_if(ms_streamer == NULL, FALSE, "ms_streamer is NULL"); + ms_retvm_if(bin == NULL, FALSE, "bin is NULL"); + ms_retvm_if(ms_streamer->nodes_table == NULL, FALSE, "ms_streamer->nodes_table is NULL"); + + bin_iterator = gst_bin_iterate_elements(GST_BIN(bin)); + it_res = gst_iterator_next(bin_iterator, &element); + + while (GST_ITERATOR_OK == it_res) { + found_element = (GstElement *) g_value_get_object(&element); + + /* Get node of this element if it appears as node */ + found_node = (media_streamer_node_s *) g_hash_table_lookup(ms_streamer->nodes_table, GST_ELEMENT_NAME(found_element)); + if (found_node) { + if (!found_node->linked_by_user) + ret = ret && __ms_element_unlink(found_element); + else + ms_info("Unprepare skipped user-linked node [%s]", found_node->name); + __ms_generate_dots(ms_streamer->pipeline, GST_ELEMENT_NAME(found_element)); + } else { + ret = ret && __ms_bin_remove_element(found_element); + } + + g_value_reset(&element); + + it_res = gst_iterator_next(bin_iterator, &element); + if (GST_ITERATOR_RESYNC == it_res) { + gst_iterator_resync(bin_iterator); + it_res = gst_iterator_next(bin_iterator, &element); + } + } + + g_value_unset(&element); + gst_iterator_free(bin_iterator); + + ms_debug_fleave(); + + return ret; +} + +int __ms_pipeline_prepare(media_streamer_s *ms_streamer) +{ + int ret = MEDIA_STREAMER_ERROR_NONE; + media_streamer_node_s *rtp = NULL; + media_streamer_node_s *demux = NULL; + media_streamer_node_s *adaptive_src = NULL; + media_streamer_node_s *adaptive_sink = NULL; + + ms_debug_fenter(); + + ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "ms_streamer is NULL"); + ms_retvm_if(ms_streamer->nodes_table == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "ms_streamer->nodes_table is NULL"); + ms_retvm_if(ms_streamer->src_bin == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "ms_streamer->src_bin is NULL"); + ms_retvm_if(ms_streamer->transform_bin == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "ms_streamer->transform_bin is NULL"); + + rtp = (media_streamer_node_s *)g_hash_table_lookup(ms_streamer->nodes_table, "rtp_container"); + demux = (media_streamer_node_s *)g_hash_table_find(ms_streamer->nodes_table, (GHRFunc)demux_find, NULL); + adaptive_src = (media_streamer_node_s *)g_hash_table_lookup(ms_streamer->nodes_table, "adaptive_src"); + adaptive_sink = (media_streamer_node_s *)g_hash_table_lookup(ms_streamer->nodes_table, "adaptive_sink"); + + if (rtp) { + ret = __ms_rtp_node_prepare(rtp) ? MEDIA_STREAMER_ERROR_NONE : MEDIA_STREAMER_ERROR_INVALID_PARAMETER; + } else if (demux) { + ret = __ms_demux_node_prepare(ms_streamer, demux); + if (MEDIA_STREAMER_ERROR_NONE != ret) + ms_error("Failed to prepare demux element"); + } else { + GstBin *nodes_bin = GST_BIN(ms_streamer->src_bin); + if (nodes_bin->numchildren == 0) { + ms_debug(" No any node is added to [%s]", GST_ELEMENT_NAME(ms_streamer->src_bin)); + return MEDIA_STREAMER_ERROR_INVALID_PARAMETER; + } + nodes_bin = GST_BIN(ms_streamer->sink_bin); + if (nodes_bin->numchildren == 0) { + ms_debug(" No any node is added to [%s]", GST_ELEMENT_NAME(ms_streamer->sink_bin)); + return MEDIA_STREAMER_ERROR_INVALID_PARAMETER; + } + } + + if (adaptive_src) { + if (GST_BIN(ms_streamer->transform_bin)->numchildren == 0) + ret = __ms_adaptive_src_node_prepare(adaptive_src, true); + else + ret = __ms_adaptive_src_node_prepare(adaptive_src, false); + } + + if (adaptive_sink) + ret = __ms_adaptive_sink_node_prepare(ms_streamer, adaptive_sink); + + if (ret != MEDIA_STREAMER_ERROR_NONE) + goto prepare_fail; + + ret = __ms_bin_foreach_elements(GST_BIN(ms_streamer->sink_bin), _ms_sink_node_prepare_iter, ms_streamer); + if (MEDIA_STREAMER_ERROR_NONE != ret) { + ms_error("Failed to prepare nodes within sink bin"); + goto prepare_fail; + } + + ret = __ms_bin_foreach_elements(GST_BIN(ms_streamer->src_bin), _ms_src_node_prepare_iter, ms_streamer); + if (MEDIA_STREAMER_ERROR_NONE != ret) { + ms_error("Failed to prepare nodes within src bin"); + goto prepare_fail; + } + + ret = __ms_state_change(ms_streamer, MEDIA_STREAMER_STATE_READY); + if (ret != MEDIA_STREAMER_ERROR_NONE) + goto prepare_fail; + + ms_debug_fleave(); + + return ret; + +prepare_fail: + __ms_pipeline_unprepare(ms_streamer); + return ret; +} + +int __ms_pipeline_unprepare(media_streamer_s *ms_streamer) +{ + int ret = MEDIA_STREAMER_ERROR_NONE; + + ms_debug_fenter(); + + ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL"); + ms_retvm_if(ms_streamer->nodes_table == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "ms_streamer->nodes_table is NULL"); + + ret = __ms_state_change(ms_streamer, MEDIA_STREAMER_STATE_IDLE); + if (ret != MEDIA_STREAMER_ERROR_NONE) + ms_error("Failed to unprepare pipeline"); + + if (!ms_streamer->is_interrupted) { + /* Unprepare resources in case of failure */ + __ms_release_resources(ms_streamer); + + if (ms_streamer->video_decoder_resource != NULL) { + ret = mm_resource_manager_mark_for_release(ms_streamer->resource_manager, + ms_streamer->video_decoder_resource); + if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) + ms_error("Failed to mark resources for release"); + + ret = mm_resource_manager_commit(ms_streamer->resource_manager); + if (ret != MEDIA_STREAMER_ERROR_NONE) + ms_error("Failed to release resources"); + else + ms_streamer->video_decoder_resource = NULL; + } + } + + /* Disconnects and clean all autoplug signals */ + g_list_free_full(ms_streamer->autoplug_sig_list, __ms_signal_destroy); + ms_streamer->autoplug_sig_list = NULL; + + /* Removes all pending pads according to list */ + g_list_free_full(ms_streamer->pads_types_list, __ms_pending_pads_remove); + ms_streamer->pads_types_list = NULL; + + media_streamer_node_s *rtp_node = (media_streamer_node_s *)g_hash_table_lookup(ms_streamer->nodes_table, "rtp_container"); + if (rtp_node) { + g_list_free_full(rtp_node->sig_list, __ms_signal_destroy); + rtp_node->sig_list = NULL; + __ms_bin_unprepare(ms_streamer, rtp_node->gst_element); + } + + __ms_bin_unprepare(ms_streamer, ms_streamer->src_bin); + __ms_bin_unprepare(ms_streamer, ms_streamer->transform_bin); + __ms_bin_unprepare(ms_streamer, ms_streamer->sink_bin); + + ms_debug_fleave(); + + return ret; +} + GstCaps *__ms_create_caps_from_fmt(media_format_h fmt) { GstCaps *caps = NULL; @@ -2520,7 +2496,7 @@ int __ms_element_get_pad_fmt(GstElement *gst_element, const char *pad_name, medi return ret; } -int __ms_element_set_fmt(media_streamer_node_s *node, const char *pad_name, media_format_h fmt) +int __ms_element_set_fmt(GstElement *gst_element, const char *pad_name, media_format_h fmt) { gboolean can_accept = FALSE; GstCaps *fmt_caps = NULL; @@ -2529,29 +2505,29 @@ int __ms_element_set_fmt(media_streamer_node_s *node, const char *pad_name, medi ms_debug_fenter(); - ms_retvm_if(!node || !pad_name || !fmt, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL"); + ms_retvm_if(!gst_element || !pad_name || !fmt, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL"); fmt_caps = __ms_create_caps_from_fmt(fmt); ms_retvm_if(!fmt_caps, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Can't convert fmt into Caps"); - factory = gst_element_get_factory(node->gst_element); - node_pad = gst_element_get_static_pad(node->gst_element, pad_name); + factory = gst_element_get_factory(gst_element); + node_pad = gst_element_get_static_pad(gst_element, pad_name); if (node_pad && GST_PAD_IS_SRC(node_pad)) can_accept = gst_element_factory_can_src_any_caps(factory, fmt_caps); else if (node_pad && GST_PAD_IS_SINK(node_pad)) can_accept = gst_element_factory_can_sink_any_caps(factory, fmt_caps); else - ms_error(" Node [%s] doesn`t have valid pad [%s]", node->name, pad_name); + ms_error("[%s] doesn`t have valid pad [%s]", GST_ELEMENT_NAME(gst_element), pad_name); if (!can_accept) { if (fmt_caps) gst_caps_unref(fmt_caps); - ms_error("Node`s pad [%s] can`t be set with the given format", pad_name); + ms_error("[%s]'s pad [%s] can`t be set with the given format", GST_ELEMENT_NAME(gst_element), pad_name); return MEDIA_STREAMER_ERROR_INVALID_OPERATION; } else { - MS_SET_INT_CAPS_PARAM(node->gst_element, pad_name, fmt_caps); - ms_info("Pad [%s] of node [%s] was set with given format", pad_name, node->name); + MS_SET_INT_CAPS_PARAM(gst_element, pad_name, fmt_caps); + ms_info("[%s]'s pad [%s] was set with given format", GST_ELEMENT_NAME(gst_element), pad_name); } MS_SAFE_UNREF(node_pad); @@ -2691,89 +2667,6 @@ int __ms_element_pull_packet(GstElement *sink_element, media_packet_h *packet) return ret; } -static void __demux_newpad_cb(GstElement * demux, GstPad * new_pad, gpointer user_data) -{ - media_streamer_s *ms_streamer = (media_streamer_s *) user_data; - - ms_debug_fenter(); - - ms_retm_if(ms_streamer == NULL, "user_data is NULL"); - ms_retm_if(new_pad == NULL, "new_pad is NULL"); - - g_mutex_lock(&ms_streamer->mutex_lock); - - g_object_ref(new_pad); - - ms_streamer->pads_types_list = g_list_insert_sorted(ms_streamer->pads_types_list, new_pad, __pad_type_compare); - - g_mutex_unlock(&ms_streamer->mutex_lock); - - ms_debug_fleave(); -} - -static void __demux_nomore_pads_combine(GstPad *src_pad, media_streamer_s *ms_streamer) -{ - GstElement *found_element = NULL; - const gchar *new_pad_type = NULL; - - ms_debug_fenter(); - - found_element = gst_pad_get_parent_element(src_pad); - new_pad_type = __ms_get_pad_type(src_pad); - - if (MS_ELEMENT_IS_VIDEO(new_pad_type)) - found_element = __ms_combine_next_element(found_element, src_pad, ms_streamer->transform_bin, MEDIA_STREAMER_NODE_TYPE_VIDEO_DECODER); - else if (MS_ELEMENT_IS_AUDIO(new_pad_type)) - found_element = __ms_combine_next_element(found_element, src_pad, ms_streamer->transform_bin, MEDIA_STREAMER_NODE_TYPE_AUDIO_DECODER); - else if (MS_ELEMENT_IS_TEXT(new_pad_type)) - found_element = __ms_combine_next_element(found_element, src_pad, ms_streamer->transform_bin, MEDIA_STREAMER_NODE_TYPE_TEXT_OVERLAY); - else - ms_error("Unsupported pad type [%s]!", new_pad_type); - - __ms_generate_dots(ms_streamer->pipeline, "after_demux_linked"); - gst_object_unref(found_element); - - ms_debug_fleave(); -} - -static void __demux_nomore_pads_cb(GstElement *demux, gpointer user_data) -{ - media_streamer_s *ms_streamer = (media_streamer_s *) user_data; - GList *iterator = NULL; - GList *list = NULL; - - ms_debug_fenter(); - - ms_retm_if(ms_streamer == NULL, "Handle is NULL"); - - g_mutex_lock(&ms_streamer->mutex_lock); - - list = ms_streamer->pads_types_list; - for (iterator = list; iterator; iterator = iterator->next) { - GstPad *src_pad = GST_PAD(iterator->data); - __demux_nomore_pads_combine(src_pad, ms_streamer); - } - - g_mutex_unlock(&ms_streamer->mutex_lock); - - ms_debug_fleave(); -} - -int __ms_demux_element_prepare(media_streamer_s * ms_streamer, media_streamer_node_s *demux_node) -{ - ms_debug_fenter(); - - ms_retvm_if(!ms_streamer, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "ms_streamer is NULL"); - ms_retvm_if(!demux_node, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "demux_node is NULL"); - - __ms_signal_create(&ms_streamer->autoplug_sig_list, demux_node->gst_element, "pad-added", G_CALLBACK(__demux_newpad_cb), ms_streamer); - __ms_signal_create(&ms_streamer->autoplug_sig_list, demux_node->gst_element, "no-more-pads", G_CALLBACK(__demux_nomore_pads_cb), ms_streamer); - - ms_debug_fleave(); - - return MEDIA_STREAMER_ERROR_NONE; -} - static void __ms_typefound_cb(GstElement *typefind, guint probability, GstCaps *caps, gpointer data) { media_streamer_s *ms_streamer = (media_streamer_s *) data; diff --git a/src/media_streamer_node.c b/src/media_streamer_node.c index f254004..d4d4303 100644 --- a/src/media_streamer_node.c +++ b/src/media_streamer_node.c @@ -29,7 +29,6 @@ #define SMACK_LABEL_LEN 255 #define DEFAULT_URI_SCHEME_LENGTH 10 -#define DEFAULT_HTTP_PORT 8888 #define _FEATURE_NAME_WIFI "http://tizen.org/feature/network.wifi" #define _FEATURE_NAME_TELEPHONY "http://tizen.org/feature/network.telephony" @@ -119,39 +118,39 @@ void __ms_get_state(media_streamer_s *ms_streamer) ms_debug_fleave(); } -static gboolean __ms_rtp_node_has_property(media_streamer_node_s *ms_node, const char *param_name) +static gboolean __ms_rtp_node_has_property(media_streamer_node_s *node, const char *param_name) { GValue *val = NULL; ms_debug_fenter(); - ms_retvm_if(!ms_node || !ms_node->gst_element, FALSE, "Error: empty node"); + ms_retvm_if(!node || !node->gst_element, FALSE, "Error: empty node"); ms_retvm_if(!param_name, FALSE, "Error: invalid property parameter"); - if (ms_node->type != MEDIA_STREAMER_NODE_TYPE_RTP) + if (node->type != MEDIA_STREAMER_NODE_TYPE_RTP) return FALSE; - val = (GValue *)g_object_get_data(G_OBJECT(ms_node->gst_element), param_name); + val = (GValue *)g_object_get_data(G_OBJECT(node->gst_element), param_name); ms_debug_fleave(); return val ? TRUE : FALSE; } -static int __ms_rtp_node_get_property(media_streamer_node_s *ms_node, param_s *param, GValue *value) +static int __ms_rtp_node_get_property(media_streamer_node_s *node, param_s *param, GValue *value) { int ret = MEDIA_STREAMER_ERROR_NONE; GValue *val = NULL; ms_debug_fenter(); - ms_retvm_if(!ms_node || !ms_node->gst_element, FALSE, "Error: empty node"); - ms_retvm_if(ms_node->type != MEDIA_STREAMER_NODE_TYPE_RTP, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Invalid node type"); + ms_retvm_if(!node || !node->gst_element, FALSE, "Error: empty node"); + ms_retvm_if(node->type != MEDIA_STREAMER_NODE_TYPE_RTP, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Invalid node type"); ms_retvm_if(!param, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Error: invalid property parameter"); ms_retvm_if(!value, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "value is NULL"); - val = (GValue *)g_object_get_data(G_OBJECT(ms_node->gst_element), param->param_name); + val = (GValue *)g_object_get_data(G_OBJECT(node->gst_element), param->param_name); if (!strcmp(param->param_name, MEDIA_STREAMER_PARAM_VIDEO_IN_PORT) || !strcmp(param->param_name, MEDIA_STREAMER_PARAM_AUDIO_IN_PORT) || !strcmp(param->param_name, MEDIA_STREAMER_PARAM_VIDEO_OUT_PORT) || @@ -169,21 +168,21 @@ static int __ms_rtp_node_get_property(media_streamer_node_s *ms_node, param_s *p return ret; } -static int __ms_rtp_node_set_property(media_streamer_node_s *ms_node, param_s *param, const char *param_value) +static int __ms_rtp_node_set_property(media_streamer_node_s *node, param_s *param, const char *param_value) { int ret = MEDIA_STREAMER_ERROR_NONE; GValue *val = NULL; ms_debug_fenter(); - ms_retvm_if(!ms_node || !ms_node->gst_element, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Error: empty node"); - ms_retvm_if(ms_node->type != MEDIA_STREAMER_NODE_TYPE_RTP, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Invalid node type"); + ms_retvm_if(!node || !node->gst_element, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Error: empty node"); + ms_retvm_if(node->type != MEDIA_STREAMER_NODE_TYPE_RTP, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Invalid node type"); ms_retvm_if(!param, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Error: invalid property parameter"); ms_retvm_if(!param_value, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "param_value is NULL"); - val = (GValue *)g_object_get_data(G_OBJECT(ms_node->gst_element), param->param_name); + val = (GValue *)g_object_get_data(G_OBJECT(node->gst_element), param->param_name); if (!val) { - ms_error("fail to get [%s] val from [%s]", param->param_name, GST_ELEMENT_NAME(ms_node->gst_element)); + ms_error("fail to get [%s] val from [%s]", param->param_name, GST_ELEMENT_NAME(node->gst_element)); return MEDIA_STREAMER_ERROR_INVALID_PARAMETER; } @@ -217,18 +216,18 @@ static int __ms_rtp_node_set_property(media_streamer_node_s *ms_node, param_s *p return ret; } -static gboolean __ms_adaptive_src_node_has_property(media_streamer_node_s *ms_node, const char * param_name) +static gboolean __ms_adaptive_src_node_has_property(media_streamer_node_s *node, const char * param_name) { GValue *val = NULL; ms_debug_fenter(); - ms_retvm_if(!ms_node || !ms_node->gst_element, FALSE, "Error: empty node"); + ms_retvm_if(!node || !node->gst_element, FALSE, "Error: empty node"); ms_retvm_if(!param_name, FALSE, "Error: invalid property parameter"); - if (ms_node->type == MEDIA_STREAMER_NODE_TYPE_SRC && - ms_node->subtype == MEDIA_STREAMER_NODE_SRC_TYPE_ADAPTIVE) { - val = (GValue *)g_object_get_data(G_OBJECT(ms_node->gst_element), param_name); + if (node->type == MEDIA_STREAMER_NODE_TYPE_SRC && + node->subtype == MEDIA_STREAMER_NODE_SRC_TYPE_ADAPTIVE) { + val = (GValue *)g_object_get_data(G_OBJECT(node->gst_element), param_name); ms_debug_fleave(); @@ -240,20 +239,20 @@ static gboolean __ms_adaptive_src_node_has_property(media_streamer_node_s *ms_no return FALSE; } -static int __ms_adaptive_src_node_get_property(media_streamer_node_s *ms_node, param_s *param, GValue *value) +static int __ms_adaptive_src_node_get_property(media_streamer_node_s *node, param_s *param, GValue *value) { int ret = MEDIA_STREAMER_ERROR_NONE; GValue *val = NULL; ms_debug_fenter(); - ms_retvm_if(!ms_node || !ms_node->gst_element, FALSE, "Error: empty node"); - ms_retvm_if(ms_node->type != MEDIA_STREAMER_NODE_TYPE_SRC && - ms_node->subtype != MEDIA_STREAMER_NODE_SRC_TYPE_ADAPTIVE, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Invalid node type"); + ms_retvm_if(!node || !node->gst_element, FALSE, "Error: empty node"); + ms_retvm_if(node->type != MEDIA_STREAMER_NODE_TYPE_SRC && + node->subtype != MEDIA_STREAMER_NODE_SRC_TYPE_ADAPTIVE, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Invalid node type"); ms_retvm_if(!param, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Error: invalid property parameter"); ms_retvm_if(!value, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "value is NULL"); - val = (GValue *)g_object_get_data(G_OBJECT(ms_node->gst_element), param->param_name); + val = (GValue *)g_object_get_data(G_OBJECT(node->gst_element), param->param_name); if (!strcmp(param->param_name, MEDIA_STREAMER_PARAM_URI)) g_value_init(value, G_TYPE_STRING); else @@ -266,22 +265,22 @@ static int __ms_adaptive_src_node_get_property(media_streamer_node_s *ms_node, p return ret; } -static int __ms_adaptive_src_node_set_property(media_streamer_node_s *ms_node, param_s *param, const char *param_value) +static int __ms_adaptive_src_node_set_property(media_streamer_node_s *node, param_s *param, const char *param_value) { int ret = MEDIA_STREAMER_ERROR_NONE; GValue *val = NULL; ms_debug_fenter(); - ms_retvm_if(!ms_node || !ms_node->gst_element, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Error: empty node"); - ms_retvm_if(ms_node->type != MEDIA_STREAMER_NODE_TYPE_SRC && - ms_node->subtype != MEDIA_STREAMER_NODE_SRC_TYPE_ADAPTIVE, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Invalid node type"); + ms_retvm_if(!node || !node->gst_element, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Error: empty node"); + ms_retvm_if(node->type != MEDIA_STREAMER_NODE_TYPE_SRC && + node->subtype != MEDIA_STREAMER_NODE_SRC_TYPE_ADAPTIVE, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Invalid node type"); ms_retvm_if(!param, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Error: invalid property parameter"); ms_retvm_if(!param_value, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "param_value is NULL"); - val = (GValue *)g_object_get_data(G_OBJECT(ms_node->gst_element), param->param_name); + val = (GValue *)g_object_get_data(G_OBJECT(node->gst_element), param->param_name); if (!val) { - ms_error("fail to get [%s] val from [%s]", param->param_name, GST_ELEMENT_NAME(ms_node->gst_element)); + ms_error("fail to get [%s] val from [%s]", param->param_name, GST_ELEMENT_NAME(node->gst_element)); return MEDIA_STREAMER_ERROR_INVALID_PARAMETER; } @@ -839,24 +838,59 @@ void __ms_node_destroy(media_streamer_node_s *node) ms_debug_fleave(); } -int __ms_node_insert_into_table(GHashTable *nodes_table, media_streamer_node_s *ms_node) +int __ms_add_node_into_bin(media_streamer_s *ms_streamer, media_streamer_node_s *node) +{ + int ret = MEDIA_STREAMER_ERROR_NONE; + GstElement *bin = NULL; + + ms_debug_fenter(); + + ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Handle is NULL"); + ms_retvm_if(node == NULL, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "node is NULL"); + + ms_info("Try to add [%s] node into streamer, node type/subtype [%d/%d]", node->name, node->type, node->subtype); + + switch (node->type) { + case MEDIA_STREAMER_NODE_TYPE_SRC: + bin = ms_streamer->src_bin; + break; + case MEDIA_STREAMER_NODE_TYPE_SINK: + bin = ms_streamer->sink_bin; + break; + default: + /* Another elements will be add into transform bin */ + bin = ms_streamer->transform_bin; + break; + } + + if (!__ms_bin_add_element(bin, node->gst_element, TRUE)) { + ms_error("Failed to add Element [%s] into [%s] bin.", node->name, GST_ELEMENT_NAME(bin)); + ret = MEDIA_STREAMER_ERROR_INVALID_OPERATION; + } + + ms_debug_fleave(); + + return ret; +} + +int __ms_node_insert_into_table(GHashTable *nodes_table, media_streamer_node_s *node) { ms_debug_fenter(); ms_retvm_if(nodes_table == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "nodes_table is NULL"); - ms_retvm_if(ms_node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "ms_node is NULL"); - ms_retvm_if(ms_node->name == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "ms_node->name is NULL"); + ms_retvm_if(node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL"); + ms_retvm_if(node->name == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node->name is NULL"); - if (g_hash_table_contains(nodes_table, ms_node->name)) { - ms_debug("Current Node [%s] already added into Media Streamer", ms_node->name); + if (g_hash_table_contains(nodes_table, node->name)) { + ms_debug("Current Node [%s] already added into Media Streamer", node->name); return MEDIA_STREAMER_ERROR_INVALID_OPERATION; } - if (!g_hash_table_insert(nodes_table, (gpointer) ms_node->name, (gpointer) ms_node)) { - ms_debug("Error: Failed to add node [%s] into Media Streamer", ms_node->name); + if (!g_hash_table_insert(nodes_table, (gpointer) node->name, (gpointer) node)) { + ms_debug("Error: Failed to add node [%s] into Media Streamer", node->name); return MEDIA_STREAMER_ERROR_INVALID_OPERATION; } - ms_info("Node [%s] added into streamer, node type/subtype [%d/%d]", ms_node->name, ms_node->type, ms_node->subtype); + ms_info("Node [%s] added into streamer, node type/subtype [%d/%d]", node->name, node->type, node->subtype); ms_debug_fleave(); @@ -865,19 +899,19 @@ int __ms_node_insert_into_table(GHashTable *nodes_table, media_streamer_node_s * void __ms_node_remove_from_table(void *data) { - media_streamer_node_s *ms_node = (media_streamer_node_s *) data; + media_streamer_node_s *node = (media_streamer_node_s *) data; ms_debug_fenter(); - ms_retm_if(ms_node == NULL, "data is NULL"); + ms_retm_if(node == NULL, "data is NULL"); - if (__ms_element_unlink(ms_node->gst_element)) { - ms_node->linked_by_user = FALSE; - ms_node->parent_streamer = NULL; - __ms_bin_remove_element(ms_node->gst_element); - ms_info("Node [%s] removed from Media Streamer", ms_node->name); + if (__ms_element_unlink(node->gst_element)) { + node->linked_by_user = FALSE; + node->parent_streamer = NULL; + __ms_bin_remove_element(node->gst_element); + ms_info("Node [%s] removed from Media Streamer", node->name); } else { - ms_error("Error: Node [%s] remove failed", ms_node->name); + ms_error("Error: Node [%s] remove failed", node->name); } ms_debug_fleave(); @@ -922,7 +956,23 @@ node_info_s * __ms_node_get_klass_by_its_type(media_streamer_node_type_e element return &nodes_info[it_klass]; } -static gboolean _src_node_prepare(const GValue *item, GValue *ret, gpointer user_data) +gboolean _ms_sink_node_prepare_iter(const GValue *item, GValue *g_ret, gpointer user_data) +{ + gboolean ret = FALSE; + + ms_retvm_if(item == NULL, FALSE, "item is NULL"); + ms_retvm_if(g_ret == NULL, FALSE, "ret is NULL"); + + ms_debug_fenter(); + + ret = __ms_element_lock_state(item, g_ret, user_data); + + ms_debug_fleave(); + + return ret; +} + +gboolean _ms_src_node_prepare_iter(const GValue *item, GValue *ret, gpointer user_data) { media_streamer_s *ms_streamer = (media_streamer_s *) user_data; GstElement *src_element = NULL; @@ -994,28 +1044,123 @@ static gboolean _src_node_prepare(const GValue *item, GValue *ret, gpointer user return TRUE; } -static gboolean _sink_node_prepare(const GValue *item, GValue *g_ret, gpointer user_data) +static GstElement *__ms_manifest_src_create(media_streamer_node_s *node) { - gboolean ret = FALSE; - - ms_retvm_if(item == NULL, FALSE, "item is NULL"); - ms_retvm_if(g_ret == NULL, FALSE, "ret is NULL"); + char *manifest_src_name = NULL; + gchar *location = NULL; + GstElement *manifest_src = NULL; + GValue *val = NULL; + const char *uri = NULL; + gchar *protocol = NULL; ms_debug_fenter(); - ret = __ms_element_lock_state(item, g_ret, user_data); + ms_retvm_if(!node, NULL, "node is NULL"); + + val = (GValue *)g_object_get_data(G_OBJECT(node->gst_element), MEDIA_STREAMER_PARAM_URI); + uri = g_value_get_string(val); + protocol = gst_uri_is_valid(uri) ? gst_uri_get_protocol(uri) : NULL; + + if (protocol && g_strrstr(protocol, "http")) { + manifest_src_name = __ms_ini_get_string("node type 1:http", DEFAULT_HTTP_SOURCE); + location = g_strdup(uri); + } else if (protocol && g_strrstr(protocol, "file")) { + manifest_src_name = __ms_ini_get_string("node type 1:file", DEFAULT_FILE_SOURCE); + location = gst_uri_get_location(uri); + } else { + ms_error("Unsupported URI protocol... Check URI is file path"); + 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 { + g_free(protocol); + ms_error("URI is not valid file path"); + return NULL; + } + } + g_free(protocol); + + 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); + 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); ms_debug_fleave(); - return ret; + return manifest_src; } -static gboolean demux_find(gpointer key, gpointer value, gpointer user_data) +int __ms_adaptive_src_node_prepare(media_streamer_node_s *node, bool auto_plug) { - return g_strrstr((char *)key, "demux") != NULL; + char *plugin_name = NULL; + GstElement *manifest_src = NULL; + GstElement *plugin_elem = NULL; + gboolean res = FALSE; + GstPad *gp = NULL; + + ms_debug_fenter(); + + ms_retvm_if(node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL"); + + if (!auto_plug) { + plugin_name = __ms_ini_get_string("node type 1:adaptive", DEFAULT_ADAPTIVE_SOURCE); + ms_retvm_if(plugin_name == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Error empty plugin name for adaptive 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 for adaptive source"); + + res = gst_bin_add(GST_BIN(node->gst_element), plugin_elem); + ms_retvm_if(res == FALSE, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, + "Error adding adaptive element to bin for adaptive source"); + } + + manifest_src = __ms_manifest_src_create(node); + ms_retvm_if(manifest_src == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, + "Error creating manifest source for adaptive source"); + + res = gst_bin_add(GST_BIN(node->gst_element), manifest_src); + ms_retvm_if(res == FALSE, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, + "Error adding manifest source to bin for adaptive source"); + + if (!auto_plug) { + res = gst_element_link(manifest_src, plugin_elem); + ms_retvm_if(res == FALSE, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, + "Error linking manifest source and element for adaptive source"); + } + + gp = gst_element_get_static_pad(node->gst_element, "src"); + ms_retvm_if(gp == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, + "Error getting source pad for adaptive source"); + + if (!auto_plug) { + g_signal_connect_object(plugin_elem, "pad-added", + G_CALLBACK(__ms_hlsdemux_pad_added_cb), gp, 0); + } else { + GstPad *manifest_src_pad = gst_element_get_static_pad(manifest_src, "src"); + gst_ghost_pad_set_target(GST_GHOST_PAD(gp), manifest_src_pad); + } + + ms_debug_fleave(); + + return MEDIA_STREAMER_ERROR_NONE; } -static int __ms_adaptive_sink_http_server_prepare(media_streamer_s * ms_streamer, media_streamer_node_s *node) +int __ms_adaptive_sink_node_prepare(media_streamer_s *ms_streamer, media_streamer_node_s *node) { int err_code = MEDIA_STREAMER_ERROR_NONE; gchar *playlist_location = NULL; @@ -1066,201 +1211,163 @@ _DONE: return err_code; } -int __ms_pipeline_prepare(media_streamer_s *ms_streamer) +//LCOV_EXCL_START +gboolean __ms_rtp_node_prepare(media_streamer_node_s *node) { - int ret = MEDIA_STREAMER_ERROR_NONE; - media_streamer_node_s *rtp_node = NULL; - media_streamer_node_s *demux = NULL; - media_streamer_node_s *adaptive_src = NULL; - media_streamer_node_s *adaptive_sink = NULL; + GstElement *rtpbin = NULL; + gboolean ret = TRUE; + GstElement *rtp_el = NULL; + GstElement *rtcp_el = NULL; + GValue *val = NULL; + const char *host = NULL; + GstElement *video_filter = NULL; + GstCaps *video_caps = NULL; + GstGhostPad *ghost_pad = NULL; + GstElement *audio_filter = NULL; + GstCaps *audio_caps = NULL; ms_debug_fenter(); - ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "ms_streamer is NULL"); - ms_retvm_if(ms_streamer->nodes_table == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "ms_streamer->nodes_table is NULL"); - ms_retvm_if(ms_streamer->src_bin == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "ms_streamer->src_bin is NULL"); - ms_retvm_if(ms_streamer->transform_bin == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "ms_streamer->transform_bin is NULL"); - - rtp_node = (media_streamer_node_s *)g_hash_table_lookup(ms_streamer->nodes_table, "rtp_container"); - demux = (media_streamer_node_s *)g_hash_table_find(ms_streamer->nodes_table, (GHRFunc)demux_find, NULL); - adaptive_src = (media_streamer_node_s *)g_hash_table_lookup(ms_streamer->nodes_table, "adaptive_src"); - 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) { - ret = __ms_demux_element_prepare(ms_streamer, demux); - if (MEDIA_STREAMER_ERROR_NONE != ret) - ms_error("Failed to prepare demux element"); - } else { - GstBin *nodes_bin = GST_BIN(ms_streamer->src_bin); - if (nodes_bin->numchildren == 0) { - ms_debug(" No any node is added to [%s]", GST_ELEMENT_NAME(ms_streamer->src_bin)); - return MEDIA_STREAMER_ERROR_INVALID_PARAMETER; - } - nodes_bin = GST_BIN(ms_streamer->sink_bin); - if (nodes_bin->numchildren == 0) { - ms_debug(" No any node is added to [%s]", GST_ELEMENT_NAME(ms_streamer->sink_bin)); - return MEDIA_STREAMER_ERROR_INVALID_PARAMETER; - } - } + ms_retvm_if(!node, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "node is NULL"); - if (adaptive_src) { - if (GST_BIN(ms_streamer->transform_bin)->numchildren == 0) - ret = __ms_adaptive_element_prepare(adaptive_src, true); - else - ret = __ms_adaptive_element_prepare(adaptive_src, false); - } - - if (adaptive_sink) - ret = __ms_adaptive_sink_http_server_prepare(ms_streamer, adaptive_sink); - - if (ret != MEDIA_STREAMER_ERROR_NONE) - goto prepare_fail; + rtpbin = __ms_element_create("rtpbin", "rtpbin"); + ms_retvm_if(!rtpbin, FALSE, "Error: creating elements for rtp container"); - ret = __ms_bin_foreach_elements(GST_BIN(ms_streamer->sink_bin), _sink_node_prepare, ms_streamer); - if (MEDIA_STREAMER_ERROR_NONE != ret) { - ms_error("Failed to prepare nodes within sink bin"); - goto prepare_fail; + if (!__ms_bin_add_element(node->gst_element, rtpbin, FALSE)) { + MS_SAFE_UNREF(rtpbin); + return FALSE; } - ret = __ms_bin_foreach_elements(GST_BIN(ms_streamer->src_bin), _src_node_prepare, ms_streamer); - if (MEDIA_STREAMER_ERROR_NONE != ret) { - ms_error("Failed to prepare nodes within src bin"); - goto prepare_fail; - } + __ms_signal_create(&node->sig_list, rtpbin, "pad-added", G_CALLBACK(__ms_rtpbin_pad_added_cb), node); - ret = __ms_state_change(ms_streamer, MEDIA_STREAMER_STATE_READY); - if (ret != MEDIA_STREAMER_ERROR_NONE) - goto prepare_fail; + val = (GValue *)g_object_get_data(G_OBJECT(node->gst_element), MEDIA_STREAMER_PARAM_HOST); + host = g_value_get_string(val); - ms_debug_fleave(); + val = (GValue *)g_object_get_data(G_OBJECT(node->gst_element), MEDIA_STREAMER_PARAM_VIDEO_IN_PORT); + if (g_value_get_int(val) > RTP_STREAM_DISABLED) { + rtp_el = __ms_element_create("udpsrc", MS_RTP_PAD_VIDEO_IN"_rtp"); + __ms_bin_add_element(node->gst_element, rtp_el, FALSE); - return ret; + rtcp_el = __ms_element_create("udpsrc", MS_RTP_PAD_VIDEO_IN"_rctp"); + __ms_bin_add_element(node->gst_element, rtcp_el, FALSE); -prepare_fail: - __ms_pipeline_unprepare(ms_streamer); - return ret; -} - -static gboolean __ms_bin_remove_elements(media_streamer_s *ms_streamer, GstElement *bin) -{ - GValue element = G_VALUE_INIT; - GstIterator *bin_iterator = NULL; - gboolean ret = TRUE; /* If Bin doesn't have any elements function returns TRUE */ - GstElement *found_element = NULL; - GstIteratorResult it_res = GST_ITERATOR_ERROR; - media_streamer_node_s *found_node = NULL; + ret = ret && gst_element_link_pads(rtp_el, "src", rtpbin, "recv_rtp_sink_0"); + ret = ret && gst_element_link_pads(rtcp_el, "src", rtpbin, "recv_rtcp_sink_0"); - ms_debug_fenter(); + g_object_set_property(G_OBJECT(rtp_el), MEDIA_STREAMER_PARAM_PORT, val); + g_object_set(G_OBJECT(rtcp_el), MEDIA_STREAMER_PARAM_PORT, (g_value_get_int(val) + 1), NULL); - ms_retvm_if(ms_streamer == NULL, FALSE, "ms_streamer is NULL"); - ms_retvm_if(bin == NULL, FALSE, "bin is NULL"); - ms_retvm_if(ms_streamer->nodes_table == NULL, FALSE, "ms_streamer->nodes_table is NULL"); + val = (GValue *)g_object_get_data(G_OBJECT(node->gst_element), MEDIA_STREAMER_PARAM_VIDEO_IN_FORMAT); + g_object_set_property(G_OBJECT(rtp_el), "caps", val); + } - bin_iterator = gst_bin_iterate_elements(GST_BIN(bin)); - it_res = gst_iterator_next(bin_iterator, &element); + val = (GValue *)g_object_get_data(G_OBJECT(node->gst_element), MEDIA_STREAMER_PARAM_AUDIO_IN_PORT); + if (g_value_get_int(val) > RTP_STREAM_DISABLED) { + rtp_el = __ms_element_create("udpsrc", MS_RTP_PAD_AUDIO_IN"_rtp"); + __ms_bin_add_element(node->gst_element, rtp_el, FALSE); - while (GST_ITERATOR_OK == it_res) { - found_element = (GstElement *) g_value_get_object(&element); + rtcp_el = __ms_element_create("udpsrc", MS_RTP_PAD_AUDIO_IN"_rctp"); + __ms_bin_add_element(node->gst_element, rtcp_el, FALSE); - /* Get node of this element if it appears as node */ - found_node = (media_streamer_node_s *) g_hash_table_lookup(ms_streamer->nodes_table, GST_ELEMENT_NAME(found_element)); - if (found_node) { - if (!found_node->linked_by_user) - ret = ret && __ms_element_unlink(found_element); - else - ms_info("Unprepare skipped user-linked node [%s]", found_node->name); - __ms_generate_dots(ms_streamer->pipeline, GST_ELEMENT_NAME(found_element)); - } else { - ret = ret && __ms_bin_remove_element(found_element); - } + ret = ret && gst_element_link_pads(rtp_el, "src", rtpbin, "recv_rtp_sink_1"); + ret = ret && gst_element_link_pads(rtcp_el, "src", rtpbin, "recv_rtcp_sink_1"); - g_value_reset(&element); + g_object_set_property(G_OBJECT(rtp_el), MEDIA_STREAMER_PARAM_PORT, val); + g_object_set(G_OBJECT(rtcp_el), MEDIA_STREAMER_PARAM_PORT, (g_value_get_int(val) + 1), NULL); - it_res = gst_iterator_next(bin_iterator, &element); - if (GST_ITERATOR_RESYNC == it_res) { - gst_iterator_resync(bin_iterator); - it_res = gst_iterator_next(bin_iterator, &element); - } + val = (GValue *)g_object_get_data(G_OBJECT(node->gst_element), MEDIA_STREAMER_PARAM_AUDIO_IN_FORMAT); + g_object_set_property(G_OBJECT(rtp_el), "caps", val); } - g_value_unset(&element); - gst_iterator_free(bin_iterator); + val = (GValue *)g_object_get_data(G_OBJECT(node->gst_element), MEDIA_STREAMER_PARAM_VIDEO_OUT_PORT); + if (g_value_get_int(val) > RTP_STREAM_DISABLED) { + rtp_el = __ms_element_create("udpsink", MS_RTP_PAD_VIDEO_OUT"_rtp"); + __ms_bin_add_element(node->gst_element, rtp_el, FALSE); - ms_debug_fleave(); + rtcp_el = __ms_element_create("udpsink", MS_RTP_PAD_VIDEO_OUT"_rctp"); + __ms_bin_add_element(node->gst_element, rtcp_el, FALSE); - return ret; -} + video_filter = __ms_element_create("capsfilter", NULL); + __ms_bin_add_element(node->gst_element, video_filter, FALSE); -static void __ms_pending_pads_remove(void *data) -{ - GstPad *pad = NULL; + video_caps = gst_caps_from_string(MEDIA_STREAMER_DEFAULT_VIDEO_RTP_FORMAT); + g_object_set(G_OBJECT(video_filter), "caps", video_caps, NULL); + gst_caps_unref(video_caps); - ms_debug_fenter(); - - ms_retm_if(data == NULL, "data is NULL"); + gst_element_link_pads(video_filter, "src", rtpbin, "send_rtp_sink_0"); - pad = GST_PAD(data); - MS_SAFE_UNREF(pad); + ghost_pad = (GstGhostPad *)gst_element_get_static_pad(node->gst_element, MS_RTP_PAD_VIDEO_IN); + if (ghost_pad) { + if (gst_ghost_pad_set_target(ghost_pad, gst_element_get_static_pad(video_filter, "sink"))) + ms_info(" Capsfilter for [%s] in RTP is set and linked", MS_RTP_PAD_VIDEO_IN); + } - ms_debug_fleave(); -} + ret = ret && gst_element_link_pads(rtpbin, "send_rtp_src_0", rtp_el, "sink"); + ret = ret && gst_element_link_pads(rtpbin, "send_rtcp_src_0", rtcp_el, "sink"); -int __ms_pipeline_unprepare(media_streamer_s *ms_streamer) -{ - int ret = MEDIA_STREAMER_ERROR_NONE; + g_object_set_property(G_OBJECT(rtp_el), MEDIA_STREAMER_PARAM_PORT, val); + g_object_set(GST_OBJECT(rtp_el), MEDIA_STREAMER_PARAM_HOST, host, NULL); + g_object_set(G_OBJECT(rtcp_el), MEDIA_STREAMER_PARAM_PORT, (g_value_get_int(val) + 1), NULL); + g_object_set(GST_OBJECT(rtcp_el), "sync", FALSE, NULL); + g_object_set(GST_OBJECT(rtcp_el), "async", FALSE, NULL); + g_object_set(GST_OBJECT(rtcp_el), MEDIA_STREAMER_PARAM_HOST, host, NULL); + } - ms_debug_fenter(); + val = (GValue *)g_object_get_data(G_OBJECT(node->gst_element), MEDIA_STREAMER_PARAM_AUDIO_OUT_PORT); + if (g_value_get_int(val) > RTP_STREAM_DISABLED) { + rtp_el = __ms_element_create("udpsink", MS_RTP_PAD_AUDIO_OUT"_rtp"); + __ms_bin_add_element(node->gst_element, rtp_el, FALSE); - ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL"); - ms_retvm_if(ms_streamer->nodes_table == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "ms_streamer->nodes_table is NULL"); + rtcp_el = __ms_element_create("udpsink", MS_RTP_PAD_AUDIO_OUT"_rctp"); + __ms_bin_add_element(node->gst_element, rtcp_el, FALSE); - ret = __ms_state_change(ms_streamer, MEDIA_STREAMER_STATE_IDLE); - if (ret != MEDIA_STREAMER_ERROR_NONE) - ms_error("Failed to unprepare pipeline"); + audio_filter = __ms_element_create("capsfilter", NULL); + __ms_bin_add_element(node->gst_element, audio_filter, FALSE); - if (!ms_streamer->is_interrupted) { - /* Unprepare resources in case of failure */ - __ms_release_resources(ms_streamer); + audio_caps = gst_caps_from_string(MEDIA_STREAMER_DEFAULT_AUDIO_RTP_FORMAT); + g_object_set(G_OBJECT(audio_filter), "caps", audio_caps, NULL); - if (ms_streamer->video_decoder_resource != NULL) { - ret = mm_resource_manager_mark_for_release(ms_streamer->resource_manager, - ms_streamer->video_decoder_resource); - if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) - ms_error("Failed to mark resources for release"); + gst_element_link_pads(audio_filter, "src", rtpbin, "send_rtp_sink_1"); - ret = mm_resource_manager_commit(ms_streamer->resource_manager); - if (ret != MEDIA_STREAMER_ERROR_NONE) - ms_error("Failed to release resources"); - else - ms_streamer->video_decoder_resource = NULL; + ghost_pad = (GstGhostPad *)gst_element_get_static_pad(node->gst_element, MS_RTP_PAD_AUDIO_IN); + if (ghost_pad) { + if (gst_ghost_pad_set_target(ghost_pad, gst_element_get_static_pad(audio_filter, "sink"))) + ms_info(" Capsfilter for [%s] in RTP is set and linked", MS_RTP_PAD_AUDIO_IN); } - } - /* Disconnects and clean all autoplug signals */ - g_list_free_full(ms_streamer->autoplug_sig_list, __ms_signal_destroy); - ms_streamer->autoplug_sig_list = NULL; + ret = ret && gst_element_link_pads(rtpbin, "send_rtp_src_1", rtp_el, "sink"); + ret = ret && gst_element_link_pads(rtpbin, "send_rtcp_src_1", rtcp_el, "sink"); - /* Removes all pending pads according to list */ - g_list_free_full(ms_streamer->pads_types_list, __ms_pending_pads_remove); - ms_streamer->pads_types_list = NULL; - - media_streamer_node_s *rtp_node = (media_streamer_node_s *)g_hash_table_lookup(ms_streamer->nodes_table, "rtp_container"); - if (rtp_node) { - g_list_free_full(rtp_node->sig_list, __ms_signal_destroy); - rtp_node->sig_list = NULL; - MS_BIN_UNPREPARE(rtp_node->gst_element); + g_object_set_property(G_OBJECT(rtp_el), MEDIA_STREAMER_PARAM_PORT, val); + g_object_set(GST_OBJECT(rtp_el), MEDIA_STREAMER_PARAM_HOST, host, NULL); + g_object_set(G_OBJECT(rtcp_el), MEDIA_STREAMER_PARAM_PORT, (g_value_get_int(val) + 1), NULL); + g_object_set(GST_OBJECT(rtcp_el), "sync", FALSE, NULL); + g_object_set(GST_OBJECT(rtcp_el), "async", FALSE, NULL); + g_object_set(GST_OBJECT(rtcp_el), MEDIA_STREAMER_PARAM_HOST, host, NULL); } - MS_BIN_UNPREPARE(ms_streamer->src_bin); - MS_BIN_UNPREPARE(ms_streamer->transform_bin); - MS_BIN_UNPREPARE(ms_streamer->sink_bin); + __ms_generate_dots(node->gst_element, "rtp_prepared"); ms_debug_fleave(); return ret; } +//LCOV_EXCL_STOP + +int __ms_demux_node_prepare(media_streamer_s *ms_streamer, media_streamer_node_s *node) +{ + ms_debug_fenter(); + + ms_retvm_if(!ms_streamer, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "ms_streamer is NULL"); + ms_retvm_if(!node, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL"); + + __ms_signal_create(&ms_streamer->autoplug_sig_list, node->gst_element, "pad-added", G_CALLBACK(__ms_demux_pad_added_cb), ms_streamer); + __ms_signal_create(&ms_streamer->autoplug_sig_list, node->gst_element, "no-more-pads", G_CALLBACK(__ms_demux_nomore_pads_cb), ms_streamer); + + ms_debug_fleave(); + + return MEDIA_STREAMER_ERROR_NONE; +} int __ms_node_set_params_from_bundle(media_streamer_node_s *node, bundle *param_list) { @@ -1676,7 +1783,7 @@ _DONE: * * @since_tizen 3.0 */ -int __ms_node_set_display(media_streamer_node_s *ms_node, const char *param_value) +int __ms_node_set_display(media_streamer_node_s *node, const char *param_value) { int ret = MEDIA_STREAMER_ERROR_NONE; Evas_Object *obj = NULL; @@ -1692,32 +1799,32 @@ int __ms_node_set_display(media_streamer_node_s *ms_node, const char *param_valu LOGD("wayland global surface id : %d", wl_info.parent_id); - gst_video_overlay_set_wl_window_wl_surface_id(GST_VIDEO_OVERLAY(ms_node->gst_element), wl_info.parent_id); + gst_video_overlay_set_wl_window_wl_surface_id(GST_VIDEO_OVERLAY(node->gst_element), wl_info.parent_id); return ret; } //LCOV_EXCL_STOP -int __ms_node_set_param_value(media_streamer_node_s *ms_node, param_s *param, const char *param_value) +int __ms_node_set_param_value(media_streamer_node_s *node, param_s *param, const char *param_value) { int ret = MEDIA_STREAMER_ERROR_NONE; ms_debug_fenter(); - ms_retvm_if(ms_node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "ms_node is NULL"); + ms_retvm_if(node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL"); ms_retvm_if(param == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "param is NULL"); ms_retvm_if(param_value == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "param_value is NULL"); - if (ms_node->type == MEDIA_STREAMER_NODE_TYPE_RTP) { - ret = __ms_rtp_node_set_property(ms_node, param, param_value); + if (node->type == MEDIA_STREAMER_NODE_TYPE_RTP) { + ret = __ms_rtp_node_set_property(node, param, param_value); ms_debug_fleave(); return ret; } - if (ms_node->type == MEDIA_STREAMER_NODE_TYPE_SRC && - ms_node->subtype == MEDIA_STREAMER_NODE_SRC_TYPE_ADAPTIVE) { - ret = __ms_adaptive_src_node_set_property(ms_node, param, param_value); + if (node->type == MEDIA_STREAMER_NODE_TYPE_SRC && + node->subtype == MEDIA_STREAMER_NODE_SRC_TYPE_ADAPTIVE) { + ret = __ms_adaptive_src_node_set_property(node, param, param_value); ms_debug_fleave(); return ret; } @@ -1725,7 +1832,7 @@ int __ms_node_set_param_value(media_streamer_node_s *ms_node, param_s *param, co if (!g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_CAMERA_ID)) { int camera_id = (int)strtol(param_value, NULL, 10); ms_retvm_if(camera_id == -1, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Invalid %s value", param->param_name); - g_object_set(ms_node->gst_element, param->origin_name, camera_id, NULL); + g_object_set(node->gst_element, param->origin_name, camera_id, NULL); } else if (!g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_CAPTURE_WIDTH) || !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_CAPTURE_HEIGHT) || !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_STREAM_TYPE) || @@ -1733,30 +1840,30 @@ int __ms_node_set_param_value(media_streamer_node_s *ms_node, param_s *param, co !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_ROTATE) || !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_FLIP) || !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_DISPLAY_GEOMETRY_METHOD)) { - g_object_set(ms_node->gst_element, param->origin_name, (int)strtol(param_value, NULL, 10), NULL); + g_object_set(node->gst_element, param->origin_name, (int)strtol(param_value, NULL, 10), NULL); } else if (!g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_IS_LIVE_STREAM) || !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_CLOCK_SYNCHRONIZED) || !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_USE_TBM) || !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_VISIBLE)) { - g_object_set(ms_node->gst_element, param->origin_name, !g_ascii_strcasecmp(param_value, "true"), NULL); + g_object_set(node->gst_element, param->origin_name, !g_ascii_strcasecmp(param_value, "true"), NULL); } else if (!g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_URI)) { - if (ms_node->type == MEDIA_STREAMER_NODE_TYPE_SRC && ms_node->subtype == MEDIA_STREAMER_NODE_SRC_TYPE_FILE) { + if (node->type == MEDIA_STREAMER_NODE_TYPE_SRC && node->subtype == MEDIA_STREAMER_NODE_SRC_TYPE_FILE) { ret = __ms_util_uri_path_check(param_value); if (ret != MEDIA_STREAMER_ERROR_NONE) return ret; } - g_object_set(ms_node->gst_element, param->origin_name, param_value, NULL); + g_object_set(node->gst_element, param->origin_name, param_value, NULL); } else if (!g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_USER_AGENT) || !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_IP_ADDRESS) || !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_AUDIO_DEVICE) || !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_HOST) || !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_SEGMENT_LOCATION) || !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_PLAYLIST_LOCATION)) { - g_object_set(ms_node->gst_element, param->origin_name, param_value, NULL); + g_object_set(node->gst_element, param->origin_name, param_value, NULL); } else if (!g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_DISPLAY)) { - ret = __ms_node_set_display(ms_node, param_value); + ret = __ms_node_set_display(node, param_value); } else { - ms_info("Can not set parameter [%s] in the node [%s]", param->param_name, ms_node->name); + ms_info("Can not set parameter [%s] in the node [%s]", param->param_name, node->name); ret = MEDIA_STREAMER_ERROR_INVALID_PARAMETER; } @@ -1799,7 +1906,7 @@ int __ms_node_set_pad_format(media_streamer_node_s *node, const char *pad_name, MS_SAFE_GFREE(rtp_caps_str); } else { - ret = __ms_element_set_fmt(node, pad_name, fmt); + ret = __ms_element_set_fmt(node->gst_element, pad_name, fmt); } ms_debug_fleave();