add mediastreamer initial code 43/40843/1 submit/tizen/20150610.042729
authoreunhae1.choi <eunhae1.choi@samsung.com>
Tue, 9 Jun 2015 14:09:38 +0000 (23:09 +0900)
committereunhae1.choi <eunhae1.choi@samsung.com>
Tue, 9 Jun 2015 14:09:38 +0000 (23:09 +0900)
Change-Id: Ic121e5611599539451f0e7f8896a845e84e58b81

20 files changed:
AUTHORS [new file with mode: 0755]
CMakeLists.txt [new file with mode: 0755]
LICENSE.APLv2 [new file with mode: 0755]
NOTICE [new file with mode: 0755]
capi-media-streamer.pc.in [new file with mode: 0755]
doc/mediastreamer_doc.h [new file with mode: 0755]
include/media_streamer.h [new file with mode: 0755]
include/media_streamer_gst.h [new file with mode: 0755]
include/media_streamer_node.h [new file with mode: 0755]
include/media_streamer_priv.h [new file with mode: 0755]
include/media_streamer_util.h [new file with mode: 0755]
packaging/capi-media-streamer.manifest [new file with mode: 0755]
packaging/capi-media-streamer.spec [new file with mode: 0755]
src/media_streamer.c [new file with mode: 0755]
src/media_streamer_gst.c [new file with mode: 0755]
src/media_streamer_node.c [new file with mode: 0755]
src/media_streamer_priv.c [new file with mode: 0755]
src/media_streamer_util.c [new file with mode: 0755]
test/CMakeLists.txt [new file with mode: 0755]
test/media_streamer_test.c [new file with mode: 0755]

