Add new APIs to set/unset decoded ready callback of the node
[platform/core/api/mediastreamer.git] / src / media_streamer_node.c
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <cynara-client.h>
18 #include <system_info.h>
19 #include <Evas.h>
20 #include <gst/video/videooverlay.h>
21 #include "media_streamer_node.h"
22 #include "media_streamer_node_resources.h"
23 #include "media_streamer_node_dpm_policy.h"
24 #include "media_streamer_util.h"
25 #include "media_streamer_gst.h"
26 #include "media_streamer_gst_webrtc.h"
27
28 #define SMACK_LABEL_LEN 255
29 #define DEFAULT_URI_SCHEME_LENGTH 10
30
31 #define _FEATURE_NAME_WIFI               "http://tizen.org/feature/network.wifi"
32 #define _FEATURE_NAME_TELEPHONY          "http://tizen.org/feature/network.telephony"
33 #define _FEATURE_NAME_ETHERNET           "http://tizen.org/feature/network.ethernet"
34 #define _FEATURE_NAME_CAMERA             "http://tizen.org/feature/camera"
35 #define _FEATURE_NAME_MICROPHONE         "http://tizen.org/feature/microphone"
36
37 static param_s param_table[] = {
38         {MEDIA_STREAMER_PARAM_CAMERA_ID, "camera-id"},
39         {MEDIA_STREAMER_PARAM_CAPTURE_WIDTH, "capture-width"},
40         {MEDIA_STREAMER_PARAM_CAPTURE_HEIGHT, "capture-height"},
41         {MEDIA_STREAMER_PARAM_IS_LIVE_STREAM, "is-live"},
42         {MEDIA_STREAMER_PARAM_IS_LIVE_STREAM, "living"},
43         {MEDIA_STREAMER_PARAM_URI, "uri"},
44         {MEDIA_STREAMER_PARAM_URI, "location"},
45         {MEDIA_STREAMER_PARAM_USER_AGENT, "user-agent"},
46         {MEDIA_STREAMER_PARAM_STREAM_TYPE, "stream-type"},
47         {MEDIA_STREAMER_PARAM_PORT, "port"},
48         {MEDIA_STREAMER_PARAM_VIDEO_IN_PORT, "video_in_port"},
49         {MEDIA_STREAMER_PARAM_AUDIO_IN_PORT, "audio_in_port"},
50         {MEDIA_STREAMER_PARAM_VIDEO_OUT_PORT, "video_out_port"},
51         {MEDIA_STREAMER_PARAM_AUDIO_OUT_PORT, "audio_out_port"},
52         {MEDIA_STREAMER_PARAM_IP_ADDRESS, "address"},
53         {MEDIA_STREAMER_PARAM_WEBRTC_PEER_TYPE, "webrtc-peer-type"},
54         {MEDIA_STREAMER_PARAM_WEBRTC_REMOTE_SESSION_DESCRIPTION, "webrtc-remote-session-description"},
55         {MEDIA_STREAMER_PARAM_WEBRTC_ADD_ICE_CANDIDATE, "webrtc-add-ice-candidate"},
56         {MEDIA_STREAMER_PARAM_AUDIO_DEVICE, "audio_device"},
57         {MEDIA_STREAMER_PARAM_CLOCK_SYNCHRONIZED, "sync"},
58         {MEDIA_STREAMER_PARAM_ROTATE, "rotate"},
59         {MEDIA_STREAMER_PARAM_FLIP, "flip"},
60         {MEDIA_STREAMER_PARAM_DISPLAY_GEOMETRY_METHOD, "display-geometry-method"},
61         {MEDIA_STREAMER_PARAM_DISPLAY, "display"},
62         {MEDIA_STREAMER_PARAM_VISIBLE, "visible"},
63         {MEDIA_STREAMER_PARAM_USE_TBM, "use-tbm"},
64         {MEDIA_STREAMER_PARAM_HOST, "host"},
65         {MEDIA_STREAMER_PARAM_SEGMENT_LOCATION, "location"},
66         {MEDIA_STREAMER_PARAM_PLAYLIST_LOCATION, "playlist-location"},
67         {NULL, NULL}
68 };
69
70 static node_info_s nodes_info[] = {
71         {"Generic", "none"},                               /* MEDIA_STREAMER_NODE_TYPE_NONE */
72         {"Source", "source"},                              /* MEDIA_STREAMER_NODE_TYPE_SRC */
73         {"Sink", "sink"},                                  /* MEDIA_STREAMER_NODE_TYPE_SINK */
74         {"Codec/Encoder/Video", "video_encoder"},          /* MEDIA_STREAMER_NODE_TYPE_VIDEO_ENCODER */
75         {"Codec/Decoder/Video", "video_decoder"},          /* MEDIA_STREAMER_NODE_TYPE_VIDEO_DECODER */
76         {"Codec/Encoder/Audio", "audio_encoder"},          /* MEDIA_STREAMER_NODE_TYPE_AUDIO_ENCODER */
77         {"Codec/Decoder/Audio", "audio_decoder"},          /* MEDIA_STREAMER_NODE_TYPE_AUDIO_DECODER */
78         {"Filter/Converter/Video", "videoconvert"},        /* MEDIA_STREAMER_NODE_TYPE_VIDEO_CONVERTER */
79         {"Filter/Converter/Audio", "audioconvert"},        /* MEDIA_STREAMER_NODE_TYPE_AUDIO_CONVERTER */
80         {MEDIA_STREAMER_STRICT, "audioresample"},          /* MEDIA_STREAMER_NODE_TYPE_AUDIO_RESAMPLE */
81         {"Codec/Payloader/Network/RTP", "rtph263pay"},     /* MEDIA_STREAMER_NODE_TYPE_VIDEO_PAY */
82         {"Codec/Payloader/Network/RTP", "rtpamrpay"},      /* MEDIA_STREAMER_NODE_TYPE_AUDIO_PAY */
83         {"Codec/Depayloader/Network/RTP", "rtph263depay"}, /* MEDIA_STREAMER_NODE_TYPE_VIDEO_DEPAY */
84         {"Codec/Depayloader/Network/RTP", "rtpamrdepay"},  /* MEDIA_STREAMER_NODE_TYPE_AUDIO_DEPAY */
85         {"Filter/Effect/Video", "videorate"},              /* MEDIA_STREAMER_NODE_TYPE_VIDEO_RATE */
86         {"Filter/Converter/Video/Scaler", "videoscale"},   /* MEDIA_STREAMER_NODE_TYPE_VIDEO_SCALE */
87         {MEDIA_STREAMER_STRICT, "textoverlay"},            /* MEDIA_STREAMER_NODE_TYPE_TEXT_OVERLAY */
88         {"Codec/Parser", "h263parse"},                     /* MEDIA_STREAMER_NODE_TYPE_PARSER */
89         {MEDIA_STREAMER_STRICT, "capsfilter"},             /* MEDIA_STREAMER_NODE_TYPE_FILTER */
90         {MEDIA_STREAMER_STRICT, "tee"},                    /* MEDIA_STREAMER_NODE_TYPE_TEE */
91         {MEDIA_STREAMER_STRICT, "queue"},                  /* MEDIA_STREAMER_NODE_TYPE_QUEUE */
92         {MEDIA_STREAMER_STRICT, "multiqueue"},             /* MEDIA_STREAMER_NODE_TYPE_MQUEUE */
93         {"Codec/Muxer", "qtmux"},                          /* MEDIA_STREAMER_NODE_TYPE_MUXER */
94         {"Codec/Demuxer", "qtdemux"},                      /* MEDIA_STREAMER_NODE_TYPE_DEMUXER */
95         {"Generic/Bin", "rtpbin"},                         /* MEDIA_STREAMER_NODE_TYPE_RTP */
96         {MEDIA_STREAMER_STRICT, "input-selector"},         /* MEDIA_STREAMER_NODE_TYPE_INPUT_SELECTOR */
97         {MEDIA_STREAMER_STRICT, "output-selector"},        /* MEDIA_STREAMER_NODE_TYPE_OUTPUT_SELECTOR */
98         {MEDIA_STREAMER_STRICT, "interleave"},             /* MEDIA_STREAMER_NODE_TYPE_INTERLEAVE */
99         {MEDIA_STREAMER_STRICT, "deinterleave"},           /* MEDIA_STREAMER_NODE_TYPE_DEINTERLEAVE */
100         {"Filter/Network/WebRTC", "webrtc_container"},     /* MEDIA_STREAMER_NODE_TYPE_WEBRTC */
101         {NULL, NULL}
102 };
103
104 static gboolean __ms_rtp_node_has_property(media_streamer_node_s *node, const char *param_name)
105 {
106         GValue *val = NULL;
107
108         ms_debug_fenter();
109
110         ms_retvm_if(!node || !node->gst_element, FALSE, "Error: empty node");
111         ms_retvm_if(!param_name, FALSE, "Error: invalid property parameter");
112
113         if (node->type != MEDIA_STREAMER_NODE_TYPE_RTP)
114                 return FALSE;
115
116         val = (GValue *)g_object_get_data(G_OBJECT(node->gst_element), param_name);
117
118         ms_debug_fleave();
119
120         return val ? TRUE : FALSE;
121 }
122
123 static int __ms_rtp_node_get_property(media_streamer_node_s *node, param_s *param, GValue *value)
124 {
125         int ret = MEDIA_STREAMER_ERROR_NONE;
126         GValue *val = NULL;
127
128         ms_debug_fenter();
129
130         ms_retvm_if(!node || !node->gst_element, FALSE, "Error: empty node");
131         ms_retvm_if(node->type != MEDIA_STREAMER_NODE_TYPE_RTP, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Invalid node type");
132         ms_retvm_if(!param, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Error: invalid property parameter");
133         ms_retvm_if(!value, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "value is NULL");
134
135
136         val = (GValue *)g_object_get_data(G_OBJECT(node->gst_element), param->param_name);
137         if (!strcmp(param->param_name, MEDIA_STREAMER_PARAM_VIDEO_IN_PORT) ||
138                 !strcmp(param->param_name, MEDIA_STREAMER_PARAM_AUDIO_IN_PORT) ||
139                 !strcmp(param->param_name, MEDIA_STREAMER_PARAM_VIDEO_OUT_PORT) ||
140                 !strcmp(param->param_name, MEDIA_STREAMER_PARAM_AUDIO_OUT_PORT)) {
141                 g_value_init(value, G_TYPE_INT);
142         } else if (!strcmp(param->param_name, MEDIA_STREAMER_PARAM_HOST)) {
143                 g_value_init(value, G_TYPE_STRING);
144         } else
145                 ret = MEDIA_STREAMER_ERROR_INVALID_PARAMETER;
146
147         g_value_copy(val, value);
148
149         ms_debug_fleave();
150
151         return ret;
152 }
153
154 static int __ms_rtp_node_set_property(media_streamer_node_s *node, param_s *param, const char *param_value)
155 {
156         int ret = MEDIA_STREAMER_ERROR_NONE;
157         GValue *val = NULL;
158
159         ms_debug_fenter();
160
161         ms_retvm_if(!node || !node->gst_element, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Error: empty node");
162         ms_retvm_if(node->type != MEDIA_STREAMER_NODE_TYPE_RTP, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Invalid node type");
163         ms_retvm_if(!param, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Error: invalid property parameter");
164         ms_retvm_if(!param_value, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "param_value is NULL");
165
166         val = (GValue *)g_object_get_data(G_OBJECT(node->gst_element), param->param_name);
167         if (!val) {
168                 ms_error("fail to get [%s] val from [%s]", param->param_name, GST_ELEMENT_NAME(node->gst_element));
169                 return MEDIA_STREAMER_ERROR_INVALID_PARAMETER;
170         }
171
172         if (!strcmp(param->param_name, MEDIA_STREAMER_PARAM_VIDEO_IN_PORT) ||
173                 !strcmp(param->param_name, MEDIA_STREAMER_PARAM_AUDIO_IN_PORT) ||
174                 !strcmp(param->param_name, MEDIA_STREAMER_PARAM_VIDEO_OUT_PORT) ||
175                 !strcmp(param->param_name, MEDIA_STREAMER_PARAM_AUDIO_OUT_PORT)) {
176                 g_value_unset(val);
177                 g_value_init(val, G_TYPE_INT);
178                 g_value_set_int(val, (int)strtol(param_value, NULL, 10));
179         } else if (!strcmp(param->param_name, MEDIA_STREAMER_PARAM_HOST)) {
180                 g_value_unset(val);
181                 g_value_init(val, G_TYPE_STRING);
182                 g_value_set_string(val, param_value);
183         } else if (!strcmp(param->param_name, MEDIA_STREAMER_PARAM_VIDEO_IN_FORMAT) ||
184                            !strcmp(param->param_name, MEDIA_STREAMER_PARAM_AUDIO_IN_FORMAT)) {
185                 GstCaps *caps = gst_caps_from_string(param_value);
186                 if (caps) {
187                         g_value_unset(val);
188                         g_value_init(val, GST_TYPE_CAPS);
189                         gst_value_set_caps(val, caps);
190                 } else {
191                         ret = MEDIA_STREAMER_ERROR_INVALID_PARAMETER;
192                 }
193         } else {
194                 ret = MEDIA_STREAMER_ERROR_INVALID_PARAMETER;
195         }
196
197         ms_debug_fleave();
198
199         return ret;
200 }
201
202 static gboolean __ms_webrtc_node_has_property(media_streamer_node_s *node, const char *param_name)
203 {
204         GValue *val = NULL;
205
206         ms_debug_fenter();
207
208         ms_retvm_if(!node || !node->gst_element, FALSE, "Error: empty node");
209         ms_retvm_if(!param_name, FALSE, "Error: invalid property parameter");
210
211         if (node->type == MEDIA_STREAMER_NODE_TYPE_WEBRTC) {
212                 val = (GValue *)g_object_get_data(G_OBJECT(node->gst_element), param_name);
213
214                 ms_debug_fleave();
215
216                 return val ? TRUE : FALSE;
217         }
218
219         ms_debug_fleave();
220
221         return FALSE;
222 }
223
224 static int __ms_webrtc_node_set_property(media_streamer_node_s *node, param_s *param, const char *param_value)
225 {
226         GValue *val = NULL;
227         int ret;
228
229         ms_debug_fenter();
230
231         ms_retvm_if(!node || !node->gst_element, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Error: empty node");
232         ms_retvm_if(node->type != MEDIA_STREAMER_NODE_TYPE_WEBRTC, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Invalid node type");
233         ms_retvm_if(!param, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Error: invalid property parameter");
234         ms_retvm_if(!param_value, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "param_value is NULL");
235
236         val = (GValue *)g_object_get_data(G_OBJECT(node->gst_element), param->param_name);
237         if (!val) {
238                 ms_error("failed to get [%s] val from [%s]", param->param_name, GST_ELEMENT_NAME(node->gst_element));
239                 return MEDIA_STREAMER_ERROR_INVALID_PARAMETER;
240         }
241
242         if (!strcmp(param->param_name, MEDIA_STREAMER_PARAM_WEBRTC_PEER_TYPE)) {
243                 if (strcmp(param_value, WEBRTC_PEER_OFFER) && strcmp(param_value, WEBRTC_PEER_ANSWER)) {
244                         ms_error("failed to set property, param value should be [%s] or [%s]", WEBRTC_PEER_OFFER, WEBRTC_PEER_ANSWER);
245                         return MEDIA_STREAMER_ERROR_INVALID_PARAMETER;
246                 }
247                 g_value_unset(val);
248                 g_value_init(val, G_TYPE_STRING);
249                 g_value_set_string(val, param_value);
250         } else if (!strcmp(param->param_name, MEDIA_STREAMER_PARAM_WEBRTC_REMOTE_SESSION_DESCRIPTION)) {
251                 ret = ms_webrtcbin_set_remote_session_description(node, param_value);
252                 if (ret != MEDIA_STREAMER_ERROR_NONE) {
253                         ms_error("failed to set remote session description\n%s", param_value);
254                         return ret;
255                 }
256                 g_value_unset(val);
257                 g_value_init(val, G_TYPE_STRING);
258                 g_value_set_string(val, param_value);
259         } else if (!strcmp(param->param_name, MEDIA_STREAMER_PARAM_WEBRTC_ADD_ICE_CANDIDATE)) {
260                 ret = ms_webrtcbin_add_ice_candidate(node, param_value);
261                 if (ret != MEDIA_STREAMER_ERROR_NONE) {
262                         ms_error("failed to add ICE candidate\n%s", param_value);
263                         return ret;
264                 }
265         } else {
266                 ms_error("failed to set property, undefined param name[%s]", param->param_name);
267                 return MEDIA_STREAMER_ERROR_INVALID_PARAMETER;
268         }
269
270         ms_debug_fleave();
271
272         return MEDIA_STREAMER_ERROR_NONE;
273 }
274
275 static gboolean __ms_adaptive_src_node_has_property(media_streamer_node_s *node, const char *param_name)
276 {
277         GValue *val = NULL;
278
279         ms_debug_fenter();
280
281         ms_retvm_if(!node || !node->gst_element, FALSE, "Error: empty node");
282         ms_retvm_if(!param_name, FALSE, "Error: invalid property parameter");
283
284         if (node->type == MEDIA_STREAMER_NODE_TYPE_SRC &&
285                 node->subtype == MEDIA_STREAMER_NODE_SRC_TYPE_ADAPTIVE) {
286                 val = (GValue *)g_object_get_data(G_OBJECT(node->gst_element), param_name);
287
288                 ms_debug_fleave();
289
290                 return val ? TRUE : FALSE;
291         }
292
293         ms_debug_fleave();
294
295         return FALSE;
296 }
297
298 static int __ms_adaptive_src_node_get_property(media_streamer_node_s *node, param_s *param, GValue *value)
299 {
300         int ret = MEDIA_STREAMER_ERROR_NONE;
301         GValue *val = NULL;
302
303         ms_debug_fenter();
304
305         ms_retvm_if(!node || !node->gst_element, FALSE, "Error: empty node");
306         ms_retvm_if(node->type != MEDIA_STREAMER_NODE_TYPE_SRC &&
307                         node->subtype != MEDIA_STREAMER_NODE_SRC_TYPE_ADAPTIVE, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Invalid node type");
308         ms_retvm_if(!param, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Error: invalid property parameter");
309         ms_retvm_if(!value, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "value is NULL");
310
311         val = (GValue *)g_object_get_data(G_OBJECT(node->gst_element), param->param_name);
312         if (!strcmp(param->param_name, MEDIA_STREAMER_PARAM_URI))
313                 g_value_init(value, G_TYPE_STRING);
314         else
315                 ret = MEDIA_STREAMER_ERROR_INVALID_PARAMETER;
316
317         g_value_copy(val, value);
318
319         ms_debug_fleave();
320
321         return ret;
322 }
323
324 static int __ms_adaptive_src_node_set_property(media_streamer_node_s *node, param_s *param, const char *param_value)
325 {
326         int ret = MEDIA_STREAMER_ERROR_NONE;
327         GValue *val = NULL;
328
329         ms_debug_fenter();
330
331         ms_retvm_if(!node || !node->gst_element, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Error: empty node");
332         ms_retvm_if(node->type != MEDIA_STREAMER_NODE_TYPE_SRC &&
333                         node->subtype != MEDIA_STREAMER_NODE_SRC_TYPE_ADAPTIVE, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Invalid node type");
334         ms_retvm_if(!param, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Error: invalid property parameter");
335         ms_retvm_if(!param_value, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "param_value is NULL");
336
337         val = (GValue *)g_object_get_data(G_OBJECT(node->gst_element), param->param_name);
338         if (!val) {
339                 ms_error("fail to get [%s] val from [%s]", param->param_name, GST_ELEMENT_NAME(node->gst_element));
340                 return MEDIA_STREAMER_ERROR_INVALID_PARAMETER;
341         }
342
343         if (!strcmp(param->param_name, MEDIA_STREAMER_PARAM_URI)) {
344                 g_value_unset(val);
345                 g_value_init(val, G_TYPE_STRING);
346                 g_value_set_string(val, param_value);
347         } else {
348                 ret = MEDIA_STREAMER_ERROR_INVALID_PARAMETER;
349         }
350
351         ms_debug_fleave();
352
353         return ret;
354 }
355
356 static int __ms_webrtc_node_is_offerer(media_streamer_node_s *node, gboolean *is_offerer)
357 {
358         GValue *val = NULL;
359         const gchar *type = NULL;
360
361         ms_retvm_if(!node || !node->gst_element, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Error: empty node");
362         ms_retvm_if(!is_offerer, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Error: is_offerer is null");
363
364         if (node->type != MEDIA_STREAMER_NODE_TYPE_WEBRTC) {
365                 ms_error("Invalid node type");
366                 return MEDIA_STREAMER_ERROR_INVALID_PARAMETER;
367         }
368
369         val = (GValue *)g_object_get_data(G_OBJECT(node->gst_element), MEDIA_STREAMER_PARAM_WEBRTC_PEER_TYPE);
370         if (!val) {
371                 ms_error("Failed to get [%s] val from [%s]", MEDIA_STREAMER_PARAM_WEBRTC_PEER_TYPE, GST_ELEMENT_NAME(node->gst_element));
372                 return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
373         }
374
375         if (!(type = g_value_get_string(val))) {
376                 ms_error("Failed to g_value_get_string()");
377                 return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
378         }
379
380         ms_info("peer type is [%s]", type);
381
382         *is_offerer = (gboolean)(!strcmp(type, WEBRTC_PEER_OFFER));
383
384         return MEDIA_STREAMER_ERROR_NONE;
385 }
386
387 int ms_node_create(media_streamer_node_s *node, media_format_h in_fmt, media_format_h out_fmt)
388 {
389         int ret = MEDIA_STREAMER_ERROR_NONE;
390         GstCaps *sink_caps = NULL;
391         GstCaps *src_caps = NULL;
392
393         ms_debug_fenter();
394
395         ms_retvm_if(node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
396
397         sink_caps = in_fmt ? ms_create_caps_from_fmt(in_fmt) : NULL;
398         src_caps = out_fmt ? ms_create_caps_from_fmt(out_fmt) : NULL;
399
400         node_plug_s plug_info = {&(nodes_info[node->type]), src_caps, sink_caps, NULL};
401
402         ms_info("Creating node with info: klass_name[%s]; default[%s]",
403                         plug_info.info->klass_name, plug_info.info->default_name);
404
405         node->gst_element = ms_node_element_create(&plug_info, node->type);
406         if (node->gst_element)
407                 node->name = gst_element_get_name(node->gst_element);
408         else
409                 return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
410
411         if (src_caps)
412                         gst_caps_unref(src_caps);
413
414         if (sink_caps)
415                         gst_caps_unref(sink_caps);
416
417         ms_debug_fleave();
418
419         return ret;
420 }
421
422 /* This signal callback is called when appsrc needs data, we add an idle handler
423  * to the mainloop to start pushing data into the appsrc */
424 static void __ms_src_start_feed_cb(GstElement *pipeline, guint size, gpointer data)
425 {
426         media_streamer_node_s *ms_src = (media_streamer_node_s *) data;
427         media_streamer_callback_s *src_callback = NULL;
428         media_streamer_custom_buffer_status_cb buffer_status_cb = NULL;
429
430         ms_debug_fenter();
431
432         ms_retm_if(ms_src == NULL, "data is NULL");
433         ms_retm_if(pipeline == NULL, "pipeline is NULL");
434
435         if (ms_src->callbacks_structure != NULL) {
436                 src_callback = (media_streamer_callback_s *) ms_src->callbacks_structure;
437                 buffer_status_cb = (media_streamer_custom_buffer_status_cb) src_callback->callback;
438                 buffer_status_cb((media_streamer_node_h) ms_src, MEDIA_STREAMER_CUSTOM_BUFFER_UNDERRUN, src_callback->user_data);
439         }
440
441         ms_debug_fleave();
442 }
443
444 /* This callback is called when appsrc has enough data and we can stop sending.
445  * We remove the idle handler from the mainloop */
446 static void __ms_src_stop_feed_cb(GstElement *pipeline, gpointer data)
447 {
448         media_streamer_node_s *ms_src = (media_streamer_node_s *) data;
449         media_streamer_callback_s *src_callback = NULL;
450         media_streamer_custom_buffer_status_cb buffer_status_cb = NULL;
451
452         ms_debug_fenter();
453
454         ms_retm_if(ms_src == NULL, "data is NULL");
455         ms_retm_if(pipeline == NULL, "pipeline is NULL");
456
457         if (ms_src->callbacks_structure != NULL) {
458                 src_callback = (media_streamer_callback_s *) ms_src->callbacks_structure;
459                 buffer_status_cb = (media_streamer_custom_buffer_status_cb) src_callback->callback;
460                 buffer_status_cb((media_streamer_node_h) ms_src, MEDIA_STREAMER_CUSTOM_BUFFER_OVERFLOW, src_callback->user_data);
461         }
462
463         ms_debug_fleave();
464 }
465
466 static int __ms_node_check_privileges(media_streamer_node_s *node)
467 {
468         int ret = MEDIA_STREAMER_ERROR_NONE;
469         int ret_val = 0;
470         char *privilege = NULL;
471         FILE* opened_file;
472         char smackLabel[SMACK_LABEL_LEN + 1];
473         char uid[10];
474         cynara *cynara_h = NULL;
475
476         ms_debug_fenter();
477
478         ms_retvm_if(node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
479
480         if (node->type == MEDIA_STREAMER_NODE_TYPE_SRC) {
481                 switch (node->subtype) {
482                 case MEDIA_STREAMER_NODE_SRC_TYPE_HTTP:
483                         privilege = "http://tizen.org/privilege/internet";
484                         break;
485                 case MEDIA_STREAMER_NODE_SRC_TYPE_ADAPTIVE:
486                         privilege = "http://tizen.org/privilege/internet";
487                         break;
488                 case MEDIA_STREAMER_NODE_SRC_TYPE_CAMERA:
489                         privilege = "http://tizen.org/privilege/camera";
490                         break;
491                 case MEDIA_STREAMER_NODE_SRC_TYPE_AUDIO_CAPTURE:
492                         privilege = "http://tizen.org/privilege/recorder";
493                         break;
494                 case MEDIA_STREAMER_NODE_SRC_TYPE_VIDEO_CAPTURE:
495                         privilege = "http://tizen.org/privilege/camera";
496                         break;
497                 default:
498                         ms_info(" [%s] subtype [%d] privileges are not needed", node->name, node->subtype);
499                         break;
500                 }
501         }
502
503         if (node->type == MEDIA_STREAMER_NODE_TYPE_SINK) {
504                 switch (node->subtype) {
505                 case MEDIA_STREAMER_NODE_SINK_TYPE_HTTP:
506                         privilege = "http://tizen.org/privilege/internet";
507                         break;
508                 default:
509                         ms_info("For current Sink Node [%s] subtype [%d] privileges are not needed", node->name, node->subtype);
510                         break;
511                 }
512         }
513
514         /* Skip checking for privilege permission in case of other types of Nodes */
515         if (privilege == NULL)
516                 return ret;
517
518         if (CYNARA_API_SUCCESS != cynara_initialize(&cynara_h, NULL)) {
519                 ms_error("Failed to initialize cynara structure\n");
520                 return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
521         }
522
523         bzero(smackLabel, SMACK_LABEL_LEN + 1);
524
525         /* Getting smack label */
526         opened_file = fopen("/proc/self/attr/current", "r");
527         if (opened_file == NULL) {
528                 ms_error("Failed to open /proc/self/attr/current\n");
529                 return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
530         }
531         ret_val = fread(smackLabel, sizeof(smackLabel), 1, opened_file);
532         fclose(opened_file);
533         if (ret_val < 0) {
534                 ms_error("Failed to read /proc/self/attr/current\n");
535                 return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
536         }
537
538         /* Getting uid */
539         snprintf(uid, sizeof(uid), "%d", getuid());
540         ms_info("%s %s %s\n", smackLabel, uid, privilege);
541
542         /* Checking with cynara for current session */
543         ret_val = cynara_check(cynara_h, smackLabel, "", uid, privilege);
544         ms_info("Cynara_check [%d] ", ret_val);
545
546         switch (ret_val) {
547         case CYNARA_API_ACCESS_ALLOWED:
548                 ms_info("Access to Node [%s] subtype [%d] is allowed", node->name, node->subtype);
549                 break;
550         case CYNARA_API_ACCESS_DENIED:
551         default:
552                 ms_error("Access to Node [%s] subtype [%d] is denied", node->name, node->subtype);
553                 ret = MEDIA_STREAMER_ERROR_PERMISSION_DENIED;
554                 break;
555         }
556
557         cynara_finish(cynara_h);
558
559         ms_debug_fleave();
560
561         return ret;
562 }
563
564 static int __ms_src_node_check_feature(media_streamer_node_s *node)
565 {
566         int ret = MEDIA_STREAMER_ERROR_NONE;
567         bool enabled = FALSE;
568         bool supported = FALSE;
569
570         ms_debug_fenter();
571
572         ms_retvm_if(node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
573
574         switch (node->subtype) {
575         case MEDIA_STREAMER_NODE_SRC_TYPE_HTTP:
576         case MEDIA_STREAMER_NODE_SRC_TYPE_RTSP:
577         case MEDIA_STREAMER_NODE_SRC_TYPE_ADAPTIVE:
578                 if (SYSTEM_INFO_ERROR_NONE == system_info_get_platform_bool(_FEATURE_NAME_WIFI, &enabled)) {
579                         ms_info("wifi status = %d", enabled);
580                         if (enabled)
581                                 supported = TRUE;
582                 } else {
583                         ms_error("SYSTEM_INFO_ERROR");
584                 }
585
586                 if (SYSTEM_INFO_ERROR_NONE == system_info_get_platform_bool(_FEATURE_NAME_TELEPHONY, &enabled)) {
587                         ms_info("telephony status = %d", enabled);
588                         if (enabled)
589                                 supported = TRUE;
590                 } else {
591                         ms_error("SYSTEM_INFO_ERROR");
592                 }
593
594                 if (SYSTEM_INFO_ERROR_NONE == system_info_get_platform_bool(_FEATURE_NAME_ETHERNET, &enabled)) {
595                         ms_info("ethernet status = %d", enabled);
596                         if (enabled)
597                                 supported = TRUE;
598                 } else {
599                         ms_error("SYSTEM_INFO_ERROR");
600                 }
601                 if (!supported)
602                         ret = MEDIA_STREAMER_ERROR_NOT_SUPPORTED;
603                 break;
604         case MEDIA_STREAMER_NODE_SRC_TYPE_AUDIO_CAPTURE:
605                 if (SYSTEM_INFO_ERROR_NONE == system_info_get_platform_bool(_FEATURE_NAME_MICROPHONE, &enabled)) {
606                         ms_info("microphone status = %d", enabled);
607                         if (enabled)
608                                 supported = TRUE;
609                 } else {
610                         ms_error("SYSTEM_INFO_ERROR");
611                 }
612                 if (!supported)
613                         ret = MEDIA_STREAMER_ERROR_NOT_SUPPORTED;
614                 break;
615         case MEDIA_STREAMER_NODE_SRC_TYPE_CAMERA:
616         case MEDIA_STREAMER_NODE_SRC_TYPE_VIDEO_CAPTURE:
617                 if (SYSTEM_INFO_ERROR_NONE == system_info_get_platform_bool(_FEATURE_NAME_CAMERA, &enabled)) {
618                         ms_info("camera status = %d", enabled);
619                         if (enabled)
620                                 supported = TRUE;
621                 } else {
622                         ms_error("SYSTEM_INFO_ERROR");
623                 }
624                 if (!supported)
625                         ret = MEDIA_STREAMER_ERROR_NOT_SUPPORTED;
626                 break;
627         default:
628                 ms_info("For current Src Node subtype [%d] privileges are not needed", node->subtype);
629                 break;
630         }
631
632         ms_debug_fleave();
633
634         return ret;
635 }
636
637 static int __ms_sink_node_check_feature(media_streamer_node_s *node)
638 {
639         int ret = MEDIA_STREAMER_ERROR_NONE;
640         bool enabled = FALSE;
641         bool supported = FALSE;
642
643         ms_debug_fenter();
644
645         ms_retvm_if(node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
646
647         switch (node->subtype) {
648         case MEDIA_STREAMER_NODE_SINK_TYPE_HTTP:
649         case MEDIA_STREAMER_NODE_SINK_TYPE_RTSP:
650         /* case MEDIA_STREAMER_NODE_SINK_TYPE_ADAPTIVE: */
651                 if (SYSTEM_INFO_ERROR_NONE == system_info_get_platform_bool(_FEATURE_NAME_WIFI, &enabled)) {
652                         ms_info("wifi status = %d", enabled);
653                         if (enabled)
654                                 supported = TRUE;
655                 } else {
656                         ms_error("SYSTEM_INFO_ERROR");
657                 }
658
659                 if (SYSTEM_INFO_ERROR_NONE == system_info_get_platform_bool(_FEATURE_NAME_TELEPHONY, &enabled)) {
660                         ms_info("telephony status = %d", enabled);
661                         if (enabled)
662                                 supported = TRUE;
663                 } else {
664                         ms_error("SYSTEM_INFO_ERROR");
665                 }
666
667                 if (SYSTEM_INFO_ERROR_NONE == system_info_get_platform_bool(_FEATURE_NAME_ETHERNET, &enabled)) {
668                         ms_info("ethernet status = %d", enabled);
669                         if (enabled)
670                                 supported = TRUE;
671                 } else {
672                         ms_error("SYSTEM_INFO_ERROR");
673                 }
674                 if (!supported)
675                         ret = MEDIA_STREAMER_ERROR_NOT_SUPPORTED;
676                 break;
677         default:
678                 ms_info("For current Sink Node subtype [%d] privileges are not needed", node->subtype);
679                 break;
680         }
681
682         ms_debug_fleave();
683
684         return ret;
685 }
686
687 int ms_src_node_create(media_streamer_node_s *node)
688 {
689         int ret = MEDIA_STREAMER_ERROR_NONE;
690         char *plugin_name = NULL;
691
692         ms_debug_fenter();
693
694         ms_retvm_if(node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
695
696         ret = __ms_node_check_privileges(node);
697         if (ret != MEDIA_STREAMER_ERROR_NONE) {
698                 ms_error("Error getting privileges for Src Node");
699                 return ret;
700         }
701
702         ret = __ms_src_node_check_feature(node);
703         if (ret != MEDIA_STREAMER_ERROR_NONE) {
704                 ms_error("Error getting feature for Src Node");
705                 return ret;
706         }
707
708         switch (node->subtype) {
709         case MEDIA_STREAMER_NODE_SRC_TYPE_FILE:
710                 plugin_name = ms_ini_get_string("node type 1:file", DEFAULT_FILE_SOURCE);
711                 node->gst_element = ms_element_create(plugin_name, NULL);
712                 break;
713         case MEDIA_STREAMER_NODE_SRC_TYPE_RTSP:
714                 plugin_name = ms_ini_get_string("node type 1:rtsp", DEFAULT_UDP_SOURCE);
715                 node->gst_element = ms_element_create(plugin_name, NULL);
716                 break;
717         case MEDIA_STREAMER_NODE_SRC_TYPE_HTTP:
718                 plugin_name = ms_ini_get_string("node type 1:http", DEFAULT_HTTP_SOURCE);
719                 node->gst_element = ms_element_create(plugin_name, NULL);
720                 break;
721         case MEDIA_STREAMER_NODE_SRC_TYPE_CAMERA:
722                 plugin_name = ms_ini_get_string("node type 1:camera", DEFAULT_CAMERA_SOURCE);
723                 node->gst_element = ms_element_create(plugin_name, NULL);
724                 break;
725         case MEDIA_STREAMER_NODE_SRC_TYPE_AUDIO_CAPTURE:
726                 plugin_name = ms_ini_get_string("node type 1:audio capture", DEFAULT_AUDIO_SOURCE);
727                 node->gst_element = ms_element_create(plugin_name, NULL);
728                 break;
729         case MEDIA_STREAMER_NODE_SRC_TYPE_VIDEO_CAPTURE:
730                 plugin_name = ms_ini_get_string("node type 1:video capture", DEFAULT_VIDEO_SOURCE);
731                 node->gst_element = ms_element_create(plugin_name, NULL);
732                 break;
733         case MEDIA_STREAMER_NODE_SRC_TYPE_VIDEO_TEST:
734                 plugin_name = ms_ini_get_string("node type 1:video test", DEFAULT_VIDEO_TEST_SOURCE);
735                 node->gst_element = ms_element_create(plugin_name, NULL);
736                 break;
737         case MEDIA_STREAMER_NODE_SRC_TYPE_AUDIO_TEST:
738                 plugin_name = ms_ini_get_string("node type 1:audio test", DEFAULT_AUDIO_TEST_SOURCE);
739                 node->gst_element = ms_element_create(plugin_name, NULL);
740                 break;
741         case MEDIA_STREAMER_NODE_SRC_TYPE_CUSTOM:
742                 plugin_name = ms_ini_get_string("node type 1:custom", DEFAULT_APP_SOURCE);
743                 node->gst_element = ms_element_create(DEFAULT_APP_SOURCE, NULL);
744                 g_object_set(G_OBJECT(node->gst_element), "emit-signals", TRUE, NULL);
745                 ms_signal_create(&node->sig_list, node->gst_element, "need-data", G_CALLBACK(__ms_src_start_feed_cb), node);
746                 ms_signal_create(&node->sig_list, node->gst_element, "enough-data", G_CALLBACK(__ms_src_stop_feed_cb), node);
747                 break;
748         case MEDIA_STREAMER_NODE_SRC_TYPE_ADAPTIVE:
749                 node->gst_element = ms_adaptive_element_create();
750                 break;
751         default:
752                 ms_error("Error: invalid Src node Type [%d]", node->subtype);
753                 break;
754         }
755
756         MS_SAFE_FREE(plugin_name);
757
758         if (node->gst_element == NULL)
759                 return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
760         else
761                 node->name = gst_element_get_name(node->gst_element);
762
763         ret = ms_node_dpm_policy_init(node);
764         if (MEDIA_STREAMER_ERROR_NONE != ret) {
765                 ms_error("Failed to init DPM policy for node [%s]", node->name);
766                 return ret;
767         }
768
769         ms_debug_fleave();
770
771         return ret;
772 }
773
774 /* The appsink has received a buffer */
775 static void __ms_sink_new_buffer_cb(GstElement *sink, gpointer *data)
776 {
777         media_streamer_node_s *ms_sink = (media_streamer_node_s *) data;
778         media_streamer_sink_callbacks_s *sink_callbacks = NULL;
779         media_streamer_sink_data_ready_cb data_ready_cb = NULL;
780
781         ms_debug_fenter();
782
783         ms_retm_if(ms_sink == NULL, "data is NULL");
784
785         if (ms_sink->callbacks_structure != NULL) {
786                 sink_callbacks = (media_streamer_sink_callbacks_s *) ms_sink->callbacks_structure;
787                 data_ready_cb = (media_streamer_sink_data_ready_cb) sink_callbacks->data_ready_cb.callback;
788
789                 if (data_ready_cb)
790                         data_ready_cb((media_streamer_node_h) ms_sink, sink_callbacks->data_ready_cb.user_data);
791         }
792
793         ms_debug_fleave();
794 }
795
796 //LCOV_EXCL_START
797 /* The appsink has got eos */
798 static void sink_eos(GstElement *sink, gpointer *data)
799 {
800         media_streamer_node_s *ms_sink = (media_streamer_node_s *) data;
801         media_streamer_sink_callbacks_s *sink_callbacks = NULL;
802         media_streamer_sink_eos_cb eos_cb = NULL;
803
804         ms_debug_fenter();
805
806         ms_retm_if(ms_sink == NULL, "data is NULL");
807
808         if (ms_sink->callbacks_structure != NULL) {
809                 sink_callbacks = (media_streamer_sink_callbacks_s *) ms_sink->callbacks_structure;
810                 eos_cb = (media_streamer_sink_eos_cb) sink_callbacks->eos_cb.callback;
811
812                 if (eos_cb)
813                         eos_cb((media_streamer_node_h) ms_sink, sink_callbacks->eos_cb.user_data);
814         }
815
816         ms_debug_fleave();
817 }
818 //LCOV_EXCL_STOP
819
820 int ms_sink_node_create(media_streamer_node_s *node)
821 {
822         int ret = MEDIA_STREAMER_ERROR_NONE;
823         char *plugin_name = NULL;
824
825         ms_debug_fenter();
826
827         ms_retvm_if(node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
828
829         ret = __ms_node_check_privileges(node);
830         if (ret != MEDIA_STREAMER_ERROR_NONE) {
831                 ms_error("Error getting privileges for Sink Node");
832                 return ret;
833         }
834
835         ret = __ms_sink_node_check_feature(node);
836         if (ret != MEDIA_STREAMER_ERROR_NONE) {
837                 ms_error("Error getting feature for Sink Node");
838                 return ret;
839         }
840
841         switch (node->subtype) {
842         case MEDIA_STREAMER_NODE_SINK_TYPE_FILE:
843                 plugin_name = ms_ini_get_string("node type 2:file", DEFAULT_FILE_SINK);
844                 node->gst_element = ms_element_create(plugin_name, NULL);
845                 break;
846         case MEDIA_STREAMER_NODE_SINK_TYPE_RTSP:
847                 plugin_name = ms_ini_get_string("node type 2:rtsp", DEFAULT_UDP_SINK);
848                 node->gst_element = ms_element_create(plugin_name, NULL);
849                 break;
850         case MEDIA_STREAMER_NODE_SINK_TYPE_HTTP:
851                 ms_error("Error: not implemented yet");
852                 break;
853         case MEDIA_STREAMER_NODE_SINK_TYPE_AUDIO:
854                 plugin_name = ms_ini_get_string("node type 2:audio", DEFAULT_AUDIO_SINK);
855                 node->gst_element = ms_element_create(plugin_name, NULL);
856                 break;
857         case MEDIA_STREAMER_NODE_SINK_TYPE_OVERLAY:
858                 plugin_name = ms_ini_get_string("node type 2:overlay", DEFAULT_VIDEO_SINK);
859                 node->gst_element = ms_element_create(plugin_name, NULL);
860                 break;
861         case MEDIA_STREAMER_NODE_SINK_TYPE_FAKE:
862                 plugin_name = ms_ini_get_string("node type 2:fake", DEFAULT_FAKE_SINK);
863                 node->gst_element = ms_element_create(plugin_name, NULL);
864                 break;
865         case MEDIA_STREAMER_NODE_SINK_TYPE_CUSTOM:
866                 plugin_name = ms_ini_get_string("node type 2:custom", DEFAULT_APP_SINK);
867                 node->gst_element = ms_element_create(plugin_name, NULL);
868                 if (node->gst_element) {
869                         g_object_set(G_OBJECT(node->gst_element), "emit-signals", TRUE, NULL);
870                         ms_signal_create(&node->sig_list, node->gst_element, "new-sample", G_CALLBACK(__ms_sink_new_buffer_cb), node);
871                         ms_signal_create(&node->sig_list, node->gst_element, "eos", G_CALLBACK(sink_eos), node);
872                 }
873                 break;
874         case MEDIA_STREAMER_NODE_SINK_TYPE_ADAPTIVE:
875                 plugin_name = ms_ini_get_string("node type 2:adaptive", DEFAULT_ADAPTIVE_SINK);
876                 node->gst_element = ms_element_create(plugin_name, "adaptive_sink");
877
878                 if (g_strrstr(plugin_name, "hlssink")) {
879                         g_object_set(G_OBJECT(node->gst_element),
880                                         "max-files", 0,
881                                         "playlist-length", 0, NULL);
882                 }
883                 break;
884         default:
885                 ms_error("Error: invalid Sink node Type [%d]", node->subtype);
886                 break;
887         }
888
889         MS_SAFE_FREE(plugin_name);
890
891         if (node->gst_element == NULL)
892                 return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
893         else
894                 node->name = gst_element_get_name(node->gst_element);
895
896         ms_debug_fleave();
897
898         return ret;
899 }
900
901 void ms_node_destroy(media_streamer_node_s *node)
902 {
903         gchar *node_name = NULL;
904
905         ms_debug_fenter();
906
907         ms_retm_if(node == NULL, "node is NULL");
908         node_name = g_strdup(node->name);
909
910         /* Disconnects and clean all node signals */
911         g_list_free_full(node->sig_list, ms_signal_destroy);
912
913         /* Deinitialize policy manager */
914         if (MEDIA_STREAMER_ERROR_NONE != ms_node_dpm_policy_deinit(node))
915                 ms_error("Failed to deinitialize DPM policy");
916
917         MS_SAFE_UNREF(node->gst_element);
918         MS_SAFE_FREE(node->name);
919         MS_SAFE_FREE(node->callbacks_structure);
920         MS_SAFE_FREE(node);
921
922         ms_info("Node [%s] has been destroyed", node_name);
923         MS_SAFE_GFREE(node_name);
924
925         ms_debug_fleave();
926 }
927
928 int ms_add_node_into_bin(media_streamer_s *ms_streamer, media_streamer_node_s *node)
929 {
930         int ret = MEDIA_STREAMER_ERROR_NONE;
931         GstElement *bin = NULL;
932
933         ms_debug_fenter();
934
935         ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Handle is NULL");
936         ms_retvm_if(node == NULL, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "node is NULL");
937
938         ms_info("Try to add [%s] node into streamer, node type/subtype [%d/%d]", node->name, node->type, node->subtype);
939
940         switch (node->type) {
941         case MEDIA_STREAMER_NODE_TYPE_SRC:
942                 bin = ms_streamer->src_bin;
943                 break;
944         case MEDIA_STREAMER_NODE_TYPE_SINK:
945                 bin = ms_streamer->sink_bin;
946                 break;
947         default:
948                 /* Another elements will be add into transform bin */
949                 bin = ms_streamer->transform_bin;
950                 break;
951         }
952
953         if (!ms_bin_add_element(bin, node->gst_element, TRUE)) {
954                 ms_error("Failed to add Element [%s] into [%s] bin.", node->name, GST_ELEMENT_NAME(bin));
955                 ret = MEDIA_STREAMER_ERROR_INVALID_OPERATION;
956         }
957
958         ms_debug_fleave();
959
960         return ret;
961 }
962
963 int ms_node_insert_into_table(GHashTable *nodes_table, media_streamer_node_s *node)
964 {
965         ms_debug_fenter();
966
967         ms_retvm_if(nodes_table == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "nodes_table is NULL");
968         ms_retvm_if(node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
969         ms_retvm_if(node->name == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node->name is NULL");
970
971         if (g_hash_table_contains(nodes_table, node->name)) {
972                 ms_debug("Current Node [%s] already added into Media Streamer", node->name);
973                 return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
974         }
975         if (!g_hash_table_insert(nodes_table, (gpointer) node->name, (gpointer) node)) {
976                 ms_debug("Error: Failed to add node [%s] into Media Streamer", node->name);
977                 return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
978         }
979
980         ms_info("Node [%s] added into streamer, node type/subtype [%d/%d]", node->name, node->type, node->subtype);
981
982         ms_debug_fleave();
983
984         return MEDIA_STREAMER_ERROR_NONE;
985 }
986
987 void ms_node_remove_from_table(void *data)
988 {
989         media_streamer_node_s *node = (media_streamer_node_s *) data;
990
991         ms_debug_fenter();
992
993         ms_retm_if(node == NULL, "data is NULL");
994
995         if (ms_element_unlink(node->gst_element)) {
996                 node->linked_by_user = FALSE;
997                 node->parent_streamer = NULL;
998                 ms_bin_remove_element(node->gst_element);
999                 ms_info("Node [%s] removed from Media Streamer", node->name);
1000         } else {
1001                 ms_error("Error: Node [%s] remove failed", node->name);
1002         }
1003
1004         ms_debug_fleave();
1005
1006 }
1007
1008 static gboolean __ms_src_need_typefind(GstPad *src_pad)
1009 {
1010         gboolean ret = FALSE;
1011
1012         ms_debug_fenter();
1013
1014         if (!src_pad || gst_pad_is_linked(src_pad))
1015                 return FALSE;
1016
1017         GstCaps *src_caps = gst_pad_query_caps(src_pad, NULL);
1018         if (gst_caps_is_any(src_caps))
1019                 ret = TRUE;
1020
1021         gst_caps_unref(src_caps);
1022
1023         ms_debug_fleave();
1024
1025         return ret;
1026 }
1027
1028 node_info_s * ms_node_get_klass_by_its_type(media_streamer_node_type_e element_type)
1029 {
1030         int it_klass;
1031
1032         ms_debug_fenter();
1033
1034         for (it_klass = 0; nodes_info[it_klass].klass_name != NULL; it_klass++) {
1035                 if (it_klass == element_type) {
1036                         ms_info("Next node`s type klass is [%s]", nodes_info[it_klass].klass_name);
1037                         break;
1038                 }
1039         }
1040
1041         ms_debug_fleave();
1042
1043         return &nodes_info[it_klass];
1044 }
1045
1046 gboolean ms_sink_node_prepare_iter(const GValue *item, GValue *g_ret, gpointer user_data)
1047 {
1048         gboolean ret = FALSE;
1049
1050         ms_retvm_if(item == NULL, FALSE, "item is NULL");
1051         ms_retvm_if(g_ret == NULL, FALSE, "ret is NULL");
1052
1053         ms_debug_fenter();
1054
1055         ret = ms_element_lock_state(item, g_ret, user_data);
1056
1057         ms_debug_fleave();
1058
1059         return ret;
1060 }
1061
1062 gboolean ms_src_node_prepare_iter(const GValue *item, GValue *ret, gpointer user_data)
1063 {
1064         media_streamer_s *ms_streamer = (media_streamer_s *) user_data;
1065         GstElement *src_element = NULL;
1066         GstElement *found_element = NULL;
1067         media_streamer_node_s *node = NULL;
1068         GstPad *src_pad = NULL;
1069
1070         ms_debug_fenter();
1071
1072         ms_retvm_if(item == NULL, FALSE, "item is NULL");
1073         ms_retvm_if(ret == NULL, FALSE, "ret is NULL");
1074         ms_retvm_if(ms_streamer == NULL, FALSE, "user_data is NULL");
1075
1076         src_element = GST_ELEMENT(g_value_get_object(item));
1077         g_object_ref(src_element);
1078         g_value_set_boolean(ret, FALSE);
1079
1080         node = (media_streamer_node_s *) g_hash_table_lookup(ms_streamer->nodes_table,
1081                 GST_ELEMENT_NAME(src_element));
1082         if (!node) {
1083                 /* If we fail to find corresponding node inside streamer
1084                         then apparently this element doesn't require resources. */
1085                 ms_debug("Could not find corresponding node [%s] inside streamer, skip it", GST_ELEMENT_NAME(src_element));
1086                 g_value_set_boolean(ret, TRUE);
1087                 g_object_unref(src_element);
1088                 return TRUE;
1089         }
1090
1091         ms_debug("Autoplug: found src element [%s]", GST_ELEMENT_NAME(src_element));
1092
1093         src_pad = gst_element_get_static_pad(src_element, "src");
1094
1095         if (__ms_src_need_typefind(src_pad)) {
1096                 ms_find_type(ms_streamer, src_element);
1097                 MS_SAFE_UNREF(src_element);
1098         } else {
1099                 /* Check the source element`s pad type */
1100                 const gchar *new_pad_type = ms_get_pad_type(src_pad);
1101                 /* If SRC Element linked by user, don`t consider the following nodes` managing */
1102                 if (gst_pad_is_linked(src_pad)) {
1103                         MS_SAFE_UNREF(src_pad);
1104                         MS_SAFE_UNREF(src_element);
1105                         g_value_set_boolean(ret, TRUE);
1106                         return TRUE;
1107                 }
1108                 /* It is media streamer Server part */
1109                 if (MS_ELEMENT_IS_VIDEO(new_pad_type) || MS_ELEMENT_IS_IMAGE(new_pad_type)) {
1110                         found_element = ms_combine_next_element(src_element, src_pad, ms_streamer->transform_bin, MEDIA_STREAMER_NODE_TYPE_FILTER);
1111                         GstCaps *videoCaps = gst_caps_from_string(MEDIA_STREAMER_DEFAULT_CAMERA_FORMAT);
1112                         g_object_set(G_OBJECT(found_element), "caps", videoCaps, NULL);
1113                         gst_caps_unref(videoCaps);
1114
1115                         found_element = ms_combine_next_element(found_element, NULL, ms_streamer->transform_bin, MEDIA_STREAMER_NODE_TYPE_VIDEO_ENCODER);
1116                         found_element = ms_combine_next_element(found_element, NULL, ms_streamer->transform_bin, MEDIA_STREAMER_NODE_TYPE_VIDEO_PAY);
1117                         found_element = ms_combine_next_element(found_element, NULL, ms_streamer->transform_bin, MEDIA_STREAMER_NODE_TYPE_RTP);
1118                 }
1119                 if (MS_ELEMENT_IS_AUDIO(new_pad_type)) {
1120                         found_element = ms_combine_next_element(src_element, src_pad, ms_streamer->transform_bin, MEDIA_STREAMER_NODE_TYPE_AUDIO_ENCODER);
1121                         found_element = ms_combine_next_element(found_element, NULL, ms_streamer->transform_bin, MEDIA_STREAMER_NODE_TYPE_AUDIO_PAY);
1122                         found_element = ms_combine_next_element(found_element, NULL, ms_streamer->transform_bin, MEDIA_STREAMER_NODE_TYPE_RTP);
1123                 }
1124                 ms_generate_dots(ms_streamer->pipeline, "after_connecting_rtp");
1125                 MS_SAFE_UNREF(found_element);
1126         }
1127         MS_SAFE_UNREF(src_pad);
1128
1129         g_value_set_boolean(ret, TRUE);
1130
1131         ms_debug_fleave();
1132
1133         return TRUE;
1134 }
1135
1136 static GstElement *__ms_manifest_src_create(media_streamer_node_s *node)
1137 {
1138         char *manifest_src_name = NULL;
1139         gchar *location = NULL;
1140         GstElement *manifest_src = NULL;
1141         GValue *val = NULL;
1142         const char *uri = NULL;
1143         gchar *protocol = NULL;
1144
1145         ms_debug_fenter();
1146
1147         ms_retvm_if(!node, NULL, "node is NULL");
1148
1149         val = (GValue *)g_object_get_data(G_OBJECT(node->gst_element), MEDIA_STREAMER_PARAM_URI);
1150         uri = g_value_get_string(val);
1151         protocol = gst_uri_is_valid(uri) ? gst_uri_get_protocol(uri) : NULL;
1152
1153         if (protocol && g_strrstr(protocol, "http")) {
1154                 manifest_src_name = ms_ini_get_string("node type 1:http", DEFAULT_HTTP_SOURCE);
1155                 location = g_strdup(uri);
1156         } else if (protocol && g_strrstr(protocol, "file")) {
1157                 manifest_src_name = ms_ini_get_string("node type 1:file", DEFAULT_FILE_SOURCE);
1158                 location = gst_uri_get_location(uri);
1159         } else {
1160                 ms_error("Unsupported URI protocol... Check URI is file path");
1161                 if (ms_util_uri_path_check(uri) == MEDIA_STREAMER_ERROR_NONE) {
1162                         manifest_src_name = ms_ini_get_string("node type 1:file", DEFAULT_FILE_SOURCE);
1163                         location = g_strdup(uri);
1164                 } else {
1165                         g_free(protocol);
1166                         ms_error("URI is not valid file path");
1167                         return NULL;
1168                 }
1169         }
1170         g_free(protocol);
1171
1172         if (manifest_src_name == NULL) {
1173                 LOGE("Error empty manifest source name for adaptive source");
1174                 g_free(location);
1175                 return NULL;
1176         }
1177
1178         manifest_src = gst_element_factory_make(manifest_src_name, NULL);
1179         g_free(manifest_src_name);
1180
1181         if (manifest_src == NULL) {
1182                 LOGE("Error creating manifest source for adaptive source");
1183                 g_free(location);
1184                 return NULL;
1185         }
1186
1187         g_object_set(manifest_src, "location", location, NULL);
1188         g_free(location);
1189
1190         ms_debug_fleave();
1191
1192         return manifest_src;
1193 }
1194
1195 int ms_adaptive_src_node_prepare(media_streamer_node_s *node, bool auto_plug)
1196 {
1197         char *plugin_name = NULL;
1198         GstElement *manifest_src = NULL;
1199         GstElement *plugin_elem = NULL;
1200         gboolean res = FALSE;
1201         GstPad *gp = NULL;
1202
1203         ms_debug_fenter();
1204
1205         ms_retvm_if(node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
1206
1207         if (!auto_plug) {
1208                 plugin_name = ms_ini_get_string("node type 1:adaptive", DEFAULT_ADAPTIVE_SOURCE);
1209                 ms_retvm_if(plugin_name == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Error empty plugin name for adaptive source");
1210                 ms_info("Creating [%s] element", plugin_name);
1211                 plugin_elem = gst_element_factory_make(plugin_name, NULL);
1212                 g_free(plugin_name);
1213                 ms_retvm_if(plugin_elem == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER,
1214                                 "Error creating element for adaptive source");
1215
1216                 res = gst_bin_add(GST_BIN(node->gst_element), plugin_elem);
1217                 ms_retvm_if(res == FALSE, MEDIA_STREAMER_ERROR_INVALID_PARAMETER,
1218                                 "Error adding adaptive element to bin for adaptive source");
1219         }
1220
1221         manifest_src = __ms_manifest_src_create(node);
1222         ms_retvm_if(manifest_src == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER,
1223                         "Error creating manifest source for adaptive source");
1224
1225         res = gst_bin_add(GST_BIN(node->gst_element), manifest_src);
1226         ms_retvm_if(res == FALSE, MEDIA_STREAMER_ERROR_INVALID_PARAMETER,
1227                         "Error adding manifest source to bin for adaptive source");
1228
1229         if (!auto_plug) {
1230                 res = gst_element_link(manifest_src, plugin_elem);
1231                 ms_retvm_if(res == FALSE, MEDIA_STREAMER_ERROR_INVALID_PARAMETER,
1232                                 "Error linking manifest source and element for adaptive source");
1233         }
1234
1235         gp = gst_element_get_static_pad(node->gst_element, "src");
1236         ms_retvm_if(gp == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER,
1237                         "Error getting source pad for adaptive source");
1238
1239         if (!auto_plug) {
1240                 g_signal_connect_object(plugin_elem, "pad-added",
1241                                 G_CALLBACK(ms_hlsdemux_pad_added_cb), gp, 0);
1242         } else {
1243                 GstPad *manifest_src_pad = gst_element_get_static_pad(manifest_src, "src");
1244                 gst_ghost_pad_set_target(GST_GHOST_PAD(gp), manifest_src_pad);
1245         }
1246
1247         ms_debug_fleave();
1248
1249         return MEDIA_STREAMER_ERROR_NONE;
1250 }
1251
1252 int ms_adaptive_sink_node_prepare(media_streamer_s *ms_streamer, media_streamer_node_s *node)
1253 {
1254         int err_code = MEDIA_STREAMER_ERROR_NONE;
1255         gchar *playlist_location = NULL;
1256         char *playlist_dir = NULL;
1257         char *split = NULL;
1258
1259         ms_debug_fenter();
1260
1261         ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "ms_streamer is NULL");
1262         ms_retvm_if(node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
1263         ms_retvm_if(node->gst_element == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node->gst_element is NULL");
1264
1265         /* Create and start http server */
1266         err_code = ms_http_server_create(&ms_streamer->http_server);
1267         if (MEDIA_STREAMER_ERROR_NONE != err_code) {
1268                 ms_error("Failed to create http server during prepare");
1269                 goto _DONE;
1270         }
1271
1272         ms_info("Starting http server");
1273         /* FIXME: find out how to set default port */
1274         err_code = ms_http_server_start(ms_streamer->http_server, DEFAULT_HTTP_PORT);
1275         if (MEDIA_STREAMER_ERROR_NONE != err_code) {
1276                 ms_error("Failed to start http server during prepare. Destroying http server");
1277                 ms_http_server_destroy(ms_streamer->http_server);
1278                 goto _DONE;
1279         }
1280
1281         g_object_get(node->gst_element, MEDIA_STREAMER_PARAM_PLAYLIST_LOCATION, &playlist_location, NULL);
1282         if (!playlist_location) {
1283                 err_code = MEDIA_STREAMER_ERROR_INVALID_OPERATION;
1284                 ms_error("Failed to get playlist location");
1285                 ms_http_server_destroy(ms_streamer->http_server);
1286                 goto _DONE;
1287         }
1288
1289         split = strrchr(playlist_location, '/');
1290         playlist_dir = g_strndup(playlist_location, split - playlist_location + 1);
1291
1292         ms_http_server_register_uri(ms_streamer->http_server, "adaptive_path", playlist_dir);
1293
1294         MS_SAFE_GFREE(playlist_location);
1295
1296 _DONE:
1297
1298         ms_debug_fleave();
1299
1300         return err_code;
1301 }
1302
1303 //LCOV_EXCL_START
1304 int ms_rtp_node_prepare(media_streamer_node_s *node)
1305 {
1306         GstElement *rtpbin = NULL;
1307         GstElement *rtp_el = NULL;
1308         GstElement *rtcp_el = NULL;
1309         GValue *val = NULL;
1310         const char *host = NULL;
1311         GstElement *video_filter = NULL;
1312         GstCaps *video_caps = NULL;
1313         GstGhostPad *ghost_pad = NULL;
1314         GstElement *audio_filter = NULL;
1315         GstCaps *audio_caps = NULL;
1316
1317         ms_debug_fenter();
1318
1319         ms_retvm_if(!node, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
1320
1321         rtpbin = ms_element_create("rtpbin", "rtpbin");
1322         ms_retvm_if(!rtpbin, FALSE, "Error: creating elements for rtp container");
1323
1324         if (!ms_bin_add_element(node->gst_element, rtpbin, FALSE)) {
1325                 MS_SAFE_UNREF(rtpbin);
1326                 return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
1327         }
1328
1329         ms_signal_create(&node->sig_list, rtpbin, "pad-added", G_CALLBACK(ms_rtpbin_pad_added_cb), node);
1330
1331         val = (GValue *)g_object_get_data(G_OBJECT(node->gst_element), MEDIA_STREAMER_PARAM_HOST);
1332         host = g_value_get_string(val);
1333
1334         val = (GValue *)g_object_get_data(G_OBJECT(node->gst_element), MEDIA_STREAMER_PARAM_VIDEO_IN_PORT);
1335         if (g_value_get_int(val) > RTP_STREAM_DISABLED) {
1336                 rtp_el = ms_element_create("udpsrc", MS_RTP_PAD_VIDEO_IN"_rtp");
1337                 ms_bin_add_element(node->gst_element, rtp_el, FALSE);
1338
1339                 rtcp_el = ms_element_create("udpsrc", MS_RTP_PAD_VIDEO_IN"_rctp");
1340                 ms_bin_add_element(node->gst_element, rtcp_el, FALSE);
1341
1342                 if (!gst_element_link_pads(rtp_el, "src", rtpbin, "recv_rtp_sink_0") ||
1343                         !gst_element_link_pads(rtcp_el, "src", rtpbin, "recv_rtcp_sink_0")) {
1344                         ms_error("Failed to link pads for rtpbin sink pad 0");
1345                         return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
1346                 }
1347
1348                 g_object_set_property(G_OBJECT(rtp_el), MEDIA_STREAMER_PARAM_PORT, val);
1349                 g_object_set(G_OBJECT(rtcp_el), MEDIA_STREAMER_PARAM_PORT, (g_value_get_int(val) + 1), NULL);
1350
1351                 val = (GValue *)g_object_get_data(G_OBJECT(node->gst_element), MEDIA_STREAMER_PARAM_VIDEO_IN_FORMAT);
1352                 g_object_set_property(G_OBJECT(rtp_el), "caps", val);
1353         }
1354
1355         val = (GValue *)g_object_get_data(G_OBJECT(node->gst_element), MEDIA_STREAMER_PARAM_AUDIO_IN_PORT);
1356         if (g_value_get_int(val) > RTP_STREAM_DISABLED) {
1357                 rtp_el = ms_element_create("udpsrc", MS_RTP_PAD_AUDIO_IN"_rtp");
1358                 ms_bin_add_element(node->gst_element, rtp_el, FALSE);
1359
1360                 rtcp_el = ms_element_create("udpsrc", MS_RTP_PAD_AUDIO_IN"_rctp");
1361                 ms_bin_add_element(node->gst_element, rtcp_el, FALSE);
1362
1363                 if (!gst_element_link_pads(rtp_el, "src", rtpbin, "recv_rtp_sink_1") ||
1364                         !gst_element_link_pads(rtcp_el, "src", rtpbin, "recv_rtcp_sink_1")) {
1365                         ms_error("Failed to link pads for rtpbin sink pad 1");
1366                         return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
1367                 }
1368
1369                 g_object_set_property(G_OBJECT(rtp_el), MEDIA_STREAMER_PARAM_PORT, val);
1370                 g_object_set(G_OBJECT(rtcp_el), MEDIA_STREAMER_PARAM_PORT, (g_value_get_int(val) + 1), NULL);
1371
1372                 val = (GValue *)g_object_get_data(G_OBJECT(node->gst_element), MEDIA_STREAMER_PARAM_AUDIO_IN_FORMAT);
1373                 g_object_set_property(G_OBJECT(rtp_el), "caps", val);
1374         }
1375
1376         val = (GValue *)g_object_get_data(G_OBJECT(node->gst_element), MEDIA_STREAMER_PARAM_VIDEO_OUT_PORT);
1377         if (g_value_get_int(val) > RTP_STREAM_DISABLED) {
1378                 rtp_el = ms_element_create("udpsink", MS_RTP_PAD_VIDEO_OUT"_rtp");
1379                 ms_bin_add_element(node->gst_element, rtp_el, FALSE);
1380
1381                 rtcp_el = ms_element_create("udpsink", MS_RTP_PAD_VIDEO_OUT"_rctp");
1382                 ms_bin_add_element(node->gst_element, rtcp_el, FALSE);
1383
1384                 video_filter = ms_element_create("capsfilter", NULL);
1385                 ms_bin_add_element(node->gst_element, video_filter, FALSE);
1386
1387                 video_caps = gst_caps_from_string(MEDIA_STREAMER_DEFAULT_VIDEO_RTP_FORMAT);
1388                 g_object_set(G_OBJECT(video_filter), "caps", video_caps, NULL);
1389                 gst_caps_unref(video_caps);
1390
1391                 gst_element_link_pads(video_filter, "src", rtpbin, "send_rtp_sink_0");
1392
1393                 ghost_pad = (GstGhostPad *)gst_element_get_static_pad(node->gst_element, MS_RTP_PAD_VIDEO_IN);
1394                 if (ghost_pad) {
1395                         if (gst_ghost_pad_set_target(ghost_pad, gst_element_get_static_pad(video_filter, "sink")))
1396                                 ms_info(" Capsfilter for [%s] in RTP is set and linked", MS_RTP_PAD_VIDEO_IN);
1397                 }
1398
1399                 if (!gst_element_link_pads(rtpbin, "send_rtp_src_0", rtp_el, "sink") ||
1400                         !gst_element_link_pads(rtpbin, "send_rtcp_src_0", rtcp_el, "sink")) {
1401                         ms_error("Failed to link pads for rtpbin src pad 0");
1402                         return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
1403                 }
1404
1405                 g_object_set_property(G_OBJECT(rtp_el), MEDIA_STREAMER_PARAM_PORT, val);
1406                 g_object_set(GST_OBJECT(rtp_el), MEDIA_STREAMER_PARAM_HOST, host, NULL);
1407                 g_object_set(G_OBJECT(rtcp_el), MEDIA_STREAMER_PARAM_PORT, (g_value_get_int(val) + 1), NULL);
1408                 g_object_set(GST_OBJECT(rtcp_el), "sync", FALSE, NULL);
1409                 g_object_set(GST_OBJECT(rtcp_el), "async", FALSE, NULL);
1410                 g_object_set(GST_OBJECT(rtcp_el), MEDIA_STREAMER_PARAM_HOST, host, NULL);
1411         }
1412
1413         val = (GValue *)g_object_get_data(G_OBJECT(node->gst_element), MEDIA_STREAMER_PARAM_AUDIO_OUT_PORT);
1414         if (g_value_get_int(val) > RTP_STREAM_DISABLED) {
1415                 rtp_el = ms_element_create("udpsink", MS_RTP_PAD_AUDIO_OUT"_rtp");
1416                 ms_bin_add_element(node->gst_element, rtp_el, FALSE);
1417
1418                 rtcp_el = ms_element_create("udpsink", MS_RTP_PAD_AUDIO_OUT"_rctp");
1419                 ms_bin_add_element(node->gst_element, rtcp_el, FALSE);
1420
1421                 audio_filter = ms_element_create("capsfilter", NULL);
1422                 ms_bin_add_element(node->gst_element, audio_filter, FALSE);
1423
1424                 audio_caps = gst_caps_from_string(MEDIA_STREAMER_DEFAULT_AUDIO_RTP_FORMAT);
1425                 g_object_set(G_OBJECT(audio_filter), "caps", audio_caps, NULL);
1426
1427                 gst_element_link_pads(audio_filter, "src", rtpbin, "send_rtp_sink_1");
1428
1429                 ghost_pad = (GstGhostPad *)gst_element_get_static_pad(node->gst_element, MS_RTP_PAD_AUDIO_IN);
1430                 if (ghost_pad) {
1431                         if (gst_ghost_pad_set_target(ghost_pad, gst_element_get_static_pad(audio_filter, "sink")))
1432                                 ms_info(" Capsfilter for [%s] in RTP is set and linked", MS_RTP_PAD_AUDIO_IN);
1433                 }
1434
1435                 if (!gst_element_link_pads(rtpbin, "send_rtp_src_1", rtp_el, "sink") ||
1436                         !gst_element_link_pads(rtpbin, "send_rtcp_src_1", rtcp_el, "sink")) {
1437                         ms_error("Failed to link pads for rtpbin src pad 1");
1438                         return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
1439                 }
1440
1441                 g_object_set_property(G_OBJECT(rtp_el), MEDIA_STREAMER_PARAM_PORT, val);
1442                 g_object_set(GST_OBJECT(rtp_el), MEDIA_STREAMER_PARAM_HOST, host, NULL);
1443                 g_object_set(G_OBJECT(rtcp_el), MEDIA_STREAMER_PARAM_PORT, (g_value_get_int(val) + 1), NULL);
1444                 g_object_set(GST_OBJECT(rtcp_el), "sync", FALSE, NULL);
1445                 g_object_set(GST_OBJECT(rtcp_el), "async", FALSE, NULL);
1446                 g_object_set(GST_OBJECT(rtcp_el), MEDIA_STREAMER_PARAM_HOST, host, NULL);
1447         }
1448
1449         ms_generate_dots(node->gst_element, "rtp_prepared");
1450
1451         ms_debug_fleave();
1452
1453         return MEDIA_STREAMER_ERROR_NONE;
1454 }
1455
1456 int ms_webrtc_node_prepare(media_streamer_s *ms_streamer, media_streamer_node_s *node)
1457 {
1458         GstElement *webrtcbin = NULL;
1459         node_info_s *node_klass_type = NULL;
1460         GObject *send_channel = NULL;
1461         gboolean is_offerer = FALSE;
1462         media_streamer_webrtc_callbacks_s *_callbacks = NULL;
1463
1464         ms_debug_fenter();
1465
1466         ms_retvm_if(!ms_streamer, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "ms_streamer is NULL");
1467         ms_retvm_if(!node, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
1468         ms_retvm_if(node->type != MEDIA_STREAMER_NODE_TYPE_WEBRTC, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is not WebRTC");
1469
1470         node_klass_type = ms_node_get_klass_by_its_type(MEDIA_STREAMER_NODE_TYPE_WEBRTC);
1471         if (!(webrtcbin = ms_find_element_in_bin_by_type(node->gst_element, node_klass_type))) {
1472                 ms_error("Could not find webrtcbin by type[%s, %s]", node_klass_type->klass_name, node_klass_type->default_name);
1473                 return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
1474         }
1475
1476         _callbacks = (media_streamer_webrtc_callbacks_s *) node->callbacks_structure;
1477         if (!_callbacks || !(_callbacks->message_cb.callback)) {
1478                 ms_error("message callback should be set before preparing");
1479                 return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
1480         }
1481
1482         if (__ms_webrtc_node_is_offerer(node, &is_offerer)) {
1483                 ms_error("Failed to get peer type");
1484                 return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
1485         }
1486
1487         if (is_offerer)
1488                 ms_signal_create(&node->sig_list, webrtcbin, "on-negotiation-needed", G_CALLBACK(ms_webrtcbin_on_negotiation_needed_cb), node);
1489
1490         ms_signal_create(&node->sig_list, webrtcbin, "on-ice-candidate", G_CALLBACK(ms_webrtcbin_on_ice_candidate_cb), node);
1491         ms_signal_create(&node->sig_list, webrtcbin, "notify::ice-gathering-state", G_CALLBACK(ms_webrtcbin_notify_ice_gathering_state_cb), NULL);
1492
1493         if (ms_element_set_state(webrtcbin, GST_STATE_READY)) {
1494                 ms_error("Faild to set state to READY");
1495                 return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
1496         }
1497
1498         g_signal_emit_by_name (webrtcbin, "create-data-channel", "channel", NULL, &send_channel);
1499         if (send_channel)
1500                 ms_info("data channel(%p) for sending is created", send_channel);
1501         else
1502                 ms_warning("Failed to create data channel");
1503
1504         ms_signal_create(&node->sig_list, webrtcbin, "on-data-channel", G_CALLBACK(ms_webrtcbin_on_data_channel_cb), ms_streamer);
1505         ms_signal_create(&node->sig_list, webrtcbin, "pad-added", G_CALLBACK(ms_webrtcbin_pad_added_cb), node);
1506
1507         ms_generate_dots(node->gst_element, "webrtc_prepared");
1508
1509         ms_debug_fleave();
1510
1511         return MEDIA_STREAMER_ERROR_NONE;
1512 }
1513
1514 //LCOV_EXCL_STOP
1515
1516 int ms_demux_node_prepare(media_streamer_s *ms_streamer, media_streamer_node_s *node)
1517 {
1518         ms_debug_fenter();
1519
1520         ms_retvm_if(!ms_streamer, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "ms_streamer is NULL");
1521         ms_retvm_if(!node, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
1522
1523         ms_signal_create(&ms_streamer->autoplug_sig_list, node->gst_element, "pad-added", G_CALLBACK(ms_demux_pad_added_cb), ms_streamer);
1524         ms_signal_create(&ms_streamer->autoplug_sig_list, node->gst_element, "no-more-pads", G_CALLBACK(ms_demux_nomore_pads_cb), ms_streamer);
1525
1526         ms_debug_fleave();
1527
1528         return MEDIA_STREAMER_ERROR_NONE;
1529 }
1530
1531 static int __ms_node_get_param_list(media_streamer_node_s *node, GList **param_list)
1532 {
1533         GParamSpec *param_spec;
1534         int it_param;
1535
1536         ms_debug_fenter();
1537
1538         ms_retvm_if(node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
1539         ms_retvm_if(param_list == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "param_list is NULL");
1540
1541         for (it_param = 0; param_table[it_param].param_name != NULL; it_param++) {
1542                 param_spec = g_object_class_find_property(G_OBJECT_GET_CLASS(node->gst_element), param_table[it_param].origin_name);
1543                 if (param_spec || __ms_rtp_node_has_property(node, param_table[it_param].origin_name) ||
1544                                 __ms_adaptive_src_node_has_property(node, param_table[it_param].origin_name)) {
1545                         ms_info("Got parameter [%s] for node [%s]", param_table[it_param].param_name, node->name);
1546                         *param_list = g_list_append(*param_list, &(param_table[it_param]));
1547                 }
1548         }
1549         ms_retvm_if(!(*param_list), MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Node [%s] doesn't have any params.", node->name);
1550
1551         ms_debug_fleave();
1552
1553         return MEDIA_STREAMER_ERROR_NONE;
1554 }
1555
1556 static int __ms_node_set_display(media_streamer_node_s *node, const char *param_value)
1557 {
1558         int ret = MEDIA_STREAMER_ERROR_NONE;
1559         Evas_Object *obj = NULL;
1560         media_streamer_wl_info_s wl_info;
1561
1562         obj = (Evas_Object *)param_value;
1563
1564         /* get wayland parent id */
1565         if (ms_get_wl_info(obj, &wl_info) != MEDIA_STREAMER_ERROR_NONE) {
1566                 LOGE("failed to get wayland info");
1567                 return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
1568         }
1569
1570         LOGD("wayland global surface id : %d", wl_info.parent_id);
1571
1572         gst_video_overlay_set_wl_window_wl_surface_id(GST_VIDEO_OVERLAY(node->gst_element), wl_info.parent_id);
1573
1574         return ret;
1575 }
1576 //LCOV_EXCL_STOP
1577 int ms_node_set_param_value(media_streamer_node_s *node, param_s *param, const char *param_value)
1578 {
1579
1580         int ret = MEDIA_STREAMER_ERROR_NONE;
1581
1582         ms_debug_fenter();
1583
1584         ms_retvm_if(node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
1585         ms_retvm_if(param == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "param is NULL");
1586         ms_retvm_if(param_value == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "param_value is NULL");
1587
1588         if (node->type == MEDIA_STREAMER_NODE_TYPE_RTP) {
1589                 ret = __ms_rtp_node_set_property(node, param, param_value);
1590                 ms_debug_fleave();
1591                 return ret;
1592         }
1593
1594         if (node->type == MEDIA_STREAMER_NODE_TYPE_WEBRTC) {
1595                 ret = __ms_webrtc_node_set_property(node, param, param_value);
1596                 ms_debug_fleave();
1597                 return ret;
1598         }
1599
1600         if (node->type == MEDIA_STREAMER_NODE_TYPE_SRC &&
1601                         node->subtype == MEDIA_STREAMER_NODE_SRC_TYPE_ADAPTIVE) {
1602                 ret = __ms_adaptive_src_node_set_property(node, param, param_value);
1603                 ms_debug_fleave();
1604                 return ret;
1605         }
1606
1607         if (!g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_CAMERA_ID)) {
1608                 int camera_id = (int)strtol(param_value, NULL, 10);
1609                 ms_retvm_if(camera_id == -1, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Invalid %s value", param->param_name);
1610                 g_object_set(node->gst_element, param->origin_name, camera_id, NULL);
1611         } else if (!g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_CAPTURE_WIDTH) ||
1612                                         !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_CAPTURE_HEIGHT) ||
1613                                         !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_STREAM_TYPE) ||
1614                                         !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_PORT) ||
1615                                         !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_ROTATE) ||
1616                                         !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_FLIP) ||
1617                                         !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_DISPLAY_GEOMETRY_METHOD)) {
1618                 g_object_set(node->gst_element, param->origin_name, (int)strtol(param_value, NULL, 10), NULL);
1619         } else if (!g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_IS_LIVE_STREAM) ||
1620                                         !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_CLOCK_SYNCHRONIZED) ||
1621                                         !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_USE_TBM) ||
1622                                         !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_VISIBLE)) {
1623                 g_object_set(node->gst_element, param->origin_name, !g_ascii_strcasecmp(param_value, "true"), NULL);
1624         } else if (!g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_URI)) {
1625                 if (node->type == MEDIA_STREAMER_NODE_TYPE_SRC && node->subtype == MEDIA_STREAMER_NODE_SRC_TYPE_FILE) {
1626                         ret = ms_util_uri_path_check(param_value);
1627                         if (ret != MEDIA_STREAMER_ERROR_NONE)
1628                                 return ret;
1629                 }
1630                 g_object_set(node->gst_element, param->origin_name, param_value, NULL);
1631         } else if (!g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_USER_AGENT) ||
1632                                         !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_IP_ADDRESS) ||
1633                                         !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_AUDIO_DEVICE) ||
1634                                         !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_HOST) ||
1635                                         !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_SEGMENT_LOCATION) ||
1636                                         !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_PLAYLIST_LOCATION)) {
1637                 g_object_set(node->gst_element, param->origin_name, param_value, NULL);
1638         } else if (!g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_DISPLAY)) {
1639                 ret = __ms_node_set_display(node, param_value);
1640         } else {
1641                 ms_info("Can not set parameter [%s] in the node [%s]", param->param_name, node->name);
1642                 ret = MEDIA_STREAMER_ERROR_INVALID_PARAMETER;
1643         }
1644
1645         ms_debug_fleave();
1646
1647         return ret;
1648 }
1649
1650 int ms_node_set_params_from_bundle(media_streamer_node_s *node, bundle *param_list)
1651 {
1652         int ret = MEDIA_STREAMER_ERROR_NONE;
1653         GList *p_list = NULL;
1654         int written_count = 0;
1655         param_s *param = NULL;
1656         GList *list_iter = NULL;
1657         char *string_val = NULL;
1658
1659         ms_debug_fenter();
1660
1661         ms_retvm_if(node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
1662         ms_retvm_if(param_list == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "param_list is NULL");
1663
1664         ret = __ms_node_get_param_list(node, &p_list);
1665         if (ret == MEDIA_STREAMER_ERROR_NONE) {
1666                 for (list_iter = p_list; list_iter != NULL; list_iter = list_iter->next) {
1667                         param = (param_s *)list_iter->data;
1668                         if (bundle_get_str(param_list, param->param_name, &string_val) != BUNDLE_ERROR_KEY_NOT_AVAILABLE) {
1669                                 ret = ms_node_set_param_value(node, param, string_val);
1670                                 if (ret == MEDIA_STREAMER_ERROR_NONE) {
1671                                         written_count++;
1672                                 } else {
1673                                         ms_error("failed to set param");
1674                                         break;
1675                                 }
1676                         }
1677                 }
1678         }
1679         g_list_free(p_list);
1680
1681         ms_info("Set [%d] parameters of [%d]", written_count, bundle_get_count(param_list));
1682         if (ret == MEDIA_STREAMER_ERROR_NONE && written_count == 0)
1683                 ret = MEDIA_STREAMER_ERROR_INVALID_PARAMETER;
1684
1685         ms_debug_fleave();
1686
1687         return ret;
1688 }
1689
1690 int ms_node_write_params_into_bundle(media_streamer_node_s *node, bundle *param_list)
1691 {
1692         int ret = MEDIA_STREAMER_ERROR_NONE;
1693         GList *p_list = NULL;
1694         param_s *param = NULL;
1695         GList *list_iter = NULL;
1696         char *string_val = NULL;
1697
1698         ms_debug_fenter();
1699
1700         ms_retvm_if(node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
1701         ms_retvm_if(param_list == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "param_list is NULL");
1702
1703         ret = __ms_node_get_param_list(node, &p_list);
1704         if (ret == MEDIA_STREAMER_ERROR_NONE) {
1705                 for (list_iter = p_list; list_iter != NULL; list_iter = list_iter->next) {
1706                         param = (param_s *)list_iter->data;
1707
1708                         if (ms_node_get_param_value(node, param, &string_val) == MEDIA_STREAMER_ERROR_NONE) {
1709                                 bundle_add_str(param_list, param->param_name, string_val);
1710                                 MS_SAFE_FREE(string_val);
1711                         }
1712                 }
1713         }
1714         if (p_list)
1715                 g_list_free(p_list);
1716
1717         ms_debug_fleave();
1718
1719         return ret;
1720 }
1721
1722 int ms_node_get_param(media_streamer_node_s *node, const char *param_name, param_s **param)
1723 {
1724         GParamSpec *param_spec;
1725         gboolean found_param = FALSE;
1726         int it_param;
1727
1728         ms_debug_fenter();
1729
1730         ms_retvm_if(node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
1731         ms_retvm_if(param_name == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "param_name is NULL");
1732         ms_retvm_if(param == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "param is NULL");
1733
1734         for (it_param = 0; param_table[it_param].param_name != NULL; it_param++) {
1735                 if (!g_strcmp0(param_name, param_table[it_param].param_name)) {
1736                         param_spec = g_object_class_find_property(G_OBJECT_GET_CLASS(node->gst_element), param_table[it_param].origin_name);
1737                         if (param_spec || __ms_rtp_node_has_property(node, param_table[it_param].origin_name) ||
1738                                         __ms_adaptive_src_node_has_property(node, param_table[it_param].origin_name) ||
1739                                         __ms_webrtc_node_has_property(node, param_table[it_param].origin_name)) {
1740                                 *param = &(param_table[it_param]);
1741                                 ms_info("Got parameter [%s] for node [%s]", (*param)->param_name, node->name);
1742                                 found_param = TRUE;
1743                                 break;
1744                         }
1745                 }
1746         }
1747         ms_retvm_if(!found_param, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Node [%s] doesn't have param [%s].", node->name, param_name);
1748
1749         ms_debug_fleave();
1750
1751         return MEDIA_STREAMER_ERROR_NONE;
1752 }
1753
1754 int ms_node_get_param_value(media_streamer_node_s *node, param_s *param, char **string_value)
1755 {
1756         int ret = MEDIA_STREAMER_ERROR_NONE;
1757         char *string_val = NULL;
1758         GParamSpec *param_spec = NULL;
1759         GValue value = G_VALUE_INIT;
1760
1761         ms_debug_fenter();
1762
1763         ms_retvm_if(node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
1764         ms_retvm_if(param == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "param is NULL");
1765         ms_retvm_if(string_value == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "string_value is NULL");
1766
1767         if (node->type == MEDIA_STREAMER_NODE_TYPE_RTP)
1768                 ret = __ms_rtp_node_get_property(node, param, &value);
1769         else if (node->type == MEDIA_STREAMER_NODE_TYPE_SRC &&
1770                                 node->subtype == MEDIA_STREAMER_NODE_SRC_TYPE_ADAPTIVE)
1771                 ret = __ms_adaptive_src_node_get_property(node, param, &value);
1772         else {
1773                 param_spec = g_object_class_find_property(G_OBJECT_GET_CLASS(node->gst_element), param->origin_name);
1774                 if (param_spec) {
1775                         g_value_init(&value, param_spec->value_type);
1776                         g_object_get_property(G_OBJECT(node->gst_element), param->origin_name, &value);
1777
1778                         ms_info("Got parameter [%s] for node [%s] with description [%s]", param->param_name, node->name, g_param_spec_get_blurb(param_spec));
1779                 } else {
1780                         ms_error("There is no parameter [%s] for node [%s]", param->origin_name, node->name);
1781                         return MEDIA_STREAMER_ERROR_INVALID_PARAMETER;
1782                 }
1783         }
1784
1785         if (!g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_CAMERA_ID) ||
1786                         !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_CAPTURE_WIDTH) ||
1787                         !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_CAPTURE_HEIGHT) ||
1788                         !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_PORT) ||
1789                         !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_VIDEO_IN_PORT) ||
1790                         !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_AUDIO_IN_PORT) ||
1791                         !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_VIDEO_OUT_PORT) ||
1792                         !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_AUDIO_OUT_PORT)) {
1793                 if (G_VALUE_HOLDS_INT(&value))
1794                         string_val = g_strdup_printf("%d", g_value_get_int(&value));
1795                 else
1796                         string_val = g_strdup_printf("%u", g_value_get_uint(&value));
1797         } else if (!g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_IS_LIVE_STREAM) ||
1798                                 !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_CLOCK_SYNCHRONIZED) ||
1799                                 !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_USE_TBM) ||
1800                                 !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_VISIBLE)) {
1801                 string_val = g_strdup(g_value_get_boolean(&value) ? "true" : "false");
1802         } else if (!g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_URI) ||
1803                                 !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_USER_AGENT) ||
1804                                 !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_IP_ADDRESS) ||
1805                                 !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_AUDIO_DEVICE) ||
1806                                 !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_HOST) ||
1807                                 !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_SEGMENT_LOCATION) ||
1808                                 !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_PLAYLIST_LOCATION)) {
1809                 string_val = g_value_dup_string(&value);
1810         } else if (!g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_STREAM_TYPE) ||
1811                                 !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_ROTATE) ||
1812                                 !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_FLIP) ||
1813                                 !g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_DISPLAY_GEOMETRY_METHOD)) {
1814                 string_val = g_strdup_printf("%d", g_value_get_enum(&value));
1815         }
1816
1817         *string_value = string_val;
1818
1819         g_value_reset(&value);
1820         g_value_unset(&value);
1821
1822         ms_debug_fleave();
1823
1824         return ret;
1825 }
1826
1827 int ms_node_set_pad_format(media_streamer_node_s *node, const char *pad_name, media_format_h fmt)
1828 {
1829         int ret = MEDIA_STREAMER_ERROR_NONE;
1830
1831         ms_debug_fenter();
1832
1833         ms_retvm_if(node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
1834         ms_retvm_if(pad_name == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "pad_name is NULL");
1835         ms_retvm_if(fmt == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "fmt is NULL");
1836
1837         if (node->type == MEDIA_STREAMER_NODE_TYPE_RTP) {
1838                 media_format_mimetype_e mime;
1839                 gchar *rtp_caps_str = NULL;
1840
1841                 /* It is needed to set 'application/x-rtp' for audio and video udpsrc */
1842                 if (g_strrstr(pad_name, MS_RTP_PAD_VIDEO_IN)) {
1843                         ret = media_format_get_video_info(fmt, &mime, NULL, NULL, NULL, NULL);
1844                         if (MEDIA_FORMAT_ERROR_NONE == ret) {
1845                                 rtp_caps_str = g_strdup_printf("application/x-rtp,media=(string)video,clock-rate=(int)90000,encoding-name=%s", ms_convert_mime_to_rtp_format(mime));
1846                                 param_s param = {MEDIA_STREAMER_PARAM_VIDEO_IN_FORMAT, MEDIA_STREAMER_PARAM_VIDEO_IN_FORMAT};
1847                                 ret = ms_node_set_param_value(node, &param, rtp_caps_str);
1848                         }
1849                 } else if (g_strrstr(pad_name, MS_RTP_PAD_AUDIO_IN)) {
1850                         int audio_channels, audio_samplerate;
1851                         ret = media_format_get_audio_info(fmt, &mime, &audio_channels, &audio_samplerate, NULL, NULL);
1852                         if (MEDIA_FORMAT_ERROR_NONE == ret) {
1853                                 rtp_caps_str = g_strdup_printf("application/x-rtp,media=(string)audio,clock-rate=(int)8000,encoding-name=(string)AMR,encoding-params=(string)1,octet-align=(string)1");
1854                                 param_s param = {MEDIA_STREAMER_PARAM_AUDIO_IN_FORMAT, MEDIA_STREAMER_PARAM_AUDIO_IN_FORMAT};
1855                                 ret = ms_node_set_param_value(node, &param, rtp_caps_str);
1856                         }
1857                 }
1858
1859                 MS_SAFE_GFREE(rtp_caps_str);
1860         } else {
1861                 ret = ms_element_set_fmt(node->gst_element, pad_name, fmt);
1862         }
1863
1864         ms_debug_fleave();
1865
1866         return ret;
1867 }
1868
1869 gboolean ms_node_resources_acquire_iter(const GValue *item, GValue *ret, gpointer user_data)
1870 {
1871         media_streamer_s *ms_streamer = (media_streamer_s *) user_data;
1872         media_streamer_node_s *node = NULL;
1873         GstElement *element = NULL;
1874
1875         ms_debug_fenter();
1876
1877         ms_retvm_if(item == NULL, FALSE, "item is NULL");
1878         ms_retvm_if(ms_streamer == NULL, FALSE, "ms_streamer is NULL");
1879         ms_retvm_if(ret == NULL, FALSE, "ret is NULL");
1880
1881         g_value_set_boolean(ret, FALSE);
1882
1883         element = GST_ELEMENT(g_value_get_object(item));
1884         g_object_ref(element);
1885
1886         node = (media_streamer_node_s *) g_hash_table_lookup(ms_streamer->nodes_table,
1887                 GST_ELEMENT_NAME(element));
1888         if (!node) {
1889                 /* If we fail to find corresponding node inside streamer
1890                         then apparently this element doesn't require resources. */
1891                 ms_debug("Could not find corresponding node [%s] inside streamer, skip it", GST_ELEMENT_NAME(element));
1892                 g_value_set_boolean(ret, TRUE);
1893                 g_object_unref(element);
1894                 return TRUE;
1895         }
1896
1897         if (MEDIA_STREAMER_ERROR_NONE != ms_node_resource_acquire(node)) {
1898                 ms_error("Failed to acquire resource for node [%s]", node->name);
1899                 g_object_unref(element);
1900                 return FALSE;
1901         }
1902
1903         g_value_set_boolean(ret, TRUE);
1904
1905         g_object_unref(element);
1906
1907         ms_debug_fleave();
1908
1909         return TRUE;
1910 }
1911
1912 gboolean ms_node_resources_release_iter(const GValue *item, GValue *ret, gpointer user_data)
1913 {
1914         media_streamer_s *ms_streamer = (media_streamer_s *) user_data;
1915         media_streamer_node_s *node = NULL;
1916         GstElement *element = NULL;
1917
1918         ms_debug_fenter();
1919
1920         ms_retvm_if(item == NULL, FALSE, "item is NULL");
1921         ms_retvm_if(ms_streamer == NULL, FALSE, "ms_streamer is NULL");
1922         ms_retvm_if(ret == NULL, FALSE, "ret is NULL");
1923
1924         g_value_set_boolean(ret, FALSE);
1925
1926         element = GST_ELEMENT(g_value_get_object(item));
1927         g_object_ref(element);
1928
1929         node = (media_streamer_node_s *) g_hash_table_lookup(ms_streamer->nodes_table,
1930                 GST_ELEMENT_NAME(element));
1931         if (!node) {
1932                 /* If we fail to find corresponding node inside streamer
1933                         then apparently this element doesn't require resources. */
1934                 ms_debug("Could not find corresponding node [%s] inside streamer, skip it", GST_ELEMENT_NAME(element));
1935                 g_value_set_boolean(ret, TRUE);
1936                 g_object_unref(element);
1937                 return TRUE;
1938         }
1939
1940         if (MEDIA_STREAMER_ERROR_NONE != ms_node_resource_release(node)) {
1941                 ms_error("Failed to release resource for node [%s]", node->name);
1942                 g_object_unref(element);
1943                 return FALSE;
1944         }
1945
1946         g_value_set_boolean(ret, TRUE);
1947
1948         g_object_unref(element);
1949
1950         ms_debug_fleave();
1951
1952         return TRUE;
1953 }
1954
1955 gboolean ms_node_dpm_policy_check_iter(const GValue *item, GValue *ret, gpointer user_data)
1956 {
1957         media_streamer_s *ms_streamer = (media_streamer_s *) user_data;
1958         media_streamer_node_s *node = NULL;
1959         GstElement *element = NULL;
1960         gboolean allowed = FALSE;
1961
1962         ms_debug_fenter();
1963
1964         ms_retvm_if(item == NULL, FALSE, "item is NULL");
1965         ms_retvm_if(ms_streamer == NULL, FALSE, "ms_streamer is NULL");
1966         ms_retvm_if(ms_streamer->nodes_table == NULL, FALSE, "ms_streamer->nodes_table is NULL");
1967         ms_retvm_if(ret == NULL, FALSE, "ret is NULL");
1968
1969         element = GST_ELEMENT(g_value_get_object(item));
1970         g_object_ref(element);
1971
1972         node = (media_streamer_node_s *) g_hash_table_lookup(ms_streamer->nodes_table,
1973                 GST_ELEMENT_NAME(element));
1974         if (!node) {
1975                 /* If we fail to find corresponding node inside streamer
1976                         then apparently this element doesn't require resources. */
1977                 ms_debug("Could not find corresponding node [%s] inside streamer, skip it", GST_ELEMENT_NAME(element));
1978                 g_value_set_boolean(ret, TRUE);
1979                 g_object_unref(element);
1980                 return TRUE;
1981         }
1982
1983         if (ms_node_dpm_policy_check(node, &allowed)) {
1984                 ms_error("Failed to check DPM policy for node [%s]", node->name);
1985                 /* Note that it should be TRUE(allowed) if the DPM API failed. */
1986                 g_value_set_boolean(ret, TRUE);
1987                 g_object_unref(element);
1988                 return FALSE;
1989         }
1990
1991         g_value_set_boolean(ret, allowed);
1992
1993         g_object_unref(element);
1994
1995         ms_debug_fleave();
1996
1997         return allowed;
1998 }