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