diff --git a/AUTHORS b/AUTHORS
new file mode 100755 (executable)
index 0000000..a0cc6e6
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,4 @@
+Eunhae Choi <eunhae1.chohi@samsung.com>
+Oleg Kopysov <o.kopysov@samsung.com>
+Andrey Shelest <a.shelest@samsung.com>
+Vyacheslav Valkovoy <v.valkovoy@samsung.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..df8d4a5
--- /dev/null
@@ -0,0 +1,104 @@
+
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+SET(fw_name "capi-media-streamer")
+
+PROJECT(${fw_name})
+
+SET(CMAKE_INSTALL_PREFIX /usr)
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+
+SET(INC_DIR include)
+INCLUDE_DIRECTORIES(${INC_DIR})
+
+SET(dependents "dlog glib-2.0 mm-common capi-media-tool iniparser bundle libtbm gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-app-1.0" )
+SET(pc_dependents "capi-base-common capi-media-tool gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-app-1.0" )
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(${fw_name} REQUIRED ${dependents})
+FOREACH(flag ${${fw_name}_CFLAGS})
+    SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "-I./include -I./include/headers ${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall")
+SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
+
+IF("${ARCH}" STREQUAL "arm")
+    ADD_DEFINITIONS("-DTARGET")
+ENDIF("${ARCH}" STREQUAL "arm")
+
+ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
+ADD_DEFINITIONS("-DTIZEN_DEBUG")
+
+SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -Wl,--rpath=/usr/lib")
+
+AUX_SOURCE_DIRECTORY (src MAIN_SRC)
+
+LIST (APPEND SOURCES
+     ${MAIN_SRC}
+     )
+
+ADD_LIBRARY(${fw_name} SHARED ${SOURCES})
+
+TARGET_LINK_LIBRARIES(${fw_name} ${${fw_name}_LDFLAGS})
+
+SET_TARGET_PROPERTIES(${fw_name}
+     PROPERTIES
+     VERSION ${FULLVER}
+     SOVERSION ${MAJORVER}
+     CLEAN_DIRECT_OUTPUT 1
+)
+
+INSTALL(TARGETS ${fw_name} DESTINATION lib)
+INSTALL(
+        DIRECTORY ${INC_DIR}/ DESTINATION include/media
+        FILES_MATCHING
+        PATTERN "media_streamer_*.h" EXCLUDE
+        PATTERN "${INC_DIR}/*.h"
+        )
+
+
+SET(PC_NAME ${fw_name})
+SET(PC_REQUIRED ${pc_dependents})
+SET(PC_LDFLAGS -l${fw_name})
+SET(PC_CFLAGS -I\${includedir}/media)
+
+CONFIGURE_FILE(
+    ${fw_name}.pc.in
+    ${CMAKE_CURRENT_SOURCE_DIR}/${fw_name}.pc
+    @ONLY
+)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${fw_name}.pc DESTINATION lib/pkgconfig)
+
+ADD_SUBDIRECTORY(test)
+
+IF(UNIX)
+
+ADD_CUSTOM_TARGET (distclean @echo cleaning for source distribution)
+ADD_CUSTOM_COMMAND(
+        DEPENDS clean
+        COMMENT "distribution clean"
+        COMMAND find
+        ARGS    .
+        -not -name config.cmake -and \(
+        -name tester.c -or
+        -name Testing -or
+        -name CMakeFiles -or
+        -name cmake.depends -or
+        -name cmake.check_depends -or
+        -name CMakeCache.txt -or
+        -name cmake.check_cache -or
+        -name *.cmake -or
+        -name Makefile -or
+        -name core -or
+        -name core.* -or
+        -name gmon.out -or
+        -name install_manifest.txt -or
+        -name *.pc -or
+        -name *~ \)
+        | grep -v TC | xargs rm -rf
+        TARGET  distclean
+        VERBATIM
+)
+
+ENDIF(UNIX)
+
diff --git a/LICENSE.APLv2 b/LICENSE.APLv2
new file mode 100755 (executable)
index 0000000..a06208b
--- /dev/null
@@ -0,0 +1,204 @@
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
diff --git a/NOTICE b/NOTICE
new file mode 100755 (executable)
index 0000000..ccdad52
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,3 @@
+Copyright (c) Samsung Electronics Co., Ltd. All rights reserved.
+Except as noted, this software is licensed under Apache License, Version 2.
+Please, see the LICENSE file for Apache License terms and conditions.
diff --git a/capi-media-streamer.pc.in b/capi-media-streamer.pc.in
new file mode 100755 (executable)
index 0000000..0da82e4
--- /dev/null
@@ -0,0 +1,11 @@
+prefix = @prefix@
+exec_prefix=@exec_prefix@
+libdir = @libdir@
+includedir = @includedir@
+
+Name : mediastreamer
+Description : Multimedia Framework MediaStreamer Library
+Requires : mm-common
+Version : @VERSION@
+Libs : -L${libdir} -lmmfstreamer
+Cflags : -I${includedir}/mmf
diff --git a/doc/mediastreamer_doc.h b/doc/mediastreamer_doc.h
new file mode 100755 (executable)
index 0000000..c050b94
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __TIZEN_MEDIASTREAMER_DOC_H__
+#define __TIZEN_MEDIASTREAMER_DOC_H__
+
+/**
+ * @file mediastreamer_doc.h
+ * @brief This file contains high level documentation of the CAPI MEDIA STREAMER API.
+ */
+
+/**
+ * @ingroup CAPI_MEDIA_FRAMEWORK
+ * @defgroup CAPI_MEDIA_MEDIASTREAMER_MODULE Media Streamer
+ * @brief  The @ref CAPI_MEDIA_MEDIASTREAMER_MODULE  APIs provides functions for building custom pipeline
+ *
+ * @section CAPI_MEDIA_MEDIASTREAMER_MODULE_HEADER Required Header
+ *   \#include <media_streamer.h>
+ *
+ * @section CAPI_MEDIASTREAMER_MODULE_OVERVIEW Overview
+ *
+ * MEDIASTREAMER allows :
+ * Create streamer handle and elements to build custom pipeline.
+ * Application can create, add and link elements manually.
+ *
+ */
+
+#endif  /* __TIZEN_MEDIASTREAMER_DOC_H__ */
diff --git a/include/media_streamer.h b/include/media_streamer.h
new file mode 100755 (executable)
index 0000000..5fd99f8
--- /dev/null
@@ -0,0 +1,926 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __TIZEN_MEDIASTREAMER_H__
+#define __TIZEN_MEDIASTREAMER_H__
+
+#include <tizen.h>
+#include <bundle.h>
+#include <mm_message.h>
+#include <media_format.h>
+#include <media_packet.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#ifndef TIZEN_ERROR_MEDIA_STREAMER
+#define TIZEN_ERROR_MEDIA_STREAMER -0x03000000
+#endif
+
+/**
+* @file media_streamer.h
+* @brief This file contains the capi media streamer API.
+*/
+
+/**
+* @addtogroup CAPI_MEDIASTREAMER_MODULE
+* @{
+*/
+
+/**
+ * @brief Media Streamer handle type.
+ *
+ * @since_tizen 3.0
+ */
+typedef void *media_streamer_h;
+
+/**
+ * @brief Media Streamer node handle type.
+ *
+ * @since_tizen 3.0
+ */
+typedef void *media_streamer_node_h;
+
+/**
+ * @brief Media streamer time type.
+ *
+ * @since_tizen 3.0
+ */
+typedef long long media_streamer_time_value;
+
+/**
+ * @brief Enumeration for media streamer node type.
+ *
+ * @since_tizen 3.0
+ */
+typedef enum
+{
+       MEDIA_STREAMER_NODE_TYPE_NONE,                 /**<  Not defined type */
+       MEDIA_STREAMER_NODE_TYPE_SRC,                  /**<  Src node type */
+       MEDIA_STREAMER_NODE_TYPE_SINK,                 /**<  Sink node type */
+       MEDIA_STREAMER_NODE_TYPE_VIDEO_ENCODER,        /**<  Video encoder node type */
+       MEDIA_STREAMER_NODE_TYPE_VIDEO_DECODER,        /**<  Video decoder node type */
+       MEDIA_STREAMER_NODE_TYPE_AUDIO_ENCODER,        /**<  Audio encoder node type */
+       MEDIA_STREAMER_NODE_TYPE_AUDIO_DECODER,        /**<  Audio decoder node type */
+       MEDIA_STREAMER_NODE_TYPE_VIDEO_CONVERTER,      /**<  Video converter node type */
+       MEDIA_STREAMER_NODE_TYPE_AUDIO_CONVERTER,      /**<  Audio converter node type */
+       MEDIA_STREAMER_NODE_TYPE_AUDIO_RESAMPLE,       /**<  Audio resample node type */
+       MEDIA_STREAMER_NODE_TYPE_VIDEO_PAY,            /**<  Rtp video payloader */
+       MEDIA_STREAMER_NODE_TYPE_AUDIO_PAY,            /**<  Rtp audio payloader */
+       MEDIA_STREAMER_NODE_TYPE_VIDEO_DEPAY,          /**<  Rtp video depayloader */
+       MEDIA_STREAMER_NODE_TYPE_AUDIO_DEPAY,          /**<  Rtp audio depayloader */
+       MEDIA_STREAMER_NODE_TYPE_PARSER,               /**<  Parser node type */
+       MEDIA_STREAMER_NODE_TYPE_FILTER,               /**<  Filter node type, to limit formats of data */
+       MEDIA_STREAMER_NODE_TYPE_TEE,                  /**<  Tee node type, splits data to multiple path */
+       MEDIA_STREAMER_NODE_TYPE_QUEUE,                /**<  Queue node type */
+       MEDIA_STREAMER_NODE_TYPE_MQUEUE,               /**<  Multiple data queue node type */
+       MEDIA_STREAMER_NODE_TYPE_MUXER,                /**<  Muxer node type */
+       MEDIA_STREAMER_NODE_TYPE_DEMUXER,              /**<  Demuxer node type */
+       MEDIA_STREAMER_NODE_TYPE_RTP,                  /**<  Rtp component to send and receive data */
+       MEDIA_STREAMER_NODE_TYPE_INPUT_SELECTOR,       /**<  N-to-1 input stream selector */
+       MEDIA_STREAMER_NODE_TYPE_OUTPUT_SELECTOR,      /**<  1-to-N output stream selector */
+       MEDIA_STREAMER_NODE_TYPE_INTERLEAVE,           /**<  Folds many mono channel into one interleaved audio stream */
+       MEDIA_STREAMER_NODE_TYPE_DEINTERLEAVE          /**<  Splits multi channel audio into many mono audio */
+} media_streamer_node_type_e;
+
+/**
+ * @brief Enumeration for media streamer source node type.
+ *
+ * @since_tizen 3.0
+ */
+typedef enum
+{
+       MEDIA_STREAMER_SRC_TYPE_NONE,           /**<  Not defined src type */
+       MEDIA_STREAMER_SRC_TYPE_FILE,           /**<  Local file src type */
+       MEDIA_STREAMER_SRC_TYPE_HTTP,           /**<  Http src type */
+       MEDIA_STREAMER_SRC_TYPE_RTSP,           /**<  Rtsp src type */
+       MEDIA_STREAMER_SRC_TYPE_CAMERA,         /**<  Camera src type */
+       MEDIA_STREAMER_SRC_TYPE_AUDIO_CAPTURE,  /**<  Audio capture src type */
+       MEDIA_STREAMER_SRC_TYPE_VIDEO_CAPTURE,  /**<  Video capture src type */
+       MEDIA_STREAMER_SRC_TYPE_AUDIO_TEST,     /**<  Audio test src type */
+       MEDIA_STREAMER_SRC_TYPE_VIDEO_TEST,     /**<  Video test src type */
+       MEDIA_STREAMER_SRC_TYPE_CUSTOM          /**<  Custom src type */
+} media_streamer_src_type_e;
+
+/**
+ * @brief Enumeration for media streamer sink node type.
+ *
+ * @since_tizen 3.0
+ */
+typedef enum
+{
+       MEDIA_STREAMER_SINK_TYPE_NONE,   /**<  Not defined sink type */
+       MEDIA_STREAMER_SINK_TYPE_FILE,   /**<  Local file sink type */
+       MEDIA_STREAMER_SINK_TYPE_RTSP,   /**<  Rtsp sink type */
+       MEDIA_STREAMER_SINK_TYPE_HTTP,   /**<  Http sink type */
+       MEDIA_STREAMER_SINK_TYPE_AUDIO,  /**<  Audio sink type */
+       MEDIA_STREAMER_SINK_TYPE_SCREEN, /**<  Screen sink type */
+       MEDIA_STREAMER_SINK_TYPE_FAKE,   /**<  Fake sink type */
+       MEDIA_STREAMER_SINK_TYPE_CUSTOM  /**<  Custom sink type */
+} media_streamer_sink_type_e;
+
+/**
+ * @brief Enumeration for media streamer state.
+ *
+ * @since_tizen 3.0
+ */
+typedef enum
+{
+       MEDIA_STREAMER_STATE_NONE,    /**<  Streamer is not created */
+       MEDIA_STREAMER_STATE_IDLE,    /**<  Streamer is created but not prepared */
+       MEDIA_STREAMER_STATE_READY,   /**<  Streamer is ready to play */
+       MEDIA_STREAMER_STATE_PLAYING, /**<  Streamer is playing */
+       MEDIA_STREAMER_STATE_PAUSED,  /**<  Streamer is paused */
+       MEDIA_STREAMER_STATE_SEEKING  /**<  Seek is under operation */
+} media_streamer_state_e;
+
+/**
+ * @brief Enumeration for media streamer error.
+ *
+ * @since_tizen 3.0
+ */
+typedef enum
+{
+       MEDIA_STREAMER_ERROR_NONE = TIZEN_ERROR_NONE,                                        /**< Successful */
+       MEDIA_STREAMER_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER,              /**< Invalid parameter */
+       MEDIA_STREAMER_ERROR_INVALID_OPERATION  = TIZEN_ERROR_INVALID_OPERATION,             /**< Invalid operation */
+       MEDIA_STREAMER_ERROR_FILE_NO_SPACE_ON_DEVICE = TIZEN_ERROR_FILE_NO_SPACE_ON_DEVICE,  /**< No space left on the device */
+       MEDIA_STREAMER_ERROR_NOT_SUPPORTED  = TIZEN_ERROR_NOT_SUPPORTED,                     /**< Not supported */
+       MEDIA_STREAMER_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED,              /**< Permission denied */
+       MEDIA_STREAMER_ERROR_INVALID_STATE = TIZEN_ERROR_MEDIA_STREAMER|0x01,                /**< Invalid state */
+       MEDIA_STREAMER_ERROR_CONNECTION_FAILED = TIZEN_ERROR_MEDIA_STREAMER|0x02,            /**< Connection failed */
+       MEDIA_STREAMER_ERROR_RESOURCE_CONFLICT = TIZEN_ERROR_MEDIA_STREAMER|0x03,            /**< Resource conflict */
+} media_streamer_error_e;
+
+/**
+ * @brief Enumeration of media streamer buffer status of custom src
+ *
+ * @since_tizen 3.0
+ */
+typedef enum
+{
+    MEDIA_STREAMER_CUSTOM_BUFFER_UNDERRUN,     /**< buffer underrun of custom src */
+    MEDIA_STREAMER_CUSTOM_BUFFER_OVERFLOW,     /**< buffer overflow of custom src */
+} media_streamer_custom_buffer_status_e;
+
+/**
+ * @brief Called when error occurs in media streamer.
+ * @since_tizen 3.0
+ * @param [in] streamer    Media streamer handle
+ * @param [in] error       The error that occurred in media steamer
+ * @param [in] user_data   The user data passed from the code where
+ *                         media_streamer_set_error_cb() was invoked
+ *                         This data will be accessible from @a media_streamer_error_cb
+ * @pre Create media streamer handle by calling media_streamer_create() function
+ * @see media_streamer_set_error_cb()
+ * @see media_streamer_unset_error_cb()
+ */
+typedef void (*media_streamer_error_cb)(media_streamer_h streamer,
+                               media_streamer_error_e error,
+                               void *user_data);
+
+/**
+ * @brief Called when media streamer state was changed.
+ * @since_tizen 3.0
+ * @param [in] streamer            Media streamer handle
+ * @param [in] previous_state      The previous state of the media steamer
+ * @param [in] current_state       The current state of media streamer
+ * @param [in] user_data           The user data passed from the code where
+ *                                 media_streamer_set_state_changed_cb() was invoked
+ *                                 This data will be accessible from @a media_streamer_state_changed_cb
+ * @pre Create media streamer handle by calling media_streamer_create() function
+ * @see media_streamer_set_state_change_cb()
+ * @see media_streamer_unset_state_change_cb()
+ */
+typedef void (*media_streamer_state_changed_cb)(media_streamer_h streamer,
+                               media_streamer_state_e previous_state,
+                               media_streamer_state_e current_state,
+                               void *user_data);
+
+/**
+ * @brief Called when the custom source needs more data or has enough data.
+ * @details This callback will be invoked when the buffer level drops below the threshold of max size
+ *          or no free space in custom source buffer.
+ * @since_tizen 3.0
+ * @remarks Callback can be applied only for MEDIA_STREAMER_SRC_TYPE_CUSTOM source type
+ * @param [in] node      Media streamer source node handle
+ * @param [in] user_data The user data passed from the callback registration function
+ * @see media_streamer_src_set_buffer_status_cb()
+ * @see media_streamer_node_get_param_list()
+ * @see media_streamer_node_set_params()
+ */
+typedef void (*media_streamer_custom_buffer_status_cb) (media_streamer_node_h node,
+                               media_streamer_custom_buffer_status_e status,
+                               void *user_data);
+
+/**
+ * @brief Called when new data is available from custom sink.
+ * @details This callback can be applied only to MEDIA_STREAMER_SINK_TYPE_CUSTOM sink type
+ * @since_tizen 3.0
+ * @param [in] node      Media streamer sink node handle
+ * @param [in] user_data The user data passed from the code where
+ *                       media_streamer_sink_set_data_ready_cb() was invoked
+ *                       This data will be accessible from @a media_streamer_sink_data_ready_cb
+ * @pre media_streamer_sink_set_data_ready_cb()
+ * @see MEDIA_STREAMER_SINK_TYPE_CUSTOM
+ * @see media_streamer_sink_set_data_ready_cb()
+ * @see media_streamer_sink_unset_data_ready_cb()
+ */
+typedef void (*media_streamer_sink_data_ready_cb)(media_streamer_node_h node,
+                               void *user_data);
+
+/**
+ * @brief  Called when the end-of-stream has been reached.
+ * @details This callback can be applied only to MEDIA_STREAMER_SINK_TYPE_CUSTOM sink type
+ * @since_tizen 3.0
+ * @param [in] node      Media streamer sink node handle
+ * @param [in] user_data The user data passed from the code where
+ *                       media_streamer_sink_set_eos_cb() was invoked
+ *                       This data will be accessible from @a media_streamer_sink_eos_cb
+ * @pre media_streamer_sink_set_eos_cb()
+ * @see MEDIA_STREAMER_SINK_TYPE_CUSTOM
+ * @see media_streamer_sink_set_eos_cb()
+ * @see media_streamer_sink_unset_eos_cb()
+ */
+typedef void (*media_streamer_sink_eos_cb)(media_streamer_node_h node,
+                               void *user_data);
+
+/**
+ * @brief Register a error callback function to be invoked when an error occurs.
+ * @since_tizen 3.0
+ * @param [in] streamer  Media streamer handle
+ * @param [in] callback  Callback function pointer
+ * @param [in] user_data The user data passed from the code where
+ *                       media_streamer_set_error_cb() was invoked
+ *                       This data will be accessible from @a media_streamer_error_cb
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #MEDIA_STREAMER_ERROR_NONE Successful
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_STATE Invalid state
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_OPERATION Invalid operation
+ * @pre Create a media streamer handle by calling media_streamer_create() function
+ * @post media_streamer_error_cb() will be invoked.
+ * @see media_streamer_unset_error_cb()
+ * @see media_streamer_error_cb()
+ */
+int media_streamer_set_error_cb(media_streamer_h streamer,
+                               media_streamer_error_cb callback,
+                               void *user_data);
+
+/**
+ * @brief Unregisters the error callback function.
+ * @since_tizen 3.0
+ * @param [in] streamer  Media streamer handle
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #MEDIA_STREAMER_ERROR_NONE Successful
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_OPERATION Invalid operation
+ * @see media_streamer_error_cb()
+ */
+int media_streamer_unset_error_cb(media_streamer_h streamer);
+
+/**
+ * @brief Register a callback that will be triggered after media streamer state was changed.
+ * @since_tizen 3.0
+ * @param [in] streamer  Media streamer handle
+ * @param [in] callback  Callback function pointer
+ * @param [in] user_data The user data passed from the code
+ *                       where media_streamer_set_state_change_cb() was invoked
+ *                       This data will be accessible from @a media_streamer_state_changed_cb
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #MEDIA_STREAMER_ERROR_NONE Successful
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_STATE Invalid state
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_OPERATION Invalid operation
+ * @pre Create a media streamer handle by calling media_streamer_create() function
+ * @post media_streamer_state_changed_cb() will be invoked.
+ * @see media_streamer_unset_state_change_cb()
+ * @see media_streamer_state_change_cb()
+ */
+int media_streamer_set_state_change_cb(media_streamer_h streamer,
+                               media_streamer_state_changed_cb callback,
+                               void *user_data);
+
+/**
+ * @brief Unregisters the state changed callback function.
+ * @since_tizen 3.0
+ * @param [in] streamer  Media streamer handle
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #MEDIA_STREAMER_ERROR_NONE Successful
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_OPERATION Invalid operation
+ * @see media_streamer_set_state_change_cb()
+ */
+int media_streamer_unset_state_change_cb(media_streamer_h streamer);
+
+/**
+ * @brief Registers a callback function to be invoked when buffer underrun or overflow is occurred.
+ * @details This function can be called only for MEDIA_STREAMER_SRC_TYPE_CUSTOM source type
+ * @since_tizen 3.0
+ * @remarks This API is used for media stream playback only.
+ * @param [in] source    Media streamer source node handle
+ * @param [in] callback  The buffer status callback function to register
+ * @param [in] user_data The user data passed from the code where
+ *                       media_streamer_src_set_buffer_status_cb() was invoked
+ *                       This data will be accessible from @a media_streamer_custom_buffer_status_cb()
+ * @return @c 0 on success,
+ *                otherwise a negative error value
+ * @retval #MEDIA_STREAMER_ERROR_NONE Successful
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_STATE Invalid state
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_OPERATION Invalid operation
+ * @pre Create a media streamer source node handle by calling media_streamer_src_create() function
+ * @pre Add created media streamer source node to media streamer by calling media_streamer_node_add() function
+ * @post media_streamer_custom_buffer_status_cb() will be invoked.
+ * @see media_streamer_src_unset_buffer_status_cb()
+ * @see media_streamer_custom_buffer_status_cb()
+ */
+int media_streamer_src_set_buffer_status_cb(media_streamer_node_h source,
+                               media_streamer_custom_buffer_status_cb callback,
+                               void *user_data);
+
+/**
+ * @brief Unregisters the src buffer status callback function.
+ * @since_tizen 3.0
+ * @param [in] source    Media streamer source node handle
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #MEDIA_STREAMER_ERROR_NONE Successful
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_OPERATION Invalid operation
+ * @see media_streamer_src_set_buffer_status_cb()
+ */
+int media_streamer_src_unset_buffer_status_cb(media_streamer_node_h source);
+
+/**
+ * @brief Register a callback function to be called when the custom sink is ready for data processing.
+ * @details This function can be called only for MEDIA_STREAMER_SINK_TYPE_CUSTOM sink type
+ * @since_tizen 3.0
+ * @param [in] sink      Media streamer sink handle
+ * @param [in] callback  Callback function pointer
+ * @param [in] user_data The user data passed from the code where
+ *                       media_streamer_sink_set_data_ready_cb() was invoked
+ *                       This data will be accessible from @a media_streamer_sink_data_ready_cb
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #MEDIA_STREAMER_ERROR_NONE Successful
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_STATE Invalid state
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_OPERATION Invalid operation
+ * @pre Create a media streamer sink handle by calling media_streamer_sink_create() function
+ * @pre Add created media streamer sink node to media streamer by calling media_streamer_node_add() function
+ * @post media_streamer_sink_data_ready_cb() will be invoked.
+ * @see media_streamer_sink_unset_data_ready_cb()
+ * @see media_streamer_sink_data_ready_cb()
+ */
+int media_streamer_sink_set_data_ready_cb(media_streamer_node_h sink,
+                               media_streamer_sink_data_ready_cb callback,
+                               void *user_data);
+
+/**
+ * @brief Unregisters the sink data ready callback function.
+ * @since_tizen 3.0
+ * @param [in] streamer  Media streamer handle
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #MEDIA_STREAMER_ERROR_NONE Successful
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_OPERATION Invalid operation
+ * @see media_streamer_sink_set_data_ready_cb()
+ */
+int media_streamer_sink_unset_data_ready_cb(media_streamer_h streamer);
+
+/**
+ * @brief Registers a callback function to be called when custom sink detect the end-of-stream.
+ * @since_tizen 3.0
+ * @param [in] sink      Media streamer sink node handle
+ * @param [in] callback  Callback function pointer
+ * @param [in] user_data The user data passed from the code where
+ *                       media_streamer_sink_set_eos_cb() was invoked.
+ *                       This data will be accessible from @a media_streamer_sink_eos_cb
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #MEDIA_STREAMER_ERROR_NONE Successful
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_STATE Invalid state
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_OPERATION Invalid operation
+ * @pre Create a media streamer sink handle by calling media_streamer_sink_create() function
+ * @pre Add created media streamer sink node to media streamer by calling media_streamer_node_add() function
+ * @post media_streamer_sink_eos_cb() will be invoked.
+ * @see media_streamer_sink_unset_eos_cb()
+ * @see media_streamer_sink_eos_cb()
+ */
+int media_streamer_sink_set_eos_cb(media_streamer_node_h sink,
+                               media_streamer_sink_eos_cb callback,
+                               void *user_data);
+
+/**
+ * @brief Unregisters the sink end-of-stream callback function.
+ * @since_tizen 3.0
+ * @param [in] streamer  Media streamer handle
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #MEDIA_STREAMER_ERROR_NONE Successful
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_OPERATION Invalid operation
+ * @see media_streamer_sink_set_eos_cb()
+ */
+int media_streamer_sink_unset_eos_cb(media_streamer_h streamer);
+
+/**
+ * @brief Creates an instance of media streamer and
+ *        passes the handle to the caller.
+ * @since_tizen 3.0
+ * @remarks You must release @a streamer using media_streamer_destroy()
+ * @param [out] streamer    Media streamer handle
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #MEDIA_STREAMER_ERROR_NONE Successful
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_OPERATION Invalid operation
+ * @post The media streamer state will be #MEDIA_STREAMER_STATE_IDLE.
+ * @see media_streamer_destroy()
+ */
+int media_streamer_create(media_streamer_h *streamer);
+
+/**
+ * @brief Sets media streamer state to MEDIA_STREAMER_STATE_READY.
+ * @since_tizen 3.0
+ * @param [in] streamer     Media streamer handle
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #MEDIA_STREAMER_ERROR_NONE Successful
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_STATE Invalid state
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_OPERATION Invalid operation
+ * @pre        The media streamer state must be set to #MEDIA_STREAMER_STATE_IDLE
+ *      by calling media_streamer_create() or media_streamer_unprepare().
+ * @pre At least one src and one sink should be added and linked in the streamer
+ *      by calling media_streamer_src_create(), media_streamer_sink_create() and media_streamer_node_link().
+ * @post The media streamer state will be #MEDIA_STREANER_STATE_READY.
+ * @see media_streamer_unprepare()
+ * @see media_streamer_create()
+ */
+int media_streamer_prepare(media_streamer_h streamer);
+
+/**
+ * @brief Sets media streamer state to MEDIA_STREAMER_STATE_IDLE.
+ * @details The most recently used media is reset and no longer associated with the media streamer.
+ * @since_tizen 3.0
+ * @param [in] streamer     Media streamer handle
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #MEDIA_STREAMER_ERROR_NONE Successful
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_STATE Invalid state
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_OPERATION Invalid operation
+ * @pre The media streamer state should be higher than #MEDIA_STREAMER_STATE_IDLE.
+ * @post The media streamer state will be #MEDIA_STREAMER_STATE_IDLE.
+ * @see media_streamer_prepare()
+ */
+int media_streamer_unprepare(media_streamer_h streamer);
+
+/**
+ * @brief Sets media streamer state to MEDIA_STREAMER_STATE_PLAYING.
+ * @details start running the current streamer, or resumes it if paused.
+ * @since_tizen 3.0
+ * @param [in] streamer     Media streamer handle
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #MEDIA_STREAMER_ERROR_NONE Successful
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_STATE Invalid state
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_OPERATION Invalid operation
+ * @pre The media streamer state must be set to #MEDIA_STREAMER_STATE_READY by calling media_streamer_prepare() or
+ *      set to #MEDIA_STREAMER_STATE_PAUSED by calling media_streamer_pause().
+ * @post The media streamer state will be #MEDIA_STREAMER_STATE_PLAYING.
+ * @see media_streamer_create()
+ * @see media_streamer_pause()
+ * @see media_streamer_stop()
+ */
+int media_streamer_play(media_streamer_h streamer);
+
+/**
+ * @brief Pause the media streamer.
+ * @since_tizen 3.0
+ * @param [in] streamer     Media streamer handle
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #MEDIA_STREAMER_ERROR_NONE Successful
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_STATE Invalid state
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_OPERATION Invalid operation
+ * @pre The media streamer state must be set to #MEDIA_STREAMER_STATE_PLAYING.
+ * @post The media streamer state will be #MEDIA_STREAMER_STATE_READY.
+ * @see media_streamer_create()
+ * @see media_streamer_play()
+ */
+int media_streamer_pause(media_streamer_h streamer);
+
+/**
+ * @brief Stops the media streamer.
+ * @since_tizen 3.0
+ * @param [in] streamer     Media streamer handle
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #MEDIA_STREAMER_ERROR_NONE Successful
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_STATE Invalid state
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_OPERATION Invalid operation
+ * @pre The media streamer state must be set to #MEDIA_STREAMER_STATE_PLAYING by calling media_streamer_start() or
+ *      set to #MEDIA_STREAMER_STATE_PAUSED by calling media_streamer_pause().
+ * @post The media streamer state will be #MEDIA_STREAMER_STATE_READY.
+ * @see media_streamer_create()
+ * @see media_streamer_start()
+ * @see media_streamer_pause()
+ */
+int media_streamer_stop(media_streamer_h streamer);
+
+/**
+ * @brief Destroys media streamer.
+ * @since_tizen 3.0
+ * @param [in] streamer     Media streamer handle
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #MEDIA_STREAMER_ERROR_NONE Successful
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_STATE Invalid state
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_OPERATION Invalid operation
+ * @pre Create a media streamer handle by calling media_streamer_create() function
+ * @post The media streamer state will be #MEDIA_STREAMER_STATE_NONE.
+ * @see media_streamer_create()
+ */
+int media_streamer_destroy(media_streamer_h streamer);
+
+/**
+ * @brief Gets media streamer state.
+ * @since_tizen 3.0
+ * @param [in]  streamer     Media streamer handle
+ * @param [out] state        Media streamer state
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #MEDIA_STREAMER_ERROR_NONE    Successful
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_STATE Invalid state
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_OPERATION Invalid operation
+ * @pre Create a media streamer handle by calling media_streamer_create() function
+ * @see #media_streamer_state_e
+ */
+int media_streamer_get_state(media_streamer_h streamer,
+                               media_streamer_state_e *state);
+
+/**
+ * @brief Creates media streamer source node.
+ * @since_tizen 3.0
+ * @privlevel public
+ * @privilege http://tizen.org/privilege/mediastorage
+ *            http://tizen.org/privilege/externalstorage
+ *            http://tizen.org/privilege/internet
+ *            http://tizen.org/privilege/camera
+ *            http://tizen.org/privilege/recorder
+ * @remarks The mediastorage privilege(http://tizen.org/privilege/mediastorage) should be added if any video/audio files are used to play located in the internal storage.
+ * @remarks The externalstorage privilege(http://tizen.org/privilege/externalstorage) should be added if any video/audio files are used to play located in the external storage.
+ * @remarks The internet privilege(http://tizen.org/privilege/internet) should be added if any URIs are used to play from network.
+ * @remarks The camera privilege(http://tizen.org/privilege/camera) should be added if the src node handle the camera device.
+ * @remarks The recorder privilege(http://tizen.org/privilege/recorder) should be added if the src node handle the recorder device.
+ * @remarks You can release @a source node using media_streamer_node_destroy() function
+ * @param [in]  type     Media streamer source node type
+ * @param [out] src      Media streamer source node handle
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #MEDIA_STREAMER_ERROR_NONE Successful
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #MEDIA_STREAMER_ERROR_PERMISSION_DENIED Permission denied
+ * @retval #MEDIA_STREAMER_ERROR_FEATURE_NOT_SUPPORTED_ON_DEVICE Not support on device
+ * @see #media_streamer_src_type_e
+ * @see media_streamer_node_destroy()
+ */
+int media_streamer_src_create(media_streamer_src_type_e type,
+                               media_streamer_node_h *src);
+
+/**
+ * @brief Pushes packet into custom source node.
+ * @details This function can be called only for MEDIA_STREAMER_SRC_TYPE_CUSTOM.
+ * @since_tizen 3.0
+ * @param [in] src       Media streamer source node handle
+ * @param [in] packet    Media packet handle
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #MEDIA_STREAMER_ERROR_NONE Successful
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_STATE Invalid state
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #MEDIA_STREAMER_ERROR_PERMISSION_DENIED Permission denied
+ * @pre Create a source node handle by calling media_streamer_src_create() function
+ * @pre        The media streamer state must be set to #MEDIA_STREAMER_STATE_IDLE at least.
+ * @see #media_packet_h
+ */
+int media_streamer_push_packet(media_streamer_node_h src,
+                               media_packet_h packet);
+
+/**
+ * @brief Creates media streamer sink node.
+ * @details This function can be called only for MEDIA_STREAMER_SINK_TYPE_CUSTOM
+ * @since_tizen 3.0
+ * @privlevel public
+ * @privilege http://tizen.org/privilege/mediastorage
+ *            http://tizen.org/privilege/externalstorage
+ *            http://tizen.org/privilege/internet
+ * @remarks The mediastorage privilege(http://tizen.org/privilege/mediastorage) should be added if any video/audio files are written in the internal storage devices.
+ * @remarks The externalstorage privilege(http://tizen.org/privilege/externalstorage) should be added if any video/audio files are written in the external storage devices.
+ * @remarks The internet privilege(http://tizen.org/privilege/internet) should be added if any URIs are used to transmit the output data.
+ * @remarks You can release @a sink node using media_streamer_node_destroy()
+ * @param [in]  type     Type of sink node to be created
+ * @param [out] sink     Media streamer sink node handle
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #MEDIA_STREAMER_ERROR_NONE Successful
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #MEDIA_STREAMER_ERROR_PERMISSION_DENIED Permission denied
+ * @retval #MEDIA_STREAMER_ERROR_FEATURE_NOT_SUPPORTED_ON_DEVICE Not support on device
+ * @see #media_streamer_sink_type_e
+ * @see media_streamer_node_destroy()
+ */
+int media_streamer_sink_create(media_streamer_sink_type_e type,
+                               media_streamer_node_h *sink);
+
+/**
+ * @brief Pulls packet from custom sink node.
+ * @details This function can be called only for MEDIA_STREAMER_SINK_TYPE_CUSTOM
+ * @since_tizen 3.0
+ * @param [in] sink      Media streamer sink node handle
+ * @param [out] packet   Media packet handle
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #MEDIA_STREAMER_ERROR_NONE Successful
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_STATE Invalid state
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_OPERATION Invalid operation
+ * @pre Create a sink node handle by calling media_streamer_sink_create() function
+ * @pre Set media_streamer_data_ready_cb by calling media_streamer_set_data_ready_cb() function.
+ * @see #media_packet_h
+ * @see media_streamer_sink_create()
+ */
+int media_streamer_pull_packet(media_streamer_node_h sink,
+                               media_packet_h *packet);
+
+/**
+ * @brief Creates media streamer node except src and sink.
+ * @details Creates node specific @a type with specific format of input
+ *          and output data.
+ * @since_tizen 3.0
+ * @remarks You can release @a node using media_streamer_node_destroy() function
+ * @param [in]  type      Created node type
+ * @param [in]  in_fmt    Media format handle for input data
+ * @param [in]  out_fmt   Media format handle for output data
+ * @param [out] node      Media streamer node handle to be created
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #MEDIA_STREAMER_ERROR_NONE Successful
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_OPERATION Invalid operation
+ * @see #media_streamer_node_type_e
+ * @see #media_format_h
+ * @see media_streamer_node_destroy()
+ */
+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);
+
+/**
+ * @brief Adds node to media streamer.
+ * @since_tizen 3.0
+ * @param [in] streamer    Media streamer handle
+ * @param [in] node        Media streamer node handle to be added
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #MEDIA_STREAMER_ERROR_NONE Successful
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_STATE Invalid state
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_OPERATION Invalid operation
+ * @pre Create media streamer handle by calling media_streamer_create() function
+ * @pre Create node handle by calling media_streamer_node_create() function
+ * @see media_streamer_create()
+ * @see media_streamer_node_create()
+ * @see media_streamer_src_create()
+ * @see media_streamer_sink_create()
+ */
+int media_streamer_node_add(media_streamer_h streamer,
+                               media_streamer_node_h node);
+
+/**
+ * @brief Destroys media streamer node.
+ * @since_tizen 3.0
+ * @param [in] node        Media streamer node handle
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #MEDIA_STREAMER_ERROR_NONE Successful
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_STATE Invalid state
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_OPERATION Invalid operation
+ * @pre Create node handle by calling media_streamer_node_create() function
+ * @pre If the node was added to media streamer, it have to be removed by calling media_streamer_node_remove() function
+ * @see media_streamer_node_create()
+ * @see media_streamer_src_create()
+ * @see media_streamer_sink_create()
+ * @see media_streamer_node_remove()
+ */
+int media_streamer_node_destroy(media_streamer_node_h node);
+
+/**
+ * @brief Remove media streamer node from streamer.
+ * @since_tizen 3.0
+ * @remarks If the node is linked, it will be unlinked before removing.
+ * @param [in] streamer    Media streamer handle
+ * @param [in] node        Media streamer node handle
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #MEDIA_STREAMER_ERROR_NONE Successful
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_STATE Invalid state
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_OPERATION Invalid operation
+ * @pre Add node to streamer by calling media_streamer_node_add() function
+ * @see media_streamer_node_add()
+ */
+int media_streamer_node_remove(media_streamer_h streamer,
+                               media_streamer_node_h node);
+
+/**
+ * @brief Sets media format for media streamer node.
+ * @since_tizen 3.0
+ * @param [in] node        Media streamer node handle
+ * @param [in] fmt         Media format handle
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #MEDIA_STREAMER_ERROR_NONE Successful
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_STATE Invalid state
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_OPERATION Invalid operation
+ * @pre Create node handle by calling media_streamer_node_create() function
+ * @see #media_format_h
+ */
+int media_streamer_node_set_format(media_streamer_node_h node,
+                               media_format_h fmt);
+
+/**
+ * @brief Gets media format for media streamer node.
+ * @since_tizen 3.0
+ * @param [in] node        Media streamer node handle
+ * @param [out] fmt        Media format handle
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #MEDIA_STREAMER_ERROR_NONE Successful
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_STATE Invalid state
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_OPERATION Invalid operation
+ * @pre Create a source node handle by calling media_streamer_node_create() function
+ * @see #media_format_h
+ */
+int media_streamer_node_get_format(media_streamer_node_h node,
+                               media_format_h *fmt);
+
+/**
+ * @brief Links two media streamer nodes.
+ * @since_tizen 3.0
+ * @param [in] src_node   Media streamer node handle
+ * @param [in] src_pad    The name of the source pad of the source node
+ * @param [in] dest_node  The destination media streamer node handle
+ * @param [in] sink_pad   The name of the sink pad of the destination node
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #MEDIA_STREAMER_ERROR_NONE Successful
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_STATE Invalid state
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_OPERATION Invalid operation
+ * @pre Create a source node and a destination node handles
+ *      by calling media_streamer_node_create() function
+ *      and add the nodes into streamer by calling media_streamer_node_add() function.
+ * @see media_streamer_node_create()
+ * @see media_streamer_node_add()
+ */
+int media_streamer_node_link(media_streamer_node_h src_node,
+                               const char *src_pad,
+                               media_streamer_node_h dest_node,
+                               const char *sink_pad);
+
+/**
+ * @brief Gets formats of node pads.
+ * @since_tizen 3.0
+ * @remark After using the src_fmt and sink_fmt, it have to be free
+ * @param [in]  node      Media streamer node handle
+ * @param [out] src_fmt    Array of source pad formats
+ * @param [out] sink_fmt   Array of sink pad formats
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #MEDIA_STREAMER_ERROR_NONE Successful
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_STATE Invalid state
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_OPERATION Invalid operation
+ * @pre Create a node handle by calling media_streamer_node_create() function
+ * @see media_streamer_node_create()
+ * @see media_streamer_src_create()
+ * @see media_streamer_sink_create()
+ */
+int media_streamer_node_get_pad_format(media_streamer_node_h node,
+                               char **src_fmt,
+                               char **sink_fmt);
+
+/**
+ * @brief Sets parameters of node.
+ * @details Many parameters can be set at one time all together by using bundle.
+ * @since_tizen 3.0
+ * @param [in] node        Media streamer node handle
+ * @param [in] param_list  Key value array of media streamer node parameters
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #MEDIA_STREAMER_ERROR_NONE Successful
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_STATE Invalid state
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_OPERATION Invalid operation
+ * @pre Create a node handle by calling media_streamer_node_create() function.
+ * @pre Get param list to set by calling media_streamer_node_get_param_list() function.
+ * @see media_streamer_node_create()
+ * @see media_streamer_src_create()
+ * @see media_streamer_sink_create()
+ * @see media_streamer_node_get_param_list()
+ * @see media_streamer_node_set_single_param()
+ */
+int media_streamer_node_set_params(media_streamer_node_h node,
+                               bundle *param_list);
+
+/**
+ * @brief Sets single parameter of node.
+ * @details Sets parameter one by one without creating param bundle.
+ * @since_tizen 3.0
+ * @param [in] node        Media streamer node handle
+ * @param [in] param_name  Param name of node
+ * @param [in] param_value Parm value of node
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #MEDIA_STREAMER_ERROR_NONE Successful
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_STATE Invalid state
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_OPERATION Invalid operation
+ * @pre Create a node handle by calling media_streamer_node_create() function.
+ * @pre Get param list to set by calling media_streamer_node_get_param_list() function.
+ * @see media_streamer_node_create()
+ * @see media_streamer_src_create()
+ * @see media_streamer_sink_create()
+ * @see media_streamer_node_get_param_list()
+ * @see media_streamer_node_set_params()
+ */
+int media_streamer_node_set_single_param(media_streamer_node_h node,
+                               const char *param_name, const char *param_value);
+
+/**
+ * @brief Gets node parameter list.
+ * @since_tizen 3.0
+ * @remark After using param_list, it have to be free by calling bundle_free() in bundle.h
+ * @param [in]  node         Media streamer node handle
+ * @param [out] param_list   Key value array of media streamer node parameters
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #MEDIA_STREAMER_ERROR_NONE Successful
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_STATE Invalid state
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_OPERATION Invalid operation
+ * @pre Create a node handle by calling media_streamer_node_create() function
+ * @post Set params which are needed to set by calling media_streamer_node_set_params() function.
+ * @see media_streamer_node_create()
+ * @see media_streamer_src_create()
+ * @see media_streamer_sink_create()
+ * @see media_streamer_node_set_params()
+ */
+int media_streamer_node_get_param_list(media_streamer_node_h node,
+                               bundle **param_list);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __TIZEN_MEDIASTREAMER_H__ */
diff --git a/include/media_streamer_gst.h b/include/media_streamer_gst.h
new file mode 100755 (executable)
index 0000000..939fd4f
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gst/gst.h>
+
+#include <media_streamer_priv.h>
+
+#define DOT_FILE_NAME "streamer"
+
+#define MEDIA_STREAMER_PIPELINE_NAME "media-streamer-pipeline"
+#define MEDIA_STREAMER_SRC_BIN_NAME "streamer_src"
+#define MEDIA_STREAMER_VIDEO_SINK_BIN_NAME "streamer_video_sink"
+#define MEDIA_STREAMER_AUDIO_SINK_BIN_NAME "streamer_audio_sink"
+#define MEDIA_STREAMER_TOPOLOGY_BIN_NAME "streamer_topology"
+
+/**
+ * @brief Generates dot files for GStreamer pipeline.
+ *
+ * @since_tizen 3.0
+ */
+void __ms_generate_dots(GstElement *bin, gchar *name_tag);
+
+/**
+ * @brief Returns the string representation of GST_STATE.
+ *
+ * @since_tizen 3.0
+ */
+const char *_ms_state_to_string(GstState state);
+
+/**
+ * @brief Creates GstElement by plugin name.
+ *
+ * @since_tizen 3.0
+ */
+GstElement *__ms_element_create(const char *plugin_name, const char *name);
+
+/**
+ * @brief Creates camera GstElement by camera plugin name.
+ *
+ * @since_tizen 3.0
+ */
+GstElement *__ms_camera_element_create(const char *microphone_plugin_name);
+
+/**
+ * @brief Creates encoder GstElement by mime type.
+ *
+ * @since_tizen 3.0
+ */
+GstElement *__ms_video_encoder_element_create(dictionary *dict, media_format_mimetype_e mime);
+
+/**
+ * @brief Creates decoder GstElement by mime type.
+ *
+ * @since_tizen 3.0
+ */
+GstElement *__ms_video_decoder_element_create(dictionary *dict, media_format_mimetype_e mime);
+
+/**
+ * @brief Creates audio encoder GstElement.
+ *
+ * @since_tizen 3.0
+ */
+GstElement *__ms_audio_encoder_element_create(void);
+
+/**
+ * @brief Creates rtp container GstElement.
+ *
+ * @since_tizen 3.0
+ */
+GstElement *__ms_rtp_element_create(media_streamer_node_s *ms_node);
+
+/**
+ * @brief Parse param for RTP node type.
+ *
+ * @since_tizen 3.0
+ */
+int __ms_rtp_set_param(
+                               media_streamer_node_s *node,
+                               const gchar *param_key,
+                               const gchar *param_value);
+
+/**
+ * @brief Creates pipeline, bus and src/sink/topology bins.
+ *
+ * @since_tizen 3.0
+ */
+int __ms_pipeline_create(media_streamer_s *ms_streamer);
+
+/**
+ * @brief Adds node to bin
+ *
+ * @since_tizen 3.0
+ */
+int __ms_add_node_into_bin(media_streamer_s *ms_streamer,media_streamer_node_s *ms_node);
+
+/**
+ * @brief Sets GstElement into state.
+ *
+ * @since_tizen 3.0
+ */
+int __ms_element_set_state(GstElement *gst_element, GstState gst_state);
+
+/**
+ * @brief Sets mediaformat into GstElement.
+ *
+ * @since_tizen 3.0
+ */
+int __ms_element_set_fmt(media_streamer_node_s *node, media_format_h fmt);
diff --git a/include/media_streamer_node.h b/include/media_streamer_node.h
new file mode 100755 (executable)
index 0000000..8843ccf
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <media_streamer_priv.h>
+
+/**
+ * @brief Creates media streamer node using input and output format.
+ *
+ * @since_tizen 3.0
+ */
+int __ms_node_create(media_streamer_node_s *node,
+                               media_format_h in_fmt,
+                               media_format_h out_fmt);
+
+/**
+ * @brief Creates media streamer source node.
+ *
+ * @since_tizen 3.0
+ */
+int __ms_src_node_create(media_streamer_node_s *node);
+
+/**
+ * @brief Creates media streamer sink node.
+ *
+ * @since_tizen 3.0
+ */
+int __ms_sink_node_create(media_streamer_node_s *node);
+
+/**
+ * @brief Destroys media streamer node.
+ *
+ * @since_tizen 3.0
+ */
+void __ms_node_destroy(void *data);
+
+/**
+ * @brief Inserts media streamer node into nodes table.
+ *
+ * @since_tizen 3.0
+ */
+void __ms_node_insert_into_table(GHashTable *nodes_table,
+                               media_streamer_node_s *ms_node);
+
+/**
+ * @brief Remove media streamer node from nodes table.
+ *
+ * @since_tizen 3.0
+ */
+int __ms_node_remove_from_table(GHashTable *nodes_table,
+                               media_streamer_node_s *ms_node);
+
+/**
+ * @brief Reads node parameters from user's bundle object.
+ *
+ * @since_tizen 3.0
+ */
+int __ms_node_read_params_from_bundle (media_streamer_node_s *node,
+               bundle *param_list);
+
+/**
+ * @brief Writes GstElement properties into user's bundle object.
+ *
+ * @since_tizen 3.0
+ */
+int __ms_node_write_params_into_bundle (media_streamer_node_s *node,
+               bundle *param_list);
diff --git a/include/media_streamer_priv.h b/include/media_streamer_priv.h
new file mode 100755 (executable)
index 0000000..10070cc
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __TIZEN_MEDIASTREAMER_PRIVATE_H__
+#define __TIZEN_MEDIASTREAMER_PRIVATE_H__
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <gst/gst.h>
+#include <stdio.h>
+
+#include <media_streamer.h>
+#include <media_streamer_util.h>
+
+/**
+ * @brief Media Streamer callbacks structure.
+ *
+ * @since_tizen 3.0
+ */
+typedef struct
+{
+       void *callback;
+       void *user_data;
+} media_streamer_callback_s;
+
+/**
+ * @brief Media Streamer source callbacks structure.
+ *
+ * @since_tizen 3.0
+ */
+typedef struct
+{
+       media_streamer_callback_s enough_data_cb;
+       media_streamer_callback_s need_data_cb;
+} media_streamer_src_callbacks_s;
+
+/**
+ * @brief Media Streamer sink callbacks structure.
+ *
+ * @since_tizen 3.0
+ */
+typedef struct
+{
+       media_streamer_callback_s data_ready_cb;
+       media_streamer_callback_s eos_cb;
+} media_streamer_sink_callbacks_s;
+
+/**
+ * @brief Media Streamer type handle.
+ *
+ * @since_tizen 3.0
+ */
+typedef struct
+{
+       media_streamer_ini_t ini;
+       GstElement *pipeline;
+
+       GstElement *src_bin;
+       GstElement *sink_video_bin;
+       GstElement *sink_audio_bin;
+       GstElement *topology_bin;
+
+       GHashTable *nodes_table;
+       GMutex mutex_lock;
+
+       GstBus *bus;
+       guint bus_watcher;
+
+       media_streamer_state_e state;
+
+       media_streamer_callback_s error_cb;
+       media_streamer_callback_s state_changed_cb;
+} media_streamer_s;
+
+/**
+ * @brief Media Streamer node type handle.
+ *
+ * @since_tizen 3.0
+ */
+typedef int (*media_streamer_node_set_param)(
+                               struct media_streamer_node_s *node,
+                               const gchar *param_key,
+                               const gchar *param_value);
+
+/**
+ * @brief Media Streamer node type handle.
+ *
+ * @since_tizen 3.0
+ */
+typedef struct
+{
+       GstElement *gst_element;
+       char *name;
+       media_streamer_s *parent_streamer;
+       media_streamer_node_type_e type;
+       int subtype;
+       media_streamer_node_set_param set_param;
+       void *callbacks_structure;
+} media_streamer_node_s;
+
+/* Private functions definition */
+
+/**
+ * @brief Destroys media streamer structure.
+ *
+ * @since_tizen 3.0
+ */
+void __ms_streamer_destroy(media_streamer_s *ms_streamer);
+
+/**
+ * @brief Creates media streamer structure.
+ *
+ * @since_tizen 3.0
+ */
+int __ms_create(media_streamer_s *ms_streamer);
+
+/**
+ * @brief Changes state of media streamer.
+ *
+ * @since_tizen 3.0
+ */
+int __ms_state_change(media_streamer_s *ms_streamer, media_streamer_state_e state);
+
+#ifdef __cplusplus
+}
+
+#endif /* __cplusplus */
+
+#endif /* __TIZEN_MEDIASTREAMER_PRIVATE_H__ */
diff --git a/include/media_streamer_util.h b/include/media_streamer_util.h
new file mode 100755 (executable)
index 0000000..dbd052c
--- /dev/null
@@ -0,0 +1,230 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __MEDIA_STREAMER_UTIL_H__
+#define __MEDIA_STREAMER_UTIL_H__
+
+#include <stdlib.h>
+#include <glib.h>
+#include <dlog.h>
+#include <iniparser.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* DLog Utils*/
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "CAPI_MEDIASTREAMER"
+
+#define FONT_COLOR_RESET    "\033[0m"
+#define FONT_COLOR_RED      "\033[31m"
+#define FONT_COLOR_GREEN    "\033[32m"
+#define FONT_COLOR_YELLOW   "\033[33m"
+#define FONT_COLOR_BLUE     "\033[34m"
+#define FONT_COLOR_PURPLE   "\033[35m"
+#define FONT_COLOR_CYAN     "\033[36m"
+#define FONT_COLOR_GRAY     "\033[37m"
+
+#define ms_debug(fmt, arg...) do { \
+       LOGD(FONT_COLOR_RESET""fmt"", ##arg);     \
+} while(0)
+
+#define ms_info(fmt, arg...) do { \
+       LOGI(FONT_COLOR_GREEN""fmt"", ##arg);     \
+} while(0)
+
+#define ms_error(fmt, arg...) do { \
+       LOGE(FONT_COLOR_RED""fmt"", ##arg);     \
+} while(0)
+
+#define ms_debug_fenter() do { \
+       LOGD(FONT_COLOR_YELLOW"<Enter>");     \
+} while(0)
+
+#define ms_debug_fleave() do { \
+       LOGD(FONT_COLOR_PURPLE"<Leave>");     \
+} while(0)
+
+#define ms_retm_if(expr, fmt, arg...) do { \
+       if(expr) { \
+       LOGE(FONT_COLOR_RED""fmt"", ##arg);     \
+       return; \
+} \
+} while(0)
+
+#define ms_retvm_if(expr, val, fmt, arg...) do { \
+       if(expr) { \
+       LOGE(FONT_COLOR_RED""fmt"", ##arg);     \
+       return(val); \
+} \
+} while(0)
+
+
+#define MS_SAFE_FREE(src)           {if(src) {free(src); src = NULL;}}
+#define MS_SAFE_GFREE(src)          {if(src) {g_free(src); src = NULL;}}
+#define MS_SAFE_UNREF(src)          {if(src) {gst_object_unref(GST_OBJECT(src)); src = NULL;}}
+#define MS_TABLE_SAFE_UNREF(src)    {if(src) {g_hash_table_unref(src); src = NULL;}}
+
+/* Ini Utils */
+#define MEDIA_STREAMER_INI_DEFAULT_PATH        "/usr/etc/media_streamer.ini"
+#define MEDIA_STREAMER_INI_MAX_STRLEN  100
+
+/**
+ * @brief Media Streamer ini settings structure.
+ *
+ * @since_tizen 3.0
+ */
+typedef struct __media_streamer_ini
+{
+       /* general */
+       gboolean generate_dot;
+
+} media_streamer_ini_t;
+
+/*Test elements*/
+#define DEFAULT_VIDEO_TEST_SOURCE                      "videotestsrc"
+#define DEFAULT_AUDIO_TEST_SOURCE                      "audiotestsrc"
+#define DEFAULT_FAKE_SINK                              "fakesink"
+#define DEFAULT_QUEUE                                  "queue"
+
+/* setting default values if each value is not specified in .ini file */
+/* general */
+#define DEFAULT_GENERATE_DOT                           FALSE
+#define DEFAULT_AUDIO_SOURCE                           "alsasrc"
+#define DEFAULT_CAMERA_SOURCE                          "camerasrc"
+#define DEFAULT_VIDEO_SOURCE                           "ximagesrc"
+#define DEFAULT_AUDIO_SINK                             "pulsesink"
+#define DEFAULT_VIDEO_SINK                             "autovideosink"
+
+/* udp streaming */
+#define DEFAULT_UDP_SOURCE                             "udpsrc"
+#define DEFAULT_UDP_SINK                               "udpsink"
+#define DEFAULT_RTP_BIN                                        "rtpbin"
+
+/* video format defaults */
+#define DEFAULT_VIDEO_ENCODER                          "omxh264enc"
+#define DEFAULT_VIDEO_DECODER                          "omxh264dec"
+#define DEFAULT_VIDEO_PARSER                           "h264parse"
+#define DEFAULT_VIDEO_RTPPAY                           "rtph264pay"
+#define DEFAULT_VIDEO_RTPDEPAY                         "rtph264depay"
+
+/* audio format defaults */
+#define DEFAULT_AUDIO_ENCODER                          "omxh264enc"
+#define DEFAULT_AUDIO_DECODER                          "omxh264dec"
+#define DEFAULT_AUDIO_PARSER                           "h264parse"
+#define DEFAULT_AUDIO_RTPPAY                           "rtph264pay"
+#define DEFAULT_AUDIO_RTPDEPAY                         "rtph264depay"
+
+#define MEDIA_STREAMER_DEFAULT_CAMERA_FORMAT "video/x-raw,width=320,height=240"
+#define MEDIA_STREAMER_DEFAULT_AUDIO_FORMAT "audio/x-raw,channels=1,rate=44100,format=S16BE"
+#define MEDIA_STREAMER_DEFAULT_ENCODER_FORMAT "video/x-h264,stream-format=byte-stream,profile=high"
+
+#define MEDIA_STREAMER_DEFAULT_DOT_DIR "/tmp"
+#define MEDIA_STREAMER_DEFAULT_INI \
+"\
+[general] \n\
+; generating dot file representing pipeline state \n\
+generate dot = no \n\
+dot dir = /tmp \n\
+\n\
+\n\
+[sources] \n\
+\n\
+audio_source = pulsesrc \n\
+camera_source = camerasrc \n\
+video_source = ximagesrc \n\
+udp_source = udpsrc \n\
+\n\
+\n\
+[sinks] \n\
+\n\
+audio_sink = pulsesink \n\
+video_sink = autovideosink \n\
+udp_sink = udpsink \n\
+\n\
+\n\
+[h263] \n\
+\n\
+encoder = avenc_h263 \n\
+decoder = avdec_h263 \n\
+rtppay = rtph263pay \n\
+rtpdepay = rtph263depay \n\
+parser = h263parse \n\
+\n\
+\n\
+[h264] \n\
+\n\
+encoder = omxh264enc \n\
+decoder = avdec_h264 \n\
+rtppay = rtph264pay \n\
+rtpdepay = rtph264depay \n\
+parser = h264parse \n\
+\n\
+\n\
+[audio-raw] \n\
+\n\
+encoder = \n\
+decoder = \n\
+rtppay = rtpL16pay \n\
+rtpdepay = rtpL16depay \n\
+\n\
+"
+
+/**
+ * @brief Load media streamer settings from ini file.
+ *
+ * @since_tizen 3.0
+ */
+int __ms_load_ini_settings(media_streamer_ini_t *ini);
+
+/**
+ * @brief Load settings from ini file into dictionary object.
+ *
+ * @since_tizen 3.0
+ */
+gboolean __ms_load_ini_dictionary(dictionary **dict);
+
+/**
+ * @brief Destroys ini dictionary object and frees all resources.
+ *
+ * @since_tizen 3.0
+ */
+gboolean __ms_destroy_ini_dictionary(dictionary *dict);
+
+/**
+ * @brief Read and copy string reading from ini file.
+ *
+ * @since_tizen 3.0
+ */
+gchar *__ms_ini_get_string(dictionary *dict, const char *ini_path,
+               char *default_str);
+
+/**
+ * @brief Converts Media Format mime type into string.
+ *
+ * @since_tizen 3.0
+ */
+const gchar *__ms_convert_mime_to_string(media_format_mimetype_e mime);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/packaging/capi-media-streamer.manifest b/packaging/capi-media-streamer.manifest
new file mode 100755 (executable)
index 0000000..56b1c62
--- /dev/null
@@ -0,0 +1,8 @@
+<manifest>
+       <request>
+               <domain name="_" />
+       </request>
+       <assign>
+               <filesystem path="/usr/bin/media_streamer_test" label="_" exec_label="none" />
+       </assign>
+</manifest>
diff --git a/packaging/capi-media-streamer.spec b/packaging/capi-media-streamer.spec
new file mode 100755 (executable)
index 0000000..cf1d34b
--- /dev/null
@@ -0,0 +1,77 @@
+Name:       capi-media-streamer
+Summary:    A Media Streamer library in Tizen Native API
+Version:    0.1.1
+Release:    0
+Group:      Multimedia/API
+License:    Apache-2.0
+URL:        http://source.tizen.org
+Source0:    %{name}-%{version}.tar.gz
+Source1001:    capi-media-streamer.manifest
+BuildRequires:  cmake
+BuildRequires:  pkgconfig(dlog)
+BuildRequires:  pkgconfig(glib-2.0)
+BuildRequires:  pkgconfig(mm-common)
+BuildRequires:  pkgconfig(capi-base-common)
+BuildRequires:  pkgconfig(capi-media-tool)
+BuildRequires:  pkgconfig(libtbm)
+BuildRequires:  pkgconfig(gstreamer-1.0)
+BuildRequires:  pkgconfig(gstreamer-plugins-base-1.0)
+BuildRequires:  pkgconfig(gstreamer-video-1.0)
+BuildRequires:  pkgconfig(gstreamer-app-1.0)
+BuildRequires:  pkgconfig(iniparser)
+BuildRequires:  pkgconfig(bundle)
+
+%description
+A MediaStreamer library in Tizen Native API.
+
+%package devel
+Summary:    Multimedia Streamer Library in Tizen Native API (Development)
+Group:      TO_BE/FILLED_IN
+Requires:   %{name} = %{version}-%{release}
+
+%description devel
+MediaStreamer Library in Tizen Native API (DEV).
+
+%prep
+%setup -q
+cp %{SOURCE1001} .
+
+%build
+%if 0%{?sec_build_binary_debug_enable}
+export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE"
+export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE"
+export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE"
+%endif
+MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'`
+cmake . -DCMAKE_INSTALL_PREFIX=/usr -DFULLVER=%{version} -DMAJORVER=${MAJORVER}
+
+
+make %{?jobs:-j%jobs}
+
+%install
+rm -rf %{buildroot}
+mkdir -p %{buildroot}/usr/share/license
+mkdir -p %{buildroot}/usr/bin
+cp LICENSE.APLv2 %{buildroot}/usr/share/license/%{name}
+cp test/media_streamer_test %{buildroot}/usr/bin
+
+%make_install
+
+%post
+/sbin/ldconfig
+
+%postun -p /sbin/ldconfig
+
+
+%files
+%manifest capi-media-streamer.manifest
+%{_libdir}/libcapi-media-streamer.so.*
+%{_datadir}/license/%{name}
+/usr/bin/*
+
+%files devel
+%{_includedir}/media/*.h
+%{_libdir}/pkgconfig/*.pc
+%{_libdir}/libcapi-media-streamer.so
+
+
diff --git a/src/media_streamer.c b/src/media_streamer.c
new file mode 100755 (executable)
index 0000000..ccfedcc
--- /dev/null
@@ -0,0 +1,517 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <mm_types.h>
+#include <dlog.h>
+
+#include <media_streamer.h>
+#include <media_streamer_priv.h>
+#include <media_streamer_node.h>
+#include <media_streamer_gst.h>
+
+/*
+* Public Implementation
+*/
+
+int media_streamer_src_create(media_streamer_src_type_e type,
+                               media_streamer_node_h *src)
+{
+       int ret = MEDIA_STREAMER_ERROR_NONE;
+
+       media_streamer_node_s *ms_src = (media_streamer_node_s*)src;
+       ms_retvm_if(ms_src == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+
+       ms_src = (media_streamer_node_s *)calloc(1, sizeof(media_streamer_node_s));
+       ms_retvm_if(ms_src == NULL, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Error allocation memory");
+
+       ms_src->type = MEDIA_STREAMER_NODE_TYPE_SRC;
+       ms_src->subtype = (media_streamer_src_type_e)type;
+       ret = __ms_src_node_create(ms_src);
+       if(ret != MEDIA_STREAMER_ERROR_NONE)
+       {
+               MS_SAFE_FREE(ms_src);
+               ms_error( "Error creating Src node [%d]",ret);
+               return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+       }
+
+       ms_info("Source node [%s] created", ms_src->name);
+       *src = (media_streamer_node_h)ms_src;
+
+       return ret;
+}
+
+int media_streamer_sink_create(media_streamer_sink_type_e type,
+                               media_streamer_node_h *sink)
+{
+       int ret = MEDIA_STREAMER_ERROR_NONE;
+
+       media_streamer_node_s *ms_sink = (media_streamer_node_s*)sink;
+       ms_retvm_if(ms_sink == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+
+       ms_sink = (media_streamer_node_s *)calloc(1, sizeof(media_streamer_node_s));
+       ms_retvm_if(ms_sink == NULL, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Error allocation memory");
+
+       ms_sink->type = MEDIA_STREAMER_NODE_TYPE_SINK;
+       ms_sink->subtype = (media_streamer_sink_type_e)type;
+       ret = __ms_sink_node_create(ms_sink);
+       if(ret != MEDIA_STREAMER_ERROR_NONE)
+       {
+               MS_SAFE_FREE(ms_sink);
+               ms_error( "Error creating Sink node [%d]",ret);
+               return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+       }
+
+       ms_info("Sink node [%s] created", ms_sink->name);
+       *sink = (media_streamer_node_h)ms_sink;
+
+       return ret;
+}
+
+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)
+{
+       int ret = MEDIA_STREAMER_ERROR_NONE;
+
+       media_streamer_node_s *ms_node = (media_streamer_node_s*)node;
+       ms_retvm_if(ms_node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+
+       ms_node = (media_streamer_node_s *)calloc(1, sizeof(media_streamer_node_s));
+       ms_retvm_if(ms_node == NULL, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Error allocation memory");
+
+       ms_node->type = type;
+       ms_node->subtype = 0;
+
+       ret = __ms_node_create(ms_node, in_fmt, out_fmt);
+       if(ret != MEDIA_STREAMER_ERROR_NONE)
+       {
+               MS_SAFE_FREE(ms_node);
+               ms_error( "Error creating Node [%d]",ret);
+               return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+       }
+
+       ms_info("Node [%s] created", ms_node->name);
+       *node = (media_streamer_node_h)ms_node;
+
+       return ret;
+}
+
+int media_streamer_node_destroy(media_streamer_node_h node)
+{
+       media_streamer_node_s *ms_node = (media_streamer_node_s*)node;
+       ms_retvm_if(ms_node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+
+       if (ms_node->parent_streamer == NULL)
+       {
+               // This node was not added into any media streamer
+               __ms_node_destroy(ms_node);
+       }
+       else
+       {
+               int ret = __ms_node_remove_from_table(ms_node->parent_streamer->nodes_table, ms_node);
+               ms_retvm_if(ret != MEDIA_STREAMER_ERROR_NONE, MEDIA_STREAMER_ERROR_INVALID_OPERATION,
+                               "Current key was not removed from nodes_table");
+       }
+
+       ms_info("Node destroyed successfully");
+       return MEDIA_STREAMER_ERROR_NONE;
+}
+
+int media_streamer_node_add(media_streamer_h streamer,
+                               media_streamer_node_h node)
+{
+       int ret = MEDIA_STREAMER_ERROR_NONE;
+
+       media_streamer_s *ms_streamer = (media_streamer_s*)streamer;
+       ms_retvm_if(streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+
+       media_streamer_node_s* ms_node = (media_streamer_node_s*)node;
+       ms_retvm_if(ms_node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+
+       g_mutex_lock(&ms_streamer->mutex_lock);
+
+       __ms_node_insert_into_table(ms_streamer->nodes_table,ms_node);
+       ms_node->parent_streamer = ms_streamer;
+
+       __ms_add_node_into_bin(ms_streamer, ms_node);
+
+       g_mutex_unlock(&ms_streamer->mutex_lock);
+
+       return ret;
+}
+
+int media_streamer_prepare(media_streamer_h streamer)
+{
+       media_streamer_s *ms_streamer = (media_streamer_s*)streamer;
+       ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+       ms_retvm_if(ms_streamer->pipeline == NULL, MEDIA_STREAMER_ERROR_INVALID_STATE, "Pipeline doesn`t exist");
+
+       g_mutex_lock(&ms_streamer->mutex_lock);
+
+       if(ms_streamer->state > MEDIA_STREAMER_STATE_IDLE)
+       {
+               ms_error("Error: Media streamer already prepared [%d]!",
+                               MEDIA_STREAMER_ERROR_INVALID_OPERATION);
+               return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+       }
+
+       if(__ms_state_change(ms_streamer, MEDIA_STREAMER_STATE_READY) != MEDIA_STREAMER_ERROR_NONE)
+       {
+               ms_error("Error: can not set state [%d]", MEDIA_STREAMER_ERROR_INVALID_OPERATION);
+               return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+       }
+       __ms_generate_dots(ms_streamer->pipeline, "prepare");
+
+       g_mutex_unlock(&ms_streamer->mutex_lock);
+
+       return MEDIA_STREAMER_ERROR_NONE;
+}
+
+int media_streamer_unprepare(media_streamer_h streamer)
+{
+       media_streamer_s *ms_streamer = (media_streamer_s*)streamer;
+       ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+       ms_retvm_if(ms_streamer->pipeline == NULL, MEDIA_STREAMER_ERROR_INVALID_STATE, "Pipeline doesn`t exist");
+
+       g_mutex_lock(&ms_streamer->mutex_lock);
+
+       if(__ms_state_change(ms_streamer, MEDIA_STREAMER_STATE_IDLE) != MEDIA_STREAMER_ERROR_NONE)
+       {
+               ms_error("Error: can not set state [%d]", MEDIA_STREAMER_ERROR_INVALID_OPERATION);
+               return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+       }
+
+       g_mutex_unlock(&ms_streamer->mutex_lock);
+
+       return MEDIA_STREAMER_ERROR_NONE;
+}
+
+int media_streamer_play(media_streamer_h streamer)
+{
+       media_streamer_s *ms_streamer = (media_streamer_s*)streamer;
+       ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+
+       g_mutex_lock(&ms_streamer->mutex_lock);
+
+       if(ms_streamer->state < MEDIA_STREAMER_STATE_READY)
+       {
+               ms_error("Error: Media streamer must be prepared first [%d]!",
+                               MEDIA_STREAMER_ERROR_INVALID_OPERATION);
+               return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+       }
+
+       if(__ms_state_change(ms_streamer, MEDIA_STREAMER_STATE_PLAYING) != MEDIA_STREAMER_ERROR_NONE)
+       {
+               ms_error("Error: can not set state [%d]", MEDIA_STREAMER_ERROR_INVALID_OPERATION);
+               return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+       }
+
+       g_mutex_unlock(&ms_streamer->mutex_lock);
+
+       return MEDIA_STREAMER_ERROR_NONE;
+}
+
+int media_streamer_create(media_streamer_h *streamer)
+{
+       int ret = MEDIA_STREAMER_ERROR_NONE;
+       media_streamer_s *ms_streamer = NULL;
+       ms_retvm_if(streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+
+       ms_streamer = (media_streamer_s *)calloc(1, sizeof(media_streamer_s));
+       ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Error allocation memory");
+
+       /* create streamer lock */
+       g_mutex_init(&ms_streamer->mutex_lock);
+
+       ms_streamer->state = MEDIA_STREAMER_STATE_NONE;
+
+       ret = __ms_create(ms_streamer);
+       if(ret!=MEDIA_STREAMER_ERROR_NONE)
+       {
+               ms_error("Error creating Media Streamer");
+               __ms_streamer_destroy(ms_streamer);
+
+               g_mutex_clear(&ms_streamer->mutex_lock);
+
+               return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+       }
+
+       if(__ms_state_change(ms_streamer, MEDIA_STREAMER_STATE_IDLE) != MEDIA_STREAMER_ERROR_NONE)
+       {
+               ms_error("Error: can not set state [%d]", MEDIA_STREAMER_ERROR_INVALID_OPERATION);
+               return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+       }
+
+       *streamer = ms_streamer;
+       ms_info("Media Streamer created successfully");
+       return ret;
+}
+
+int media_streamer_destroy(media_streamer_h streamer)
+{
+       media_streamer_s *ms_streamer = (media_streamer_s*)streamer;
+       ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+
+       g_mutex_lock(&ms_streamer->mutex_lock);
+
+       __ms_streamer_destroy(ms_streamer);
+
+       g_mutex_unlock(&ms_streamer->mutex_lock);
+       g_mutex_clear(&ms_streamer->mutex_lock);
+
+       ms_info("Media Streamer destroyed successfully");
+
+       return MEDIA_STREAMER_ERROR_NONE;
+}
+
+int media_streamer_set_error_cb(media_streamer_h streamer,
+                               media_streamer_error_cb callback,
+                               void *data)
+{
+       return MEDIA_STREAMER_ERROR_NONE;
+}
+
+int media_streamer_unset_error_cb(media_streamer_h streamer)
+{
+       return MEDIA_STREAMER_ERROR_NONE;
+}
+
+int media_streamer_set_state_change_cb(media_streamer_h streamer,
+                               media_streamer_state_changed_cb callback,
+                               void *data)
+{
+       return MEDIA_STREAMER_ERROR_NONE;
+}
+
+int media_streamer_unset_state_change_cb(media_streamer_h streamer)
+{
+       return MEDIA_STREAMER_ERROR_NONE;
+}
+
+int media_streamer_src_set_buffer_status_cb(media_streamer_node_h source,
+                               media_streamer_custom_buffer_status_cb callback,
+                               void *user_data)
+{
+       return MEDIA_STREAMER_ERROR_NONE;
+}
+
+int media_streamer_src_unset_buffer_status_cb(media_streamer_node_h source)
+{
+       return MEDIA_STREAMER_ERROR_NONE;
+}
+
+int media_streamer_sink_set_data_ready_cb(media_streamer_node_h sink,
+                               media_streamer_sink_data_ready_cb callback,
+                               void *data)
+{
+       return MEDIA_STREAMER_ERROR_NONE;
+}
+
+int media_streamer_sink_unset_data_ready_cb(media_streamer_node_h source)
+{
+       return MEDIA_STREAMER_ERROR_NONE;
+}
+
+int media_streamer_sink_set_eos_cb(media_streamer_node_h sink,
+                               media_streamer_sink_eos_cb callback,
+                               void *data)
+{
+       return MEDIA_STREAMER_ERROR_NONE;
+}
+
+int media_streamer_sink_unset_eos_cb(media_streamer_node_h source)
+{
+       return MEDIA_STREAMER_ERROR_NONE;
+}
+
+int media_streamer_pause(media_streamer_h streamer)
+{
+       media_streamer_s *ms_streamer = (media_streamer_s*)streamer;
+       ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+
+       g_mutex_lock(&ms_streamer->mutex_lock);
+
+       if(__ms_state_change(ms_streamer, MEDIA_STREAMER_STATE_PAUSED) != MEDIA_STREAMER_ERROR_NONE)
+       {
+               ms_error("Error: can not set state [%d]", MEDIA_STREAMER_ERROR_INVALID_OPERATION);
+               return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+       }
+
+       g_mutex_unlock(&ms_streamer->mutex_lock);
+
+       return MEDIA_STREAMER_ERROR_NONE;
+}
+
+int media_streamer_stop(media_streamer_h streamer)
+{
+       media_streamer_s *ms_streamer = (media_streamer_s*)streamer;
+       ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+
+       g_mutex_lock(&ms_streamer->mutex_lock);
+
+       if(ms_streamer->state < MEDIA_STREAMER_STATE_READY)
+       {
+               ms_error("Error: Media streamer must be prepared first [%d]!",
+                               MEDIA_STREAMER_ERROR_INVALID_OPERATION);
+               return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+       }
+
+       if(__ms_state_change(ms_streamer, MEDIA_STREAMER_STATE_READY) != MEDIA_STREAMER_ERROR_NONE)
+       {
+               ms_error("Error: can not set state [%d]", MEDIA_STREAMER_ERROR_INVALID_OPERATION);
+               return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+       }
+
+       g_mutex_unlock(&ms_streamer->mutex_lock);
+
+       return MEDIA_STREAMER_ERROR_NONE;
+}
+
+int media_streamer_get_state(media_streamer_h streamer,
+                               media_streamer_state_e *state)
+{
+       media_streamer_s *ms_streamer = (media_streamer_s*)streamer;
+       ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+
+       *state = ms_streamer->state;
+
+       return MEDIA_STREAMER_ERROR_NONE;
+}
+
+int media_streamer_seek(media_streamer_h streamer,
+                               media_streamer_time_value time)
+{
+       return MEDIA_STREAMER_ERROR_NONE;
+}
+
+int media_streamer_push_packet(media_streamer_node_h src,
+                               media_packet_h packet)
+{
+       return MEDIA_STREAMER_ERROR_NONE;
+}
+
+int media_streamer_pull_packet(media_streamer_node_h sink,
+                               media_packet_h *packet)
+{
+       return MEDIA_STREAMER_ERROR_NONE;
+}
+
+int media_streamer_node_set_format(media_streamer_node_h node,
+                               media_format_h fmt)
+{
+       int ret = MEDIA_STREAMER_ERROR_NONE;
+       media_streamer_node_s *ms_node = (media_streamer_node_s*)node;
+       ms_retvm_if(ms_node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+       ms_retvm_if(fmt == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Format is NULL");
+
+       ret = __ms_element_set_fmt(node, fmt);
+       return ret;
+}
+
+int media_streamer_node_get_format(media_streamer_node_h node,
+                               media_format_h *fmt)
+{
+       int ret = MEDIA_STREAMER_ERROR_NONE;
+       media_streamer_node_s *ms_node = (media_streamer_node_s*)node;
+       ms_retvm_if(ms_node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+       ms_retvm_if(fmt == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Format is NULL");
+
+
+       return ret;
+}
+
+int media_streamer_node_link(media_streamer_node_h src_node,
+                               const char *src_pad,
+                               media_streamer_node_h dest_node,
+                               const char *sink_pad)
+{
+       int ret = MEDIA_STREAMER_ERROR_NONE;
+       media_streamer_node_s *ms_src_node = (media_streamer_node_s*)src_node;
+       ms_retvm_if(ms_src_node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+
+       media_streamer_node_s *ms_dest_node = (media_streamer_node_s*)dest_node;
+       ms_retvm_if(ms_dest_node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+       gchar *src_element_name = gst_element_get_name(ms_src_node->gst_element);
+       gchar *sink_element_name = gst_element_get_name(ms_dest_node->gst_element);
+
+       ms_retvm_if(src_pad == NULL, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Pad is NULL");
+       ms_retvm_if(sink_pad == NULL, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Pad is NULL");
+
+       gboolean link_ret;
+
+       link_ret = gst_element_link_pads (ms_src_node->gst_element, src_pad, ms_dest_node->gst_element, sink_pad);
+       if(!link_ret)
+       {
+               ms_error("Can not link [%s]->%s pad to [%s]->%s pad, ret code [%d] ", src_pad, sink_pad, src_element_name, sink_element_name, link_ret);
+               ret = MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+       }
+
+       MS_SAFE_GFREE(src_element_name);
+       MS_SAFE_GFREE(sink_element_name);
+       return ret;
+}
+
+int media_streamer_node_get_pad_format(media_streamer_node_h node,
+                               char **in_fmt,
+                               char **out_fmt)
+{
+       return MEDIA_STREAMER_ERROR_NONE;
+}
+
+int media_streamer_node_set_params(media_streamer_node_h node,
+                               bundle *param_list)
+{
+       int ret = MEDIA_STREAMER_ERROR_NONE;
+
+       media_streamer_node_s *ms_node = (media_streamer_node_s*)node;
+       ms_retvm_if(ms_node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+       ms_retvm_if(ms_node->gst_element == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+       ms_retvm_if(param_list == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Parameters list is NULL");
+
+       ret = __ms_node_read_params_from_bundle(ms_node,param_list);
+       ms_retvm_if(ret != MEDIA_STREAMER_ERROR_NONE, MEDIA_STREAMER_ERROR_INVALID_OPERATION,
+                       "Parameters list is NULL");
+
+       return ret;
+}
+
+int media_streamer_node_get_param_list(media_streamer_node_h node,
+                               bundle **param_list)
+{
+       media_streamer_node_s *ms_node =(media_streamer_node_s*)node;
+       ms_retvm_if(ms_node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+       ms_retvm_if(param_list == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Param list pionter is NULL");
+
+       bundle *ms_params = NULL;
+       ms_params = bundle_create();
+       ms_retvm_if(ms_params == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Error creating new params object");
+
+       if (__ms_node_write_params_into_bundle(ms_node, ms_params) != MEDIA_STREAMER_ERROR_NONE)
+       {
+               ms_info("Node [%s] do not have any params.", ms_node->name);
+               bundle_free(ms_params);
+               *param_list = NULL;
+
+               return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+       }
+
+       *param_list = ms_params;
+       return MEDIA_STREAMER_ERROR_NONE;
+}
diff --git a/src/media_streamer_gst.c b/src/media_streamer_gst.c
new file mode 100755 (executable)
index 0000000..e452e03
--- /dev/null
@@ -0,0 +1,1146 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <bundle.h>
+#include <media_streamer_gst.h>
+
+#define MS_ELEMENT_IS_SINK(el) g_str_has_suffix(el, "sink")
+#define MS_ELEMENT_IS_SOURCE(el) g_str_has_suffix(el, "source")
+#define MS_ELEMENT_IS_AUDIO(el) g_str_has_prefix(el, "audio")
+#define MS_ELEMENT_IS_VIDEO(el) g_str_has_prefix(el, "video")
+
+void __ms_generate_dots(GstElement *bin, gchar *name_tag)
+{
+       gchar *dot_name;
+       ms_retm_if(bin == NULL, "Handle is NULL");
+
+       if (!name_tag)
+       {
+               dot_name = g_strdup(DOT_FILE_NAME);
+       }
+       else
+       {
+               dot_name = g_strconcat (DOT_FILE_NAME, ".", name_tag, NULL);
+       }
+
+       GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS(GST_BIN(bin), GST_DEBUG_GRAPH_SHOW_ALL, dot_name);
+
+       MS_SAFE_GFREE (dot_name);
+}
+
+const char *_ms_state_to_string(GstState state)
+{
+       static const char pending[] = "PENDING\0";
+       static const char null_s[] = "NULL\0";
+       static const char ready[] = "READY\0";
+       static const char paused[] = "PAUSED\0";
+       static const char playing[] = "PLAYING\0";
+       switch(state)
+       {
+               case GST_STATE_VOID_PENDING:
+                       return pending;
+                       break;
+               case GST_STATE_NULL:
+                       return null_s;
+                       break;
+               case GST_STATE_READY:
+                       return ready;
+                       break;
+               case GST_STATE_PAUSED:
+                       return paused;
+                       break;
+               case GST_STATE_PLAYING:
+                       return playing;
+                       break;
+               default:
+                       return "\0";
+                       break;
+       };
+       return 0;
+}
+
+static int __ms_add_ghostpad(GstElement *gst_element,
+                               const char *pad_name,
+                               GstElement *gst_bin,
+                               const char *ghost_pad_name)
+{
+       ms_retvm_if(!ghost_pad_name || !gst_bin, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+
+       int ret = MEDIA_STREAMER_ERROR_NONE;
+
+       GstPad *ghost_pad = NULL;
+       gchar *bin_name = gst_element_get_name(gst_bin);
+
+       if(!gst_element || !pad_name)
+       {
+               ghost_pad = gst_ghost_pad_new_no_target(ghost_pad_name, GST_PAD_SRC);
+               gst_element_add_pad(GST_ELEMENT(gst_bin), ghost_pad);
+                                       ms_info("Added %s empty ghostpad into [%s]", bin_name);
+                                       ret = MEDIA_STREAMER_ERROR_NONE;
+       }
+       else
+       {
+               gchar *element_name = gst_element_get_name(gst_element);
+               GstPad *element_pad = gst_element_get_static_pad(gst_element, pad_name);
+               if(!element_pad)
+               {
+                       //maybe it is request pad
+                       element_pad = gst_element_get_request_pad(gst_element, pad_name);
+               }
+               if(element_pad != NULL)
+               {
+                       ghost_pad = gst_ghost_pad_new(ghost_pad_name, element_pad);
+                       gst_pad_set_active(ghost_pad, TRUE);
+
+                       gst_element_add_pad(GST_ELEMENT(gst_bin), ghost_pad);
+                       ms_info("Added %s ghostpad from [%s] into [%s]", pad_name, element_name, bin_name);
+                       MS_SAFE_UNREF(element_pad);
+                       MS_SAFE_GFREE(element_name);
+
+                       ret = MEDIA_STREAMER_ERROR_NONE;
+               }
+               else
+               {
+                       ms_error("Error: element [%s] does not have valid [%s] pad for adding into [%s] bin",
+                                       element_name, pad_name, bin_name);
+                       ret = MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+               }
+       }
+
+       MS_SAFE_GFREE(bin_name);
+
+       return ret;
+}
+
+static GObject *__ms_get_property_owner(GstElement *element, const gchar *key, GValue *value)
+{
+       GParamSpec *param;
+       GObject *obj = NULL;
+
+       if (GST_IS_CHILD_PROXY(element))
+       {
+               int i;
+               int childs_count = gst_child_proxy_get_children_count(GST_CHILD_PROXY(element));
+
+               param = NULL;
+               for(i = 0; (i < childs_count) && (param == NULL); ++i)
+               {
+                       obj = gst_child_proxy_get_child_by_index(GST_CHILD_PROXY(element),i);
+                       param = g_object_class_find_property(G_OBJECT_GET_CLASS(obj), key);
+               }
+               ms_retvm_if(param == NULL || obj == NULL, NULL, "Error: Bin object does not have property [%s].", key);
+       }
+       else
+       {
+               obj = G_OBJECT(element);
+               param = g_object_class_find_property
+                               (G_OBJECT_GET_CLASS(obj), key);
+       }
+
+       g_value_init(value, param->value_type);
+
+       if (param->flags & G_PARAM_WRITABLE)
+       {
+               g_object_get_property(G_OBJECT(obj), key, value);
+       }
+       else
+       {
+               // Skip properties which user can not change.
+               ms_error("Error: node param [%s] is not writable!", key);
+               return NULL;
+       }
+       ms_info("%-20s: %s\n", g_param_spec_get_name(param), g_param_spec_get_blurb(param));
+
+       return obj;
+}
+
+static void __ms_element_set_property(GstElement *element, const gchar *key, const gchar *param_value)
+{
+       gchar *element_name = gst_element_get_name(element);
+       GValue value = G_VALUE_INIT;
+       GObject *obj = __ms_get_property_owner(element, key, &value);
+
+       if(obj == NULL)
+       {
+               ms_debug("Element [%s] does not have property [%s].", element_name, key);
+               MS_SAFE_GFREE(element_name);
+               return;
+       }
+
+       switch(G_VALUE_TYPE(&value))
+       {
+               case G_TYPE_STRING:
+                       g_value_set_string(&value, param_value);
+                       ms_info("Set string value: [%s]", g_value_get_string(&value));
+                       break;
+
+               case G_TYPE_BOOLEAN:
+               {
+                       gboolean bool_val = !g_strcmp0(param_value, "true") ? TRUE : FALSE;
+                       g_value_set_boolean(&value, bool_val);
+                       ms_info("Set boolean value: [%d]", g_value_get_boolean(&value));
+                       break;
+               }
+
+               case G_TYPE_ULONG:
+               {
+                       unsigned long pulong = atol(param_value);
+                       g_value_set_ulong(&value, pulong);
+                       ms_info("Set ulong value: [%lu]", g_value_get_ulong(&value));
+                       break;
+               }
+
+               case G_TYPE_LONG:
+               {
+                       long plong = atol(param_value);
+                       g_value_set_long(&value, plong);
+                       ms_info("Set long value: [%ld]", g_value_get_long(&value));
+                       break;
+               }
+
+               case G_TYPE_UINT:
+               {
+                       unsigned int puint = atoi(param_value);
+                       g_value_set_uint(&value, puint);
+                       ms_info("Set uint value: [%u]", g_value_get_uint(&value));
+                       break;
+               }
+
+               case G_TYPE_INT:
+               {
+                       int pint = atoi(param_value);
+                       g_value_set_int(&value, pint);
+                       ms_info("Set int value: [%d]", g_value_get_int(&value));
+                       break;
+               }
+
+               case G_TYPE_UINT64:
+               {
+                       unsigned long long puint64 = strtoull(param_value, NULL, 10);
+                       g_value_set_uint64(&value, puint64);
+                       ms_info("Set long value: [%llu]", g_value_get_uint64(&value));
+                       break;
+               }
+
+               case G_TYPE_INT64:
+               {
+                       long long pint64 = strtoll(param_value, NULL, 10);
+                       g_value_set_int64(&value, pint64);
+                       ms_info("Set long value: [%ll]", g_value_get_int64(&value));
+                       break;
+               }
+               case G_TYPE_FLOAT:
+               {
+                       float pfloat = strtof(param_value, NULL);
+                       g_value_set_float(&value, pfloat);
+                       ms_info("Set long value: [%15.7g]", g_value_get_float(&value));
+                       break;
+               }
+               case G_TYPE_DOUBLE:
+               {
+                       double pdouble = strtod(param_value, NULL);
+                       g_value_set_double(&value, pdouble);
+                       ms_info("Set long value: [%15.7g]", g_value_get_float(&value));
+                       break;
+       }
+       default:
+               if(G_VALUE_TYPE(&value) == GST_TYPE_CAPS)
+               {
+                       GstCaps *caps = gst_caps_from_string(param_value);
+
+                       if (!caps)
+                       {
+                               ms_error("Can not create caps from param value.");
+                       }
+                       else
+                       {
+                               ms_info("Create Caps from params and set to the object.");
+                               g_object_set(obj, key, caps, NULL);
+                               gst_caps_unref(caps);
+                       }
+                       return;
+               }
+               else
+               {
+                       ms_info("Got unknown type with param->value_type [%d]", G_VALUE_TYPE(&value));
+                       return;
+               }
+               break;
+       }
+       g_object_set_property(obj, key, &value);
+       MS_SAFE_GFREE(element_name);
+}
+
+#if 0
+static void __ms_link_elements_on_pad_added_cb(GstPad *new_pad, GstElement *sink_element)
+{
+       GstPadLinkReturn ret;
+       GstPad *sink_pad;
+       gchar *new_pad_name = NULL;
+       gchar *sink_element_name = NULL;
+       gchar *peer_pad_name = NULL;
+       GstPad *peer_pad = NULL;
+
+       sink_pad = gst_element_get_static_pad(sink_element, "sink");
+       ms_retm_if(sink_pad == NULL, "Sinkpad is NULL");
+
+       sink_element_name = gst_element_get_name(sink_element);
+       new_pad_name = gst_pad_get_name(new_pad);
+
+       if(!gst_pad_is_linked(sink_pad))
+       {
+               ms_info("Pads [rtpbin].[%s] and [%s].[sink] are not linked\n", new_pad_name, sink_element_name);
+
+               ret = gst_pad_link(new_pad, sink_pad);
+               if(GST_PAD_LINK_FAILED (ret))
+               {
+                       ms_error("Failed to link [rtpbin].[%s] and [%s].[sink]\n", new_pad_name, sink_element_name);
+               }
+               else
+               {
+                       ms_info("Succeeded to link [rtpbin].[%s]->[%s].[sink]\n", new_pad_name, sink_element_name);
+               }
+       }
+       else
+       {
+               peer_pad = gst_pad_get_peer(sink_pad);
+               peer_pad_name = gst_pad_get_name(peer_pad);
+
+               ms_debug("Pads [rtpbin].[%s]->[%s].[sink] are previously linked\n", peer_pad_name, sink_element_name);
+
+               ret = gst_pad_unlink(peer_pad, sink_pad);
+               if(!ret)
+               {
+                       ms_error("Filed to unlink pads [rtpbin].[%s] <-and-> [%s].[sink] \n", peer_pad_name, sink_element_name);
+               }
+               else
+               {
+                       ms_info("Pads [rtpbin].[%s] <-and-> [%s].[sink] are unlinked successfully\n", peer_pad_name, sink_element_name);
+               }
+
+               ret = gst_pad_link(new_pad, sink_pad);
+               if(GST_PAD_LINK_FAILED(ret))
+               {
+                       ms_error("Failed to link [rtpbin].[%s] and [%s].[sink]\n", new_pad_name, sink_element_name);
+               }
+               else
+               {
+                       ms_info("Succeeded to link [rtpbin].[%s]->[%s].[sink]\n", new_pad_name, sink_element_name);
+               }
+       }
+
+       MS_SAFE_GFREE(sink_element_name);
+       MS_SAFE_GFREE(new_pad_name);
+       MS_SAFE_GFREE(peer_pad_name);
+}
+
+static void __ms_got_rtpstream_on_pad_added_cb(media_streamer_node_s *ms_node, GstPad *new_pad, const gchar *compared_type)
+{
+       GstPad *src_pad;
+       GstCaps *src_pad_caps = NULL;
+       GstStructure *src_pad_struct = NULL;
+
+       gchar *sink_element_name = NULL;
+       GstElement *sink_element;
+
+       GValue elem=G_VALUE_INIT;
+       const gchar *depay_klass_name = "Codec/Depayloader/Network/RTP";
+       GstIterator *bin_iterator;
+
+       gchar *new_pad_name = gst_pad_get_name(new_pad);
+       gchar *source_pad_name = g_strdup_printf("%s_source", compared_type);
+
+       bin_iterator = gst_bin_iterate_elements(GST_BIN(ms_node->parent_streamer->topology_bin));
+       while(GST_ITERATOR_OK == gst_iterator_next(bin_iterator, &elem))
+       {
+
+               sink_element = (GstElement *)g_value_get_object(&elem);
+               sink_element_name = gst_element_get_name(sink_element);
+
+               const gchar *klass_name = gst_element_factory_get_klass(gst_element_get_factory(sink_element));
+
+               if( g_strrstr(klass_name, depay_klass_name))
+               {
+                       src_pad = gst_element_get_static_pad (sink_element, "src");
+                       ms_retm_if(src_pad == NULL, "Src pad is NULL");
+
+                       src_pad_caps = gst_pad_query_caps(src_pad,NULL);
+                       src_pad_struct = gst_caps_get_structure(src_pad_caps, 0);
+                       const gchar *src_pad_type = gst_structure_get_name(src_pad_struct);
+
+                       if (g_strrstr(src_pad_type, compared_type))
+                       {
+                               ms_debug("Element to connect [%s] has type [%s] \n", sink_element_name, src_pad_type);
+                               GstPad *video_source_pad = gst_element_get_static_pad(ms_node->gst_element, source_pad_name);
+
+                               gst_ghost_pad_set_target(GST_GHOST_PAD(video_source_pad), new_pad);
+                               gst_pad_set_active(video_source_pad, TRUE);
+                               __ms_generate_dots(ms_node->parent_streamer->pipeline);
+                       }
+
+                       gst_caps_unref(src_pad_caps);
+
+                       MS_SAFE_UNREF(src_pad);
+               }
+               g_value_reset(&elem);
+       }
+       g_value_unset(&elem);
+       gst_iterator_free(bin_iterator);
+       MS_SAFE_GFREE(sink_element_name);
+       MS_SAFE_GFREE(source_pad_name);
+       MS_SAFE_FREE(new_pad_name);
+}
+#endif
+
+static void __ms_rtpbin_pad_added_cb(GstElement *src, GstPad *new_pad, gpointer user_data)
+{
+       GstCaps *src_pad_caps = NULL;
+       GstStructure *src_pad_struct = NULL;
+       GstPad *target_pad = NULL;
+
+       gchar *new_pad_name = NULL;
+       gchar *src_element_name = NULL;
+
+       media_streamer_node_s *ms_node = (media_streamer_node_s *)user_data;
+       ms_retm_if(ms_node == NULL, "Handle is NULL");
+
+       new_pad_name = gst_pad_get_name(new_pad);
+       src_element_name = gst_element_get_name(src);
+       ms_debug("Pad [%s] added on [%s]\n", new_pad_name, src_element_name);
+
+       target_pad = gst_ghost_pad_get_target(GST_GHOST_PAD(new_pad));
+       src_pad_caps = gst_pad_query_caps(target_pad,NULL);
+       src_pad_struct = gst_caps_get_structure(src_pad_caps, 0);
+
+       const gchar *src_pad_type = gst_structure_get_string(src_pad_struct, "media");
+       ms_debug("type is [%s]", src_pad_type);
+
+       if(ms_node->parent_streamer == NULL)
+       {
+               ms_error("Node doesn`t have parent streamer:\n");
+       }
+       else
+       {
+               gchar *source_pad_name = NULL;
+               GstElement *sink_bin = NULL;
+               if(g_strrstr(src_pad_type, "video"))
+               {
+                       source_pad_name = g_strdup_printf("%s_source", "video");
+                       sink_bin = ms_node->parent_streamer->sink_video_bin;
+               }
+               else if(g_strrstr(src_pad_type, "audio"))
+               {
+                       source_pad_name = g_strdup_printf("%s_source", "audio");
+                       sink_bin = ms_node->parent_streamer->sink_audio_bin;
+               }
+
+               if(source_pad_name != NULL)
+               {
+                       if(gst_object_get_parent(GST_OBJECT(sink_bin)) == NULL)
+                       {
+                               gst_bin_add(GST_BIN(ms_node->parent_streamer->pipeline), sink_bin);
+                       }
+                       gst_element_sync_state_with_parent(sink_bin);
+
+
+                       GstPad *source_pad = gst_element_get_static_pad(ms_node->gst_element, source_pad_name);
+                       gst_ghost_pad_set_target(GST_GHOST_PAD(source_pad), new_pad);
+                       gst_pad_set_active(source_pad, TRUE);
+
+                       GstPad *sink_pad = gst_bin_find_unlinked_pad(GST_BIN(sink_bin), GST_PAD_SINK);
+                       if(sink_pad != NULL)
+                       {
+                               __ms_add_ghostpad(gst_pad_get_parent(sink_pad), "sink", sink_bin, "sink");
+                               if (gst_element_link_pads(ms_node->gst_element, source_pad_name, sink_bin, "sink"))
+                               {
+                                       __ms_element_set_state(ms_node->gst_element, GST_STATE_PLAYING);
+                                       __ms_generate_dots(ms_node->parent_streamer->pipeline, "playing");
+                               }
+                               else
+                               {
+                                       ms_error("Failed to link [rtp_containeer].[%s] and [sink_bin].[sink]\n", source_pad_name);
+                               }
+                               MS_SAFE_UNREF(sink_pad);
+                       }
+                       MS_SAFE_UNREF(source_pad);
+                       MS_SAFE_GFREE(source_pad_name);
+               }
+       }
+
+       gst_caps_unref(src_pad_caps);
+       MS_SAFE_UNREF(target_pad);
+       MS_SAFE_GFREE(new_pad_name);
+       MS_SAFE_GFREE(src_element_name);
+}
+
+int __ms_element_set_state(GstElement *gst_element, GstState gst_state)
+{
+       ms_retvm_if(gst_element == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+
+       GstStateChangeReturn ret_state;
+       gchar *element_name = gst_element_get_name(gst_element);
+
+       ret_state = gst_element_set_state(gst_element, gst_state);
+       if(ret_state == GST_STATE_CHANGE_FAILURE)
+       {
+               ms_error("Failed to set element [%s] into %s state", element_name, _ms_state_to_string(gst_state));
+               MS_SAFE_GFREE(element_name);
+               return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+       }
+
+       MS_SAFE_GFREE(element_name);
+       return MEDIA_STREAMER_ERROR_NONE;
+}
+
+GstElement *__ms_element_create(const char *plugin_name, const char *name)
+{
+       ms_retvm_if(plugin_name == NULL, (GstElement*)NULL, "Error empty plugin name");
+       ms_info("Creating [%s] element", plugin_name);
+       return gst_element_factory_make(plugin_name, name);
+}
+
+GstElement *__ms_camera_element_create(const char *camera_plugin_name)
+{
+       ms_retvm_if(camera_plugin_name == NULL, (GstElement*)NULL, "Error empty camera plugin name");
+
+       gboolean gst_ret = FALSE;
+       GstElement *camera_bin = gst_bin_new("camera_src");
+       GstElement *camera_elem = __ms_element_create(camera_plugin_name, NULL);
+       GstElement *filter = __ms_element_create("capsfilter", NULL);
+       GstElement *scale = __ms_element_create("videoscale", NULL);
+       GstElement *videoconvert = __ms_element_create("videoconvert", NULL);
+       ms_retvm_if(!filter || !camera_elem || !camera_bin || !scale || !videoconvert , (GstElement*)NULL,
+                       "Error: creating elements for camera bin");
+
+       GstCaps *videoCaps = gst_caps_from_string(MEDIA_STREAMER_DEFAULT_CAMERA_FORMAT);
+       g_object_set (G_OBJECT (filter), "caps", videoCaps, NULL);
+       gst_caps_unref(videoCaps);
+
+       gst_bin_add_many(GST_BIN(camera_bin), camera_elem, filter, scale, videoconvert, NULL);
+       gst_ret = gst_element_link_many(camera_elem, filter, scale, videoconvert, NULL);
+       if (gst_ret != TRUE)
+       {
+               ms_error("Failed to link elements into camerabin");
+               MS_SAFE_UNREF(camera_bin);
+       }
+
+       __ms_add_ghostpad(videoconvert, "src", camera_bin, "src");
+
+       return camera_bin;
+}
+
+GstElement *__ms_video_encoder_element_create(dictionary *dict , media_format_mimetype_e mime)
+{
+       char *plugin_name = NULL;
+       char *format_prefix = NULL;
+
+       format_prefix = g_strdup_printf("%s:encoder", __ms_convert_mime_to_string(mime));
+       plugin_name = __ms_ini_get_string(dict, format_prefix, DEFAULT_VIDEO_DECODER);
+       GstElement *encoder_elem = __ms_element_create(plugin_name,NULL);
+       MS_SAFE_FREE(format_prefix);
+       MS_SAFE_FREE(plugin_name);
+
+       format_prefix = g_strdup_printf("%s:parser", __ms_convert_mime_to_string(mime));
+       plugin_name = __ms_ini_get_string(dict, format_prefix, DEFAULT_VIDEO_PARSER);
+       GstElement *encoder_parser = __ms_element_create(plugin_name,NULL);
+       MS_SAFE_FREE(format_prefix);
+       MS_SAFE_FREE(plugin_name);
+
+       gboolean gst_ret = FALSE;
+       GstElement *encoder_bin = gst_bin_new("video_encoder");
+       GstElement *filter = __ms_element_create("capsfilter", NULL);
+       ms_retvm_if(!filter || !encoder_elem || !encoder_bin || !encoder_parser, (GstElement*)NULL,
+                       "Error: creating elements for video encoder bin");
+
+       format_prefix = g_strdup_printf("video/x-%s,stream-format=byte-stream,profile=high",
+                                       __ms_convert_mime_to_string(mime));
+       GstCaps *videoCaps = gst_caps_from_string(format_prefix);
+       g_object_set(G_OBJECT(filter), "caps", videoCaps, NULL);
+       MS_SAFE_FREE(format_prefix);
+
+       gst_caps_unref(videoCaps);
+
+       gst_bin_add_many(GST_BIN(encoder_bin), encoder_elem, filter, encoder_parser, NULL);
+       gst_ret = gst_element_link_many(encoder_elem, filter, encoder_parser, NULL);
+       if (gst_ret != TRUE)
+       {
+               ms_error("Failed to link elements into encoder_bin");
+               MS_SAFE_UNREF(encoder_bin);
+       }
+
+       __ms_add_ghostpad(encoder_parser, "src", encoder_bin, "src");
+       __ms_add_ghostpad(encoder_elem, "sink", encoder_bin, "sink");
+
+       return encoder_bin;
+}
+
+GstElement *__ms_video_decoder_element_create(dictionary *dict , media_format_mimetype_e mime)
+{
+       char *plugin_name = NULL;
+       char *format_prefix = NULL;
+       gboolean is_omx = FALSE;
+       GstElement *last_elem = NULL;
+
+       format_prefix = g_strdup_printf("%s:decoder", __ms_convert_mime_to_string(mime));
+       plugin_name = __ms_ini_get_string(dict, format_prefix, DEFAULT_VIDEO_DECODER);
+       GstElement *decoder_elem = __ms_element_create(plugin_name,NULL);
+       MS_SAFE_FREE(format_prefix);
+       MS_SAFE_FREE(plugin_name);
+
+       format_prefix = g_strdup_printf("%s:parser", __ms_convert_mime_to_string(mime));
+       plugin_name = __ms_ini_get_string(dict, format_prefix, DEFAULT_VIDEO_PARSER);
+       GstElement *decoder_parser = __ms_element_create(plugin_name,NULL);
+
+       if(mime == MEDIA_FORMAT_H264_SP)
+       {
+               g_object_set(G_OBJECT(decoder_parser), "config-interval", 5, NULL);
+       }
+
+       is_omx = g_strrstr(format_prefix, "omx");
+       MS_SAFE_FREE(format_prefix);
+       MS_SAFE_FREE(plugin_name);
+
+       gboolean gst_ret = FALSE;
+       GstElement *decoder_bin = gst_bin_new("video_decoder");
+       GstElement *decoder_queue = __ms_element_create("queue",NULL);
+       ms_retvm_if(!decoder_elem || !decoder_queue || !decoder_bin || !decoder_parser, (GstElement*)NULL,
+                       "Error: creating elements for video decoder bin");
+
+       gst_bin_add_many(GST_BIN(decoder_bin), decoder_queue, decoder_elem, decoder_parser, NULL);
+       gst_ret = gst_element_link_many(decoder_queue, decoder_parser, decoder_elem, NULL);
+       if (gst_ret != TRUE)
+       {
+               ms_error("Failed to link elements into decoder_bin");
+               MS_SAFE_UNREF(decoder_bin);
+               return NULL;
+       }
+       last_elem = decoder_elem;
+
+       if(!is_omx)
+       {
+               GstElement *video_conv = __ms_element_create("videoconvert",NULL);
+               GstElement *video_scale = __ms_element_create("videoscale",NULL);
+               ms_retvm_if(!video_conv || !video_scale, (GstElement*)NULL,
+                               "Error: creating elements for video decoder bin");
+               gst_bin_add_many(GST_BIN(decoder_bin), video_conv, video_scale, NULL);
+               gst_ret = gst_element_link_many(decoder_elem, video_conv, video_scale, NULL);
+               if (gst_ret != TRUE)
+               {
+                       ms_error("Failed to link elements into decoder_bin");
+                       MS_SAFE_UNREF(decoder_bin);
+                       return NULL;
+               }
+               last_elem = video_scale;
+       }
+
+       __ms_add_ghostpad(last_elem, "src", decoder_bin, "src");
+       __ms_add_ghostpad(decoder_queue, "sink", decoder_bin, "sink");
+
+       return decoder_bin;
+}
+
+GstElement *__ms_audio_encoder_element_create(void)
+{
+       gboolean gst_ret = FALSE;
+       GstElement *audio_convert = __ms_element_create("audioconvert",NULL);
+       GstElement *audio_filter = __ms_element_create("capsfilter",NULL);
+       GstElement *audio_enc_bin = gst_bin_new("audio_encoder");
+       ms_retvm_if(!audio_convert || !audio_filter || !audio_enc_bin, (GstElement*)NULL,
+                       "Error: creating elements for encoder bin");
+
+       GstCaps *audioCaps = gst_caps_from_string(MEDIA_STREAMER_DEFAULT_AUDIO_FORMAT);
+       g_object_set(G_OBJECT(audio_filter), "caps", audioCaps, NULL);
+       gst_caps_unref(audioCaps);
+
+       gst_bin_add_many(GST_BIN(audio_enc_bin), audio_convert, audio_filter, NULL);
+       gst_ret = gst_element_link_many(audio_filter, audio_convert, NULL);
+       if (gst_ret != TRUE)
+       {
+               ms_error("Failed to link elements into decoder_bin");
+               MS_SAFE_UNREF(audio_enc_bin);
+       }
+
+       __ms_add_ghostpad(audio_convert, "src", audio_enc_bin, "src");
+       __ms_add_ghostpad(audio_filter, "sink", audio_enc_bin, "sink");
+
+       return audio_enc_bin;
+}
+
+GstElement *__ms_rtp_element_create(media_streamer_node_s *ms_node)
+{
+       ms_retvm_if(ms_node == NULL, (GstElement*)NULL, "Error empty rtp node Handle");
+
+       GstElement *rtp_container = gst_bin_new("rtp_container");
+       GstElement *rtp_elem = __ms_element_create("rtpbin", "rtpbin");
+       ms_retvm_if(!rtp_container || !rtp_elem, (GstElement*)NULL,
+                       "Error: creating elements for rtp container");
+
+       gst_bin_add(GST_BIN(rtp_container), rtp_elem);
+       g_signal_connect (rtp_elem, "pad-added", G_CALLBACK (__ms_rtpbin_pad_added_cb), ms_node);
+
+       return rtp_container;
+}
+
+static gboolean __ms_get_rtp_elements(media_streamer_node_s *ms_node,
+                               GstElement **rtp_elem, GstElement **rtcp_elem, const gchar *elem_name)
+{
+       gboolean ret = FALSE;
+       gchar *rtp_elem_name = NULL;
+       gchar *rtcp_elem_name = NULL;
+       gchar *plugin_name = NULL;
+
+       GstElement *rtpbin = gst_bin_get_by_name(GST_BIN(ms_node->gst_element), "rtpbin");
+
+       ms_retvm_if(!elem_name, FALSE, "Empty rtp element name.");
+
+       if(MS_ELEMENT_IS_SOURCE(elem_name))
+       {
+               plugin_name = g_strdup("udpsrc");
+       }
+       else if(MS_ELEMENT_IS_SINK(elem_name))
+       {
+               plugin_name = g_strdup("udpsink");
+       }
+       else
+       {
+               ms_error("Error: invalid parameter name [%s]", elem_name);
+               return FALSE;
+       }
+
+       rtp_elem_name = g_strdup_printf("%s_rtp", elem_name);
+       rtcp_elem_name = g_strdup_printf("%s_rtcp", elem_name);
+
+       // Find video udp rtp/rtcp element if it present.
+       *rtp_elem = gst_bin_get_by_name(GST_BIN(ms_node->gst_element), rtp_elem_name);
+       *rtcp_elem = gst_bin_get_by_name(GST_BIN(ms_node->gst_element), rtcp_elem_name);
+
+       // Create new udp element if it did not found.
+       if((NULL == *rtp_elem) && (NULL == *rtcp_elem))
+       {
+               *rtp_elem = __ms_element_create(plugin_name, rtp_elem_name);
+               *rtcp_elem = __ms_element_create(plugin_name, rtcp_elem_name);
+       }
+       else
+       {
+               //rtp/rtcp elements already into rtp bin.
+               MS_SAFE_GFREE(rtp_elem_name);
+               MS_SAFE_GFREE(rtcp_elem_name);
+               MS_SAFE_GFREE(plugin_name);
+               return TRUE;
+       }
+
+       gst_bin_add_many(GST_BIN(ms_node->gst_element),
+                       *rtp_elem, *rtcp_elem, NULL);
+
+       if(MS_ELEMENT_IS_SINK(elem_name))
+       {
+               g_object_set(GST_OBJECT(*rtcp_elem), "sync", FALSE, NULL);
+               g_object_set(GST_OBJECT(*rtcp_elem), "async", FALSE, NULL);
+
+               if(MS_ELEMENT_IS_VIDEO(elem_name))
+               {
+                       __ms_add_ghostpad(rtpbin, "send_rtp_sink_0", ms_node->gst_element, "video_sink");
+                       ret = gst_element_link_pads(rtpbin, "send_rtp_src_0", *rtp_elem, "sink") &&
+                                       gst_element_link_pads(rtpbin, "send_rtcp_src_0",*rtcp_elem, "sink");
+               }
+               else
+               {
+                       __ms_add_ghostpad(rtpbin, "send_rtp_sink_1", ms_node->gst_element, "audio_sink");
+                       ret = gst_element_link_pads(rtpbin, "send_rtp_src_1", *rtp_elem, "sink") &&
+                                       gst_element_link_pads(rtpbin, "send_rtcp_src_1",*rtcp_elem, "sink");
+               }
+       }
+       else
+       {
+               if(MS_ELEMENT_IS_VIDEO(elem_name))
+               {
+                       ret = gst_element_link_pads(*rtp_elem, "src", rtpbin, "recv_rtp_sink_0") &&
+                                       gst_element_link_pads (*rtcp_elem, "src", rtpbin, "recv_rtcp_sink_0");
+                       __ms_add_ghostpad(NULL, NULL, ms_node->gst_element, "video_source");
+               }
+               else
+               {
+                       ret = gst_element_link_pads(*rtp_elem, "src", rtpbin, "recv_rtp_sink_1") &&
+                                       gst_element_link_pads (*rtcp_elem, "src", rtpbin, "recv_rtcp_sink_1");
+                       __ms_add_ghostpad(NULL, NULL, ms_node->gst_element, "audio_source");
+               }
+       }
+
+       if(!ret)
+       {
+               ms_error("Can not link [rtpbin] pad to [%s] pad, ret code [%d] ", rtp_elem, ret);
+               ret = MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+       }
+
+       __ms_generate_dots(ms_node->gst_element, "rtp");
+       MS_SAFE_GFREE(rtp_elem_name);
+       MS_SAFE_GFREE(rtcp_elem_name);
+       MS_SAFE_GFREE(plugin_name);
+
+       return ret;
+}
+
+int __ms_rtp_set_param(
+                               media_streamer_node_s *ms_node,
+                               const gchar *param_key,
+                               const gchar *param_value)
+{
+       ms_retvm_if(!ms_node && !ms_node->gst_element, MEDIA_STREAMER_ERROR_NONE, "Error: empty node");
+
+       gchar **tokens = NULL;
+       gchar *elem_name = NULL;
+       guint i = 0;
+       GstElement *rtp_elem = NULL;
+       GstElement *rtcp_elem = NULL;
+
+       tokens = g_strsplit(param_key,",",3);
+       ms_retvm_if(tokens == NULL, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Invalid rtp parameter line.");
+       elem_name = tokens[0];
+
+       if(FALSE == __ms_get_rtp_elements(ms_node, &rtp_elem, &rtcp_elem, elem_name))
+       {
+               ms_error("Error: invalid parameter [%s]", param_key);
+               return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+       }
+
+       for(i = 1; (tokens && tokens[i]); i++)
+       {
+               ms_retvm_if(!rtp_elem || !rtcp_elem,
+                               MEDIA_STREAMER_ERROR_INVALID_OPERATION,
+                               "Error: [%s] did not found or created into streamer", tokens[i]);
+
+               if(!g_strcmp0(tokens[i], "port"))
+               {
+                       __ms_element_set_property(rtp_elem, tokens[i], param_value);
+                       gchar *next_port = g_strdup(param_value);
+                       next_port[strlen(next_port)-1] += 1;
+                       __ms_element_set_property(rtcp_elem, tokens[i], next_port);
+                       MS_SAFE_GFREE(next_port);
+               }
+               else if(!g_strcmp0(tokens[i], "host") && MS_ELEMENT_IS_SINK(elem_name))
+               {
+                       __ms_element_set_property(rtp_elem, tokens[i], param_value);
+                       __ms_element_set_property(rtcp_elem, tokens[i], param_value);
+               }
+               else if(!g_strcmp0(tokens[i], "format") && MS_ELEMENT_IS_SOURCE(elem_name))
+               {
+                       __ms_element_set_property(rtp_elem, "caps", param_value);
+               }
+
+       }
+       g_strfreev(tokens);
+
+       return MEDIA_STREAMER_ERROR_NONE;
+}
+
+int __ms_add_node_into_bin(media_streamer_s *ms_streamer,media_streamer_node_s *ms_node)
+{
+       int ret = MEDIA_STREAMER_ERROR_NONE;
+       ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Handle is NULL");
+       ms_retvm_if(ms_node == NULL, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Handle is NULL");
+
+       ms_info("Try to add [%s] node into streamer, node type/subtype [%d/%d]",
+                       ms_node->name, ms_node->type, ms_node->subtype);
+
+       gchar *bin_name = NULL;
+       gboolean gst_ret = FALSE;
+
+       switch(ms_node->type)
+       {
+               case MEDIA_STREAMER_NODE_TYPE_SRC:
+                       gst_ret = gst_bin_add(GST_BIN(ms_streamer->src_bin),ms_node->gst_element);
+                       bin_name = g_strdup(MEDIA_STREAMER_SRC_BIN_NAME);
+                       break;
+               case MEDIA_STREAMER_NODE_TYPE_SINK:
+                       switch(ms_node->subtype)
+                       {
+                               case MEDIA_STREAMER_SINK_TYPE_SCREEN:
+                                       gst_ret = gst_bin_add(GST_BIN(ms_streamer->sink_video_bin),ms_node->gst_element);
+                                       bin_name = g_strdup(MEDIA_STREAMER_VIDEO_SINK_BIN_NAME);
+                                       break;
+                               case MEDIA_STREAMER_SINK_TYPE_AUDIO:
+                                       gst_ret = gst_bin_add(GST_BIN(ms_streamer->sink_audio_bin),ms_node->gst_element);
+                                       bin_name = g_strdup(MEDIA_STREAMER_AUDIO_SINK_BIN_NAME);
+                                       break;
+                               default:
+                                       gst_ret = gst_bin_add(GST_BIN(ms_streamer->sink_video_bin),ms_node->gst_element);
+                                       bin_name = g_strdup(MEDIA_STREAMER_VIDEO_SINK_BIN_NAME);
+                                       break;
+                       }
+                       break;
+               case MEDIA_STREAMER_NODE_TYPE_AUDIO_ENCODER:
+                       gst_ret = gst_bin_add(GST_BIN(ms_streamer->topology_bin),ms_node->gst_element);
+                       bin_name = g_strdup(MEDIA_STREAMER_TOPOLOGY_BIN_NAME);
+                       break;
+               case MEDIA_STREAMER_NODE_TYPE_VIDEO_DECODER:
+                       gst_ret = gst_bin_add(GST_BIN(ms_streamer->sink_video_bin),ms_node->gst_element);
+                       bin_name = g_strdup(MEDIA_STREAMER_VIDEO_SINK_BIN_NAME);
+                       break;
+               case MEDIA_STREAMER_NODE_TYPE_VIDEO_DEPAY:
+                       gst_ret = gst_bin_add(GST_BIN(ms_streamer->sink_video_bin),ms_node->gst_element);
+                       bin_name = g_strdup(MEDIA_STREAMER_VIDEO_SINK_BIN_NAME);
+                       break;
+               case MEDIA_STREAMER_NODE_TYPE_AUDIO_DEPAY:
+                       gst_ret = gst_bin_add(GST_BIN(ms_streamer->sink_audio_bin),ms_node->gst_element);
+                       bin_name = g_strdup(MEDIA_STREAMER_AUDIO_SINK_BIN_NAME);
+                       break;
+               case MEDIA_STREAMER_NODE_TYPE_AUDIO_RESAMPLE:
+                       gst_ret = gst_bin_add(GST_BIN(ms_streamer->sink_audio_bin),ms_node->gst_element);
+                       bin_name = g_strdup(MEDIA_STREAMER_AUDIO_SINK_BIN_NAME);
+                       break;
+               case MEDIA_STREAMER_NODE_TYPE_AUDIO_CONVERTER:
+                       gst_ret = gst_bin_add(GST_BIN(ms_streamer->sink_audio_bin),ms_node->gst_element);
+                       bin_name = g_strdup(MEDIA_STREAMER_AUDIO_SINK_BIN_NAME);
+                       break;
+               default:
+                       // Another elements will be add into topology bin
+                       gst_ret = gst_bin_add(GST_BIN(ms_streamer->topology_bin),ms_node->gst_element);
+                       bin_name = g_strdup(MEDIA_STREAMER_TOPOLOGY_BIN_NAME);
+                       break;
+       }
+
+       if(!gst_ret)
+       {
+               ms_error("Failed to add Element [%s] into [%s] bin.", ms_node->name, bin_name);
+               ret = MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+       }
+       else
+       {
+               ms_info("Success added Element [%s] into [%s] bin.", ms_node->name, bin_name);
+               ret = MEDIA_STREAMER_ERROR_NONE;
+       }
+
+       MS_SAFE_GFREE(bin_name);
+
+       return ret;
+}
+
+
+static gboolean __ms_bus_cb(GstBus *bus, GstMessage *message, gpointer userdata)
+{
+       int ret = MEDIA_STREAMER_ERROR_NONE;
+       media_streamer_s *ms_streamer = (media_streamer_s*)userdata;
+       ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+       ms_retvm_if(ms_streamer->pipeline == NULL, MEDIA_STREAMER_ERROR_INVALID_STATE, "Pipeline doesn`t exist");
+
+       /* Parse message */
+       if (message != NULL)
+       {
+               switch (GST_MESSAGE_TYPE(message))
+               {
+                       case GST_MESSAGE_ERROR:
+                       {
+                               GError *err;
+                               gchar *debug;
+                               gst_message_parse_error (message, &err, &debug);
+
+                               ms_error("[Source: %s] Error: %s", GST_OBJECT_NAME(GST_OBJECT_CAST(GST_ELEMENT(GST_MESSAGE_SRC (message)))), err->message);
+
+                               MS_SAFE_FREE(err);
+                               MS_SAFE_FREE(debug);
+                               break;
+                       }
+
+                       case GST_MESSAGE_STATE_CHANGED:
+                       {
+                               if (GST_MESSAGE_SRC (message) == GST_OBJECT (ms_streamer->pipeline))
+                               {
+                                       GstState state_old, state_new, state_pending;
+                                       gchar *state_transition_name;
+
+                                       gst_message_parse_state_changed (message, &state_old, &state_new, &state_pending);
+                                       ms_info ("GST_MESSAGE_STATE_CHANGED: [%s] %s -> %s\n",
+                                               gst_object_get_name(GST_MESSAGE_SRC(message)),
+                                               _ms_state_to_string(state_old),
+                                               _ms_state_to_string(state_new));
+
+                                       state_transition_name = g_strdup_printf ("%s_%s",
+                                               gst_element_state_get_name (state_old),
+                                               gst_element_state_get_name (state_new));
+
+                                       __ms_generate_dots(ms_streamer->pipeline, state_transition_name);
+
+                                       MS_SAFE_GFREE (state_transition_name);
+
+                                       if (state_old == GST_STATE_NULL && state_new == GST_STATE_READY)
+                                       {
+                                               ms_info("[Success] GST_STATE_NULL => GST_STATE_READY");
+
+                                               /* Pause Media_Streamer */
+                                               ret = __ms_element_set_state(ms_streamer->pipeline, GST_STATE_PAUSED);
+                                               if(ret != MEDIA_STREAMER_ERROR_NONE)
+                                               {
+                                                       ms_error("ERROR - Pause pipeline");
+                                                       return FALSE;
+                                               }
+                                       }
+
+                                       if (state_old == GST_STATE_READY && state_new == GST_STATE_PAUSED)
+                                       {
+                                               ms_info("[Success] GST_STATE_READY => GST_STATE_PAUSED");
+
+                                               ret = __ms_element_set_state(ms_streamer->pipeline, GST_STATE_PLAYING);
+                                               if(ret != MEDIA_STREAMER_ERROR_NONE)
+                                               {
+                                                       ms_error("ERROR - Play Pipeline");
+                                                       return FALSE;
+                                               }
+                                       }
+                               }
+                               break;
+                       }
+
+                       case GST_MESSAGE_EOS:
+                       {
+                               ms_info("GST_MESSAGE_EOS end-of-stream");
+                               ret = __ms_element_set_state(ms_streamer->pipeline, GST_STATE_PAUSED);
+                               if(ret != MEDIA_STREAMER_ERROR_NONE)
+                               {
+                                       ms_error("ERROR - Pause Pipeline");
+                                       return FALSE;
+                               }
+                               break;
+                       }
+                       default:
+                               break;
+               }
+       }
+       return TRUE;
+}
+
+int __ms_pipeline_create(media_streamer_s *ms_streamer)
+{
+       ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+
+       gst_init(NULL, NULL);
+
+       ms_streamer->pipeline = gst_pipeline_new(MEDIA_STREAMER_PIPELINE_NAME);
+       ms_retvm_if(ms_streamer->pipeline == NULL,
+                       MEDIA_STREAMER_ERROR_INVALID_OPERATION,"Error creating pipeline");
+
+       ms_streamer->bus = gst_pipeline_get_bus(GST_PIPELINE(ms_streamer->pipeline));
+       ms_retvm_if(ms_streamer->bus == NULL,
+                       MEDIA_STREAMER_ERROR_INVALID_OPERATION,"Error getting the bus of the pipeline");
+
+       ms_streamer->bus_watcher = gst_bus_add_watch (ms_streamer->bus, (GstBusFunc)__ms_bus_cb, ms_streamer);
+
+       ms_streamer->src_bin = gst_bin_new(MEDIA_STREAMER_SRC_BIN_NAME);
+       ms_retvm_if(ms_streamer->src_bin == NULL,
+                       MEDIA_STREAMER_ERROR_INVALID_OPERATION,"Error creating Src bin");
+
+//     g_signal_connect(ms_streamer->src_bin, "element-added", G_CALLBACK(__src_bin_element_added_cb), ms_streamer);
+
+       ms_streamer->sink_video_bin = gst_bin_new(MEDIA_STREAMER_VIDEO_SINK_BIN_NAME);
+       ms_retvm_if(ms_streamer->sink_video_bin == NULL,
+                       MEDIA_STREAMER_ERROR_INVALID_OPERATION,"Error creating Sink bin");
+//     g_signal_connect(ms_streamer->sink_bin, "element-added", G_CALLBACK(__sink_bin_element_added_cb), ms_streamer);
+
+       ms_streamer->sink_audio_bin = gst_bin_new(MEDIA_STREAMER_AUDIO_SINK_BIN_NAME);
+       ms_retvm_if(ms_streamer->sink_audio_bin == NULL,
+                       MEDIA_STREAMER_ERROR_INVALID_OPERATION,"Error creating Audio Sink bin");
+
+       ms_streamer->topology_bin = gst_bin_new(MEDIA_STREAMER_TOPOLOGY_BIN_NAME);
+       ms_retvm_if(ms_streamer->topology_bin == NULL,
+                       MEDIA_STREAMER_ERROR_INVALID_OPERATION,"Error creating Topology bin");
+//     g_signal_connect(ms_streamer->topology_bin, "element-added", G_CALLBACK(__bin_element_added_cb), ms_streamer);
+
+       gst_bin_add_many(GST_BIN(ms_streamer->pipeline), ms_streamer->src_bin,
+                                       ms_streamer->topology_bin, NULL);
+
+       return MEDIA_STREAMER_ERROR_NONE;
+}
+
+static GstCaps *__ms_create_caps_from_fmt(media_format_h fmt)
+{
+       GstCaps *caps = NULL;
+       media_format_mimetype_e mime;
+       gchar *format_name = NULL;
+       int width;
+       int height;
+       int avg_bps;
+       int max_bps;
+       int channel;
+       int samplerate;
+       int bit;
+
+       if (media_format_get_video_info(fmt, &mime, &width, &height, &avg_bps, &max_bps) == MEDIA_PACKET_ERROR_NONE)
+       {
+
+               ms_info("Creating video Caps from media format [width=%d, height=%d, bps=%d, mime=%d]",
+                               width, height, avg_bps, mime);
+
+               if (mime & MEDIA_FORMAT_RAW)
+               {
+                       format_name = g_strdup(__ms_convert_mime_to_string(mime));
+                       caps = gst_caps_new_simple("video/x-raw",
+//                                     "framerate", GST_TYPE_FRACTION, max_bps, avg_bps,
+                                       "format", G_TYPE_STRING, format_name,
+                                       "width", G_TYPE_INT, width,
+                                       "height", G_TYPE_INT, height, NULL);
+               }
+               else
+               {
+                       //mime & MEDIA_FORMAT_ENCODED
+                       format_name = g_strdup_printf("video/x-%s", __ms_convert_mime_to_string(mime));
+                       caps = gst_caps_new_simple(format_name,
+                                       "framerate", GST_TYPE_FRACTION, max_bps, avg_bps,
+                                       "width", G_TYPE_INT, width,
+                                       "height", G_TYPE_INT, height, NULL);
+               }
+
+       }
+       else if (media_format_get_audio_info(fmt, &mime, &channel, &samplerate, &bit, &avg_bps) == MEDIA_PACKET_ERROR_NONE)
+       {
+               ms_info("Creating audio Caps from media format [channel=%d, samplerate=%d, bit=%d, avg_bps=%d, mime=%d]",
+                               channel, samplerate, bit, avg_bps, mime);
+
+               if (mime & MEDIA_FORMAT_RAW)
+               {
+                       format_name = g_strdup(__ms_convert_mime_to_string(mime));
+                       caps = gst_caps_new_simple("audio/x-raw",
+                                       "channels", G_TYPE_INT, channel,
+                                       "format", G_TYPE_STRING, format_name,
+                                       "rate", G_TYPE_INT, samplerate, NULL);
+               }
+               else
+               {
+                       ms_error("Encoded audio formats does not supported yet.");
+               }
+       }
+       else
+       {
+               ms_error("Failed getting media info from fmt.");
+       }
+       MS_SAFE_GFREE(format_name);
+
+       return caps;
+}
+
+int __ms_element_set_fmt(media_streamer_node_s *node, media_format_h fmt)
+{
+       GstCaps *caps = NULL;
+       GObject *obj = NULL;
+       GValue value = G_VALUE_INIT;
+       caps = __ms_create_caps_from_fmt(fmt);
+       ms_retvm_if(caps == NULL, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Fail creating caps from fmt.");
+
+       obj = __ms_get_property_owner(node->gst_element, "caps", &value);
+       gst_value_set_caps(&value, caps);
+       g_object_set_property(obj, "caps", &value);
+       gst_caps_unref(caps);
+
+       return MEDIA_STREAMER_ERROR_NONE;
+}
diff --git a/src/media_streamer_node.c b/src/media_streamer_node.c
new file mode 100755 (executable)
index 0000000..5fb4413
--- /dev/null
@@ -0,0 +1,453 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <media_streamer_node.h>
+#include <media_streamer_util.h>
+#include <media_streamer_gst.h>
+
+int __ms_node_create(media_streamer_node_s *node,
+                               media_format_h in_fmt,
+                               media_format_h out_fmt)
+{
+       ms_retvm_if(node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+
+       dictionary *dict = NULL;
+       char *plugin_name = NULL;
+       media_format_mimetype_e mime;
+
+       if (MEDIA_FORMAT_ERROR_NONE != media_format_get_video_info(out_fmt, &mime, NULL, NULL, NULL, NULL))
+       {
+               media_format_get_audio_info(out_fmt, &mime, NULL, NULL, NULL, NULL);
+       }
+       char* format_prefix = NULL;
+
+       __ms_load_ini_dictionary(&dict);
+
+       switch(node->type)
+       {
+               case MEDIA_STREAMER_NODE_TYPE_VIDEO_ENCODER:
+                       format_prefix = g_strdup_printf("%s:encoder", __ms_convert_mime_to_string(mime));
+                       plugin_name = __ms_ini_get_string(dict,
+                                       format_prefix, DEFAULT_VIDEO_ENCODER);
+                       node->gst_element = __ms_video_encoder_element_create(dict, mime);
+                       break;
+               case MEDIA_STREAMER_NODE_TYPE_VIDEO_DECODER:
+                       format_prefix = g_strdup_printf("%s:decoder", __ms_convert_mime_to_string(mime));
+                       plugin_name = __ms_ini_get_string(dict,
+                                       format_prefix, DEFAULT_VIDEO_DECODER);
+                       node->gst_element = __ms_video_decoder_element_create(dict, mime);
+                       break;
+               case MEDIA_STREAMER_NODE_TYPE_PARSER:
+                       format_prefix = g_strdup_printf("%s:parser", __ms_convert_mime_to_string(mime));
+                       plugin_name = __ms_ini_get_string(dict,
+                                       format_prefix, DEFAULT_VIDEO_PARSER);
+                       node->gst_element = __ms_element_create(plugin_name, NULL);
+                       break;
+               case MEDIA_STREAMER_NODE_TYPE_FILTER:
+                       node->gst_element = __ms_element_create("capsfilter", NULL);
+                       break;
+               case MEDIA_STREAMER_NODE_TYPE_VIDEO_PAY:
+                       format_prefix = g_strdup_printf("%s:rtppay", __ms_convert_mime_to_string(mime));
+                       plugin_name = __ms_ini_get_string(dict,
+                                       format_prefix, DEFAULT_VIDEO_RTPPAY);
+                       node->gst_element = __ms_element_create(plugin_name, NULL);
+                       break;
+               case MEDIA_STREAMER_NODE_TYPE_AUDIO_PAY:
+                       plugin_name = __ms_ini_get_string(dict,
+                                       "audio-raw:rtppay", DEFAULT_AUDIO_RTPPAY);
+                       node->gst_element = __ms_element_create(plugin_name, NULL);
+                       break;
+               case MEDIA_STREAMER_NODE_TYPE_VIDEO_DEPAY:
+                       format_prefix = g_strdup_printf("%s:rtpdepay", __ms_convert_mime_to_string(mime));
+                       plugin_name = __ms_ini_get_string(dict,
+                                       format_prefix, DEFAULT_VIDEO_RTPDEPAY);
+                       node->gst_element = __ms_element_create(plugin_name, NULL);
+                       break;
+               case MEDIA_STREAMER_NODE_TYPE_AUDIO_DEPAY:
+                       plugin_name = __ms_ini_get_string(dict,
+                                       "audio-raw:rtpdepay", DEFAULT_AUDIO_RTPPAY);
+                       node->gst_element = __ms_element_create(plugin_name, NULL);
+                       break;
+               case MEDIA_STREAMER_NODE_TYPE_RTP:
+                       node->gst_element = __ms_rtp_element_create(node);
+                       node->set_param = (media_streamer_node_set_param)__ms_rtp_set_param;
+                       break;
+               case MEDIA_STREAMER_NODE_TYPE_QUEUE:
+                       node->gst_element = __ms_element_create(DEFAULT_QUEUE, NULL);
+                       break;
+               case MEDIA_STREAMER_NODE_TYPE_AUDIO_ENCODER:
+                       node->gst_element = __ms_audio_encoder_element_create();
+                       break;
+               case MEDIA_STREAMER_NODE_TYPE_VIDEO_CONVERTER:
+                       node->gst_element = __ms_element_create("videoconvert", NULL);
+                       break;
+               case MEDIA_STREAMER_NODE_TYPE_AUDIO_CONVERTER:
+                       node->gst_element = __ms_element_create("audioconvert", NULL);
+                       break;
+               case MEDIA_STREAMER_NODE_TYPE_AUDIO_RESAMPLE:
+                       node->gst_element = __ms_element_create("audioresample", NULL);
+                       break;
+               default:
+                       ms_error( "Error: invalid node Type [%d]",node->type);
+                       break;
+       }
+
+       ms_retvm_if(node->gst_element == NULL, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Error creating GstElement");
+
+       node->name = gst_element_get_name(node->gst_element);
+
+       MS_SAFE_FREE(plugin_name);
+       MS_SAFE_FREE(format_prefix);
+       __ms_destroy_ini_dictionary(dict);
+
+       return MEDIA_STREAMER_ERROR_NONE;
+}
+
+
+int __ms_src_node_create(media_streamer_node_s *node)
+{
+       ms_retvm_if(node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+
+       dictionary *dict = NULL;
+       char *plugin_name = NULL;
+
+       __ms_load_ini_dictionary(&dict);
+
+       switch(node->subtype)
+       {
+               case MEDIA_STREAMER_SRC_TYPE_FILE:
+                       ms_error("Error: not implemented yet");
+                       break;
+               case MEDIA_STREAMER_SRC_TYPE_RTSP:
+                       node->gst_element = __ms_element_create(DEFAULT_UDP_SOURCE, NULL);
+                       break;
+               case MEDIA_STREAMER_SRC_TYPE_HTTP:
+                       ms_error("Error: not implemented yet");
+                       break;
+               case MEDIA_STREAMER_SRC_TYPE_CAMERA:
+                       plugin_name = __ms_ini_get_string(dict,
+                                       "sources:camera_source",DEFAULT_CAMERA_SOURCE);
+                       node->gst_element = __ms_camera_element_create(plugin_name);
+
+                       break;
+               case MEDIA_STREAMER_SRC_TYPE_AUDIO_CAPTURE:
+                       plugin_name = __ms_ini_get_string(dict,
+                                       "sources:audio_source",DEFAULT_AUDIO_SOURCE);
+                       node->gst_element = __ms_element_create(plugin_name, NULL);
+                       break;
+               case MEDIA_STREAMER_SRC_TYPE_VIDEO_CAPTURE:
+                       plugin_name = __ms_ini_get_string(dict,
+                                       "sources:video_source",DEFAULT_VIDEO_SOURCE);
+                       node->gst_element = __ms_element_create(plugin_name, NULL);
+                       break;
+               case MEDIA_STREAMER_SRC_TYPE_VIDEO_TEST:
+                       node->gst_element = __ms_element_create(DEFAULT_VIDEO_TEST_SOURCE, NULL);
+                       g_object_set (G_OBJECT (node->gst_element), "is-live", true, NULL);
+                       break;
+               case MEDIA_STREAMER_SRC_TYPE_AUDIO_TEST:
+                       node->gst_element = __ms_element_create(DEFAULT_AUDIO_TEST_SOURCE, NULL);
+                       break;
+               case MEDIA_STREAMER_SRC_TYPE_CUSTOM:
+                       ms_error("Error: not implemented yet");
+                       break;
+               default:
+                       ms_error( "Error: invalid Src node Type [%d]",node->subtype);
+                       break;
+       }
+
+       ms_retvm_if(node->gst_element == NULL, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Error creating GstElement");
+       node->name = gst_element_get_name(node->gst_element);
+
+       MS_SAFE_FREE(plugin_name);
+       __ms_destroy_ini_dictionary(dict);
+
+       return MEDIA_STREAMER_ERROR_NONE;
+}
+
+int __ms_sink_node_create(media_streamer_node_s *node)
+{
+       ms_retvm_if(node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+
+       dictionary *dict = NULL;
+       char *plugin_name = NULL;
+
+       __ms_load_ini_dictionary(&dict);
+
+       switch(node->subtype)
+       {
+               case MEDIA_STREAMER_SINK_TYPE_FILE:
+                       ms_error("Error: not implemented yet");
+                       break;
+               case MEDIA_STREAMER_SINK_TYPE_RTSP:
+                       node->gst_element = __ms_element_create(DEFAULT_UDP_SINK, NULL);
+                       break;
+               case MEDIA_STREAMER_SINK_TYPE_HTTP:
+                       ms_error("Error: not implemented yet");
+                       break;
+               case MEDIA_STREAMER_SINK_TYPE_AUDIO:
+                       plugin_name = __ms_ini_get_string(dict,
+                                       "sinks:audio_sink",DEFAULT_AUDIO_SINK);
+                       node->gst_element = __ms_element_create(plugin_name, NULL);
+                       break;
+               case MEDIA_STREAMER_SINK_TYPE_SCREEN:
+                       plugin_name = __ms_ini_get_string(dict,
+                                       "sinks:video_sink",DEFAULT_VIDEO_SINK);
+                       node->gst_element = __ms_element_create(plugin_name, NULL);
+                       break;
+               case MEDIA_STREAMER_SINK_TYPE_FAKE:
+                       node->gst_element = __ms_element_create(DEFAULT_FAKE_SINK, NULL);
+                       break;
+               case MEDIA_STREAMER_SINK_TYPE_CUSTOM:
+
+                       break;
+               default:
+                       ms_error( "Error: invalid Sink node Type [%d]",node->subtype);
+                       break;
+       }
+
+       ms_retvm_if(node->gst_element == NULL, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Error creating GstElement");
+       node->name = gst_element_get_name(node->gst_element);
+
+       MS_SAFE_FREE(plugin_name);
+       __ms_destroy_ini_dictionary(dict);
+
+       return MEDIA_STREAMER_ERROR_NONE;
+}
+
+void __ms_node_destroy(void *data)
+{
+       char *node_name = NULL;
+       media_streamer_node_s *node = (media_streamer_node_s*)data;
+       ms_retm_if(node == NULL, "Empty value while deleting element from table");
+
+       node_name = g_strdup(node->name);
+       MS_SAFE_UNREF(node->gst_element);
+       MS_SAFE_FREE(node->name);
+
+       ms_info("Node [%s] destroyed", node_name);
+       MS_SAFE_FREE(node_name);
+}
+
+void __ms_node_insert_into_table(GHashTable *nodes_table,
+                               media_streamer_node_s *ms_node)
+{
+       if(g_hash_table_contains(nodes_table,ms_node->name))
+       {
+               ms_debug( "Current Node [%s] already added", ms_node->name);
+               return;
+       }
+       g_hash_table_insert(nodes_table,(gpointer)ms_node->name,(gpointer)ms_node);
+       ms_info("Node [%s] added into streamer, node type/subtype [%d/%d]",
+                       ms_node->name, ms_node->type, ms_node->subtype);
+}
+
+int __ms_node_remove_from_table(GHashTable *nodes_table,
+                               media_streamer_node_s *ms_node)
+{
+       ms_retvm_if(nodes_table == NULL, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Handle is NULL");
+       ms_retvm_if(ms_node == NULL, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Handle is NULL");
+
+       gboolean g_ret = g_hash_table_remove(nodes_table, ms_node->name);
+       ms_retvm_if(g_ret != TRUE, MEDIA_STREAMER_ERROR_INVALID_OPERATION,
+                       "Error while removing element from table");
+
+       return MEDIA_STREAMER_ERROR_NONE;
+}
+
+static void __params_foreach_cb(const char *key,
+                               const int type,
+                               const bundle_keyval_t *kv,
+                               void *user_data)
+{
+       int ret = MEDIA_STREAMER_ERROR_NONE;
+       media_streamer_node_s *ms_node = (media_streamer_node_s*)user_data;
+       ms_retm_if(ms_node == NULL, "Handle is NULL");
+
+       void *basic_val = NULL;
+       size_t basic_size = 0;
+
+       ms_info("Try to add parameter [%s] with type [%d] to the node [%s].", key, type, ms_node->name);
+
+       if(!bundle_keyval_type_is_array((bundle_keyval_t *)kv))
+       {
+               bundle_keyval_get_basic_val((bundle_keyval_t *)kv, &basic_val, &basic_size);
+               ms_info("Read param value[%s] with size [%d].", (gchar*)basic_val, basic_size);
+
+               if(ms_node->set_param != NULL)
+               {
+                       ret = ms_node->set_param(ms_node, (gchar*)key, (gchar*)basic_val);
+               }
+               else
+               {
+                       ret = MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+               }
+
+       }
+       else
+       {
+               ret = MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+       }
+
+       ms_retm_if(ret != MEDIA_STREAMER_ERROR_NONE,
+                       "Error while adding param [%s,%s] to the node [%s]",
+                       key, type, ms_node->name);
+}
+
+int __ms_node_read_params_from_bundle (media_streamer_node_s *node,
+               bundle *param_list)
+{
+       int ret = MEDIA_STREAMER_ERROR_NONE;
+       bundle_foreach(param_list, __params_foreach_cb, (void*)node);
+       return ret;
+}
+
+int __ms_node_write_params_into_bundle (media_streamer_node_s *node,
+               bundle *param_list)
+{
+       GParamSpec **property_specs;
+       guint num_properties, i;
+       char *string_val = NULL;
+
+       property_specs = g_object_class_list_properties
+                       (G_OBJECT_GET_CLASS(node->gst_element), &num_properties);
+
+       if (num_properties <= 0)
+       {
+               return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+       }
+
+       ms_info("Getting parameter of the Node [%s]", node->name );
+
+       for (i = 0; i < num_properties; i++)
+       {
+               GValue value = { 0, };
+               GParamSpec *param = property_specs[i];
+
+               g_value_init(&value, param->value_type);
+               if (param->flags & G_PARAM_READWRITE)
+               {
+                       g_object_get_property(G_OBJECT(node->gst_element), param->name, &value);
+               }
+               else
+               {
+                       // Skip properties which user can not change.
+                       continue;
+               }
+
+               ms_info("%-20s: %s\n", g_param_spec_get_name(param), g_param_spec_get_blurb(param));
+
+               switch(G_VALUE_TYPE(&value))
+               {
+                       case G_TYPE_STRING:
+                               bundle_add_str(param_list, g_param_spec_get_name(param), g_value_get_string(&value));
+                               ms_info("Got string value: [%s]", g_value_get_string(&value));
+                               break;
+
+                       case G_TYPE_BOOLEAN:
+                               string_val = g_strdup_printf("%s", g_value_get_boolean(&value) ? "true" : "false");
+                               bundle_add_str(param_list, g_param_spec_get_name(param), string_val);
+                               ms_info("Got boolean value: [%s]", string_val);
+                               break;
+
+                       case G_TYPE_ULONG:
+                       {
+                               GParamSpecULong *pulong = G_PARAM_SPEC_ULONG(param);
+                               string_val = g_strdup_printf("%lu", g_value_get_ulong(&value));
+                               bundle_add_str(param_list, g_param_spec_get_name(param), string_val);
+                               ms_info("Got ulong value: [%s], range: %lu - %lu (default %s)",
+                               string_val, pulong->minimum, pulong->maximum);
+                               break;
+                       }
+
+                       case G_TYPE_LONG:
+                       {
+                               GParamSpecLong *plong = G_PARAM_SPEC_LONG(param);
+                               string_val = g_strdup_printf("%ld", g_value_get_long(&value));
+                               bundle_add_str(param_list, g_param_spec_get_name(param), string_val);
+                               ms_info("Got long value: [%s], range: %ld - %ld (default %s)",
+                               string_val, plong->minimum, plong->maximum);
+                               break;
+                       }
+
+                       case G_TYPE_UINT:
+                       {
+                               GParamSpecUInt *puint = G_PARAM_SPEC_UINT(param);
+                               string_val = g_strdup_printf("%u", g_value_get_uint(&value));
+                               bundle_add_str(param_list, g_param_spec_get_name(param), string_val);
+                               ms_info("Got uint value: [%s], range: %u - %u",
+                               string_val, puint->minimum, puint->maximum);
+                               break;
+                       }
+
+                       case G_TYPE_INT:
+                       {
+                               GParamSpecInt *pint = G_PARAM_SPEC_INT(param);
+                               string_val = g_strdup_printf("%d", g_value_get_int(&value));
+                               bundle_add_str(param_list, g_param_spec_get_name(param), string_val);
+                               ms_info("Got int value: [%s], range: %d - %d",
+                               string_val, pint->minimum, pint->maximum);
+                               break;
+                       }
+
+                       case G_TYPE_UINT64:
+                       {
+                               GParamSpecUInt64 *puint64 = G_PARAM_SPEC_UINT64(param);
+                               string_val = g_strdup_printf("%" G_GUINT64_FORMAT, g_value_get_uint64(&value));
+                               bundle_add_str(param_list, g_param_spec_get_name(param), string_val);
+                               ms_info("Got uint64 value: [%s], range: %" G_GUINT64_FORMAT "- %" G_GUINT64_FORMAT,
+                               string_val, puint64->minimum, puint64->maximum);
+                               break;
+                       }
+
+                       case G_TYPE_INT64:
+                       {
+                               GParamSpecInt64 *pint64 = G_PARAM_SPEC_INT64(param);
+                               string_val = g_strdup_printf("%" G_GINT64_FORMAT, g_value_get_int64(&value));
+                               bundle_add_str(param_list, g_param_spec_get_name(param), string_val);
+                               ms_info("Got uint64 value: [%s], range: %" G_GINT64_FORMAT "- %" G_GINT64_FORMAT,
+                               string_val, pint64->minimum, pint64->maximum);
+                               break;
+                       }
+
+                       case G_TYPE_FLOAT:
+                       {
+                               GParamSpecFloat *pfloat = G_PARAM_SPEC_FLOAT(param);
+                               string_val = g_strdup_printf("%15.7g", g_value_get_float(&value));
+                               bundle_add_str(param_list, g_param_spec_get_name(param), string_val);
+                               ms_info("Got float value: [%s], range:%15.7g -%15.7g",
+                               string_val, pfloat->minimum, pfloat->maximum);
+                               break;
+                       }
+
+                       case G_TYPE_DOUBLE:
+                       {
+                               GParamSpecDouble *pdouble = G_PARAM_SPEC_DOUBLE(param);
+                               string_val = g_strdup_printf("%15.7g", g_value_get_double(&value));
+                               bundle_add_str(param_list, g_param_spec_get_name(param), string_val);
+                               ms_info("Got double value: [%s], range:%15.7g -%15.7g",
+                               string_val, pdouble->minimum, pdouble->maximum);
+                               break;
+                       }
+
+                       default:
+                               ms_info("Got unknown type with param->value_type [%d]", param->value_type);
+                               break;
+
+                               MS_SAFE_FREE(string_val);
+               }
+       }
+       return MEDIA_STREAMER_ERROR_NONE;
+}
diff --git a/src/media_streamer_priv.c b/src/media_streamer_priv.c
new file mode 100755 (executable)
index 0000000..7e9b540
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "media_streamer_priv.h"
+#include "media_streamer_util.h"
+#include "media_streamer_node.h"
+#include "media_streamer_gst.h"
+
+int __ms_state_change(media_streamer_s *ms_streamer, media_streamer_state_e state)
+{
+       int ret = MEDIA_STREAMER_ERROR_NONE;
+
+       ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+
+       media_streamer_state_e previous_state= ms_streamer->state;
+       ms_retvm_if(previous_state == state, MEDIA_STREAMER_ERROR_NONE, "Media streamer already in this state");
+
+       switch(state)
+       {
+               case MEDIA_STREAMER_STATE_NONE:
+                       /*
+                        * Media streamer must be in IDLE state
+                        * Unlink and destroy all bins and elements.
+                        */
+                       if (previous_state != MEDIA_STREAMER_STATE_IDLE)
+                       {
+                               __ms_state_change(ms_streamer, MEDIA_STREAMER_STATE_IDLE);
+                       }
+                       break;
+               case MEDIA_STREAMER_STATE_IDLE:
+                       /*
+                        * Unlink all gst_elements, set pipeline into state NULL
+                        */
+                       if (previous_state != MEDIA_STREAMER_STATE_NONE)
+                       {
+                               ret = __ms_element_set_state(ms_streamer->pipeline, GST_STATE_NULL);
+                       }
+                       break;
+               case MEDIA_STREAMER_STATE_READY:
+                       break;
+               case MEDIA_STREAMER_STATE_PLAYING:
+                       ret = __ms_element_set_state(ms_streamer->pipeline, GST_STATE_PLAYING);
+                       break;
+               case MEDIA_STREAMER_STATE_PAUSED:
+                       ret = __ms_element_set_state(ms_streamer->pipeline, GST_STATE_PAUSED);
+                       break;
+               case MEDIA_STREAMER_STATE_SEEKING:
+               default:
+               {
+                       ms_info("Error: invalid state [%s]", state);
+                       return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+               }
+       }
+
+       if(ret != MEDIA_STREAMER_ERROR_NONE)
+       {
+               ms_error("Failed change state");
+               return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+       }
+
+       ms_streamer->state = state;
+       ms_info("Media streamer state changed to [%d]", state);
+       return ret;
+}
+
+int __ms_create(media_streamer_s *ms_streamer)
+{
+       int ret = MEDIA_STREAMER_ERROR_NONE;
+
+       ret = __ms_load_ini_settings(&ms_streamer->ini);
+       ms_retvm_if(ret!=MEDIA_STREAMER_ERROR_NONE,
+                       MEDIA_STREAMER_ERROR_INVALID_OPERATION,"Error load ini file");
+
+       ms_streamer->nodes_table = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, __ms_node_destroy);
+       ms_retvm_if(ms_streamer->nodes_table == NULL,
+                       MEDIA_STREAMER_ERROR_INVALID_OPERATION,"Error creating hash table");
+
+       ret = __ms_pipeline_create(ms_streamer);
+       if (ret != MEDIA_STREAMER_ERROR_NONE)
+       {
+               ms_error("Error while creating media streamer pipeline.");
+               return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+       }
+
+       ms_info("Media streamer pipeline created successfully.");
+
+       return ret;
+}
+
+static void __node_remove_cb(gpointer key,
+                               gpointer value,
+                               gpointer user_data)
+{
+       media_streamer_s *ms_streamer = (media_streamer_s*)user_data;
+       ms_retm_if(ms_streamer == NULL, "Handle is NULL");
+
+       media_streamer_node_s *ms_node = (media_streamer_node_s*)value;
+       ms_retm_if(ms_node == NULL, "Handle is NULL");
+
+       ms_info("Try to delete [%s] node from streamer, node type/subtype [%d/%d]",
+                       ms_node->name, ms_node->type, ms_node->subtype);
+
+       gchar *bin_name = NULL;
+       gboolean gst_ret = FALSE;
+
+       __ms_element_set_state(ms_node->gst_element, GST_STATE_NULL);
+       gst_object_ref(ms_node->gst_element);
+
+       switch(ms_node->type)
+       {
+               case MEDIA_STREAMER_NODE_TYPE_SRC:
+                       gst_ret = gst_bin_remove(GST_BIN(ms_streamer->src_bin),ms_node->gst_element);
+                       bin_name = g_strdup(MEDIA_STREAMER_SRC_BIN_NAME);
+                       break;
+               case MEDIA_STREAMER_NODE_TYPE_SINK:
+                       gst_ret = gst_bin_remove(GST_BIN(ms_streamer->sink_video_bin),ms_node->gst_element);
+                       bin_name = g_strdup(MEDIA_STREAMER_VIDEO_SINK_BIN_NAME);
+                       break;
+               default:
+                       gst_ret = gst_bin_remove(GST_BIN(ms_streamer->topology_bin),ms_node->gst_element);
+                       bin_name = g_strdup(MEDIA_STREAMER_TOPOLOGY_BIN_NAME);
+                       break;
+       }
+
+       if(!gst_ret)
+       {
+               ms_error("Failed to remove Element [%s] from bin [%s]", ms_node->name, bin_name);
+       }
+       else
+       {
+               ms_info("Success removed Element [%s] from bin [%s]", ms_node->name, bin_name);
+       }
+
+       MS_SAFE_GFREE(bin_name);
+
+}
+
+
+void __ms_streamer_destroy(media_streamer_s *ms_streamer)
+{
+       if(__ms_state_change(ms_streamer, MEDIA_STREAMER_STATE_NONE) != MEDIA_STREAMER_ERROR_NONE)
+       {
+               ms_error("Error: can not set state [%d]", MEDIA_STREAMER_ERROR_INVALID_OPERATION);
+       }
+
+       gst_element_unlink_many(ms_streamer->src_bin,
+                               ms_streamer->topology_bin,
+                               ms_streamer->sink_video_bin, NULL);
+
+       g_hash_table_foreach(ms_streamer->nodes_table, __node_remove_cb,(gpointer)ms_streamer);
+
+       if(ms_streamer->src_bin && !gst_bin_remove(GST_BIN(ms_streamer->pipeline),ms_streamer->src_bin))
+       {
+               ms_error("Failed to remove src_bin from pipeline");
+       }
+       else
+       {
+               ms_info("src_bin removed from pipeline");
+       }
+
+       if(ms_streamer->sink_video_bin && !gst_bin_remove(GST_BIN(ms_streamer->pipeline),ms_streamer->sink_video_bin))
+       {
+               ms_error("Failed to remove sink_bin from pipeline");
+       }
+       else
+       {
+               ms_info("sink_bin removed from pipeline");
+       }
+
+
+       if(ms_streamer->topology_bin && !gst_bin_remove(GST_BIN(ms_streamer->pipeline),ms_streamer->topology_bin))
+       {
+               ms_error("Failed to remove topology_bin from pipeline");
+       }
+       else
+       {
+               ms_info("topology_bin removed from pipeline");
+       }
+
+
+       ms_streamer->state = MEDIA_STREAMER_STATE_NONE;
+
+       MS_TABLE_SAFE_UNREF(ms_streamer->nodes_table);
+       MS_SAFE_UNREF(ms_streamer->bus);
+       MS_SAFE_UNREF(ms_streamer->pipeline);
+
+       MS_SAFE_FREE(ms_streamer);
+
+//     gst_deinit();
+}
diff --git a/src/media_streamer_util.c b/src/media_streamer_util.c
new file mode 100755 (executable)
index 0000000..46d9fdd
--- /dev/null
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __MEDIA_STREAMER_UTIL_C__
+#define __MEDIA_STREAMER_UTIL_C__
+
+#include <glib/gstdio.h>
+
+#include <media_streamer.h>
+#include <media_streamer_util.h>
+
+#ifdef MEDIA_STREAMER_DEFAULT_INI
+       static gboolean __ms_generate_default_ini(void);
+#endif
+
+static void __ms_check_ini_status(void);
+
+gchar* __ms_ini_get_string(dictionary *dict,
+               const char *ini_path, char *default_str)
+{
+       gchar *result_str = NULL;
+
+       ms_retvm_if(ini_path == NULL, NULL, "Invalid ini path");
+
+       if (dict == NULL)
+       {
+               result_str = g_strdup(default_str);
+       }
+       else
+       {
+               gchar *str = NULL;
+               str = iniparser_getstring(dict, ini_path, default_str);
+               if (str &&
+                               (strlen(str) > 0) &&
+                               (strlen(str) < MEDIA_STREAMER_INI_MAX_STRLEN))
+               {
+                       result_str = g_strdup(str);
+               }
+               else
+               {
+                       result_str = g_strdup(default_str);
+               }
+       }
+       return result_str;
+}
+
+gboolean __ms_load_ini_dictionary(dictionary **dict)
+{
+       ms_retvm_if(dict == NULL, FALSE, "Handle is NULL");
+
+       __ms_check_ini_status();
+
+       dictionary *ms_dict = NULL;
+
+       /* loading existing ini file */
+       ms_dict = iniparser_load(MEDIA_STREAMER_INI_DEFAULT_PATH);
+
+       /* if no file exists. create one with set of default values */
+       if (!ms_dict)
+       {
+#ifdef MEDIA_STREAMER_DEFAULT_INI
+               ms_debug("No inifile found. Media streamer will create default inifile.");
+               if (FALSE == __ms_generate_default_ini())
+               {
+                       ms_debug("Creating default .ini file failed. Media-streamer will use default values.");
+               }
+               else
+               {
+                       /* load default ini */
+                       ms_dict = iniparser_load(MEDIA_STREAMER_INI_DEFAULT_PATH);
+               }
+#else
+               ms_debug("No ini file found.");
+               return FALSE;
+#endif
+       }
+
+       *dict = ms_dict;
+       return TRUE;
+}
+
+gboolean __ms_destroy_ini_dictionary(dictionary *dict)
+{
+       ms_retvm_if(dict == NULL, FALSE, "Handle is null");
+
+       /* free dict as we got our own structure */
+       iniparser_freedict(dict);
+
+       return TRUE;
+}
+
+int __ms_load_ini_settings(media_streamer_ini_t *ini)
+{
+       dictionary *dict = NULL;
+
+       /* get ini values */
+       memset(ini, 0, sizeof(media_streamer_ini_t));
+
+       if (__ms_load_ini_dictionary(&dict))
+       {
+               /* general */
+               ini->generate_dot = iniparser_getboolean(dict, "general:generate dot", DEFAULT_GENERATE_DOT);
+               if (ini->generate_dot == TRUE)
+               {
+                       gchar *dot_path = iniparser_getstring(dict, "general:dot dir" , MEDIA_STREAMER_DEFAULT_DOT_DIR);
+                       ms_debug("generate_dot is TRUE, dot file will be stored into %s",dot_path);
+                       g_setenv ("GST_DEBUG_DUMP_DOT_DIR", dot_path, FALSE);
+               }
+
+       }
+       else /* if dict is not available just fill the structure with default value */
+       {
+               ms_debug("failed to load ini. using hardcoded default");
+
+               /* general settings*/
+               ini->generate_dot = DEFAULT_GENERATE_DOT;
+       }
+
+       __ms_destroy_ini_dictionary(dict);
+
+       /* general */
+       ms_debug("generate_dot : %d\n", ini->generate_dot);
+
+       return MEDIA_STREAMER_ERROR_NONE;
+}
+
+static void __ms_check_ini_status(void)
+{
+       FILE *fp = fopen(MEDIA_STREAMER_INI_DEFAULT_PATH, "r");
+       int file_size = 0;
+       int status = 0;
+
+       if(fp == NULL)
+       {
+               ms_debug("Failed to get media streamer ini file.");
+       }
+       else
+       {
+               fseek(fp, 0, SEEK_END);
+               file_size = ftell(fp);
+               fclose(fp);
+               if (file_size < 5)
+               {
+                       ms_debug("media_streamer.ini file size=%d, Corrupted! Removed", file_size);
+                       status = g_remove(MEDIA_STREAMER_INI_DEFAULT_PATH);
+                       if (status == -1)
+                       {
+                               ms_error("failed to delete corrupted ini");
+                       }
+               }
+       }
+}
+
+#ifdef MEDIA_STREAMER_DEFAULT_INI
+static gboolean __ms_generate_default_ini(void)
+{
+       FILE *fp = NULL;
+       gchar *default_ini = MEDIA_STREAMER_DEFAULT_INI;
+
+
+       /* create new file */
+       fp = fopen(MEDIA_STREAMER_INI_DEFAULT_PATH, "wt");
+
+       if (!fp)
+       {
+               return FALSE;
+       }
+
+       /* writing default ini file */
+       if (strlen(default_ini) != fwrite(default_ini, 1, strlen(default_ini), fp))
+       {
+               fclose(fp);
+               return FALSE;
+       }
+
+       fclose(fp);
+       return TRUE;
+}
+#endif
+
+const gchar *__ms_convert_mime_to_string(media_format_mimetype_e mime)
+{
+       switch(mime)
+       {
+               case MEDIA_FORMAT_I420:
+                       return "I420";
+               case MEDIA_FORMAT_YV12:
+                       return "YV12";
+               case MEDIA_FORMAT_H263:
+                       return "h263";
+               case MEDIA_FORMAT_H264_HP:
+               case MEDIA_FORMAT_H264_MP:
+               case MEDIA_FORMAT_H264_SP:
+                       return "h264";
+               case MEDIA_FORMAT_PCM:
+                       return "S16BE";
+               default:
+                       ms_error("Invalid or Unsupported media format [%d].", mime);
+                       return NULL;
+               break;
+       }
+
+}
+#endif
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..cccb136
--- /dev/null
@@ -0,0 +1,24 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+SET(fw_test "${fw_name}-test")
+
+INCLUDE_DIRECTORIES(../include)
+
+link_directories(${CMAKE_SOURCE_DIR}/../)
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(${fw_test} REQUIRED glib-2.0)
+FOREACH(flag ${${fw_test}_CFLAGS})
+    SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+
+aux_source_directory(. sources)
+
+FOREACH(src ${sources})
+    GET_FILENAME_COMPONENT(src_name ${src} NAME_WE)
+    MESSAGE("${src_name}")
+    ADD_EXECUTABLE(${src_name} ${src})
+    TARGET_LINK_LIBRARIES(${src_name} capi-media-streamer ${${fw_test}_LDFLAGS})
+ENDFOREACH()
+
diff --git a/test/media_streamer_test.c b/test/media_streamer_test.c
new file mode 100755 (executable)
index 0000000..f789c06
--- /dev/null
@@ -0,0 +1,940 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+#include <glib/gprintf.h>
+
+#include <media_streamer.h>
+
+typedef enum
+{
+       MENU_STATE_UNKNOWN = 0,
+       MENU_STATE_MAIN_MENU,
+       MENU_STATE_BROADCAST_MENU,
+       MENU_STATE_VOIP_MENU,
+       MENU_STATE_PRESET_MENU
+} menu_state_e;
+
+typedef enum
+{
+       SUBMENU_STATE_UNKNOWN = 0,
+       SUBMENU_STATE_GETTING_IP,
+       SUBMENU_STATE_AUTOPLUG = 3,
+       SUBMENU_STATE_FORMAT
+} submenu_state_e;
+
+#define SECOND_VOIP_MASK 0x8
+#define DOUBLE_STREAMER_MASK 0x10
+
+typedef enum
+{
+       PRESET_UNKNOWN = 0,
+       PRESET_RTP_STREAMER = 0x01,
+       PRESET_RTP_CLIENT = 0x02,
+       PRESET_VOIP = PRESET_RTP_STREAMER | PRESET_RTP_CLIENT,
+       PRESET_VOIP_2 = PRESET_VOIP | SECOND_VOIP_MASK,
+       PRESET_DOUBLE_VOIP_SERVER = PRESET_RTP_STREAMER | DOUBLE_STREAMER_MASK,
+       PRESET_DOUBLE_VOIP_SERVER_2 = PRESET_RTP_STREAMER | DOUBLE_STREAMER_MASK | SECOND_VOIP_MASK,
+       PRESET_DOUBLE_VOIP_CLIENT = PRESET_RTP_CLIENT | DOUBLE_STREAMER_MASK,
+       PRESET_DOUBLE_VOIP_CLIENT_2 = PRESET_RTP_CLIENT | DOUBLE_STREAMER_MASK | SECOND_VOIP_MASK
+} preset_type_e;
+
+#define PACKAGE "media_streamer_test"
+/*---------------------------------------------------------------------------
+|    GLOBAL VARIABLE DEFINITIONS:                     |
+---------------------------------------------------------------------------*/
+
+static media_streamer_h g_media_streamer;
+static media_streamer_h g_media_streamer_2;
+static media_streamer_h current_media_streamer = &g_media_streamer;
+
+//#define ONE_DEVICE_TEST
+#define MAX_STRING_LEN    2048
+#define DEFAULT_IP_ADDR "127.0.0.1"
+
+#define VIDEO_PORT 5000
+#define AUDIO_PORT 6000
+
+//#define DISABLE_AUDIO
+//#define DISABLE_VIDEO
+
+/*---------------------------------------------------------------------------
+|    LOCAL VARIABLE DEFINITIONS:                      |
+---------------------------------------------------------------------------*/
+GMainLoop *g_loop;
+
+gchar *g_broadcast_address = NULL;
+menu_state_e g_menu_state = MENU_STATE_MAIN_MENU;
+submenu_state_e g_sub_menu_state = SUBMENU_STATE_UNKNOWN;
+preset_type_e g_menu_preset = PRESET_UNKNOWN;
+
+gboolean g_autoplug_mode = FALSE;
+
+media_format_h vfmt_raw = NULL;
+media_format_h vfmt_encoded = NULL;
+media_format_h afmt_raw = NULL;
+
+/*---------------------------------------------------------------------------
+|    LOCAL FUNCTION PROTOTYPES:                       |
+---------------------------------------------------------------------------*/
+
+static gboolean _create(media_streamer_h *streamer)
+{
+       g_print("== create \n");
+
+       if(*streamer != NULL)
+       {
+               return TRUE;
+       }
+
+       int ret = MEDIA_STREAMER_ERROR_NONE;
+
+       ret = media_streamer_create(streamer);
+
+       if( ret != MEDIA_STREAMER_ERROR_NONE)
+       {
+               g_print("Fail to create media streamer");
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+static gboolean _prepare(void)
+{
+       g_print("== prepare \n");
+       int ret = MEDIA_STREAMER_ERROR_NONE;
+
+       ret = media_streamer_prepare(current_media_streamer);
+       if( ret != MEDIA_STREAMER_ERROR_NONE)
+       {
+               g_print("Fail to prepare media streamer");
+               return FALSE;
+       }
+       g_print("== success prepare \n");
+
+       return TRUE;
+}
+
+static gboolean _unprepare(void)
+{
+       g_print("== unprepare \n");
+       int ret = MEDIA_STREAMER_ERROR_NONE;
+
+       ret = media_streamer_unprepare(current_media_streamer);
+       if( ret != MEDIA_STREAMER_ERROR_NONE)
+       {
+               g_print("Fail to unprepare media streamer");
+               return FALSE;
+       }
+       g_print("== success unprepare \n");
+
+       return TRUE;
+}
+
+static gboolean _play()
+{
+       g_print("== play \n");
+       int ret = MEDIA_STREAMER_ERROR_NONE;
+
+       ret = media_streamer_play(current_media_streamer);
+       if( ret != MEDIA_STREAMER_ERROR_NONE)
+       {
+               g_print("Fail to play media streamer");
+               return FALSE;
+       }
+       g_print("== success play \n");
+
+       return TRUE;
+}
+
+static gboolean _destroy(media_streamer_h streamer)
+{
+       g_print("== destroy \n");
+       int ret = MEDIA_STREAMER_ERROR_NONE;
+
+       if(streamer == NULL)
+       {
+               g_print("media streamer already destroyed");
+               return TRUE;
+       }
+
+       ret = media_streamer_destroy(streamer);
+       if( ret != MEDIA_STREAMER_ERROR_NONE)
+       {
+               g_print("Fail to destroy media streamer");
+               return FALSE;
+       }
+
+       g_menu_preset = PRESET_UNKNOWN;
+       g_print("== success destroy \n");
+       return TRUE;
+}
+
+static void create_formats(void)
+{
+       if(!vfmt_raw || !vfmt_encoded || afmt_raw)
+       {
+               g_print("Formats already created!");
+       }
+
+       /* Define video raw format */
+       media_format_create(&vfmt_raw);
+       if (media_format_set_video_mime(vfmt_raw, MEDIA_FORMAT_YV12) != MEDIA_FORMAT_ERROR_NONE)
+       {
+               g_print("media_format_set_video_mime failed!");
+       }
+       media_format_set_video_width(vfmt_raw, 800);
+       media_format_set_video_height(vfmt_raw, 600);
+       media_format_set_video_avg_bps(vfmt_raw, 10000);
+       media_format_set_video_max_bps(vfmt_raw, 30000);
+
+       /* Define encoded video format */
+       media_format_create(&vfmt_encoded);
+       if (media_format_set_video_mime(vfmt_encoded, MEDIA_FORMAT_H264_SP) != MEDIA_FORMAT_ERROR_NONE)
+       {
+               g_print("media_format_set_video_mime failed!");
+       }
+       media_format_set_video_width(vfmt_encoded, 800);
+       media_format_set_video_height(vfmt_encoded, 600);
+       media_format_set_video_avg_bps(vfmt_encoded, 10000);
+       media_format_set_video_max_bps(vfmt_encoded, 30000);
+
+       /* Define audio raw format */
+       media_format_create(&afmt_raw);
+       if (media_format_set_audio_mime(afmt_raw, MEDIA_FORMAT_PCM) != MEDIA_FORMAT_ERROR_NONE)
+       {
+               g_print("media_format_set_audio_mime failed!");
+       }
+       media_format_set_audio_channel(afmt_raw, 1);
+       media_format_set_audio_samplerate(afmt_raw, 44100);
+       media_format_set_audio_bit(afmt_raw, 16);
+}
+
+static void set_rtp_params (media_streamer_node_h rtp_node,
+                               const gchar *ip,
+                               int video_port,
+                               int audio_port,
+                               gboolean port_reverse)
+{
+       bundle *params = bundle_create();
+
+#ifndef DISABLE_AUDIO
+       gchar *audio_src_port = g_strdup_printf("%d", port_reverse ? (audio_port + 5) : audio_port);
+       gchar *audio_sink_port = g_strdup_printf("%d", port_reverse ? audio_port : (audio_port + 5));
+
+       if(g_menu_preset & PRESET_RTP_STREAMER)
+       {
+               bundle_add_str(params, "audio_sink,port", audio_sink_port);
+               bundle_add_str(params, "audio_sink,host", ip);
+       }
+       if(g_menu_preset & PRESET_RTP_CLIENT)
+       {
+               bundle_add_str(params, "audio_source,port", audio_src_port);
+               bundle_add_str(params, "audio_source,format",
+                               "application/x-rtp,media=audio,clock-rate=44100,encoding-name=L16,"
+                               "encoding-params=1,channels=1,payload=96");
+       }
+
+       g_free(audio_src_port);
+       g_free(audio_sink_port);
+#endif
+
+#ifndef DISABLE_VIDEO
+       gchar *video_src_port = g_strdup_printf("%d", port_reverse ? (video_port + 5) : video_port);
+       gchar *video_sink_port = g_strdup_printf("%d", port_reverse ? video_port : (video_port + 5));
+
+       if(g_menu_preset & PRESET_RTP_STREAMER)
+       {
+               bundle_add_str(params, "video_sink,port", video_sink_port);
+               bundle_add_str(params, "video_sink,host", ip);
+       }
+       if(g_menu_preset & PRESET_RTP_CLIENT)
+       {
+               bundle_add_str(params, "video_source,port", video_src_port);
+               bundle_add_str(params, "video_source,format",
+                               "application/x-rtp,media=video,clock-rate=90000,encoding-name=H264");
+       }
+
+       g_free(video_src_port);
+       g_free(video_sink_port);
+#endif
+
+       media_streamer_node_set_params(rtp_node, params);
+       bundle_free(params);
+       params = NULL;
+}
+
+static gboolean _create_rtp_streamer(media_streamer_node_h rtp_bin)
+{
+       g_print("== _create_rtp_streamer \n");
+
+#ifndef DISABLE_VIDEO
+       //********************** video source ***********************************
+       media_streamer_node_h video_src = NULL;
+#ifdef ONE_DEVICE_TEST
+       if(g_menu_preset & SECOND_VOIP_MASK)
+       {
+               media_streamer_src_create(MEDIA_STREAMER_SRC_TYPE_VIDEO_TEST, &video_src);
+       }
+       else
+       {
+               media_streamer_src_create(MEDIA_STREAMER_SRC_TYPE_CAMERA, &video_src);
+       }
+#else
+       media_streamer_src_create(MEDIA_STREAMER_SRC_TYPE_CAMERA, &video_src);
+#endif
+//     media_streamer_node_set_fmt(video_src, vfmt_raw);
+       media_streamer_node_add(current_media_streamer, video_src);
+
+       //********************** encoder ****************************************
+       media_streamer_node_h video_enc = NULL;
+       media_streamer_node_create(MEDIA_STREAMER_NODE_TYPE_VIDEO_ENCODER, NULL, vfmt_encoded, &video_enc);
+       media_streamer_node_add(current_media_streamer, video_enc);
+
+
+       //********************** videopay ***************************************
+       media_streamer_node_h video_pay = NULL;
+       media_streamer_node_create(MEDIA_STREAMER_NODE_TYPE_VIDEO_PAY, NULL, vfmt_encoded, &video_pay);
+       media_streamer_node_add(current_media_streamer, video_pay);
+
+       //====================Linking Video Streamer===========================//
+       media_streamer_node_link(video_src, "src", video_enc, "sink");
+       media_streamer_node_link(video_enc, "src", video_pay, "sink");
+       media_streamer_node_link(video_pay, "src", rtp_bin, "video_sink");
+       //======================================================================//
+
+       g_print("== success streamer video part \n");
+#endif
+
+#ifndef DISABLE_AUDIO
+       //********************** audiosrc ***********************************
+       media_streamer_node_h audio_src = NULL;
+       media_streamer_src_create(MEDIA_STREAMER_SRC_TYPE_AUDIO_CAPTURE, &audio_src);
+       media_streamer_node_add(current_media_streamer, audio_src);
+
+       //********************** audioencoder ***********************************
+       media_streamer_node_h audio_enc = NULL;
+       media_streamer_node_create(MEDIA_STREAMER_NODE_TYPE_AUDIO_ENCODER, NULL, NULL, &audio_enc);
+       media_streamer_node_add(current_media_streamer, audio_enc);
+
+
+       //********************** rtpL16pay ***********************************
+       media_streamer_node_h audio_pay = NULL;
+       media_streamer_node_create(MEDIA_STREAMER_NODE_TYPE_AUDIO_PAY, NULL, NULL, &audio_pay);
+       media_streamer_node_add(current_media_streamer, audio_pay);
+
+       //====================Linking Audio Streamer===========================//
+       media_streamer_node_link(audio_src, "src", audio_enc, "sink");
+       media_streamer_node_link(audio_enc, "src", audio_pay, "sink");
+       media_streamer_node_link(audio_pay, "src", rtp_bin, "audio_sink");
+       //======================================================================//
+
+       g_print("== success streamer audio part \n");
+#endif
+
+       return TRUE;
+}
+
+static gboolean _create_rtp_client(media_streamer_node_h rtp_bin)
+{
+       g_print("== _create_rtp_client \n");
+
+#ifndef DISABLE_VIDEO
+       //********************** video_depay***********************************
+       media_streamer_node_h video_depay = NULL;
+       media_streamer_node_create(MEDIA_STREAMER_NODE_TYPE_VIDEO_DEPAY, NULL, vfmt_encoded, &video_depay);
+       media_streamer_node_add(current_media_streamer, video_depay);
+
+       //********************** videodec ***********************************
+       media_streamer_node_h video_dec = NULL;
+       media_streamer_node_create(MEDIA_STREAMER_NODE_TYPE_VIDEO_DECODER, NULL, vfmt_encoded, &video_dec);
+       media_streamer_node_add(current_media_streamer, video_dec);
+
+       //********************** videosink ***********************************
+       media_streamer_node_h video_sink = NULL;
+       media_streamer_sink_create(MEDIA_STREAMER_SINK_TYPE_SCREEN, &video_sink);
+       media_streamer_node_add(current_media_streamer, video_sink);
+
+       //====================Linking Video Client===========================//
+       media_streamer_node_link(video_depay, "src", video_dec, "sink");
+       media_streamer_node_link(video_dec, "src", video_sink,"sink");
+//     media_streamer_node_link(rtp_bin, "video_source", video_depay,"sink");
+
+       g_print("== success client video part \n");
+#endif
+
+#ifndef DISABLE_AUDIO
+       //********************** audiodepay ***********************************
+       media_streamer_node_h audio_depay = NULL;
+       media_streamer_node_create(MEDIA_STREAMER_NODE_TYPE_AUDIO_DEPAY, NULL, NULL, &audio_depay);
+       media_streamer_node_add(current_media_streamer, audio_depay);
+
+       //********************** audioconvert ***********************************
+       media_streamer_node_h audio_converter = NULL;
+       media_streamer_node_create(MEDIA_STREAMER_NODE_TYPE_AUDIO_CONVERTER, NULL, NULL, &audio_converter);
+       media_streamer_node_add(current_media_streamer, audio_converter);
+
+       //********************** audioresample ***********************************
+       media_streamer_node_h audio_res = NULL;
+       media_streamer_node_create(MEDIA_STREAMER_NODE_TYPE_AUDIO_RESAMPLE, NULL, NULL, &audio_res);
+       media_streamer_node_add(current_media_streamer, audio_res);
+
+       //********************** audiosink ***********************************
+       media_streamer_node_h audio_sink = NULL;
+       media_streamer_sink_create(MEDIA_STREAMER_SINK_TYPE_AUDIO, &audio_sink);
+       media_streamer_node_add(current_media_streamer, audio_sink);
+
+       //====================Linking Audio Client===========================//
+       media_streamer_node_link(audio_depay, "src", audio_converter, "sink");
+       media_streamer_node_link(audio_converter, "src", audio_res, "sink");
+       media_streamer_node_link(audio_res, "src", audio_sink,"sink");
+//     media_streamer_node_link(rtp_bin, "audio_source", audio_depay,"sink");
+       //======================================================================//
+
+       g_print("== success client audio part \n");
+#endif
+
+       return TRUE;
+}
+
+static media_streamer_node_h _create_rtp(
+                               int video_port,
+                               int audio_port,
+                               gboolean second_client)
+{
+       g_print("== create rtp node for current preset \n");
+
+       //********************** rtpbin ***********************************
+       media_streamer_node_h rtp_bin = NULL;
+       media_streamer_node_create(MEDIA_STREAMER_NODE_TYPE_RTP, vfmt_encoded, vfmt_encoded, &rtp_bin);
+       set_rtp_params(rtp_bin, g_broadcast_address, video_port, audio_port, second_client);
+       media_streamer_node_add(current_media_streamer, rtp_bin);
+       return rtp_bin;
+}
+
+/***************************************************************/
+/**  Testsuite */
+/***************************************************************/
+
+void quit()
+{
+       reset_current_menu_state();
+       g_main_loop_quit(g_loop);
+}
+
+/*
+ * Function resets menu state to the main menu state
+ * and cleans media streamer handle.
+ */
+void reset_current_menu_state(void)
+{
+       g_menu_state = MENU_STATE_MAIN_MENU;
+       g_autoplug_mode = FALSE;
+       current_media_streamer = NULL;
+
+       if (g_media_streamer)
+       {
+               _destroy(g_media_streamer);
+               g_media_streamer = NULL;
+       }
+
+       if (g_media_streamer_2)
+       {
+               _destroy(g_media_streamer_2);
+               g_media_streamer_2 = NULL;
+       }
+
+       if(g_broadcast_address != NULL)
+       {
+               g_free(g_broadcast_address);
+               g_broadcast_address = NULL;
+       }
+}
+
+static void display_getting_ip_menu(void)
+{
+       g_print("\n");
+       g_print("Please input IP address for broadcasting\n");
+       g_print("By default will be used [%s]\n", DEFAULT_IP_ADDR);
+}
+
+static void display_autoplug_select_menu(void)
+{
+       g_print("\n");
+       g_print("Please select Media Streamer pluging mode\n");
+       g_print("By default will be used [%s] mode\n",
+                       g_autoplug_mode == TRUE ? "autoplug" : "manual");
+       g_print("1. Manual mode \n");
+       g_print("2. Autoplug mode \n");
+}
+
+static void display_preset_menu(void)
+{
+       g_print("\n");
+       g_print("====================================================\n");
+       g_print("   media streamer test: Preset menu v0.3\n");
+       g_print("----------------------------------------------------\n");
+       g_print("1. create media streamer \n");
+       g_print("2. set up current preset \n");
+       g_print("4. prepare \n");
+       g_print("5. unprepare \n");
+       g_print("6. play \n");
+       g_print("7. destroy media streamer \n\n");
+       g_print("b. back \n");
+       g_print("----------------------------------------------------\n");
+       g_print("====================================================\n");
+}
+
+static void display_voip_menu(void)
+{
+       g_print("\n");
+       g_print("====================================================\n");
+       g_print("   media streamer test: VoIP menu v0.3\n");
+       g_print("----------------------------------------------------\n");
+       g_print("1. one streamer VoIP 1 \n");
+       g_print("2. one streamer VoIP 2 \n");
+       g_print("3. two streamers VoIP server 1 \n");
+       g_print("4. two streamers VoIP server 2 \n");
+       g_print("5. two streamers VoIP client 1 \n");
+       g_print("6. two streamers VoIP client 2 \n");
+       g_print("b. back \n");
+       g_print("----------------------------------------------------\n");
+       g_print("====================================================\n");
+}
+
+static void display_broadcast_menu(void)
+{
+       g_print("\n");
+       g_print("====================================================\n");
+       g_print("   media streamer test: Broadcast menu v0.3\n");
+       g_print("----------------------------------------------------\n");
+       g_print("1. Broadcast client \n");
+       g_print("2. Broadcast streamer \n");
+       g_print("b. back \n");
+       g_print("----------------------------------------------------\n");
+       g_print("====================================================\n");
+}
+
+static void display_main_menu(void)
+{
+       g_print("\n");
+       g_print("====================================================\n");
+       g_print("   media streamer test: Main menu v0.3\n");
+       g_print("----------------------------------------------------\n");
+       g_print("1. Broadcast \n");
+       g_print("2. VOIP \n");
+       g_print("q. quit \n");
+       g_print("----------------------------------------------------\n");
+       g_print("====================================================\n");
+}
+
+static void display_menu(void)
+{
+       if (g_sub_menu_state == SUBMENU_STATE_UNKNOWN)
+       {
+               switch (g_menu_state)
+               {
+                       case MENU_STATE_MAIN_MENU:
+                               display_main_menu();
+                               break;
+                       case MENU_STATE_BROADCAST_MENU:
+                               display_broadcast_menu();
+                               break;
+                       case MENU_STATE_VOIP_MENU:
+                               display_voip_menu();
+                               break;
+                       case MENU_STATE_PRESET_MENU:
+                               display_preset_menu();
+                               break;
+                       default:
+                               g_print("*** Unknown status.\n");
+                               break;
+               }
+       }
+       else
+       {
+               switch (g_sub_menu_state)
+               {
+                       case SUBMENU_STATE_GETTING_IP:
+                               display_getting_ip_menu();
+                               break;
+                       case SUBMENU_STATE_AUTOPLUG:
+                               display_autoplug_select_menu();
+                               break;
+                       case SUBMENU_STATE_FORMAT:
+//                             display_format_menu();
+                               break;
+                       default:
+                               g_print("*** Unknown Submenu state.\n");
+                               break;
+               }
+       }
+
+}
+
+static void run_preset(void)
+{
+       media_streamer_node_h rtp_bin = NULL;
+       create_formats();
+
+       switch(g_menu_preset)
+       {
+               case PRESET_RTP_STREAMER:
+                       rtp_bin = _create_rtp(VIDEO_PORT, AUDIO_PORT, FALSE);
+                       _create_rtp_streamer(rtp_bin);
+                       break;
+               case PRESET_RTP_CLIENT:
+                       rtp_bin = _create_rtp(VIDEO_PORT, AUDIO_PORT, TRUE);
+                       _create_rtp_client(rtp_bin);
+                       break;
+               case PRESET_VOIP:
+                       rtp_bin = _create_rtp(VIDEO_PORT, AUDIO_PORT, FALSE);
+                       _create_rtp_streamer(rtp_bin);
+                       _create_rtp_client(rtp_bin);
+                       break;
+               case PRESET_VOIP_2:
+                       rtp_bin = _create_rtp(VIDEO_PORT, AUDIO_PORT, TRUE);
+                       _create_rtp_streamer(rtp_bin);
+                       _create_rtp_client(rtp_bin);
+                       break;
+               case PRESET_DOUBLE_VOIP_SERVER:
+                       rtp_bin = _create_rtp(VIDEO_PORT, AUDIO_PORT, FALSE);
+                       _create_rtp_streamer(rtp_bin);
+                       break;
+               case PRESET_DOUBLE_VOIP_SERVER_2:
+                       rtp_bin = _create_rtp(VIDEO_PORT+10, AUDIO_PORT+10, TRUE);
+                       _create_rtp_streamer(rtp_bin);
+                       break;
+               case PRESET_DOUBLE_VOIP_CLIENT:
+                       rtp_bin = _create_rtp(VIDEO_PORT+10, AUDIO_PORT+10, FALSE);
+                       _create_rtp_client(rtp_bin);
+                       break;
+               case PRESET_DOUBLE_VOIP_CLIENT_2:
+                       rtp_bin = _create_rtp(VIDEO_PORT, AUDIO_PORT, TRUE);
+                       _create_rtp_client(rtp_bin);
+                       break;
+               default:
+                       g_print("Invalid menu preset was selected!");
+                       break;
+       }
+}
+
+void _interpret_main_menu(char *cmd)
+{
+       int len = strlen(cmd);
+
+       if(len == 1)
+       {
+               if ( !strncmp(cmd, "1", len))
+               {
+                       g_menu_state = MENU_STATE_BROADCAST_MENU;
+               }
+               else if ( !strncmp(cmd, "2", len))
+               {
+                       g_menu_state = MENU_STATE_VOIP_MENU;
+               }
+               else if ( !strncmp(cmd, "q", len))
+               {
+                       quit();
+               }
+       }
+       else
+       {
+               g_print("wrong command\n");
+       }
+}
+
+//=====================Broadcast Menu============================//
+void _interpret_broadcast_menu(char *cmd)
+{
+       int len = strlen(cmd);
+
+       if(len == 1)
+       {
+               if( !strncmp(cmd, "1", len))
+               {
+                       g_menu_preset = PRESET_RTP_CLIENT;
+                       g_menu_state = MENU_STATE_PRESET_MENU;
+               }
+               else if( !strncmp(cmd, "2", len))
+               {
+                       g_menu_preset = PRESET_RTP_STREAMER;
+                       g_menu_state = MENU_STATE_PRESET_MENU;
+               }
+               else if( !strncmp(cmd, "b", len))
+               {
+                       reset_current_menu_state();
+                       display_menu();
+               }
+       }
+       else
+       {
+               g_print("wrong command\n");
+       }
+}
+
+void _interpret_voip_menu(char *cmd)
+{
+       int len = strlen(cmd);
+
+       if(len == 1)
+       {
+               if( !strncmp(cmd, "1", len))
+               {
+                       g_menu_preset = PRESET_VOIP;
+                       g_menu_state = MENU_STATE_PRESET_MENU;
+               }
+               else if( !strncmp(cmd, "2", len))
+               {
+                       g_menu_preset = PRESET_VOIP_2;
+                       g_menu_state = MENU_STATE_PRESET_MENU;
+               }
+               else if( !strncmp(cmd, "3", len))
+               {
+                       //double Server 1
+                       g_menu_preset = PRESET_DOUBLE_VOIP_SERVER;
+                       g_menu_state = MENU_STATE_PRESET_MENU;
+               }
+               else if( !strncmp(cmd, "4", len))
+               {
+                       //double Server 2
+                       g_menu_preset = PRESET_DOUBLE_VOIP_SERVER_2;
+                       g_menu_state = MENU_STATE_PRESET_MENU;
+               }
+               else if( !strncmp(cmd, "5", len))
+               {
+                       //double Client 1
+                       g_menu_preset = PRESET_DOUBLE_VOIP_CLIENT;
+                       g_menu_state = MENU_STATE_PRESET_MENU;
+               }
+               else if( !strncmp(cmd, "6", len))
+               {
+                       //double Client 2
+                       g_menu_preset = PRESET_DOUBLE_VOIP_CLIENT_2;
+                       g_menu_state = MENU_STATE_PRESET_MENU;
+               }
+               else if( !strncmp(cmd, "b", len))
+               {
+                       reset_current_menu_state();
+                       //display_menu();
+               }
+
+       }
+       else
+       {
+               g_print("wrong command\n");
+       }
+}
+
+void _interpret_getting_ip_menu(char *cmd)
+{
+       int min_len = strlen("0.0.0.0");
+       int cmd_len = strlen(cmd);
+       if(g_broadcast_address != NULL)
+       {
+               g_free(g_broadcast_address);
+       }
+
+       if(cmd_len > min_len)
+       {
+               g_broadcast_address = g_strdup(cmd);
+               g_print("== IP address setted to [%s]\n", g_broadcast_address);
+       }
+       else
+       {
+               g_broadcast_address = g_strdup(DEFAULT_IP_ADDR);
+               g_print("Invalid IP. Default address will be used [%s]\n", DEFAULT_IP_ADDR);
+       }
+
+       run_preset();
+       g_sub_menu_state = SUBMENU_STATE_UNKNOWN;
+}
+
+void _interpret_autoplug_menu(char *cmd)
+{
+
+       int cmd_number = atoi(cmd)-1;
+
+
+       if(cmd_number == 1 || cmd_number == 0)
+       {
+               g_autoplug_mode = cmd_number;
+       }
+       else
+       {
+               g_print("Invalid input. Default autoplug mode will be used\n");
+       }
+       g_print("Selected pluging mode is [%s]\n",
+                       g_autoplug_mode == TRUE ? "autoplug" : "manual");
+
+       if(g_menu_preset & PRESET_RTP_STREAMER)
+       {
+               g_sub_menu_state = SUBMENU_STATE_GETTING_IP;
+       }
+       else
+       {
+               run_preset();
+               g_sub_menu_state = SUBMENU_STATE_UNKNOWN;
+       }
+}
+
+void _interpret_preset_menu(char *cmd)
+{
+       int len = strlen(cmd);
+
+       if(len == 1 || len == 2)
+       {
+               if( !strncmp(cmd, "1", len))
+               {
+                       if((g_menu_preset & DOUBLE_STREAMER_MASK) &&
+                                       (g_menu_preset & PRESET_RTP_CLIENT))
+                       {
+                               _create(&g_media_streamer_2);
+                               current_media_streamer = g_media_streamer_2;
+                               g_print("== success create media streamer 2\n");
+                       }
+                       else
+                       {
+                               _create(&g_media_streamer);
+                               current_media_streamer = g_media_streamer;
+                               g_print("== success create media streamer\n");
+                       }
+
+               }
+               else if( !strncmp(cmd, "2", len))
+               {
+                       // call the run_preset function after autoplug mode was selected;
+                       g_sub_menu_state = SUBMENU_STATE_AUTOPLUG;
+               }
+               else if( !strncmp(cmd, "4", len))
+               {
+                       _prepare();
+               }
+               else if( !strncmp(cmd, "5", len))
+               {
+                       _unprepare();
+               }
+               else if( !strncmp(cmd, "6", len))
+               {
+                       _play(g_media_streamer);
+               }
+               else if( !strncmp(cmd, "7", len))
+               {
+                       _destroy(current_media_streamer);
+                       current_media_streamer = NULL;
+               }
+               else if( !strncmp(cmd, "b", len))
+               {
+                       if(g_menu_preset & DOUBLE_STREAMER_MASK)
+                       {
+                               g_menu_state = MENU_STATE_VOIP_MENU;
+                               g_autoplug_mode = FALSE;
+                               current_media_streamer = NULL;
+                       }
+                       else
+                       {
+                               reset_current_menu_state();
+                       }
+                       display_menu();
+               }
+
+       }
+       else
+       {
+               g_print("wrong command\n");
+       }
+}
+
+static void interpret_cmd(char *cmd)
+{
+       if(g_sub_menu_state == SUBMENU_STATE_UNKNOWN)
+       {
+               switch(g_menu_state)
+               {
+                       case MENU_STATE_MAIN_MENU:
+                               _interpret_main_menu(cmd);
+                               break;
+                       case MENU_STATE_BROADCAST_MENU:
+                               _interpret_broadcast_menu(cmd);
+                               break;
+                       case MENU_STATE_VOIP_MENU:
+                               _interpret_voip_menu(cmd);
+                               break;
+                       case MENU_STATE_PRESET_MENU:
+                               _interpret_preset_menu(cmd);
+                               break;
+                       default:
+                               g_print("Invalid command\n");
+                               return;
+                               break;
+               }
+       }
+       else
+       {
+               switch (g_sub_menu_state)
+               {
+                       case SUBMENU_STATE_GETTING_IP:
+                               _interpret_getting_ip_menu(cmd);
+                               break;
+                       case SUBMENU_STATE_AUTOPLUG:
+                               _interpret_autoplug_menu(cmd);
+                               break;
+                       case SUBMENU_STATE_FORMAT:
+                               //display_format_menu();
+                               break;
+                       default:
+                               g_print("*** Unknown Submenu state.\n");
+                               break;
+               }
+       }
+
+       display_menu();
+}
+
+gboolean input(GIOChannel *channel)
+{
+       gchar buf[MAX_STRING_LEN];
+       gsize read;
+       GError *error = NULL;
+
+       g_io_channel_read_chars(channel, buf, MAX_STRING_LEN, &read, &error);
+
+       buf[read] = '\0';
+       g_strstrip(buf);
+       interpret_cmd(buf);
+
+       return TRUE;
+
+}
+
+int main(int argc, char **argv)
+{
+       GIOChannel *stdin_channel;
+       stdin_channel = g_io_channel_unix_new(0);
+       g_io_channel_set_flags(stdin_channel, G_IO_FLAG_NONBLOCK, NULL);
+       g_io_add_watch(stdin_channel, G_IO_IN,(GIOFunc)input, NULL);
+
+       display_menu();
+
+       g_loop = g_main_loop_new(NULL, FALSE);
+       g_main_loop_run(g_loop);
+       return 0;
+}