Wrap g_hash_table_remove() with ms_node_remove_from_table()
[platform/core/api/mediastreamer.git] / src / media_streamer.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 <stdlib.h>
18 #include <string.h>
19 #include <dlog.h>
20 #include "media_streamer.h"
21 #include "media_streamer_priv.h"
22 #include "media_streamer_node.h"
23 #include "media_streamer_gst.h"
24
25 /*
26 * Public Implementation
27 */
28
29 int media_streamer_node_create_src(media_streamer_node_src_type_e type, media_streamer_node_h *src)
30 {
31         int ret = MEDIA_STREAMER_ERROR_NONE;
32         media_streamer_node_s *ms_src = NULL;
33
34         ms_debug_fenter();
35
36         ms_retvm_if(src == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "src is NULL");
37
38         ms_src = (media_streamer_node_s *) calloc(1, sizeof(media_streamer_node_s));
39         ms_retvm_if(ms_src == NULL, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Error allocation memory");
40
41         ms_src->type = MEDIA_STREAMER_NODE_TYPE_SRC;
42         ms_src->subtype = (media_streamer_node_src_type_e) type;
43
44         ret = ms_src_node_create(ms_src);
45         if (ret != MEDIA_STREAMER_ERROR_NONE) {
46                 ms_error("Error creating Src node [%d]", ret);
47                 ms_node_destroy(ms_src);
48                 return ret;
49         }
50
51         ms_info("Source node [%s] created", ms_src->name);
52         *src = (media_streamer_node_h) ms_src;
53
54         ms_debug_fleave();
55
56         return ret;
57 }
58
59 int media_streamer_node_create_sink(media_streamer_node_sink_type_e type, media_streamer_node_h *sink)
60 {
61         int ret = MEDIA_STREAMER_ERROR_NONE;
62         media_streamer_node_s *ms_sink = NULL;
63
64         ms_debug_fenter();
65
66         ms_retvm_if(sink == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "sink is NULL");
67
68         ms_sink = (media_streamer_node_s *) calloc(1, sizeof(media_streamer_node_s));
69         ms_retvm_if(ms_sink == NULL, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Error allocation memory");
70
71         ms_sink->type = MEDIA_STREAMER_NODE_TYPE_SINK;
72         ms_sink->subtype = (media_streamer_node_sink_type_e) type;
73
74         ret = ms_sink_node_create(ms_sink);
75         if (ret != MEDIA_STREAMER_ERROR_NONE) {
76                 ms_node_destroy(ms_sink);
77                 ms_error("Error creating Sink node [%d]", ret);
78                 return ret;
79         }
80
81         ms_info("Sink node [%s] created", ms_sink->name);
82         *sink = (media_streamer_node_h) ms_sink;
83
84         ms_debug_fleave();
85
86         return ret;
87 }
88
89 int media_streamer_node_create(media_streamer_node_type_e type, media_format_h in_fmt, media_format_h out_fmt, media_streamer_node_h *node)
90 {
91         int ret = MEDIA_STREAMER_ERROR_NONE;
92         media_streamer_node_s *ms_node = NULL;
93
94         ms_debug_fenter();
95
96         ms_retvm_if(node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
97
98         ms_node = (media_streamer_node_s *) calloc(1, sizeof(media_streamer_node_s));
99         ms_retvm_if(ms_node == NULL, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Error allocation memory");
100
101         ms_node->type = type;
102         ms_node->subtype = 0;
103
104         ret = ms_node_create(ms_node, in_fmt, out_fmt);
105         if (ret != MEDIA_STREAMER_ERROR_NONE) {
106                 ms_node_destroy(ms_node);
107                 ms_error("Error creating Node [%d]", ret);
108                 return ret;
109         } else {
110                 ms_info("Node [%s] created", ms_node->name);
111         }
112
113         *node = (media_streamer_node_h) ms_node;
114
115         ms_debug_fleave();
116
117         return ret;
118 }
119
120 int media_streamer_node_destroy(media_streamer_node_h node)
121 {
122         media_streamer_node_s *ms_node = (media_streamer_node_s *) node;
123
124         ms_debug_fenter();
125
126         ms_retvm_if(ms_node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
127
128         if (ms_node->parent_streamer == NULL) {
129                 /* This node was not added into any media streamer */
130                 ms_node_destroy(ms_node);
131         } else {
132                 ms_error("Node destroy error: needed to remove node from media streamer before destroying.");
133                 return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
134         }
135
136         ms_debug_fleave();
137
138         return MEDIA_STREAMER_ERROR_NONE;
139 }
140
141 int media_streamer_node_remove(media_streamer_h streamer, media_streamer_node_h node)
142 {
143         int ret = MEDIA_STREAMER_ERROR_NONE;
144         media_streamer_node_s *ms_node = (media_streamer_node_s *) node;
145         media_streamer_s *ms_streamer = (media_streamer_s *) streamer;
146
147         ms_debug_fenter();
148
149         ms_retvm_if(ms_node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
150         ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "streamer is NULL");
151         ms_retvm_if(ms_streamer->nodes_table == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "streamer->nodes_table is NULL");
152         ms_retvm_if(ms_streamer->state > MEDIA_STREAMER_STATE_IDLE, MEDIA_STREAMER_ERROR_INVALID_STATE, "Error: Media streamer must be in IDLE state");
153         ms_retvm_if(ms_streamer != ms_node->parent_streamer, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Node [%s] added into another Media Streamer object", ms_node->name);
154
155         g_mutex_lock(&ms_streamer->mutex_lock);
156
157         ret = ms_node_remove_from_table(ms_streamer->nodes_table, ms_node);
158
159         g_mutex_unlock(&ms_streamer->mutex_lock);
160
161         ms_debug_fleave();
162
163         return ret;
164 }
165
166 int media_streamer_node_add(media_streamer_h streamer, media_streamer_node_h node)
167 {
168         int ret = MEDIA_STREAMER_ERROR_NONE;
169         media_streamer_s *ms_streamer = (media_streamer_s *) streamer;
170         media_streamer_node_s *ms_node = (media_streamer_node_s *) node;
171
172         ms_debug_fenter();
173
174         ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "streamer is NULL");
175         ms_retvm_if(ms_streamer->nodes_table == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "streamer->nodes_table is NULL");
176         ms_retvm_if(ms_node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
177         ms_retvm_if(ms_node->parent_streamer != NULL, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Node [%s] already added into Media Streamer object", ms_node->name);
178
179         g_mutex_lock(&ms_streamer->mutex_lock);
180
181         ret = ms_node_insert_into_table(ms_streamer->nodes_table, ms_node);
182         if (ret == MEDIA_STREAMER_ERROR_NONE) {
183                 ms_node->parent_streamer = ms_streamer;
184                 ret = ms_add_node_into_bin(ms_streamer, ms_node);
185         }
186
187         g_mutex_unlock(&ms_streamer->mutex_lock);
188
189         ms_debug_fleave();
190
191         return ret;
192 }
193
194 int media_streamer_prepare(media_streamer_h streamer)
195 {
196         int ret = MEDIA_STREAMER_ERROR_NONE;
197         media_streamer_s *ms_streamer = (media_streamer_s *) streamer;
198
199         ms_debug_fenter();
200
201         ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "streamer is NULL");
202         ms_retvm_if(ms_streamer->state > MEDIA_STREAMER_STATE_IDLE, MEDIA_STREAMER_ERROR_INVALID_STATE, "Error: Media streamer already prepared");
203
204         g_mutex_lock(&ms_streamer->mutex_lock);
205
206         ms_generate_dots(ms_streamer->pipeline, "before_prepare");
207
208         ret = ms_pipeline_prepare(ms_streamer);
209
210         ms_generate_dots(ms_streamer->pipeline, "after_prepare");
211
212         g_mutex_unlock(&ms_streamer->mutex_lock);
213
214         ms_pipeline_get_state(ms_streamer);
215
216         ms_debug_fleave();
217
218         return ret;
219 }
220
221 int media_streamer_unprepare(media_streamer_h streamer)
222 {
223         int ret = MEDIA_STREAMER_ERROR_NONE;
224         media_streamer_s *ms_streamer = (media_streamer_s *) streamer;
225
226         ms_debug_fenter();
227
228         ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "streamer is NULL");
229         ms_retvm_if(ms_streamer->state < MEDIA_STREAMER_STATE_READY, MEDIA_STREAMER_ERROR_INVALID_STATE, "Error: Media streamer must be prepared first!");
230
231         g_mutex_lock(&ms_streamer->mutex_lock);
232
233         ms_generate_dots(ms_streamer->pipeline, "before_unprepare");
234
235         ret = ms_pipeline_unprepare(ms_streamer);
236
237         ms_http_server_destroy(ms_streamer->http_server);
238
239         ms_generate_dots(ms_streamer->pipeline, "after_unprepare");
240
241         g_mutex_unlock(&ms_streamer->mutex_lock);
242
243         ms_debug_fleave();
244
245         return ret;
246 }
247
248 int media_streamer_play(media_streamer_h streamer)
249 {
250         int ret = MEDIA_STREAMER_ERROR_NONE;
251         media_streamer_s *ms_streamer = (media_streamer_s *) streamer;
252
253         ms_debug_fenter();
254
255         ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "streamer is NULL");
256         ms_retvm_if(ms_streamer->state < MEDIA_STREAMER_STATE_READY, MEDIA_STREAMER_ERROR_INVALID_STATE, "Error: Media streamer must be prepared first!");
257
258         g_mutex_lock(&ms_streamer->mutex_lock);
259
260         ret = ms_set_state(ms_streamer, MEDIA_STREAMER_STATE_PLAYING);
261
262         g_mutex_unlock(&ms_streamer->mutex_lock);
263
264         ms_pipeline_get_state(ms_streamer);
265
266         ms_debug_fleave();
267
268         return ret;
269 }
270
271 int media_streamer_create(media_streamer_h *streamer)
272 {
273         int ret = MEDIA_STREAMER_ERROR_NONE;
274         media_streamer_s *ms_streamer = NULL;
275
276         ms_debug_fenter();
277
278         ms_retvm_if(streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "streamer is NULL");
279
280         ms_streamer = (media_streamer_s *) calloc(1, sizeof(media_streamer_s));
281         ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Error allocation memory");
282
283         /* create streamer lock */
284         g_mutex_init(&ms_streamer->mutex_lock);
285
286         g_mutex_lock(&ms_streamer->mutex_lock);
287
288         ret = ms_create(ms_streamer);
289         if (ret != MEDIA_STREAMER_ERROR_NONE) {
290                 ms_error("Error creating Media Streamer");
291                 g_mutex_unlock(&ms_streamer->mutex_lock);
292                 ms_destroy(ms_streamer);
293
294                 return ret;
295         }
296
297         ms_streamer->pend_state = MEDIA_STREAMER_STATE_NONE;
298         ret = ms_set_state(ms_streamer, MEDIA_STREAMER_STATE_IDLE);
299         *streamer = ms_streamer;
300
301         g_mutex_unlock(&ms_streamer->mutex_lock);
302
303         ms_info("Media Streamer created successfully");
304
305         ms_debug_fleave();
306
307         return ret;
308 }
309
310 int media_streamer_destroy(media_streamer_h streamer)
311 {
312         int ret = MEDIA_STREAMER_ERROR_NONE;
313         media_streamer_s *ms_streamer = (media_streamer_s *) streamer;
314
315         ms_debug_fenter();
316
317         ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "streamer is NULL");
318         ms_retvm_if(ms_streamer->state > MEDIA_STREAMER_STATE_IDLE, MEDIA_STREAMER_ERROR_INVALID_STATE, "Error: Media streamer must be unprepared before destroying!");
319
320         ret = ms_destroy(ms_streamer);
321
322         ms_debug_fleave();
323
324         return ret;
325 }
326
327 int media_streamer_set_error_cb(media_streamer_h streamer, media_streamer_error_cb callback, void *data)
328 {
329         media_streamer_s *ms_streamer = (media_streamer_s *) streamer;
330
331         ms_debug_fenter();
332
333         ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "streamer is NULL");
334         ms_retvm_if(callback == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "callback is NULL");
335
336         g_mutex_lock(&ms_streamer->mutex_lock);
337
338         ms_streamer->error_cb.callback = callback;
339         ms_streamer->error_cb.user_data = data;
340
341         g_mutex_unlock(&ms_streamer->mutex_lock);
342
343         ms_debug_fleave();
344
345         return MEDIA_STREAMER_ERROR_NONE;
346 }
347
348 int media_streamer_unset_error_cb(media_streamer_h streamer)
349 {
350         media_streamer_s *ms_streamer = (media_streamer_s *) streamer;
351
352         ms_debug_fenter();
353
354         ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "streamer is NULL");
355
356         g_mutex_lock(&ms_streamer->mutex_lock);
357
358         ms_streamer->error_cb.callback = NULL;
359         ms_streamer->error_cb.user_data = NULL;
360
361         g_mutex_unlock(&ms_streamer->mutex_lock);
362
363         ms_debug_fleave();
364
365         return MEDIA_STREAMER_ERROR_NONE;
366 }
367
368 int media_streamer_set_state_change_cb(media_streamer_h streamer, media_streamer_state_changed_cb callback, void *data)
369 {
370         media_streamer_s *ms_streamer = (media_streamer_s *) streamer;
371
372         ms_debug_fenter();
373
374         ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "streamer is NULL");
375         ms_retvm_if(callback == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "callback is NULL");
376
377         g_mutex_lock(&ms_streamer->mutex_lock);
378
379         ms_streamer->state_changed_cb.callback = callback;
380         ms_streamer->state_changed_cb.user_data = data;
381
382         g_mutex_unlock(&ms_streamer->mutex_lock);
383
384         ms_debug_fleave();
385
386         return MEDIA_STREAMER_ERROR_NONE;
387 }
388
389 int media_streamer_unset_state_change_cb(media_streamer_h streamer)
390 {
391         media_streamer_s *ms_streamer = (media_streamer_s *) streamer;
392
393         ms_debug_fenter();
394
395         ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "streamer is NULL");
396
397         g_mutex_lock(&ms_streamer->mutex_lock);
398
399         ms_streamer->state_changed_cb.callback = NULL;
400         ms_streamer->state_changed_cb.user_data = NULL;
401
402         g_mutex_unlock(&ms_streamer->mutex_lock);
403
404         ms_debug_fleave();
405
406         return MEDIA_STREAMER_ERROR_NONE;
407 }
408
409 int media_streamer_src_set_buffer_status_cb(media_streamer_node_h src, media_streamer_custom_buffer_status_cb callback, void *user_data)
410 {
411         media_streamer_node_s *ms_src = (media_streamer_node_s *) src;
412         media_streamer_callback_s *src_callback = NULL;
413
414         ms_debug_fenter();
415
416         ms_retvm_if(ms_src == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "source is NULL");
417         ms_retvm_if(callback == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "callback is NULL");
418
419         if (!ms_src->callbacks_structure) {
420                 src_callback = (media_streamer_callback_s *) calloc(1, sizeof(media_streamer_callback_s));
421                 ms_retvm_if(src_callback == NULL, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Error allocation memory");
422         } else {
423                 src_callback = (media_streamer_callback_s *) ms_src->callbacks_structure;
424         }
425
426         src_callback->callback = callback;
427         src_callback->user_data = user_data;
428
429         ms_src->callbacks_structure = (void *)src_callback;
430
431         ms_debug_fleave();
432
433         return MEDIA_STREAMER_ERROR_NONE;
434 }
435
436 int media_streamer_src_unset_buffer_status_cb(media_streamer_node_h src)
437 {
438         media_streamer_node_s *ms_src = (media_streamer_node_s *) src;
439
440         ms_debug_fenter();
441
442         ms_retvm_if(ms_src == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "source is NULL");
443
444         media_streamer_callback_s *src_callback = (media_streamer_callback_s *) ms_src->callbacks_structure;
445         src_callback->callback = NULL;
446         src_callback->user_data = NULL;
447
448         ms_debug_fleave();
449
450         return MEDIA_STREAMER_ERROR_NONE;
451 }
452
453 int media_streamer_sink_set_data_ready_cb(media_streamer_node_h sink, media_streamer_sink_data_ready_cb callback, void *data)
454 {
455         media_streamer_node_s *ms_sink = (media_streamer_node_s *) sink;
456         media_streamer_sink_callbacks_s *sink_callbacks = NULL;
457
458         ms_debug_fenter();
459
460         ms_retvm_if(ms_sink == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "sink is NULL");
461         ms_retvm_if(callback == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "callback is NULL");
462
463         sink_callbacks = ms_sink->callbacks_structure;
464         if (!sink_callbacks) {
465                 sink_callbacks = (media_streamer_sink_callbacks_s *) calloc(1, sizeof(media_streamer_sink_callbacks_s));
466                 ms_retvm_if(sink_callbacks == NULL, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Error allocation memory");
467         }
468
469         sink_callbacks->data_ready_cb.callback = callback;
470         sink_callbacks->data_ready_cb.user_data = data;
471
472         ms_sink->callbacks_structure = (void *)sink_callbacks;
473
474         ms_debug_fleave();
475
476         return MEDIA_STREAMER_ERROR_NONE;
477 }
478
479 int media_streamer_sink_unset_data_ready_cb(media_streamer_node_h sink)
480 {
481         media_streamer_node_s *ms_sink = (media_streamer_node_s *) sink;
482         media_streamer_sink_callbacks_s *sink_callbacks = NULL;
483
484         ms_debug_fenter();
485
486         ms_retvm_if(ms_sink == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "sink is NULL");
487
488         sink_callbacks = ms_sink->callbacks_structure;
489         ms_retvm_if(sink_callbacks == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Callback didn't set yet");
490
491         sink_callbacks->data_ready_cb.callback = NULL;
492         sink_callbacks->data_ready_cb.user_data = NULL;
493
494         ms_sink->callbacks_structure = (void *)sink_callbacks;
495
496         ms_debug_fleave();
497
498         return MEDIA_STREAMER_ERROR_NONE;
499 }
500
501 int media_streamer_sink_set_eos_cb(media_streamer_node_h sink, media_streamer_sink_eos_cb callback, void *data)
502 {
503         media_streamer_node_s *ms_sink = (media_streamer_node_s *) sink;
504         media_streamer_sink_callbacks_s *sink_callbacks = NULL;
505
506         ms_debug_fenter();
507
508         ms_retvm_if(ms_sink == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "sink is NULL");
509         ms_retvm_if(callback == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "callback is NULL");
510
511         sink_callbacks = ms_sink->callbacks_structure;
512         if (!sink_callbacks) {
513                 sink_callbacks = (media_streamer_sink_callbacks_s *) calloc(1, sizeof(media_streamer_sink_callbacks_s));
514                 ms_retvm_if(sink_callbacks == NULL, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Error allocation memory");
515         }
516
517         sink_callbacks->eos_cb.callback = callback;
518         sink_callbacks->eos_cb.user_data = data;
519
520         ms_sink->callbacks_structure = (void *)sink_callbacks;
521
522         ms_debug_fleave();
523
524         return MEDIA_STREAMER_ERROR_NONE;
525 }
526
527 int media_streamer_sink_unset_eos_cb(media_streamer_node_h sink)
528 {
529         media_streamer_node_s *ms_sink = (media_streamer_node_s *) sink;
530         media_streamer_sink_callbacks_s *sink_callbacks = NULL;
531
532         ms_debug_fenter();
533
534         ms_retvm_if(ms_sink == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "sink is NULL");
535
536         sink_callbacks = ms_sink->callbacks_structure;
537         ms_retvm_if(sink_callbacks == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Callback didn't set yet");
538
539         sink_callbacks->data_ready_cb.callback = NULL;
540         sink_callbacks->data_ready_cb.user_data = NULL;
541
542         ms_sink->callbacks_structure = (void *)sink_callbacks;
543
544         ms_debug_fleave();
545
546         return MEDIA_STREAMER_ERROR_NONE;
547 }
548
549 int media_streamer_pause(media_streamer_h streamer)
550 {
551         int ret = MEDIA_STREAMER_ERROR_NONE;
552         media_streamer_s *ms_streamer = (media_streamer_s *) streamer;
553
554         ms_debug_fenter();
555
556         ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "streamer is NULL");
557         ms_retvm_if(ms_streamer->state != MEDIA_STREAMER_STATE_PLAYING, MEDIA_STREAMER_ERROR_INVALID_STATE, "Error: Media streamer must be in PLAYING state.");
558
559
560         g_mutex_lock(&ms_streamer->mutex_lock);
561
562         ret = ms_set_state(ms_streamer, MEDIA_STREAMER_STATE_PAUSED);
563
564         g_mutex_unlock(&ms_streamer->mutex_lock);
565
566         ms_pipeline_get_state(ms_streamer);
567
568         ms_debug_fleave();
569
570         return ret;
571 }
572
573 int media_streamer_stop(media_streamer_h streamer)
574 {
575         int ret = MEDIA_STREAMER_ERROR_NONE;
576         media_streamer_s *ms_streamer = (media_streamer_s *) streamer;
577
578         ms_debug_fenter();
579
580         ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "streamer is NULL");
581         ms_retvm_if(!(ms_streamer->state == MEDIA_STREAMER_STATE_PLAYING || ms_streamer->state == MEDIA_STREAMER_STATE_PAUSED), MEDIA_STREAMER_ERROR_INVALID_STATE, "Error: Media streamer must be in PLAYING or PAUSED state.");
582
583         g_mutex_lock(&ms_streamer->mutex_lock);
584
585         ret = ms_seek(streamer, 0, FALSE);
586
587         if (ret != MEDIA_STREAMER_ERROR_NONE)
588                 ms_error("Error while putting media streamer to zero playing position");
589         else
590                 ret = ms_set_state(ms_streamer, MEDIA_STREAMER_STATE_PAUSED);
591
592         ms_http_server_stop(ms_streamer->http_server);
593
594         g_mutex_unlock(&ms_streamer->mutex_lock);
595
596         ms_pipeline_get_state(ms_streamer);
597
598         ms_debug_fleave();
599
600         return ret;
601 }
602
603 int media_streamer_get_state(media_streamer_h streamer, media_streamer_state_e *state)
604 {
605         media_streamer_s *ms_streamer = (media_streamer_s *) streamer;
606
607         ms_debug_fenter();
608
609         ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "streamer is NULL");
610         ms_retvm_if(state == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "state is NULL");
611
612         *state = ms_streamer->state;
613
614         ms_debug_fleave();
615
616         return MEDIA_STREAMER_ERROR_NONE;
617 }
618
619 int media_streamer_set_play_position(media_streamer_h streamer, int time, bool accurate, media_streamer_position_changed_cb callback, void *user_data)
620 {
621         int ret = MEDIA_STREAMER_ERROR_NONE;
622         int duration = MS_TIME_NONE;
623         media_streamer_s *ms_streamer = (media_streamer_s *) streamer;
624
625         ms_debug_fenter();
626
627         ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "streamer is NULL");
628         ms_retvm_if(ms_streamer->state < MEDIA_STREAMER_STATE_PLAYING || ms_streamer->state > MEDIA_STREAMER_STATE_PAUSED, MEDIA_STREAMER_ERROR_INVALID_STATE, "The media streamer state is not in the appropriate state");
629         /* Notify: the seeking must be reset while streamer got ASYNC_DONE message */
630         ms_retvm_if(ms_streamer->is_seeking, MEDIA_STREAMER_ERROR_INVALID_STATE, "Media streamer is seeking");
631
632         g_mutex_lock(&ms_streamer->mutex_lock);
633
634         /* if query duration failed or returns duration value MS_TIME_NONE,
635          * we suppose that pipeline does not support seek. */
636         ret = ms_get_duration(ms_streamer, &duration);
637         if (ret == MEDIA_STREAMER_ERROR_NONE && duration != MS_TIME_NONE) {
638                 ms_streamer->seek_done_cb.callback = callback;
639                 ms_streamer->seek_done_cb.user_data = user_data;
640
641                 ret = ms_seek(streamer, time, accurate);
642         } else
643                 ret = MEDIA_STREAMER_ERROR_NOT_SUPPORTED;
644
645         g_mutex_unlock(&ms_streamer->mutex_lock);
646
647         ms_debug_fleave();
648
649         return ret;
650 }
651
652 int media_streamer_get_play_position(media_streamer_h streamer, int *time)
653 {
654         int ret = MEDIA_STREAMER_ERROR_NONE;
655         media_streamer_s *ms_streamer = (media_streamer_s *) streamer;
656
657         ms_debug_fenter();
658
659         ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "streamer is NULL");
660         ms_retvm_if(ms_streamer->state < MEDIA_STREAMER_STATE_PLAYING || ms_streamer->state > MEDIA_STREAMER_STATE_PAUSED, MEDIA_STREAMER_ERROR_INVALID_STATE, "The media streamer state is not in the appropriate state");
661
662         g_mutex_lock(&ms_streamer->mutex_lock);
663
664         ret = ms_get_position(streamer, time);
665
666         g_mutex_unlock(&ms_streamer->mutex_lock);
667
668         ms_debug_fleave();
669
670         return ret;
671 }
672
673 int media_streamer_get_duration(media_streamer_h streamer, int *duration)
674 {
675         int ret = MEDIA_STREAMER_ERROR_NONE;
676         media_streamer_s *ms_streamer = (media_streamer_s *) streamer;
677
678         ms_debug_fenter();
679
680         ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "streamer is NULL");
681         ms_retvm_if(ms_streamer->state < MEDIA_STREAMER_STATE_PLAYING || ms_streamer->state > MEDIA_STREAMER_STATE_PAUSED, MEDIA_STREAMER_ERROR_INVALID_STATE, "The media streamer state is not in the appropriate state");
682
683         g_mutex_lock(&ms_streamer->mutex_lock);
684
685         ret = ms_get_duration(streamer, duration);
686
687         g_mutex_unlock(&ms_streamer->mutex_lock);
688
689         ms_debug_fleave();
690
691         return ret;
692 }
693
694 int media_streamer_node_push_packet(media_streamer_node_h src, media_packet_h packet)
695 {
696         media_streamer_node_s *ms_node = (media_streamer_node_s *) src;
697
698         ms_debug_fenter();
699
700         ms_retvm_if(ms_node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "src is NULL");
701         ms_retvm_if(ms_node->type != MEDIA_STREAMER_NODE_TYPE_SRC, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Node type must be Src type for pushing packets.");
702         ms_retvm_if(ms_node->subtype != MEDIA_STREAMER_NODE_SRC_TYPE_CUSTOM, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Source Node must be a custom type for pushing packets.");
703
704         ms_debug_fleave();
705
706         return ms_element_push_packet(ms_node->gst_element, packet);
707 }
708
709 int media_streamer_node_pull_packet(media_streamer_node_h sink, media_packet_h *packet)
710 {
711         media_streamer_node_s *ms_node = (media_streamer_node_s *) sink;
712
713         ms_debug_fenter();
714
715         ms_retvm_if(ms_node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "sink is NULL");
716         ms_retvm_if(packet == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "packet is NULL");
717         ms_retvm_if(ms_node->gst_element == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "gst_element is NULL");
718         ms_retvm_if(ms_node->type != MEDIA_STREAMER_NODE_TYPE_SINK, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Node type must be Sink type for pulling packets.");
719         ms_retvm_if(ms_node->subtype != MEDIA_STREAMER_NODE_SINK_TYPE_CUSTOM, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Sink Node must be a custom type for pulling packets.");
720
721         ms_debug_fleave();
722
723         return ms_element_pull_packet(ms_node->gst_element, packet);
724 }
725
726 int media_streamer_node_link(media_streamer_node_h node1, const char *src_pad_name, media_streamer_node_h node2, const char *sink_pad_name)
727 {
728         int ret = MEDIA_STREAMER_ERROR_NONE;
729         media_streamer_node_s *ms_src_node = (media_streamer_node_s *) node1;
730         media_streamer_node_s *ms_dest_node = (media_streamer_node_s *) node2;
731         gboolean link_ret = FALSE;
732
733         ms_debug_fenter();
734
735         ms_retvm_if(ms_src_node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node1 is NULL");
736         ms_retvm_if(ms_dest_node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node2 is NULL");
737
738         link_ret = gst_element_link_pads(ms_src_node->gst_element, src_pad_name, ms_dest_node->gst_element, sink_pad_name);
739
740         if (!link_ret) {
741                 ms_error("Can not link [%s]:%s pad to [%s]:%s pad, ret code [%d] ", ms_src_node->name, src_pad_name, ms_dest_node->name, sink_pad_name, link_ret);
742                 ret = MEDIA_STREAMER_ERROR_INVALID_OPERATION;
743         } else {
744                 ms_info("Linked successfully [%s]:%s pad to [%s]:%s pad, ret code [%d] ", ms_src_node->name, src_pad_name, ms_dest_node->name, sink_pad_name, link_ret);
745                 ms_src_node->linked_by_user = TRUE;
746                 ms_dest_node->linked_by_user = TRUE;
747         }
748
749         ms_debug_fleave();
750
751         return ret;
752 }
753
754 int media_streamer_node_set_pad_format(media_streamer_node_h node, const char *pad_name, media_format_h fmt)
755 {
756         media_streamer_node_s *ms_node = (media_streamer_node_s *) node;
757
758         ms_debug_fenter();
759
760         ms_retvm_if(ms_node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
761         ms_retvm_if(fmt == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "fmt is NULL");
762
763         ms_debug_fleave();
764
765         /* By default it sets format to object's property 'caps' */
766         return ms_node_set_pad_format(node, pad_name, fmt);
767 }
768
769 int media_streamer_node_get_pad_format(media_streamer_node_h node, const char *pad_name, media_format_h *fmt)
770 {
771         media_streamer_node_s *ms_node = (media_streamer_node_s *) node;
772
773         ms_debug_fenter();
774
775         ms_retvm_if(ms_node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
776         ms_retvm_if(pad_name == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "pad_name is NULL");
777         ms_retvm_if(fmt == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "fmt is NULL");
778
779         ms_debug_fleave();
780
781         return ms_element_get_pad_fmt(ms_node->gst_element, pad_name, fmt);
782 }
783
784 int media_streamer_node_get_pad_name(media_streamer_node_h node, char ***src_pad_name, int *src_pad_num, char ***sink_pad_name, int *sink_pad_num)
785 {
786         int ret = MEDIA_STREAMER_ERROR_NONE;
787         media_streamer_node_s *ms_node = (media_streamer_node_s *) node;
788
789         ms_debug_fenter();
790
791         ms_retvm_if(ms_node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
792         ms_retvm_if(src_pad_name == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "src_pad_name is NULL");
793         ms_retvm_if(src_pad_num == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "src_pad_num is NULL");
794         ms_retvm_if(sink_pad_name == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "sink_pad_name is NULL");
795         ms_retvm_if(sink_pad_num == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "sink_pad_num is NULL");
796         ms_retvm_if(ms_node->gst_element == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "gst_element is NULL");
797
798         ret = ms_element_pad_names(ms_node->gst_element, GST_PAD_SRC, src_pad_name, src_pad_num);
799         ms_retvm_if(ret, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Error iterating src pads");
800
801         ret = ms_element_pad_names(ms_node->gst_element, GST_PAD_SINK, sink_pad_name, sink_pad_num);
802         ms_retvm_if(ret, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Error iterating sink pads");
803
804         ms_debug_fleave();
805
806         return ret;
807 }
808
809 int media_streamer_node_set_params(media_streamer_node_h node, bundle *param_list)
810 {
811         int ret = MEDIA_STREAMER_ERROR_NONE;
812         media_streamer_node_s *ms_node = (media_streamer_node_s *) node;
813
814         ms_debug_fenter();
815
816         ms_retvm_if(ms_node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
817         ms_retvm_if(ms_node->gst_element == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "gst_element is NULL");
818         ms_retvm_if(param_list == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "param_list is NULL");
819
820         ret = ms_node_set_params_from_bundle(ms_node, param_list);
821
822         ms_debug_fleave();
823
824         return ret;
825 }
826
827 int media_streamer_node_get_params(media_streamer_node_h node, bundle **param_list)
828 {
829         int ret = MEDIA_STREAMER_ERROR_NONE;
830         media_streamer_node_s *ms_node = (media_streamer_node_s *) node;
831         bundle *ms_params = NULL;
832
833         ms_debug_fenter();
834
835         ms_retvm_if(ms_node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
836         ms_retvm_if(param_list == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "param_list pionter is NULL");
837
838         ms_params = bundle_create();
839         ms_retvm_if(ms_params == NULL, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Error creating new params object");
840
841         ret = ms_node_write_params_into_bundle(ms_node, ms_params);
842         if (ret == MEDIA_STREAMER_ERROR_NONE)
843                 *param_list = ms_params;
844         else
845                 bundle_free(ms_params);
846
847         ms_debug_fleave();
848
849         return ret;
850 }
851
852 int media_streamer_node_set_param(media_streamer_node_h node, const char *param_name, const char *param_value)
853 {
854         int ret = MEDIA_STREAMER_ERROR_NONE;
855         media_streamer_node_s *ms_node = (media_streamer_node_s *) node;
856         param_s *param = NULL;
857
858         ms_debug_fenter();
859
860         ms_retvm_if(ms_node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
861         ms_retvm_if(ms_node->gst_element == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "gst_element is NULL");
862         ms_retvm_if(param_name == NULL || param_value == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Parameters name or value is NULL");
863
864         ret = ms_node_get_param(node, param_name, &param);
865         if (ret == MEDIA_STREAMER_ERROR_NONE)
866                 ret = ms_node_set_param_value(node, param, param_value);
867
868         ms_debug_fleave();
869
870         return ret;
871 }
872
873 int media_streamer_node_get_param(media_streamer_node_h node, const char *param_name, char **param_value)
874 {
875         int ret = MEDIA_STREAMER_ERROR_NONE;
876         media_streamer_node_s *ms_node = (media_streamer_node_s *) node;
877         param_s *param = NULL;
878
879         ms_debug_fenter();
880
881         ms_retvm_if(ms_node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
882         ms_retvm_if(param_name == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "param_name is NULL");
883         ms_retvm_if(param_value == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "param_value is NULL");
884
885         ret = ms_node_get_param(ms_node, param_name, &param);
886         if (ret == MEDIA_STREAMER_ERROR_NONE)
887                 ret = ms_node_get_param_value(ms_node, param, param_value);
888
889         ms_debug_fleave();
890
891         return ret;
892 }
893
894 int media_streamer_set_interrupted_cb(media_streamer_h streamer, media_streamer_interrupted_cb callback, void *user_data)
895 {
896         media_streamer_s *ms_streamer = (media_streamer_s *) streamer;
897
898         ms_debug_fenter();
899
900         ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "streamer is NULL");
901         ms_retvm_if(callback == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "callback is NULL");
902
903         g_mutex_lock(&ms_streamer->mutex_lock);
904
905         ms_streamer->interrupted_cb.callback = callback;
906         ms_streamer->interrupted_cb.user_data = user_data;
907
908         g_mutex_unlock(&ms_streamer->mutex_lock);
909
910         ms_debug_fleave();
911
912         return MEDIA_STREAMER_ERROR_NONE;
913 }
914
915 int media_streamer_unset_interrupted_cb(media_streamer_h streamer)
916 {
917         media_streamer_s *ms_streamer = (media_streamer_s *) streamer;
918
919         ms_debug_fenter();
920
921         ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "streamer is NULL");
922
923         g_mutex_lock(&ms_streamer->mutex_lock);
924
925         ms_streamer->interrupted_cb.callback = NULL;
926         ms_streamer->interrupted_cb.user_data = NULL;
927
928         g_mutex_unlock(&ms_streamer->mutex_lock);
929
930         ms_debug_fleave();
931
932         return MEDIA_STREAMER_ERROR_NONE;
933 }
934
935 int media_streamer_node_set_decoded_ready_cb(media_streamer_node_h node, media_streamer_node_decoded_ready_cb callback, void *user_data)
936 {
937         media_streamer_node_s *ms_node = (media_streamer_node_s *) node;
938
939         ms_debug_fenter();
940
941         ms_retvm_if(ms_node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
942         ms_retvm_if(callback == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "callback is NULL");
943
944         if (ms_node->type == MEDIA_STREAMER_NODE_TYPE_WEBRTC) {
945                 media_streamer_webrtc_callbacks_s **_callbacks = (media_streamer_webrtc_callbacks_s **)&(ms_node->callbacks_structure);
946
947                 if (!*_callbacks) {
948                         *_callbacks = (media_streamer_webrtc_callbacks_s *) calloc(1, sizeof(media_streamer_webrtc_callbacks_s));
949                         ms_retvm_if(*_callbacks == NULL, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Error allocation memory");
950                 }
951                 (*_callbacks)->decoded_ready_cb.callback = callback;
952                 (*_callbacks)->decoded_ready_cb.user_data = user_data;
953         } else {
954                 /* It can be accepted other types in the future. */
955                 ms_error("Not supported node type[%d]", ms_node->type);
956                 return MEDIA_STREAMER_ERROR_INVALID_PARAMETER;
957         }
958
959         ms_debug_fleave();
960
961         return MEDIA_STREAMER_ERROR_NONE;
962 }
963
964 int media_streamer_node_unset_decoded_ready_cb(media_streamer_node_h node)
965 {
966         media_streamer_node_s *ms_node = (media_streamer_node_s *) node;
967
968         ms_debug_fenter();
969
970         ms_retvm_if(ms_node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
971
972         if (ms_node->type == MEDIA_STREAMER_NODE_TYPE_WEBRTC) {
973                 media_streamer_webrtc_callbacks_s **_callbacks = (media_streamer_webrtc_callbacks_s **)&(ms_node->callbacks_structure);
974
975                 ms_retvm_if(*_callbacks == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "callbacks is NULL");
976                 ms_retvm_if((*_callbacks)->decoded_ready_cb.callback == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER,
977                                                                                                                 "decoded_ready_cb.callback is NULL");
978
979                 (*_callbacks)->decoded_ready_cb.callback = NULL;
980                 (*_callbacks)->decoded_ready_cb.user_data = NULL;
981
982                 if (!(*_callbacks)->message_cb.callback) {
983                         free(ms_node->callbacks_structure);
984                         ms_node->callbacks_structure = NULL;
985                 }
986         } else {
987                 /* It can be accepted other types in the future. */
988                 ms_error("Not supported node type[%d]", ms_node->type);
989                 return MEDIA_STREAMER_ERROR_INVALID_PARAMETER;
990         }
991
992         ms_debug_fleave();
993
994         return MEDIA_STREAMER_ERROR_NONE;
995 }
996
997 int media_streamer_webrtc_node_set_message_cb(media_streamer_node_h webrtc, media_streamer_webrtc_message_cb callback, void *user_data)
998 {
999         media_streamer_node_s *ms_node = (media_streamer_node_s *) webrtc;
1000         media_streamer_webrtc_callbacks_s **_callbacks;
1001
1002         ms_retvm_if(ms_node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
1003         ms_retvm_if(callback == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "callback is NULL");
1004         ms_retvm_if(ms_node->type != MEDIA_STREAMER_NODE_TYPE_WEBRTC, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is not for WebRTC");
1005
1006         ms_debug_fenter();
1007
1008         _callbacks = (media_streamer_webrtc_callbacks_s **)&(ms_node->callbacks_structure);
1009         if (!*_callbacks) {
1010                 *_callbacks = (media_streamer_webrtc_callbacks_s *) calloc(1, sizeof(media_streamer_webrtc_callbacks_s));
1011                 ms_retvm_if(*_callbacks == NULL, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Error allocation memory");
1012         }
1013
1014         (*_callbacks)->message_cb.callback = callback;
1015         (*_callbacks)->message_cb.user_data = user_data;
1016
1017         ms_debug_fleave();
1018
1019         return MEDIA_STREAMER_ERROR_NONE;
1020 }
1021
1022 int media_streamer_webrtc_node_unset_message_cb(media_streamer_node_h webrtc)
1023 {
1024         media_streamer_node_s *ms_node = (media_streamer_node_s *) webrtc;
1025         media_streamer_webrtc_callbacks_s **_callbacks;
1026
1027         ms_debug_fenter();
1028
1029         ms_retvm_if(ms_node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
1030         ms_retvm_if(ms_node->type != MEDIA_STREAMER_NODE_TYPE_WEBRTC, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is not for WebRTC");
1031
1032         _callbacks = (media_streamer_webrtc_callbacks_s **)&(ms_node->callbacks_structure);
1033
1034         ms_retvm_if(*_callbacks == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "callbacks is NULL");
1035         ms_retvm_if((*_callbacks)->message_cb.callback == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "message_cb.callback is NULL");
1036
1037         (*_callbacks)->message_cb.callback = NULL;
1038         (*_callbacks)->message_cb.user_data = NULL;
1039
1040         if (!(*_callbacks)->decoded_ready_cb.callback) {
1041                 free(ms_node->callbacks_structure);
1042                 ms_node->callbacks_structure = NULL;
1043         }
1044
1045         ms_debug_fleave();
1046
1047         return MEDIA_STREAMER_ERROR_NONE;
1048 }