2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 #include "media_streamer.h"
21 #include "media_streamer_priv.h"
22 #include "media_streamer_node.h"
23 #include "media_streamer_gst.h"
26 * Public Implementation
29 int media_streamer_node_create_src(media_streamer_node_src_type_e type, media_streamer_node_h *src)
31 int ret = MEDIA_STREAMER_ERROR_NONE;
32 media_streamer_node_s *ms_src = NULL;
36 ms_retvm_if(src == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "src is NULL");
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");
41 ms_src->type = MEDIA_STREAMER_NODE_TYPE_SRC;
42 ms_src->subtype = (media_streamer_node_src_type_e) type;
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);
51 ms_info("Source node [%s] created", ms_src->name);
52 *src = (media_streamer_node_h) ms_src;
59 int media_streamer_node_create_sink(media_streamer_node_sink_type_e type, media_streamer_node_h *sink)
61 int ret = MEDIA_STREAMER_ERROR_NONE;
62 media_streamer_node_s *ms_sink = NULL;
66 ms_retvm_if(sink == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "sink is NULL");
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");
71 ms_sink->type = MEDIA_STREAMER_NODE_TYPE_SINK;
72 ms_sink->subtype = (media_streamer_node_sink_type_e) type;
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);
81 ms_info("Sink node [%s] created", ms_sink->name);
82 *sink = (media_streamer_node_h) ms_sink;
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)
91 int ret = MEDIA_STREAMER_ERROR_NONE;
92 media_streamer_node_s *ms_node = NULL;
96 ms_retvm_if(node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
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");
101 ms_node->type = type;
102 ms_node->subtype = 0;
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);
110 ms_info("Node [%s] created", ms_node->name);
113 *node = (media_streamer_node_h) ms_node;
120 int media_streamer_node_destroy(media_streamer_node_h node)
122 media_streamer_node_s *ms_node = (media_streamer_node_s *) node;
126 ms_retvm_if(ms_node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
128 if (ms_node->parent_streamer == NULL) {
129 /* This node was not added into any media streamer */
130 ms_node_destroy(ms_node);
132 ms_error("Node destroy error: needed to remove node from media streamer before destroying.");
133 return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
138 return MEDIA_STREAMER_ERROR_NONE;
141 int media_streamer_node_remove(media_streamer_h streamer, media_streamer_node_h node)
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;
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);
155 g_mutex_lock(&ms_streamer->mutex_lock);
157 ret = ms_node_remove_from_table(ms_streamer->nodes_table, ms_node);
159 g_mutex_unlock(&ms_streamer->mutex_lock);
166 int media_streamer_node_add(media_streamer_h streamer, media_streamer_node_h node)
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;
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);
179 g_mutex_lock(&ms_streamer->mutex_lock);
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);
187 g_mutex_unlock(&ms_streamer->mutex_lock);
194 int media_streamer_prepare(media_streamer_h streamer)
196 int ret = MEDIA_STREAMER_ERROR_NONE;
197 media_streamer_s *ms_streamer = (media_streamer_s *) streamer;
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");
204 g_mutex_lock(&ms_streamer->mutex_lock);
206 ms_generate_dots(ms_streamer->pipeline, "before_prepare");
208 ret = ms_pipeline_prepare(ms_streamer);
210 ms_generate_dots(ms_streamer->pipeline, "after_prepare");
212 g_mutex_unlock(&ms_streamer->mutex_lock);
214 ms_pipeline_get_state(ms_streamer);
221 int media_streamer_unprepare(media_streamer_h streamer)
223 int ret = MEDIA_STREAMER_ERROR_NONE;
224 media_streamer_s *ms_streamer = (media_streamer_s *) streamer;
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!");
231 g_mutex_lock(&ms_streamer->mutex_lock);
233 ms_generate_dots(ms_streamer->pipeline, "before_unprepare");
235 ret = ms_pipeline_unprepare(ms_streamer);
237 ms_http_server_destroy(ms_streamer->http_server);
239 ms_generate_dots(ms_streamer->pipeline, "after_unprepare");
241 g_mutex_unlock(&ms_streamer->mutex_lock);
248 int media_streamer_play(media_streamer_h streamer)
250 int ret = MEDIA_STREAMER_ERROR_NONE;
251 media_streamer_s *ms_streamer = (media_streamer_s *) streamer;
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!");
258 g_mutex_lock(&ms_streamer->mutex_lock);
260 ret = ms_set_state(ms_streamer, MEDIA_STREAMER_STATE_PLAYING);
262 g_mutex_unlock(&ms_streamer->mutex_lock);
264 ms_pipeline_get_state(ms_streamer);
271 int media_streamer_create(media_streamer_h *streamer)
273 int ret = MEDIA_STREAMER_ERROR_NONE;
274 media_streamer_s *ms_streamer = NULL;
278 ms_retvm_if(streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "streamer is NULL");
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");
283 /* create streamer lock */
284 g_mutex_init(&ms_streamer->mutex_lock);
286 g_mutex_lock(&ms_streamer->mutex_lock);
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);
297 ms_streamer->pend_state = MEDIA_STREAMER_STATE_NONE;
298 ret = ms_set_state(ms_streamer, MEDIA_STREAMER_STATE_IDLE);
299 *streamer = ms_streamer;
301 g_mutex_unlock(&ms_streamer->mutex_lock);
303 ms_info("Media Streamer created successfully");
310 int media_streamer_destroy(media_streamer_h streamer)
312 int ret = MEDIA_STREAMER_ERROR_NONE;
313 media_streamer_s *ms_streamer = (media_streamer_s *) streamer;
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!");
320 ret = ms_destroy(ms_streamer);
327 int media_streamer_set_error_cb(media_streamer_h streamer, media_streamer_error_cb callback, void *data)
329 media_streamer_s *ms_streamer = (media_streamer_s *) streamer;
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");
336 g_mutex_lock(&ms_streamer->mutex_lock);
338 ms_streamer->error_cb.callback = callback;
339 ms_streamer->error_cb.user_data = data;
341 g_mutex_unlock(&ms_streamer->mutex_lock);
345 return MEDIA_STREAMER_ERROR_NONE;
348 int media_streamer_unset_error_cb(media_streamer_h streamer)
350 media_streamer_s *ms_streamer = (media_streamer_s *) streamer;
354 ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "streamer is NULL");
356 g_mutex_lock(&ms_streamer->mutex_lock);
358 ms_streamer->error_cb.callback = NULL;
359 ms_streamer->error_cb.user_data = NULL;
361 g_mutex_unlock(&ms_streamer->mutex_lock);
365 return MEDIA_STREAMER_ERROR_NONE;
368 int media_streamer_set_state_change_cb(media_streamer_h streamer, media_streamer_state_changed_cb callback, void *data)
370 media_streamer_s *ms_streamer = (media_streamer_s *) streamer;
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");
377 g_mutex_lock(&ms_streamer->mutex_lock);
379 ms_streamer->state_changed_cb.callback = callback;
380 ms_streamer->state_changed_cb.user_data = data;
382 g_mutex_unlock(&ms_streamer->mutex_lock);
386 return MEDIA_STREAMER_ERROR_NONE;
389 int media_streamer_unset_state_change_cb(media_streamer_h streamer)
391 media_streamer_s *ms_streamer = (media_streamer_s *) streamer;
395 ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "streamer is NULL");
397 g_mutex_lock(&ms_streamer->mutex_lock);
399 ms_streamer->state_changed_cb.callback = NULL;
400 ms_streamer->state_changed_cb.user_data = NULL;
402 g_mutex_unlock(&ms_streamer->mutex_lock);
406 return MEDIA_STREAMER_ERROR_NONE;
409 int media_streamer_src_set_buffer_status_cb(media_streamer_node_h src, media_streamer_custom_buffer_status_cb callback, void *user_data)
411 media_streamer_node_s *ms_src = (media_streamer_node_s *) src;
412 media_streamer_callback_s *src_callback = NULL;
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");
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");
423 src_callback = (media_streamer_callback_s *) ms_src->callbacks_structure;
426 src_callback->callback = callback;
427 src_callback->user_data = user_data;
429 ms_src->callbacks_structure = (void *)src_callback;
433 return MEDIA_STREAMER_ERROR_NONE;
436 int media_streamer_src_unset_buffer_status_cb(media_streamer_node_h src)
438 media_streamer_node_s *ms_src = (media_streamer_node_s *) src;
442 ms_retvm_if(ms_src == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "source is NULL");
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;
450 return MEDIA_STREAMER_ERROR_NONE;
453 int media_streamer_sink_set_data_ready_cb(media_streamer_node_h sink, media_streamer_sink_data_ready_cb callback, void *data)
455 media_streamer_node_s *ms_sink = (media_streamer_node_s *) sink;
456 media_streamer_sink_callbacks_s *sink_callbacks = NULL;
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");
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");
469 sink_callbacks->data_ready_cb.callback = callback;
470 sink_callbacks->data_ready_cb.user_data = data;
472 ms_sink->callbacks_structure = (void *)sink_callbacks;
476 return MEDIA_STREAMER_ERROR_NONE;
479 int media_streamer_sink_unset_data_ready_cb(media_streamer_node_h sink)
481 media_streamer_node_s *ms_sink = (media_streamer_node_s *) sink;
482 media_streamer_sink_callbacks_s *sink_callbacks = NULL;
486 ms_retvm_if(ms_sink == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "sink is NULL");
488 sink_callbacks = ms_sink->callbacks_structure;
489 ms_retvm_if(sink_callbacks == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Callback didn't set yet");
491 sink_callbacks->data_ready_cb.callback = NULL;
492 sink_callbacks->data_ready_cb.user_data = NULL;
494 ms_sink->callbacks_structure = (void *)sink_callbacks;
498 return MEDIA_STREAMER_ERROR_NONE;
501 int media_streamer_sink_set_eos_cb(media_streamer_node_h sink, media_streamer_sink_eos_cb callback, void *data)
503 media_streamer_node_s *ms_sink = (media_streamer_node_s *) sink;
504 media_streamer_sink_callbacks_s *sink_callbacks = NULL;
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");
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");
517 sink_callbacks->eos_cb.callback = callback;
518 sink_callbacks->eos_cb.user_data = data;
520 ms_sink->callbacks_structure = (void *)sink_callbacks;
524 return MEDIA_STREAMER_ERROR_NONE;
527 int media_streamer_sink_unset_eos_cb(media_streamer_node_h sink)
529 media_streamer_node_s *ms_sink = (media_streamer_node_s *) sink;
530 media_streamer_sink_callbacks_s *sink_callbacks = NULL;
534 ms_retvm_if(ms_sink == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "sink is NULL");
536 sink_callbacks = ms_sink->callbacks_structure;
537 ms_retvm_if(sink_callbacks == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Callback didn't set yet");
539 sink_callbacks->data_ready_cb.callback = NULL;
540 sink_callbacks->data_ready_cb.user_data = NULL;
542 ms_sink->callbacks_structure = (void *)sink_callbacks;
546 return MEDIA_STREAMER_ERROR_NONE;
549 int media_streamer_pause(media_streamer_h streamer)
551 int ret = MEDIA_STREAMER_ERROR_NONE;
552 media_streamer_s *ms_streamer = (media_streamer_s *) streamer;
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.");
560 g_mutex_lock(&ms_streamer->mutex_lock);
562 ret = ms_set_state(ms_streamer, MEDIA_STREAMER_STATE_PAUSED);
564 g_mutex_unlock(&ms_streamer->mutex_lock);
566 ms_pipeline_get_state(ms_streamer);
573 int media_streamer_stop(media_streamer_h streamer)
575 int ret = MEDIA_STREAMER_ERROR_NONE;
576 media_streamer_s *ms_streamer = (media_streamer_s *) streamer;
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.");
583 g_mutex_lock(&ms_streamer->mutex_lock);
585 ret = ms_seek(streamer, 0, FALSE);
587 if (ret != MEDIA_STREAMER_ERROR_NONE)
588 ms_error("Error while putting media streamer to zero playing position");
590 ret = ms_set_state(ms_streamer, MEDIA_STREAMER_STATE_PAUSED);
592 ms_http_server_stop(ms_streamer->http_server);
594 g_mutex_unlock(&ms_streamer->mutex_lock);
596 ms_pipeline_get_state(ms_streamer);
603 int media_streamer_get_state(media_streamer_h streamer, media_streamer_state_e *state)
605 media_streamer_s *ms_streamer = (media_streamer_s *) streamer;
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");
612 *state = ms_streamer->state;
616 return MEDIA_STREAMER_ERROR_NONE;
619 int media_streamer_set_play_position(media_streamer_h streamer, int time, bool accurate, media_streamer_position_changed_cb callback, void *user_data)
621 int ret = MEDIA_STREAMER_ERROR_NONE;
622 int duration = MS_TIME_NONE;
623 media_streamer_s *ms_streamer = (media_streamer_s *) streamer;
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");
632 g_mutex_lock(&ms_streamer->mutex_lock);
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;
641 ret = ms_seek(streamer, time, accurate);
643 ret = MEDIA_STREAMER_ERROR_NOT_SUPPORTED;
645 g_mutex_unlock(&ms_streamer->mutex_lock);
652 int media_streamer_get_play_position(media_streamer_h streamer, int *time)
654 int ret = MEDIA_STREAMER_ERROR_NONE;
655 media_streamer_s *ms_streamer = (media_streamer_s *) streamer;
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");
662 g_mutex_lock(&ms_streamer->mutex_lock);
664 ret = ms_get_position(streamer, time);
666 g_mutex_unlock(&ms_streamer->mutex_lock);
673 int media_streamer_get_duration(media_streamer_h streamer, int *duration)
675 int ret = MEDIA_STREAMER_ERROR_NONE;
676 media_streamer_s *ms_streamer = (media_streamer_s *) streamer;
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");
683 g_mutex_lock(&ms_streamer->mutex_lock);
685 ret = ms_get_duration(streamer, duration);
687 g_mutex_unlock(&ms_streamer->mutex_lock);
694 int media_streamer_node_push_packet(media_streamer_node_h src, media_packet_h packet)
696 media_streamer_node_s *ms_node = (media_streamer_node_s *) src;
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.");
706 return ms_element_push_packet(ms_node->gst_element, packet);
709 int media_streamer_node_pull_packet(media_streamer_node_h sink, media_packet_h *packet)
711 media_streamer_node_s *ms_node = (media_streamer_node_s *) sink;
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.");
723 return ms_element_pull_packet(ms_node->gst_element, packet);
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)
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;
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");
738 link_ret = gst_element_link_pads(ms_src_node->gst_element, src_pad_name, ms_dest_node->gst_element, sink_pad_name);
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;
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;
754 int media_streamer_node_set_pad_format(media_streamer_node_h node, const char *pad_name, media_format_h fmt)
756 media_streamer_node_s *ms_node = (media_streamer_node_s *) node;
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");
765 /* By default it sets format to object's property 'caps' */
766 return ms_node_set_pad_format(node, pad_name, fmt);
769 int media_streamer_node_get_pad_format(media_streamer_node_h node, const char *pad_name, media_format_h *fmt)
771 media_streamer_node_s *ms_node = (media_streamer_node_s *) node;
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");
781 return ms_element_get_pad_fmt(ms_node->gst_element, pad_name, fmt);
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)
786 int ret = MEDIA_STREAMER_ERROR_NONE;
787 media_streamer_node_s *ms_node = (media_streamer_node_s *) node;
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");
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");
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");
809 int media_streamer_node_set_params(media_streamer_node_h node, bundle *param_list)
811 int ret = MEDIA_STREAMER_ERROR_NONE;
812 media_streamer_node_s *ms_node = (media_streamer_node_s *) node;
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");
820 ret = ms_node_set_params_from_bundle(ms_node, param_list);
827 int media_streamer_node_get_params(media_streamer_node_h node, bundle **param_list)
829 int ret = MEDIA_STREAMER_ERROR_NONE;
830 media_streamer_node_s *ms_node = (media_streamer_node_s *) node;
831 bundle *ms_params = NULL;
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");
838 ms_params = bundle_create();
839 ms_retvm_if(ms_params == NULL, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Error creating new params object");
841 ret = ms_node_write_params_into_bundle(ms_node, ms_params);
842 if (ret == MEDIA_STREAMER_ERROR_NONE)
843 *param_list = ms_params;
845 bundle_free(ms_params);
852 int media_streamer_node_set_param(media_streamer_node_h node, const char *param_name, const char *param_value)
854 int ret = MEDIA_STREAMER_ERROR_NONE;
855 media_streamer_node_s *ms_node = (media_streamer_node_s *) node;
856 param_s *param = NULL;
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");
864 ret = ms_node_get_param(node, param_name, ¶m);
865 if (ret == MEDIA_STREAMER_ERROR_NONE)
866 ret = ms_node_set_param_value(node, param, param_value);
873 int media_streamer_node_get_param(media_streamer_node_h node, const char *param_name, char **param_value)
875 int ret = MEDIA_STREAMER_ERROR_NONE;
876 media_streamer_node_s *ms_node = (media_streamer_node_s *) node;
877 param_s *param = NULL;
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");
885 ret = ms_node_get_param(ms_node, param_name, ¶m);
886 if (ret == MEDIA_STREAMER_ERROR_NONE)
887 ret = ms_node_get_param_value(ms_node, param, param_value);
894 int media_streamer_set_interrupted_cb(media_streamer_h streamer, media_streamer_interrupted_cb callback, void *user_data)
896 media_streamer_s *ms_streamer = (media_streamer_s *) streamer;
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");
903 g_mutex_lock(&ms_streamer->mutex_lock);
905 ms_streamer->interrupted_cb.callback = callback;
906 ms_streamer->interrupted_cb.user_data = user_data;
908 g_mutex_unlock(&ms_streamer->mutex_lock);
912 return MEDIA_STREAMER_ERROR_NONE;
915 int media_streamer_unset_interrupted_cb(media_streamer_h streamer)
917 media_streamer_s *ms_streamer = (media_streamer_s *) streamer;
921 ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "streamer is NULL");
923 g_mutex_lock(&ms_streamer->mutex_lock);
925 ms_streamer->interrupted_cb.callback = NULL;
926 ms_streamer->interrupted_cb.user_data = NULL;
928 g_mutex_unlock(&ms_streamer->mutex_lock);
932 return MEDIA_STREAMER_ERROR_NONE;
935 int media_streamer_node_set_decoded_ready_cb(media_streamer_node_h node, media_streamer_node_decoded_ready_cb callback, void *user_data)
937 media_streamer_node_s *ms_node = (media_streamer_node_s *) node;
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");
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);
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");
951 (*_callbacks)->decoded_ready_cb.callback = callback;
952 (*_callbacks)->decoded_ready_cb.user_data = user_data;
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;
961 return MEDIA_STREAMER_ERROR_NONE;
964 int media_streamer_node_unset_decoded_ready_cb(media_streamer_node_h node)
966 media_streamer_node_s *ms_node = (media_streamer_node_s *) node;
970 ms_retvm_if(ms_node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
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);
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");
979 (*_callbacks)->decoded_ready_cb.callback = NULL;
980 (*_callbacks)->decoded_ready_cb.user_data = NULL;
982 if (!(*_callbacks)->message_cb.callback) {
983 free(ms_node->callbacks_structure);
984 ms_node->callbacks_structure = NULL;
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;
994 return MEDIA_STREAMER_ERROR_NONE;
997 int media_streamer_webrtc_node_set_message_cb(media_streamer_node_h webrtc, media_streamer_webrtc_message_cb callback, void *user_data)
999 media_streamer_node_s *ms_node = (media_streamer_node_s *) webrtc;
1000 media_streamer_webrtc_callbacks_s **_callbacks;
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");
1008 _callbacks = (media_streamer_webrtc_callbacks_s **)&(ms_node->callbacks_structure);
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");
1014 (*_callbacks)->message_cb.callback = callback;
1015 (*_callbacks)->message_cb.user_data = user_data;
1019 return MEDIA_STREAMER_ERROR_NONE;
1022 int media_streamer_webrtc_node_unset_message_cb(media_streamer_node_h webrtc)
1024 media_streamer_node_s *ms_node = (media_streamer_node_s *) webrtc;
1025 media_streamer_webrtc_callbacks_s **_callbacks;
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");
1032 _callbacks = (media_streamer_webrtc_callbacks_s **)&(ms_node->callbacks_structure);
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");
1037 (*_callbacks)->message_cb.callback = NULL;
1038 (*_callbacks)->message_cb.user_data = NULL;
1040 if (!(*_callbacks)->decoded_ready_cb.callback) {
1041 free(ms_node->callbacks_structure);
1042 ms_node->callbacks_structure = NULL;
1047 return MEDIA_STREAMER_ERROR_NONE;