Tizen 2.1 base
authorJinkun Jang <jinkun.jang@samsung.com>
Tue, 12 Mar 2013 16:49:59 +0000 (01:49 +0900)
committerJinkun Jang <jinkun.jang@samsung.com>
Tue, 12 Mar 2013 16:49:59 +0000 (01:49 +0900)
31 files changed:
AUTHORS [new file with mode: 0644]
LICENSE.APLv2 [new file with mode: 0644]
Makefile.am [new file with mode: 0644]
NOTICE [new file with mode: 0644]
autogen.sh [new file with mode: 0755]
configure.ac [new file with mode: 0755]
libmm-player.manifest [new file with mode: 0755]
mm-player.pc.in [new file with mode: 0644]
packaging/libmm-player.spec [new file with mode: 0644]
src/Makefile.am [new file with mode: 0644]
src/include/mm_player.h [new file with mode: 0644]
src/include/mm_player_asm.h [new file with mode: 0644]
src/include/mm_player_attrs.h [new file with mode: 0644]
src/include/mm_player_audioeffect.h [new file with mode: 0644]
src/include/mm_player_capture.h [new file with mode: 0755]
src/include/mm_player_ini.h [new file with mode: 0644]
src/include/mm_player_internal.h [new file with mode: 0644]
src/include/mm_player_pd.h [new file with mode: 0644]
src/include/mm_player_priv.h [new file with mode: 0644]
src/include/mm_player_streaming.h [new file with mode: 0644]
src/include/mm_player_utils.h [new file with mode: 0644]
src/mm_player.c [new file with mode: 0644]
src/mm_player_asm.c [new file with mode: 0644]
src/mm_player_attrs.c [new file with mode: 0644]
src/mm_player_audioeffect.c [new file with mode: 0644]
src/mm_player_capture.c [new file with mode: 0755]
src/mm_player_ini.c [new file with mode: 0644]
src/mm_player_pd.c [new file with mode: 0644]
src/mm_player_priv.c [new file with mode: 0644]
src/mm_player_streaming.c [new file with mode: 0644]
src/mm_player_utils.c [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..9c96f2e
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,3 @@
+JongHyuk Choi <jhchoi.choi at samsung dot com>\r
+YeJin Cho <cho.yejin at samsung dot com>\r
+YoungHwan An <younghwan_.an at samsung dot com>\r
diff --git a/LICENSE.APLv2 b/LICENSE.APLv2
new file mode 100644 (file)
index 0000000..9c13a9b
--- /dev/null
@@ -0,0 +1,204 @@
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
+\r
+                                 Apache License\r
+                           Version 2.0, January 2004\r
+                        http://www.apache.org/licenses/\r
+\r
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\r
+\r
+   1. Definitions.\r
+\r
+      "License" shall mean the terms and conditions for use, reproduction,\r
+      and distribution as defined by Sections 1 through 9 of this document.\r
+\r
+      "Licensor" shall mean the copyright owner or entity authorized by\r
+      the copyright owner that is granting the License.\r
+\r
+      "Legal Entity" shall mean the union of the acting entity and all\r
+      other entities that control, are controlled by, or are under common\r
+      control with that entity. For the purposes of this definition,\r
+      "control" means (i) the power, direct or indirect, to cause the\r
+      direction or management of such entity, whether by contract or\r
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the\r
+      outstanding shares, or (iii) beneficial ownership of such entity.\r
+\r
+      "You" (or "Your") shall mean an individual or Legal Entity\r
+      exercising permissions granted by this License.\r
+\r
+      "Source" form shall mean the preferred form for making modifications,\r
+      including but not limited to software source code, documentation\r
+      source, and configuration files.\r
+\r
+      "Object" form shall mean any form resulting from mechanical\r
+      transformation or translation of a Source form, including but\r
+      not limited to compiled object code, generated documentation,\r
+      and conversions to other media types.\r
+\r
+      "Work" shall mean the work of authorship, whether in Source or\r
+      Object form, made available under the License, as indicated by a\r
+      copyright notice that is included in or attached to the work\r
+      (an example is provided in the Appendix below).\r
+\r
+      "Derivative Works" shall mean any work, whether in Source or Object\r
+      form, that is based on (or derived from) the Work and for which the\r
+      editorial revisions, annotations, elaborations, or other modifications\r
+      represent, as a whole, an original work of authorship. For the purposes\r
+      of this License, Derivative Works shall not include works that remain\r
+      separable from, or merely link (or bind by name) to the interfaces of,\r
+      the Work and Derivative Works thereof.\r
+\r
+      "Contribution" shall mean any work of authorship, including\r
+      the original version of the Work and any modifications or additions\r
+      to that Work or Derivative Works thereof, that is intentionally\r
+      submitted to Licensor for inclusion in the Work by the copyright owner\r
+      or by an individual or Legal Entity authorized to submit on behalf of\r
+      the copyright owner. For the purposes of this definition, "submitted"\r
+      means any form of electronic, verbal, or written communication sent\r
+      to the Licensor or its representatives, including but not limited to\r
+      communication on electronic mailing lists, source code control systems,\r
+      and issue tracking systems that are managed by, or on behalf of, the\r
+      Licensor for the purpose of discussing and improving the Work, but\r
+      excluding communication that is conspicuously marked or otherwise\r
+      designated in writing by the copyright owner as "Not a Contribution."\r
+\r
+      "Contributor" shall mean Licensor and any individual or Legal Entity\r
+      on behalf of whom a Contribution has been received by Licensor and\r
+      subsequently incorporated within the Work.\r
+\r
+   2. Grant of Copyright License. Subject to the terms and conditions of\r
+      this License, each Contributor hereby grants to You a perpetual,\r
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r
+      copyright license to reproduce, prepare Derivative Works of,\r
+      publicly display, publicly perform, sublicense, and distribute the\r
+      Work and such Derivative Works in Source or Object form.\r
+\r
+   3. Grant of Patent License. Subject to the terms and conditions of\r
+      this License, each Contributor hereby grants to You a perpetual,\r
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r
+      (except as stated in this section) patent license to make, have made,\r
+      use, offer to sell, sell, import, and otherwise transfer the Work,\r
+      where such license applies only to those patent claims licensable\r
+      by such Contributor that are necessarily infringed by their\r
+      Contribution(s) alone or by combination of their Contribution(s)\r
+      with the Work to which such Contribution(s) was submitted. If You\r
+      institute patent litigation against any entity (including a\r
+      cross-claim or counterclaim in a lawsuit) alleging that the Work\r
+      or a Contribution incorporated within the Work constitutes direct\r
+      or contributory patent infringement, then any patent licenses\r
+      granted to You under this License for that Work shall terminate\r
+      as of the date such litigation is filed.\r
+\r
+   4. Redistribution. You may reproduce and distribute copies of the\r
+      Work or Derivative Works thereof in any medium, with or without\r
+      modifications, and in Source or Object form, provided that You\r
+      meet the following conditions:\r
+\r
+      (a) You must give any other recipients of the Work or\r
+          Derivative Works a copy of this License; and\r
+\r
+      (b) You must cause any modified files to carry prominent notices\r
+          stating that You changed the files; and\r
+\r
+      (c) You must retain, in the Source form of any Derivative Works\r
+          that You distribute, all copyright, patent, trademark, and\r
+          attribution notices from the Source form of the Work,\r
+          excluding those notices that do not pertain to any part of\r
+          the Derivative Works; and\r
+\r
+      (d) If the Work includes a "NOTICE" text file as part of its\r
+          distribution, then any Derivative Works that You distribute must\r
+          include a readable copy of the attribution notices contained\r
+          within such NOTICE file, excluding those notices that do not\r
+          pertain to any part of the Derivative Works, in at least one\r
+          of the following places: within a NOTICE text file distributed\r
+          as part of the Derivative Works; within the Source form or\r
+          documentation, if provided along with the Derivative Works; or,\r
+          within a display generated by the Derivative Works, if and\r
+          wherever such third-party notices normally appear. The contents\r
+          of the NOTICE file are for informational purposes only and\r
+          do not modify the License. You may add Your own attribution\r
+          notices within Derivative Works that You distribute, alongside\r
+          or as an addendum to the NOTICE text from the Work, provided\r
+          that such additional attribution notices cannot be construed\r
+          as modifying the License.\r
+\r
+      You may add Your own copyright statement to Your modifications and\r
+      may provide additional or different license terms and conditions\r
+      for use, reproduction, or distribution of Your modifications, or\r
+      for any such Derivative Works as a whole, provided Your use,\r
+      reproduction, and distribution of the Work otherwise complies with\r
+      the conditions stated in this License.\r
+\r
+   5. Submission of Contributions. Unless You explicitly state otherwise,\r
+      any Contribution intentionally submitted for inclusion in the Work\r
+      by You to the Licensor shall be under the terms and conditions of\r
+      this License, without any additional terms or conditions.\r
+      Notwithstanding the above, nothing herein shall supersede or modify\r
+      the terms of any separate license agreement you may have executed\r
+      with Licensor regarding such Contributions.\r
+\r
+   6. Trademarks. This License does not grant permission to use the trade\r
+      names, trademarks, service marks, or product names of the Licensor,\r
+      except as required for reasonable and customary use in describing the\r
+      origin of the Work and reproducing the content of the NOTICE file.\r
+\r
+   7. Disclaimer of Warranty. Unless required by applicable law or\r
+      agreed to in writing, Licensor provides the Work (and each\r
+      Contributor provides its Contributions) on an "AS IS" BASIS,\r
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\r
+      implied, including, without limitation, any warranties or conditions\r
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\r
+      PARTICULAR PURPOSE. You are solely responsible for determining the\r
+      appropriateness of using or redistributing the Work and assume any\r
+      risks associated with Your exercise of permissions under this License.\r
+\r
+   8. Limitation of Liability. In no event and under no legal theory,\r
+      whether in tort (including negligence), contract, or otherwise,\r
+      unless required by applicable law (such as deliberate and grossly\r
+      negligent acts) or agreed to in writing, shall any Contributor be\r
+      liable to You for damages, including any direct, indirect, special,\r
+      incidental, or consequential damages of any character arising as a\r
+      result of this License or out of the use or inability to use the\r
+      Work (including but not limited to damages for loss of goodwill,\r
+      work stoppage, computer failure or malfunction, or any and all\r
+      other commercial damages or losses), even if such Contributor\r
+      has been advised of the possibility of such damages.\r
+\r
+   9. Accepting Warranty or Additional Liability. While redistributing\r
+      the Work or Derivative Works thereof, You may choose to offer,\r
+      and charge a fee for, acceptance of support, warranty, indemnity,\r
+      or other liability obligations and/or rights consistent with this\r
+      License. However, in accepting such obligations, You may act only\r
+      on Your own behalf and on Your sole responsibility, not on behalf\r
+      of any other Contributor, and only if You agree to indemnify,\r
+      defend, and hold each Contributor harmless for any liability\r
+      incurred by, or claims asserted against, such Contributor by reason\r
+      of your accepting any such warranty or additional liability.\r
+\r
+   END OF TERMS AND CONDITIONS\r
+\r
+   APPENDIX: How to apply the Apache License to your work.\r
+\r
+      To apply the Apache License to your work, attach the following\r
+      boilerplate notice, with the fields enclosed by brackets "[]"\r
+      replaced with your own identifying information. (Don't include\r
+      the brackets!)  The text should be enclosed in the appropriate\r
+      comment syntax for the file format. We also recommend that a\r
+      file or class name and description of purpose be included on the\r
+      same "printed page" as the copyright notice for easier\r
+      identification within third-party archives.\r
+\r
+   Copyright [yyyy] [name of copyright owner]\r
+\r
+   Licensed under the Apache License, Version 2.0 (the "License");\r
+   you may not use this file except in compliance with the License.\r
+   You may obtain a copy of the License at\r
+\r
+       http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+\r
diff --git a/Makefile.am b/Makefile.am
new file mode 100644 (file)
index 0000000..4234d3f
--- /dev/null
@@ -0,0 +1,7 @@
+ACLOCAL_AMFLAGS='-I m4' 
+SUBDIRS = src
+
+pcfiles = mm-player.pc
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = $(pcfiles)
+EXTRA_DIST = $(pcfiles)
diff --git a/NOTICE b/NOTICE
new file mode 100644 (file)
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/autogen.sh b/autogen.sh
new file mode 100755 (executable)
index 0000000..1bf3d9c
--- /dev/null
@@ -0,0 +1,5 @@
+aclocal
+libtoolize --copy -f
+autoheader
+autoconf
+automake --add-missing --copy --foreign
diff --git a/configure.ac b/configure.ac
new file mode 100755 (executable)
index 0000000..4070017
--- /dev/null
@@ -0,0 +1,102 @@
+#                                               -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ(2.61)
+AC_INIT([libmm-player],[0.0.1])
+AC_CONFIG_SRCDIR([src/mm_player_priv.c])
+AC_CONFIG_HEADER([config.h])
+AM_INIT_AUTOMAKE([-Wall -Werror foreign])
+
+# Checks for programs.
+AC_PROG_CC
+AC_PROG_LIBTOOL
+
+AC_FUNC_MMAP
+AC_FUNC_REALLOC
+AC_FUNC_SELECT_ARGTYPES
+AC_FUNC_STAT
+AC_FUNC_VPRINTF
+AC_HEADER_STDBOOL
+AC_HEADER_STDC
+AC_HEADER_TIME
+AC_PROG_GCC_TRADITIONAL
+
+# Checks for libraries.
+
+# Checks for header files.
+AC_HEADER_STDC
+AC_CHECK_HEADERS([fcntl.h stdlib.h string.h syslog.h unistd.h])
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_HEADER_STDBOOL
+AC_C_CONST
+AC_TYPE_INT64_T
+AC_HEADER_TIME
+
+# Checks for library functions.
+AC_FUNC_MALLOC
+AC_FUNC_MEMCMP
+AC_FUNC_STAT
+AC_CHECK_FUNCS([gettimeofday memset strchr strstr])
+
+PKG_CHECK_MODULES(MMTA, mm-ta)
+AC_SUBST(MMTA_CFLAGS)
+AC_SUBST(MMTA_LIBS)
+
+PKG_CHECK_MODULES(MMCOMMON,mm-common)
+AC_SUBST(MMCOMMON_CFLAGS)
+AC_SUBST(MMCOMMON_LIBS)
+
+PKG_CHECK_MODULES(MMSOUND,mm-sound)
+AC_SUBST(MMSOUND_CFLAGS)
+AC_SUBST(MMSOUND_LIBS)
+
+PKG_CHECK_MODULES(GLIB, glib-2.0)
+AC_SUBST(GLIB_CFLAGS)
+AC_SUBST(GLIB_LIBS)
+
+PKG_CHECK_MODULES(GST, gstreamer-0.10 >= 0.10)
+AC_SUBST(GST_CFLAGS)
+AC_SUBST(GST_LIBS)
+
+PKG_CHECK_MODULES(GST_PLUGIN_BASE, gstreamer-plugins-base-0.10 >= 0.10)
+AC_SUBST(GST_PLUGIN_BASE_CFLAGS)
+AC_SUBST(GST_PLUGIN_BASE_LIBS)
+
+PKG_CHECK_MODULES(GST_INTERFACE, gstreamer-interfaces-0.10 >= 0.10)
+AC_SUBST(GST_INTERFACE_CFLAGS)
+AC_SUBST(GST_LIBS)
+
+PKG_CHECK_MODULES(GST_APP, gstreamer-app-0.10 >= 0.10)
+AC_SUBST(GST_APP_CFLAGS)
+AC_SUBST(GST_APP_LIBS)
+
+PKG_CHECK_MODULES(MMSESSION, mm-session)
+AC_SUBST(MMSESSION_CFLAGS)
+AC_SUBST(MMSESSION_LIBS)
+
+PKG_CHECK_MODULES(MMUTIL, mmutil-imgp)
+AC_SUBST(MMUTIL_CFLAGS)
+AC_SUBST(MMUTIL_LIBS)
+
+PKG_CHECK_MODULES(AUDIOSESSIONMGR, audio-session-mgr)
+AC_SUBST(AUDIOSESSIONMGR_CFLAGS)
+AC_SUBST(AUDIOSESSIONMGR_LIBS)
+
+PKG_CHECK_MODULES(ICU, icu-i18n)
+AC_SUBST(ICU_CFLAGS)
+AC_SUBST(ICU_LIBS)
+
+PKG_CHECK_MODULES(INIPARSER, iniparser)
+AC_SUBST(INIPARSER_CFLAGS)
+AC_SUBST(INIPARSER_LIBS)
+
+PKG_CHECK_MODULES(VCONF, vconf)
+AC_SUBST(VCONF_CFLAGS)
+AC_SUBST(VCONF_LIBS)
+
+AC_CONFIG_FILES([Makefile
+                src/Makefile
+                mm-player.pc
+])
+AC_OUTPUT
diff --git a/libmm-player.manifest b/libmm-player.manifest
new file mode 100755 (executable)
index 0000000..a76fdba
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+       <request>
+               <domain name="_" />
+       </request>
+</manifest>
diff --git a/mm-player.pc.in b/mm-player.pc.in
new file mode 100644 (file)
index 0000000..6db989c
--- /dev/null
@@ -0,0 +1,11 @@
+prefix = @prefix@
+exec_prefix=@exec_prefix@
+libdir = @libdir@
+includedir = @includedir@
+
+Name : mm-player
+Description : Multimedia Framework Player Library
+Requires : mm-common
+Version : @VERSION@
+Libs : -L${libdir} -lmmfplayer
+Cflags : -I${includedir}/mmf
diff --git a/packaging/libmm-player.spec b/packaging/libmm-player.spec
new file mode 100644 (file)
index 0000000..2a41c77
--- /dev/null
@@ -0,0 +1,77 @@
+
+Name:       libmm-player
+Summary:    Multimedia Framework Player Library
+Version:    0.2.11
+Release:    1
+Group:      System/Libraries
+License:    Apache License, Version 2.0
+URL:        http://source.tizen.org
+Source0:    %{name}-%{version}.tar.gz
+Requires(post):  /sbin/ldconfig
+Requires(postun):  /sbin/ldconfig
+BuildRequires:  pkgconfig(mm-ta)
+BuildRequires:  pkgconfig(mm-common)
+BuildRequires:  pkgconfig(mm-sound)
+BuildRequires:  pkgconfig(gstreamer-0.10)
+BuildRequires:  pkgconfig(gstreamer-plugins-base-0.10)
+BuildRequires:  pkgconfig(gstreamer-interfaces-0.10)
+BuildRequires:  pkgconfig(gstreamer-app-0.10)
+BuildRequires:  pkgconfig(mm-session)
+BuildRequires:  pkgconfig(mmutil-imgp)
+BuildRequires:  pkgconfig(audio-session-mgr)
+BuildRequires:  pkgconfig(iniparser)
+BuildRequires:  pkgconfig(vconf)
+BuildRequires:  pkgconfig(icu-i18n)
+
+BuildRoot:  %{_tmppath}/%{name}-%{version}-build
+
+%description
+
+%package devel
+Summary:    Multimedia Framework Player Library (DEV)
+Group:      Development/Libraries
+Requires:   %{name} = %{version}-%{release}
+
+%description devel
+
+%prep
+%setup -q
+
+%build
+
+./autogen.sh
+
+CFLAGS+=" -DEXPORT_API=\"__attribute__((visibility(\\\"default\\\")))\" "; export CFLAGS
+LDFLAGS+="-Wl,--rpath=%{_prefix}/lib -Wl,--hash-style=both -Wl,--as-needed"; export LDFLAGS
+
+CFLAGS=$CFLAGS LDFLAGS=$LDFLAGS ./configure --prefix=%{_prefix} --disable-static
+
+# Call make instruction with smp support
+make -j1 
+
+%install
+rm -rf %{buildroot}
+%make_install
+
+%clean
+rm -rf %{buildroot}
+
+
+
+%post -p /sbin/ldconfig
+
+%postun -p /sbin/ldconfig
+
+
+%files
+%manifest libmm-player.manifest
+%defattr(-,root,root,-)
+%{_libdir}/*.so.*
+
+
+%files devel
+%defattr(-,root,root,-)
+%{_libdir}/*.so
+%{_includedir}/mmf/*.h
+%{_libdir}/pkgconfig/*
+
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644 (file)
index 0000000..8e1523e
--- /dev/null
@@ -0,0 +1,56 @@
+lib_LTLIBRARIES = libmmfplayer.la
+
+includelibmmfplayerdir = $(includedir)/mmf
+
+includelibmmfplayer_HEADERS = include/mm_player.h \
+                             include/mm_player_internal.h \
+                             include/mm_player_audioeffect.h
+
+libmmfplayer_la_SOURCES = mm_player.c \
+                         mm_player_priv.c \
+                         mm_player_ini.c \
+                         mm_player_utils.c \
+                         mm_player_asm.c \
+                         mm_player_attrs.c \
+                         mm_player_capture.c \
+                         mm_player_pd.c \
+                         mm_player_streaming.c \
+                         mm_player_audioeffect.c
+
+libmmfplayer_la_CFLAGS =  -I$(srcdir)/include \
+                         $(MMCOMMON_CFLAGS) \
+                         $(MMTA_CFLAGS) \
+                         $(MMUTIL_CFLAGS) \
+                         $(GST_CFLAGS) \
+                         $(GST_INTERFACE_CFLAGS) \
+                         $(GST_APP_CFLAGS) \
+                         $(MMSESSION_CFLAGS) \
+                         $(MMSOUND_CFLAGS) \
+                         $(AUDIOSESSIONMGR_CFLAGS) \
+                         $(VCONF_CFLAGS) \
+                          $(ICU_CFLAGS)
+
+noinst_HEADERS = include/mm_player_utils.h \
+                include/mm_player_ini.h \
+                include/mm_player_priv.h \
+                include/mm_player_asm.h \
+                include/mm_player_attrs.h \
+                include/mm_player_capture.h \
+                include/mm_player_pd.h \
+                include/mm_player_streaming.h
+
+libmmfplayer_la_LIBADD = $(GST_LIBS) \
+                        $(MMCOMMON_LIBS) \
+                        $(MMTA_LIBS) \
+                        $(MMUTIL_LIBS) \
+                        $(GST_INTERFACE_LIBS) \
+                        $(GST_APP_LIBS) \
+                        $(INIPARSER_LIBS) \
+                        $(MMSESSION_LIBS) \
+                        $(MMSOUND_LIBS) \
+                        $(AUDIOSESSIONMGR_LIBS) \
+                        $(VCONF_LIBS) \
+                         $(ICU_LIBS)
+
+libmmfplayer_la_CFLAGS += $(MMLOG_CFLAGS) -DMMF_LOG_OWNER=0x008 -DMMF_DEBUG_PREFIX=\"MMF-PLAYER\" -D_INTERNAL_SESSION_MANAGER_
+libmmfplayer_la_LIBADD += $(MMLOG_LIBS)
diff --git a/src/include/mm_player.h b/src/include/mm_player.h
new file mode 100644 (file)
index 0000000..4200347
--- /dev/null
@@ -0,0 +1,1556 @@
+/*
+ * libmm-player
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YeJin Cho <cho.yejin@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>
+ *
+ * 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 __MM_PLAYER_H__
+#define        __MM_PLAYER_H__
+
+
+/*===========================================================================================
+|                                                                                           |
+|  INCLUDE FILES                                        |
+|                                                                                           |
+========================================================================================== */
+
+#include <glib.h>
+
+#include <mm_types.h>
+#include <mm_message.h>
+
+#ifdef __cplusplus
+       extern "C" {
+#endif
+
+/**
+       @addtogroup PLAYER
+       @{
+
+       @par
+       This part describes APIs used for playback of multimedia contents.
+       All multimedia contents are created by a media player through handle of playback.
+       In creating a player, it displays the player's status or information
+       by registering callback function.
+
+       @par
+       In case of streaming playback, network has to be opend by using datanetwork API. 
+       If proxy, cookies and the other attributes for streaming playback are needed, 
+       set those attributes using mm_player_set_attribute() before create player.
+
+       @par
+       The subtitle for local video playback is supported. Set "subtitle_uri" attribute 
+       using mm_player_set_attribute() before the application creates the player.
+       Then the application could receive MMMessageParamType which includes subtitle string and duration.
+
+       @par
+       Player can have 5 states, and each state can be changed by calling
+       described functions on "Figure1. State of Player".
+
+       @par
+       @image html             player_state.jpg        "Figure1. State of Player"      width=12cm
+       @image latex    player_state.jpg        "Figure1. State of Player"      width=12cm
+
+       @par
+       Most of functions which change player state work as synchronous. But, mm_player_start() should be used
+       asynchronously. Both mm_player_pause() and mm_player_resume() should also be used asynchronously 
+       in the case of streaming data.
+       So, application have to confirm the result of those APIs through message callback function.
+
+       @par
+       Note that "None" and Null" state could be reached from any state
+       by calling mm_player_destroy() and mm_player_unrealize().
+
+       @par
+       <div><table>
+       <tr>
+       <td><B>FUNCTION</B></td>
+       <td><B>PRE-STATE</B></td>
+       <td><B>POST-STATE</B></td>
+       <td><B>SYNC TYPE</B></td>
+       </tr>
+       <tr>
+       <td>mm_player_create()</td>
+       <td>NONE</td>
+       <td>NULL</td>
+       <td>SYNC</td>
+       </tr>
+       <tr>
+       <td>mm_player_destroy()</td>
+       <td>NULL</td>
+       <td>NONE</td>
+       <td>SYNC</td>
+       </tr>
+       <tr>
+       <td>mm_player_realize()</td>
+       <td>NULL</td>
+       <td>READY</td>
+       <td>SYNC</td>
+       </tr>
+       <tr>
+       <td>mm_player_unrealize()</td>
+       <td>READY</td>
+       <td>NULL</td>
+       <td>SYNC</td>
+       </tr>
+       <tr>
+       <td>mm_player_start()</td>
+       <td>READY</td>
+       <td>PLAYING</td>
+       <td>ASYNC</td>
+       </tr>
+       <tr>
+       <td>mm_player_stop()</td>
+       <td>PLAYING</td>
+       <td>READY</td>
+       <td>SYNC</td>
+       </tr>
+       <tr>
+       <td>mm_player_pause()</td>
+       <td>PLAYING</td>
+       <td>PAUSED</td>
+       <td>ASYNC</td>
+       </tr>
+       <tr>
+       <td>mm_player_resume()</td>
+       <td>PAUSED</td>
+       <td>PLAYING</td>
+       <td>ASYNC</td>
+       </tr>
+       <tr>
+       <td>mm_player_set_message_callback()</td>
+       <td>N/A</td>
+       <td>N/A</td>
+       <td>SYNC</td>
+       </tr>
+       <tr>
+       <td>mm_player_get_state()</td>
+       <td>N/A</td>
+       <td>N/A</td>
+       <td>SYNC</td>
+       </tr>
+       <tr>
+       <td>mm_player_set_volume()</td>
+       <td>N/A</td>
+       <td>N/A</td>
+       <td>SYNC</td>
+       </tr>
+       <tr>
+       <td>mm_player_get_volume()</td>
+       <td>N/A</td>
+       <td>N/A</td>
+       <td>SYNC</td>
+       </tr>
+       <tr>
+       <td>mm_player_set_position()</td>
+       <td>N/A</td>
+       <td>N/A</td>
+       <td>SYNC</td>
+       </tr>
+       <tr>
+       <td>mm_player_get_position()</td>
+       <td>N/A</td>
+       <td>N/A</td>
+       <td>SYNC</td>
+       </tr>
+       <tr>
+       <td>mm_player_get_attribute()</td>
+       <td>N/A</td>
+       <td>N/A</td>
+       <td>SYNC</td>
+       </tr>
+       <tr>
+       <td>mm_player_set_attribute()</td>
+       <td>N/A</td>
+       <td>N/A</td>
+       <td>SYNC</td>
+       </tr>
+       </table></div>
+
+       @par
+       Following are the attributes supported in player which may be set after initialization. \n
+       Those are handled as a string.
+
+       @par
+       <div><table>
+       <tr>
+       <td>PROPERTY</td>
+       <td>TYPE</td>
+       <td>VALID TYPE</td>
+       </tr>
+       <tr>
+       <td>"profile_uri"</td>
+       <td>string</td>
+       <td>N/A</td>
+       </tr>
+       <tr>
+       <td>"content_duration"</td>
+       <td>int</td>
+       <td>range</td>
+       </tr>
+       <tr>
+       <td>"content_video_width"</td>
+       <td>int</td>
+       <td>range</td>
+       </tr>
+       <tr>
+       <td>"content_video_height"</td>
+       <td>int</td>
+       <td>range</td>
+       </tr>
+       <tr>
+       <td>"display_evas_do_scaling"</td>
+       <td>int</td>
+       <td>range</td>
+       </tr>
+       <tr>
+       <td>"display_evas_surface_sink"</td>
+       <td>string</td>
+       <td>N/A</td>
+       </tr>
+       <tr>
+       <td>"profile_user_param"</td>
+       <td>data</td>
+       <td>N/A</td>
+       </tr>
+       <tr>
+       <td>"profile_play_count"</td>
+       <td>int</td>
+       <td>range</td>
+       </tr>
+       <tr>
+       <td>"streaming_type"</td>
+       <td>int</td>
+       <td>range</td>
+       </tr>
+       <tr>
+       <td>"streaming_udp_timeout"</td>
+       <td>int</td>
+       <td>range</td>
+       </tr>
+       <tr>
+       <td>"streaming_user_agent"</td>
+       <td>string</td>
+       <td>N/A</td>
+       </tr>
+       <tr>
+       <td>"streaming_wap_profile"</td>
+       <td>string</td>
+       <td>N/A</td>
+       </tr>
+       <tr>
+       <td>"streaming_network_bandwidth"</td>
+       <td>int</td>
+       <td>range</td>
+       </tr>
+       <tr>
+       <td>"streaming_cookie"</td>
+       <td>string</td>
+       <td>N/A</td>
+       </tr>
+       <tr>
+       <td>"streaming_proxy_ip"</td>
+       <td>string</td>
+       <td>N/A</td>
+       </tr>
+       <tr>
+       <td>"streaming_proxy_port"</td>
+       <td>int</td>
+       <td>range</td>
+       </tr>
+       <tr>
+       <td>"display_overlay"</td>
+       <td>data</td>
+       <td>N/A</td>
+       </tr>
+       <tr>
+       <td>"display_rotation"</td>
+       <td>int</td>
+       <td>range</td>
+       </tr>
+       <tr>
+       <td>"subtitle_uri"</td>
+       <td>string</td>
+       <td>N/A</td>
+       </tr>
+       </table></div>
+
+       @par
+       Following attributes are supported for playing stream data. Those value can be readable only and valid after starting playback.\n
+       Please use mm_fileinfo for local playback. 
+
+       @par
+       <div><table>
+       <tr>
+       <td>PROPERTY</td>
+       <td>TYPE</td>
+       <td>VALID TYPE</td>
+       </tr>
+       <tr>
+       <td>"content_video_found"</td>
+       <td>string</td>
+       <td>N/A</td>
+       </tr>
+       <tr>
+       <td>"content_video_codec"</td>
+       <td>string</td>
+       <td>N/A</td>
+       </tr>
+       <tr>
+       <td>"content_video_track_num"</td>
+       <td>int</td>
+       <td>range</td>
+       </tr>
+       <tr>
+       <td>"content_audio_found"</td>
+       <td>string</td>
+       <td>N/A</td>
+       </tr>
+       <tr>
+       <td>"content_audio_codec"</td>
+       <td>string</td>
+       <td>N/A</td>
+       </tr>
+       <tr>
+       <td>"content_audio_bitrate"</td>
+       <td>int</td>
+       <td>array</td>
+       </tr>
+       <tr>
+       <td>"content_audio_channels"</td>
+       <td>int</td>
+       <td>range</td>
+       </tr>
+       <tr>
+       <td>"content_audio_samplerate"</td>
+       <td>int</td>
+       <td>array</td>
+       </tr>
+       <tr>
+       <td>"content_audio_track_num"</td>
+       <td>int</td>
+       <td>range</td>
+       </tr>
+       <tr>
+       <td>"content_text_track_num"</td>
+       <td>int</td>
+       <td>range</td>
+       </tr>
+       <tr>
+       <td>"tag_artist"</td>
+       <td>string</td>
+       <td>N/A</td>
+       </tr>
+       <tr>
+       <td>"tag_title"</td>
+       <td>string</td>
+       <td>N/A</td>
+       </tr>
+       <tr>
+       <td>"tag_album"</td>
+       <td>string</td>
+       <td>N/A</td>
+       </tr>
+       <tr>
+       <td>"tag_genre"</td>
+       <td>string</td>
+       <td>N/A</td>
+       </tr>
+       <tr>
+       <td>"tag_author"</td>
+       <td>string</td>
+       <td>N/A</td>
+       </tr>
+       <tr>
+       <td>"tag_copyright"</td>
+       <td>string</td>
+       <td>N/A</td>
+       </tr>
+       <tr>
+       <td>"tag_date"</td>
+       <td>string</td>
+       <td>N/A</td>
+       </tr>
+       <tr>
+       <td>"tag_description"</td>
+       <td>string</td>
+       <td>N/A</td>
+       </tr>
+       <tr>
+       <td>"tag_track_num"</td>
+       <td>int</td>
+       <td>range</td>
+       </tr>
+       </table></div>
+
+ */
+
+
+/*===========================================================================================
+|                                                                                           |
+|  GLOBAL DEFINITIONS AND DECLARATIONS                                        |
+|                                                                                           |
+========================================================================================== */
+
+/**
+ * MM_PLAYER_URI:
+ *
+ * uri to play (string)
+ *
+ */
+#define MM_PLAYER_CONTENT_URI                                  "profile_uri"
+/**
+ * MM_PLAYER_CONTENT_DURATION:
+ *
+ * get the duration (int) as millisecond, It's guaranteed after calling mm_player_start() or 
+ * receiving MM_MESSAGE_BEGIN_OF_STREAM. 
+ *
+ */
+#define MM_PLAYER_CONTENT_DURATION                     "content_duration"
+/**
+ * MM_PLAYER_VIDEO_ROTATION
+ *
+ * can change video angle (int)
+ * @see MMDisplayRotationType
+ */
+#define MM_PLAYER_VIDEO_ROTATION                               "display_rotation"
+/**
+ * MM_PLAYER_VIDEO_WIDTH:
+ *
+ * get the video width (int), It's guaranteed after calling mm_player_start() or 
+ * receiving MM_MESSAGE_BEGIN_OF_STREAM. 
+ *
+ */
+#define MM_PLAYER_VIDEO_WIDTH                          "content_video_width"
+/**
+ * MM_PLAYER_VIDEO_HEIGHT:
+ *
+ * get the video height (int), It's guaranteed after calling mm_player_start() or 
+ * receiving MM_MESSAGE_BEGIN_OF_STREAM. 
+ *
+ */
+#define MM_PLAYER_VIDEO_HEIGHT                         "content_video_height"
+/**
+ * MM_PLAYER_VIDEO_EVAS_SURFACE_DO_SCALING:
+ *
+ * set whether or not to scale frames size for evas surface.
+ * if TRUE, it scales down width, height size of frames with given size.
+ * if FALSE, it does not scale down any frames.
+ *
+ */
+#define MM_PLAYER_VIDEO_EVAS_SURFACE_DO_SCALING                "display_evas_do_scaling"
+/**
+ * MM_PLAYER_VIDEO_EVAS_SURFACE_SINK:
+ *
+ * get the video evas surface sink plugin name (string), It's guaranteed after calling mm_player_create()
+ *
+ */
+#define MM_PLAYER_VIDEO_EVAS_SURFACE_SINK              "display_evas_surface_sink"
+/**
+ * MM_PLAYER_MEM_SRC:
+ *
+ * set memory pointer to play (data)
+ *
+ */
+#define MM_PLAYER_MEMORY_SRC                                   "profile_user_param"
+/**
+ * MM_PLAYER_PLAYBACK_COUNT
+ *
+ * can set playback count (int), Default value is 1 and -1 is for infinity playing until releasing it. 
+ *
+ */
+#define MM_PLAYER_PLAYBACK_COUNT                               "profile_play_count"
+/**
+ * MM_PLAYER_SUBTITLE_URI
+ *
+ * set the subtitle path (string)
+ */
+#define MM_PLAYER_SUBTITLE_URI                                 "subtitle_uri"
+/**
+ * MM_PLAYER_STREAMING_TYPE
+ *
+ * set the streaming type (int)
+ * @see MMStreamingType
+ */
+#define MM_PLAYER_STREAMING_TYPE                               "streaming_type"
+/**
+ * MM_PLAYER_STREAMING_UDP_TIMEOUT
+ *
+ * set the streaming udp timeout(int)
+ */
+#define MM_PLAYER_STREAMING_UDP_TIMEOUT                "streaming_udp_timeout"
+/**
+ * MM_PLAYER_STREAMING_USER_AGENT
+ *
+ * set the streaming user agent (string)
+ */
+#define MM_PLAYER_STREAMING_USER_AGENT         "streaming_user_agent"
+/**
+ * MM_PLAYER_STREAMING_WAP_PROFILE
+ *
+ * set the streaming wap profile (int)
+ */
+#define MM_PLAYER_STREAMING_WAP_PROFILE                "streaming_wap_profile"
+/**
+ * MM_PLAYER_STREAMING_NET_BANDWIDTH
+ *
+ * set the streaming network bandwidth (int)
+ */
+#define MM_PLAYER_STREAMING_NET_BANDWIDTH      "streaming_network_bandwidth"
+/**
+ * MM_PLAYER_STREAMING_COOKIE
+ *
+ * set the streaming cookie (int)
+ */
+#define MM_PLAYER_STREAMING_COOKIE                     "streaming_cookie"
+/**
+ * MM_PLAYER_STREAMING_PROXY_IP
+ *
+ * set the streaming proxy ip (string)
+ */
+#define MM_PLAYER_STREAMING_PROXY_IP                   "streaming_proxy_ip"
+/**
+ * MM_PLAYER_STREAMING_PROXY_PORT
+ *
+ * set the streaming proxy port (int)
+ */
+#define MM_PLAYER_STREAMING_PROXY_PORT         "streaming_proxy_port"
+/**
+ * MM_PLAYER_VIDEO_CODEC
+ *
+ * codec the video data is stored in (string)
+ */
+#define MM_PLAYER_VIDEO_CODEC                          "content_video_codec"
+/**
+ * MM_PLAYER_VIDEO_TRACK_NUM
+ *
+ * track number inside a collection  (int)
+ */
+#define MM_PLAYER_VIDEO_TRACK_NUM                      "content_video_track_num"
+/**
+ * MM_PLAYER_AUDIO_CODEC
+ *
+ * codec the audio data is stored in (string)
+ */
+#define MM_PLAYER_AUDIO_CODEC                          "content_audio_codec"
+/**
+ * MM_PLAYER_AUDIO_BITRATE
+ *
+ * set the streaming proxy port (int)
+ */
+#define MM_PLAYER_AUDIO_BITRATE                                "content_audio_bitrate"
+/**
+ * MM_PLAYER_AUDIO_CHANNEL
+ *
+ * the number of audio channel (int)
+ */
+#define MM_PLAYER_AUDIO_CHANNEL                                "content_audio_channels"
+/**
+ * MM_PLAYER_AUDIO_SAMPLERATE
+ *
+ * audio samplerate  (int)
+ */
+#define MM_PLAYER_AUDIO_SAMPLERATE                     "content_audio_samplerate"
+/**
+ * MM_PLAYER_AUDIO_TRACK_NUM
+ *
+ * track number inside a collection (int)
+ */
+#define MM_PLAYER_AUDIO_TRACK_NUM                      "content_audio_track_num"
+/**
+ * MM_PLAYER_TEXT_TRACK_NUM
+ *
+ * track number inside a collection (int)
+ */
+#define MM_PLAYER_TEXT_TRACK_NUM                       "content_text_track_num"
+/**
+ * MM_PLAYER_TAG_ARTIST
+ *
+ * person(s) responsible for the recording (string)
+ */
+#define MM_PLAYER_TAG_ARTIST                                   "tag_artist"
+/**
+ * MM_PLAYER_TAG_ARTIST
+ *
+ * title (string)
+ */
+#define MM_PLAYER_TAG_TITLE                                    "tag_title"
+/**
+ * MM_PLAYER_TAG_ARTIST
+ *
+ * album containing this data (string)
+ */
+#define MM_PLAYER_TAG_ALBUM                                    "tag_album"
+/**
+ * MM_PLAYER_TAG_ARTIST
+ *
+ * genre this data belongs to (string)
+ */
+#define MM_PLAYER_TAG_GENRE                                    "tag_genre"
+/**
+ * MM_PLAYER_TAG_ARTIST
+ *
+ * author (string)
+ */
+#define MM_PLAYER_TAG_AUTHOUR                          "tag_author"
+/**
+ * MM_PLAYER_TAG_ARTIST
+ *
+ * copyright notice of the data (string)
+ */
+#define MM_PLAYER_TAG_COPYRIGHT                                "tag_copyright"
+/**
+ * MM_PLAYER_TAG_ARTIST
+ *
+ * date the data was created (string)
+ */
+#define MM_PLAYER_TAG_DATE                                     "tag_date"
+/**
+ * MM_PLAYER_TAG_ARTIST
+ *
+ * short text describing the content of the data (string)
+ */
+#define MM_PLAYER_TAG_DESCRIPRION                              "tag_description"
+/**
+ * MM_PLAYER_TAG_ARTIST
+ *
+ * track number inside a collection (int)
+ */
+#define MM_PLAYER_TAG_TRACK_NUM                                "tag_track_num"
+/**
+ * MM_PLAYER_PD_MODE
+ *
+ * progressive download mode (int)
+ */
+#define MM_PLAYER_PD_MODE                                              "pd_mode"
+
+/**
+ * Enumerations of player state.
+ */
+typedef enum {
+       MM_PLAYER_STATE_NULL,                           /**< Player is created, but not realized yet */
+       MM_PLAYER_STATE_READY,                          /**< Player is ready to play media */
+       MM_PLAYER_STATE_PLAYING,                        /**< Player is now playing media */
+       MM_PLAYER_STATE_PAUSED,                         /**< Player is paused while playing media */
+       MM_PLAYER_STATE_NONE,                           /**< Player is not created yet */
+       MM_PLAYER_STATE_NUM,                            /**< Number of player states */
+} MMPlayerStateType;
+
+/**
+ * Enumerations of position formats.
+ * Used while invoking mm_player_get_position/mm_player_set_position APIs
+ */
+typedef enum {
+       MM_PLAYER_POS_FORMAT_TIME,                      /**< Format for time based */
+       MM_PLAYER_POS_FORMAT_PERCENT,                   /**< Format for percentage */
+       MM_PLAYER_POS_FORMAT_NUM,                       /**< Number of position formats */
+} MMPlayerPosFormatType;
+
+/**
+ * Enumeration for attribute values types.
+ */
+typedef enum {
+ MM_PLAYER_ATTRS_TYPE_INVALID = -1,        /**< Type is invalid */
+ MM_PLAYER_ATTRS_TYPE_INT,                 /**< Integer type */
+ MM_PLAYER_ATTRS_TYPE_DOUBLE,              /**< Double type */
+ MM_PLAYER_ATTRS_TYPE_STRING,              /**< UTF-8 String type */
+ MM_PLAYER_ATTRS_TYPE_DATA,                /**< Pointer type */
+ MM_PLAYER_ATTRS_TYPE_ARRAY,               /**< Array type */
+ MM_PLAYER_ATTRS_TYPE_RANGE,               /**< Range type */
+ MM_PLAYER_ATTRS_TYPE_NUM,                 /**< Number of attribute type */
+} MMPlayerAttrsType;
+
+/**
+ * Enumeration for attribute validation type.
+ */
+typedef enum {
+ MM_PLAYER_ATTRS_VALID_TYPE_INVALID = -1,              /**< Invalid validation type */
+ MM_PLAYER_ATTRS_VALID_TYPE_NONE,                              /**< Do not check validity */
+ MM_PLAYER_ATTRS_VALID_TYPE_INT_ARRAY,          /**< validity checking type of integer array */
+ MM_PLAYER_ATTRS_VALID_TYPE_INT_RANGE,          /**< validity checking type of integer range */
+ MM_PLAYER_ATTRS_VALID_TYPE_DOUBLE_ARRAY,              /**< validity checking type of double array */
+ MM_PLAYER_ATTRS_VALID_TYPE_DOUBLE_RANGE,       /**< validity checking type of double range */
+} MMPlayerAttrsValidType;
+
+/**
+ * Enumeration for attribute access flag.
+ */
+typedef enum {
+ MM_PLAYER_ATTRS_FLAG_NONE = 0,                                        /**< None flag is set */
+ MM_PLAYER_ATTRS_FLAG_READABLE = 1 << 0,                       /**< Readable */
+ MM_PLAYER_ATTRS_FLAG_WRITABLE = 1 << 1,                       /**< Writable */
+ MM_PLAYER_ATTRS_FLAG_MODIFIED = 1 << 2,                       /**< Modified */
+
+ MM_PLAYER_ATTRS_FLAG_RW = MM_PLAYER_ATTRS_FLAG_READABLE | MM_PLAYER_ATTRS_FLAG_WRITABLE, /**< Readable and Writable */
+} MMPlayerAttrsFlag;
+
+/**
+ * Enumeration for progressive download
+ */
+typedef enum {
+        MM_PLAYER_PD_MODE_NONE,
+        MM_PLAYER_PD_MODE_URI,
+        MM_PLAYER_PD_MODE_FILE // not tested yet, because of no fixed scenario
+}MMPlayerPDMode;
+
+/**
+ * Enumeration of track types
+ */
+typedef enum {
+       MM_PLAYER_TRACK_TYPE_AUDIO,
+       MM_PLAYER_TRACK_TYPE_VIDEO,
+       MM_PLAYER_TRACK_TYPE_TEXT
+}MMPlayerTrackType;
+
+/**
+ * Attribute validity structure
+ */
+typedef struct {
+        MMPlayerAttrsType type;
+        MMPlayerAttrsValidType validity_type;
+        MMPlayerAttrsFlag flag;
+       /**
+         * a union that describes validity of the attribute.
+         * Only when type is 'MM_ATTRS_TYPE_INT' or 'MM_ATTRS_TYPE_DOUBLE',
+         * the attribute can have validity.
+        */
+        union {
+               /**
+                  * Validity structure for integer array.
+                */
+               struct {
+                       int *array;  /**< a pointer of array */
+                       int count;   /**< size of array */
+                       int d_val;
+               } int_array;
+               /**
+                  * Validity structure for integer range.
+                */
+               struct {
+                       int min;   /**< minimum range */
+                       int max;   /**< maximum range */
+                       int d_val;
+               } int_range;
+               /**
+               * Validity structure for double array.
+               */
+               struct {
+                       double   * array;  /**< a pointer of array */
+                       int    count;   /**< size of array */
+                       double d_val;
+               } double_array;
+               /**
+               * Validity structure for double range.
+               */
+               struct {
+                       double   min;   /**< minimum range */
+                       double   max;   /**< maximum range */
+                       double d_val;
+               } double_range;
+       };
+} MMPlayerAttrsInfo;
+
+/**
+ * Volume type.
+ *
+ * @see                mm_player_set_volume, mm_player_get_volume
+ */
+typedef struct {
+       float   level[MM_VOLUME_CHANNEL_NUM];   /**< Relative volume factor for each channels */
+} MMPlayerVolumeType;
+
+/**
+ * Audio stream callback function type.
+ *
+ * @param      stream          [in]    Reference pointer to audio frame data
+ * @param      stream_size     [in]    Size of audio frame data
+ * @param      user_param      [in]    User defined parameter which is passed when set
+ *                                                             audio stream callback
+ *
+ * @return     This callback function have to return MM_ERROR_NONE.
+ */
+typedef bool   (*mm_player_audio_stream_callback) (void *stream, int stream_size, void *user_param);
+
+
+/*===========================================================================================
+|                                                                                           |
+|  GLOBAL FUNCTION PROTOTYPES                                        |
+|                                                                                           |
+========================================================================================== */
+
+/**
+ * This function creates a player object for playing multimedia contents. \n
+ * The attributes of player are created to get/set some values with application. \n
+ * And, mutex, gstreamer and other resources are initialized at this time. \n
+ * If player is created, the state will become MM_PLAYER_STATE_NULL.
+ *
+ * @param      player          [out]   Handle of player
+ *
+ * @return     This function returns zero on success, or negative value with error code. \n
+ *                     Please refer 'mm_error.h' to know it in detail.
+ * @pre                None
+ * @post       MM_PLAYER_STATE_NULL 
+ * @see                mm_player_destroy
+ * @remark     You can create multiple handles on a context at the same time. \n
+ *                     However, player cannot guarantee proper operation because of limitation of resources, \n
+ *                     such as audio device or display device.  
+ *
+ * @par Example
+ * @code
+char *g_err_attr_name = NULL;
+
+if (mm_player_create(&g_player) != MM_ERROR_NONE) 
+{
+       printf("failed to create player\n");
+}
+
+if (mm_player_set_attribute(g_player,
+                                               &g_err_attr_name,
+                                               "profile_uri", filename, strlen(filename),
+                                               "display_overlay", (void*)&g_win.xid, sizeof(g_win.xid),
+                                               NULL) != MM_ERROR_NONE) 
+{
+       printf("failed to set %s attribute\n", g_err_attr_name);
+       free(g_err_attr_name);
+}
+
+mm_player_set_message_callback(g_player, msg_callback, (void*)g_player);
+ * @endcode
+ */
+int mm_player_create(MMHandleType *player);
+
+/**
+ * This function releases player object and all resources which were created by mm_player_create(). \n
+ * And, player handle will also be destroyed. 
+ *
+ * @param      player          [in]    Handle of player
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ * @pre                Player state may be MM_PLAYER_STATE_NULL. \n
+ *                     But, it can be called in any state. 
+ * @post               Because handle is released, there is no any state.
+ * @see                mm_player_create
+ * @remark     This method can be called with a valid player handle from any state to \n
+ *                     completely shutdown the player operation.
+ * 
+ * @par Example
+ * @code
+if (mm_player_destroy(g_player) != MM_ERROR_NONE) 
+{
+       printf("failed to destroy player\n");
+}
+ * @endcode 
+ */
+int mm_player_destroy(MMHandleType player);
+
+/**
+ * This function parses uri and makes gstreamer pipeline by uri scheme. \n
+ * So, uri should be set before realizing with mm_player_set_attribute(). \n
+ *
+ * @param      player          [in]    Handle of player
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ *
+ * @pre                Player state should be MM_PLAYER_STATE_NULL.
+ * @post               Player state will be MM_PLAYER_STATE_READY. 
+ * @see                mm_player_unrealize
+ * @remark     None
+ * @par Example
+ * @code
+if (mm_player_realize(g_player) != MM_ERROR_NONE) 
+{
+       printf("failed to realize player\n");
+}
+ * @endcode
+ */
+int mm_player_realize(MMHandleType player) ;
+
+/**
+ * This function uninitializes player object. So, resources and allocated memory \n
+ * will be freed. And, gstreamer pipeline is also destroyed. So, if you want to play \n
+ * other contents, player should be created again after destruction or realized with new uri. 
+ *
+ * @param      player          [in]    Handle of player
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ * @pre                Player state may be MM_PLAYER_STATE_READY to unrealize. \n
+ *                     But, it can be called in any state.  
+ * @post               Player state will be MM_PLAYER_STATE_NULL.
+ * @see                mm_player_realize
+ * @remark     This method can be called with a valid player handle from any state.
+ * 
+ * @par Example
+ * @code
+if (mm_player_unrealize(g_player) != MM_ERROR_NONE) 
+{
+       printf("failed to unrealize player\n");
+}
+ * @endcode 
+ */
+int mm_player_unrealize(MMHandleType player);
+
+/**
+ * This function is to get current state of player. \n
+ * Application have to check current state before doing some action. 
+ *
+ * @param      player          [in]    Handle of player
+ * @param      state       [out] current state of player on success
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ *
+ * @see                MMPlayerStateType
+ * @remark     None
+ * @par Example
+ * @code
+if (mm_player_get_state(g_player, &state) != MM_ERROR_NONE) 
+{
+       printf("failed to get state\n");
+} 
+ * @endcode 
+ */
+int mm_player_get_state(MMHandleType player, MMPlayerStateType *state);
+
+/**
+ * This function is to set relative volume of player. \n
+ * So, It controls logical volume value. \n
+ * But, if developer want to change system volume, mm sound api should be used. 
+ *
+ * @param      player          [in]    Handle of player
+ * @param      volume          [in]    Volume factor of each channel
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ * @see                MMPlayerVolumeType, mm_player_get_volume
+ * @remark     The range of factor range is from 0 to 1.0. (1.0 = 100%) And, default value is 1.0. 
+ * @par Example
+ * @code
+MMPlayerVolumeType volume;
+int i = 0;
+
+for (i = 0; i < MM_VOLUME_CHANNEL_NUM; i++)
+       volume.level[i] = MM_VOLUME_LEVEL_MAX;
+
+if (mm_player_set_volume(g_player, &volume) != MM_ERROR_NONE)
+{
+    printf("failed to set volume\n");
+}
+ * @endcode 
+ */
+int mm_player_set_volume(MMHandleType player, MMPlayerVolumeType *volume);
+
+/**
+ * This function is to get current volume factor of player.
+ *
+ * @param      player          [in]    Handle of player.
+ * @param      volume          [out]   Volume factor of each channel.
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ * 
+ * @see                MMPlayerVolumeType, mm_player_set_volume
+ * @remark     None
+ * @par Example
+ * @code
+MMPlayerVolumeType volume;
+int i;
+
+if (mm_player_get_volume(g_player, &volume) != MM_ERROR_NONE)
+{
+        printf("failed to get volume\n");
+}
+
+for (i = 0; i < MM_VOLUME_CHANNEL_NUM; i++)
+       printf("channel[%d] = %d \n", i, volume.level[i]);
+ * @endcode 
+ */
+int mm_player_get_volume(MMHandleType player, MMPlayerVolumeType *volume);
+
+/**
+ * This function is to start playing media contents. Demux(parser), codec and related plugins are decided \n
+ * at this time. And, MM_MESSAGE_BEGIN_OF_STREAM will be posted through callback function registered \n
+ * by mm_player_set_message_callback().
+ *
+ * @param      player          [in]    Handle of player
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ * @remark
+ *
+ * @pre                Player state may be MM_PLAYER_STATE_READY.
+ * @post               Player state will be MM_PLAYER_STATE_PLAYING. 
+ * @see                mm_player_stop 
+ * @remark     None
+ * @par Example 
+ * @code       
+if (mm_player_start(g_player) != MM_ERROR_NONE) 
+{
+       printf("failed to start player\n");
+}
+ * @endcode 
+ */
+int mm_player_start(MMHandleType player);
+
+/**
+ * This function is to stop playing media contents and it's different with pause. \n
+ * If mm_player_start() is called after this, content will be started again from the beginning. \n
+ * So, it can be used to close current playback.  
+ *
+ * @param      player          [in]    Handle of player
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ *
+ * @pre                Player state may be MM_PLAYER_STATE_PLAYING.
+ * @post               Player state will be MM_PLAYER_STATE_READY.
+ * @see                mm_player_start 
+ * @remark     None
+ * @par Example 
+ * @code
+if (mm_player_stop(g_player) != MM_ERROR_NONE) 
+{
+       printf("failed to stop player\n");
+}
+ * @endcode 
+ */
+int mm_player_stop(MMHandleType player);
+
+/**
+ * This function is to pause playing media contents.
+ *
+ * @param      player          [in]    Handle of player.
+ *
+ * @return     This function returns zero on success, or negative value with error code. 
+ *
+ * @pre                Player state may be MM_PLAYER_STATE_PLAYING.
+ * @post               Player state will be MM_PLAYER_STATE_PAUSED.
+ * @see                mm_player_resume 
+ * @remark     None
+ * @par Example 
+ * @code
+if (mm_player_pause(g_player) != MM_ERROR_NONE) 
+{
+       printf("failed to pause player\n");
+}
+ * @endcode 
+ */
+int mm_player_pause(MMHandleType player);
+
+/**
+ * This function is to resume paused media contents.
+ *
+ * @param      player          [in]    Handle of player.
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ *
+ * @pre                Player state may be MM_PLAYER_STATE_PAUSED.
+ * @post               Player state will be MM_PLAYER_STATE_PLAYING.
+ * @see                mm_player_pause 
+ * @remark     None 
+ * @par Example 
+ * @code
+if (mm_player_resume(g_player) != MM_ERROR_NONE) 
+{
+       printf("failed to resume player\n");
+}
+ * @endcode 
+ */
+int mm_player_resume(MMHandleType player);
+
+/**
+ * This function is to set the position for playback. \n
+ * So, it can be seeked to requested position. \n
+ * 
+ * @param      player          [in]    Handle of player
+ * @param      format          [in]    Format of position.
+ * @param      pos                     [in]    Position for playback
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ * @see                MMPlayerPosFormatType, mm_player_get_position
+ * @remark  the unit of time-based format is millisecond and other case is percent.  
+ * @par Example 
+ * @code
+int position = 1000; //1sec
+
+if (mm_player_set_position(g_player, MM_PLAYER_POS_FORMAT_TIME, position) != MM_ERROR_NONE)
+{
+       g_print("failed to set position\n");
+} 
+ * @endcode 
+ */
+int mm_player_set_position(MMHandleType player, MMPlayerPosFormatType format, int pos);
+
+/**
+ * This function is to get current position of playback content.
+ *
+ * @param      player          [in]    Handle of player.
+ * @param      format          [in]    Format of position.
+ * @param    pos        [out] contains current position on success or zero in case of failure.
+ *
+ * @return     This function returns zero on success, or negative value with errors
+ * @see                MMPlayerPosFormatType, mm_player_set_position
+ * @remark     the unit of time-based format is millisecond and other case is percent.  
+ * @par Example 
+ * @code
+int position = 0;
+int duration = 0;
+
+mm_player_get_position(g_player, MM_PLAYER_POS_FORMAT_TIME, &position);
+
+mm_player_get_attribute(g_player, &g_err_name, "content_duration", &duration, NULL);
+
+printf("pos: [%d/%d] msec\n", position, duration);
+ * @endcode 
+ */
+int mm_player_get_position(MMHandleType player, MMPlayerPosFormatType format, int *pos);
+
+/**
+ * This function is to get current buffer position of playback content.
+ *
+ * @param      player          [in]    Handle of player.
+ * @param      format          [in]    Format of position.
+ * @param      start_pos               [out] contains buffer start  position on success or zero in case of failure.
+ * @param      stop_pos        [out] contains buffer current  position on success or zero in case of failure.
+ *
+ * @return     This function returns zero on success, or negative value with errors
+ * @see                MMPlayerPosFormatType, mm_player_set_position
+ * @remark     the unit of time-based format is millisecond and other case is percent.  
+ * @par Example 
+ * @code
+int start_pos = 0, stop_pos = 0;
+
+mm_player_get_buffer_position(g_player, MM_PLAYER_POS_FORMAT_PERCENT, &start_pos, &stop_pos );
+
+printf("buffer position: [%d] ~ [%d] \%\n", start_pos, stop_pos );
+ * @endcode 
+ */
+int mm_player_get_buffer_position(MMHandleType player, MMPlayerPosFormatType format, int *start_pos, int *stop_pos);
+
+/**
+ * This function is to activate the section repeat. If it's set, selected section will be played \n
+ * continually before deactivating it by mm_player_deactivate_section_repeat(). \n
+ * The unit for setting is millisecond.
+ *
+ * @param      player          [in]    Handle of player.
+ * @param      start_pos               [in]    start position.
+ * @param      end_pos                 [in]    end position.
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ * @see                mm_player_deactivate_section_repeat
+ * @remark     None
+ * @par Example 
+ * @code
+int position;
+int endtime = 4000; //msec
+
+mm_player_get_position(g_player, MM_PLAYER_POS_FORMAT_TIME, &position);
+
+mm_player_activate_section_repeat(g_player, position, position+endtime);
+ * @endcode 
+ */
+int mm_player_activate_section_repeat(MMHandleType player, int start_pos, int end_pos);
+
+/**
+ * This function is to deactivate the section repeat.
+ *
+ * @param      player          [in]    Handle of player.
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ * @see                mm_player_activate_section_repeat
+ * @remark     None 
+ * @par Example 
+ * @code
+if ( mm_player_deactivate_section_repeat(g_player) != MM_ERROR_NONE)
+{
+       printf("failed to deactivate section repeat\n");
+} 
+ * @endcode 
+ */
+int mm_player_deactivate_section_repeat(MMHandleType player);
+
+/**
+ * This function sets callback function for receiving messages from player.
+ * So, player can notify warning, error and normal cases to application. 
+ *
+ * @param      player          [in]    Handle of player.
+ * @param      callback        [in]    Message callback function.
+ * @param      user_param      [in]    User parameter which is passed to callback function.
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ * @see                MMMessageCallback
+ * @remark     None 
+ * @par Example 
+ * @code
+int msg_callback(int message, MMMessageParamType *param, void *user_param) 
+{
+       switch (message)
+       {
+               case MM_MESSAGE_ERROR:
+                       //do something
+                       break;
+               
+               case MM_MESSAGE_END_OF_STREAM:
+                       //do something
+                       break;
+             
+               case MM_MESSAGE_STATE_CHANGED:
+                       //do something
+                       break;
+               
+               case MM_MESSAGE_BEGIN_OF_STREAM:
+                       //do something
+                       break;
+               
+               default:
+                       break;
+       }
+       return TRUE;
+}
+
+mm_player_set_message_callback(g_player, msg_callback, (void*)g_player);
+ * @endcode 
+ */
+int mm_player_set_message_callback(MMHandleType player, MMMessageCallback callback, void *user_param);
+
+/**
+ * This function set callback function for receiving audio stream from player. \n
+ * So, application can get raw audio data and modify it. \n
+ * But, if callback don't return or holds it for long time, performance can be deteriorated. \n
+ * It's only supported when audio stream is included in file. \n
+ * So, if there is video stream or DRM content, it can't be used.
+ *
+ * @param      player          [in]    Handle of player.
+ * @param      callback                [in]    Audio stream callback function.
+ * @param      user_param      [in]    User parameter.
+ *
+ * @return     This function returns zero on success, or negative value with error
+ *                     code.
+ * @see                mm_player_audio_stream_callback
+ * @remark     It can be used for audio playback only.  
+ * @par Example 
+ * @code
+bool audio_callback(void *stream, int stream_size, void *user_param)
+{
+       printf("audio stream callback\n");
+       return TRUE;
+}
+mm_player_set_audio_stream_callback(g_player, audio_callback, NULL);
+ * @endcode 
+ */
+ int mm_player_set_audio_stream_callback(MMHandleType player, mm_player_audio_stream_callback callback, void *user_param);
+
+/**
+ * This function is to mute volume of player
+ *
+ * @param      player  [in]    Handle of player
+ * @param      mute    [in]    Mute(1) or not mute(0)
+ *
+ * @return     This function returns zero on success, or negative value with error code
+ * @see                mm_player_get_mute
+ * @remark     None
+ * @par Example 
+ * @code
+if (mm_player_set_mute(g_player, TRUE) != MM_ERROR_NONE)
+{
+       printf("failed to set mute\n");
+} 
+ * @endcode 
+ */
+int mm_player_set_mute(MMHandleType player, int mute);
+
+/**
+ * This function is to get mute value of player
+ *
+ * @param      player  [in]    Handle of player
+ * @param      mute    [out]   Sound is muted
+ *
+ * @return     This function returns zero on success, or negative value with error code
+ * @see                mm_player_set_mute
+ * @remark     None
+ * @par Example 
+ * @code
+int mute;
+if (mm_player_get_mute(g_player, &mute) != MM_ERROR_NONE)
+{
+       printf("failed to get mute\n");
+}
+
+printf("mute status:%d\n", mute);
+ * @endcode 
+ */
+int mm_player_get_mute(MMHandleType player, int *mute);
+
+/**
+ * This function is to adjust subtitle postion. So, subtitle can show at the adjusted position. \n
+ * If pos is negative, subtitle will be displayed previous time, the other hand forward time. \n
+ *
+ * @param      player  [in]    Handle of player
+ * @param      pos             [in]    postion to be adjusted
+ *
+ * @return     This function returns zero on success, or negative value with error
+ *                     code
+ * @see                mm_player_adjust_subtitle_position
+ * @remark     None
+ * @par Example
+ * @code
+int pos;
+
+pos = 5000;
+if (mm_player_adjust_subtitle_position(g_player, MM_PLAYER_POS_FORMAT_TIME, pos) != MM_ERROR_NONE)
+{
+       printf("failed to adjust subtitle postion.\n");
+}
+ * @endcode
+ */
+
+int mm_player_adjust_subtitle_position(MMHandleType player, MMPlayerPosFormatType format, int pos);
+
+/**
+ * This function is to set subtitle silent status. So, subtitle can show or hide during playback \n
+ * by this value. But, one subtitle file should be set with "subtitle_uri" attribute before calling mm_player_realize(); \n
+ * Player FW parses subtitle file and send text data including timestamp to application \n
+ * through message callback with MM_MESSAGE_UPDATE_SUBTITLE will be. \n
+ * So, application have to render it. And, subtitle can be supported only in a seprate file. \n
+ * So, it's not supported for embedded case.
+ *
+ * @param      player  [in]    Handle of player
+ * @param      silent  [in]    silent(integer value except 0) or not silent(0)
+ *
+ * @return     This function returns zero on success, or negative value with error
+ *                     code 
+ * @see                mm_player_get_subtitle_silent, MM_MESSAGE_UPDATE_SUBTITLE
+ * @remark     None 
+ * @par Example 
+ * @code
+mm_player_set_attribute(g_player,
+                                       &g_err_name,
+                                       "subtitle_uri", g_subtitle_uri, strlen(g_subtitle_uri),
+                                       NULL
+                                       );
+                                                       
+if (mm_player_set_subtitle_silent(g_player, TRUE) != MM_ERROR_NONE)
+{
+       printf("failed to set subtitle silent\n");
+} 
+ * @endcode 
+ */
+int mm_player_set_subtitle_silent(MMHandleType player, int silent);
+
+/**
+ * This function is to get silent status of subtitle.
+ *
+ * @param      player  [in]    Handle of player
+ * @param      silent  [out]   subtitle silent property
+ *
+ * @return     This function returns zero on success, or negative value with error
+ *                     code 
+ * @see                mm_player_set_subtitle_silent, MM_MESSAGE_UPDATE_SUBTITLE
+ * @remark     None 
+ * @par Example 
+ * @code
+int silent = FALSE;
+if (mm_player_get_subtitle_silent(g_player, &silent) != MM_ERROR_NONE)
+{
+       printf("failed to set subtitle silent\n");
+}
+ * @endcode 
+ */
+int mm_player_get_subtitle_silent(MMHandleType player, int *silent);
+
+/**
+ * This function is to set attributes into player. Multiple attributes can be set simultaneously. \n
+ * If one of attribute fails, this function will stop at the point and let you know the name which is failed. \n
+ *
+ * @param      player                          [in]    Handle of player.
+ * @param      err_attr_name                   [out]  Name of attribute which is failed to set
+ * @param      first_attribute_name    [in]    Name of the first attribute to set
+ * @param   ...                                        [in]    Value for the first attribute, followed optionally by more name/value pairs, terminated by NULL.
+ *                                                                      But, in the case of data or string type, it should be name/value/size.
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ *
+ * @see                mm_player_get_attribute
+ * @remark     This function must be terminated by NULL argument.
+ *                     And, if this function is failed, err_attr_name param must be free. 
+ * @par Example 
+ * @code
+char *g_err_attr_name = NULL;
+
+if (mm_player_set_attribute(g_player, 
+                                               &g_err_attr_name, 
+                                               "profile_uri", filename, strlen(filename),
+                                               "profile_play_count", count,
+                                               NULL) != MM_ERROR_NONE)
+{
+       printf("failed to set %s attribute\n", g_err_attr_name);
+       free(g_err_attr_name);
+}
+
+ * @endcode 
+ */
+int mm_player_set_attribute(MMHandleType player,  char **err_attr_name, const char *first_attribute_name, ...)G_GNUC_NULL_TERMINATED;
+
+/**
+ * This function is to get attributes from player. Multiple attributes can be got simultaneously.
+ *
+ * @param      player                          [in]    Handle of player.
+ * @param      err_attr_name                   [out]  Name of attribute which is failed to get
+ * @param      first_attribute_name    [in]    Name of the first attribute to get
+ * @param      ...                                     [out] Value for the first attribute, followed optionally by more name/value pairs, terminated by NULL.
+ *                                                                      But, in the case of data or string type, it should be name/value/size.
+ *
+ * @return     This function returns zero on success, or negative value with error
+ *                     code.
+ * @see                mm_player_set_attribute
+ * @remark     This function must be terminated by NULL argument.
+ *                     And, if this function is failed, err_attr_name param must be free. 
+ * @par Example 
+ * @code
+char *g_err_attr_name = NULL;
+
+if (mm_player_get_attribute(g_player, &g_err_attr_name, "content_duration", &duration, NULL) != MM_ERROR_NONE)
+{
+       printf("failed to set %s attribute\n", g_err_attr_name);
+       free(g_err_attr_name);
+}
+ * @endcode 
+ */
+int mm_player_get_attribute(MMHandleType player,  char **err_attr_name, const char *first_attribute_name, ...)G_GNUC_NULL_TERMINATED;
+
+/**
+ * This function is to get detail information of attribute.
+ *
+ * @param      player                           [in]   Handle of player.
+ * @param   attribute_name              [in]   Name of the attribute to get
+ * @param   info                                [out]  Attribute infomation
+ *
+ * @return     This function returns zero on success, or negative value with error
+ *                     code.
+ *
+ * @see                mm_player_set_attribute, mm_player_get_attribute
+ * @remark     None
+ * @par Example 
+ * @code
+if (mm_player_get_attribute_info (g_player, "display_method", &method_info) != MM_ERROR_NONE)
+{
+       printf("failed to get info\n");
+}
+
+printf("type:%d \n", method_info.type); //int, double..
+printf("flag:%d \n", method_info.flag); //readable, writable..
+printf("validity type:%d \n", method_info.validity_type); //range, array..
+
+if (method_info. validity_type == MM_PLAYER_ATTRS_VALID_TYPE_INT_RANGE)
+{
+       printf("range min:%d\n", method_info.int_range.min);
+       printf("range max:%d\n", method_info.int_range.max);
+}
+ * @endcode 
+ */
+int mm_player_get_attribute_info(MMHandleType player,  const char *attribute_name, MMPlayerAttrsInfo *info);
+
+/**
+ * This function is to get download position and total size of progressive download
+ *
+ * @param      player          [in]    Handle of player.
+ * @param      current_pos     [in]    Download position currently (bytes)
+ * @param      total_size      [in]    Total size of file (bytes)
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ *
+ * @see
+ * @remark
+ * @par Example
+ * @code
+guint64 current_pos = 0LLU;
+guint64 total_size = 0LLU;
+
+if (mm_player_get_pd_status(g_player, &current_pos, &total_size, NULL) != MM_ERROR_NONE)
+{
+       printf("current download pos = %llu, total size = %llu\n", current_pos, total_size);
+}
+ * @endcode
+ */
+int mm_player_get_pd_status(MMHandleType player, guint64 *current_pos, guint64 *total_size);
+
+/**
+ * This function sets callback function for receiving messages of PD downloader.
+ *
+ * @param      player          [in]    Handle of player.
+ * @param      callback                [in]    Message callback function.
+ * @param      user_param      [in]    User parameter which is passed to callback function.
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ * @see
+ * @remark     None
+ * @par Example
+ * @code
+int msg_callback(int message, MMMessageParamType *param, void *user_param)
+{
+       switch (message)
+       {
+               case MM_MESSAGE_PD_DOWNLOADER_START:
+                       printf("Progressive download is started...\n");
+                       break;
+               case MM_MESSAGE_PD_DOWNLOADER_END:
+                       printf("Progressive download is ended...\n");
+                       break;
+               default:
+                       break;
+       }
+       return TRUE;
+}
+
+mm_player_set_pd_message_callback(g_player, msg_callback, NULL);
+ * @endcode
+ */
+int mm_player_set_pd_message_callback(MMHandleType player, MMMessageCallback callback, void *user_param);
+
+/**
+ * This function is to get the track count
+ *
+ * @param      player          [in]    handle of player.
+ * @param      track_type      [in]    type of the track type
+ * @param      info                    [out]   the count of the track
+ *
+ * @return     This function returns zero on success, or negative value with error
+ *                     code.
+ *
+ * @see
+ * @remark     None
+ * @par Example
+ * @code
+gint audio_count = 0;
+
+if (mm_player_get_track_count (g_player, MM_PLAYER_TRACK_TYPE_AUDIO, &audio_count) != MM_ERROR_NONE)
+{
+       printf("failed to get audio track count\n");
+}
+
+printf("audio track count : %d \n", audio_count);
+ * @endcode
+ */
+int mm_player_get_track_count(MMHandleType player,  MMPlayerTrackType track_type, int *count);
+
+
+/**
+       @}
+ */
+
+#ifdef __cplusplus
+       }
+#endif
+
+#endif /* __MM_PLAYER_H__ */
diff --git a/src/include/mm_player_asm.h b/src/include/mm_player_asm.h
new file mode 100644 (file)
index 0000000..cd9197f
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * libmm-player
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YeJin Cho <cho.yejin@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>
+ *
+ * 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 __MM_PLAYER_ASM_H__
+#define __MM_PLAYER_ASM_H__
+
+#include <glib.h>
+#include <mm_types.h>
+#include <mm_error.h>
+
+#include <mm_session.h>
+#include <mm_session_private.h>
+#include <audio-session-manager.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+       int handle;
+       int pid;
+       int by_asm_cb;
+       int event_src;
+       ASM_sound_states_t state;
+       ASM_sound_events_t event;
+} MMPlayerASM;
+
+/* returns allocated handle */
+gint _mmplayer_asm_register(MMPlayerASM* sm, ASM_sound_cb_t callback, void* param);
+gint _mmplayer_asm_deregister(MMPlayerASM* sm);
+gint _mmplayer_asm_set_state(MMHandleType player, ASM_sound_states_t state);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MM_PLAYER_ASM_H__ */
diff --git a/src/include/mm_player_attrs.h b/src/include/mm_player_attrs.h
new file mode 100644 (file)
index 0000000..846bbba
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * libmm-player
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YeJin Cho <cho.yejin@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>
+ *
+ * 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 __MM_PLAYER_ATTRS_H__
+#define        __MM_PLAYER_ATTRS_H__
+
+#ifdef __cplusplus
+       extern "C" {
+#endif
+
+/**
+ * This function set values of attributes.
+ *
+ * @param[in]  handle                  Handle of player.
+ * @param[in]  err_atr_name            Name of attribute that is failed (NULL can be set if it's not require to check. )
+ * @param[in]  attribute_name  Name of the first attribute to set
+ * @param[in]  args_list                       List of attributes and values
+ * @return     This function returns zero on success, or negative value with error code.
+ * @remarks
+ * @see                _mmplayer_get_attribute()
+ *
+ */
+int _mmplayer_set_attribute(MMHandleType handle,  char **err_atr_name, const char *attribute_name, va_list args_list);
+/**
+ * This function get values of attributes.
+ *
+ * @param[in]  handle                  Handle of player.
+ * @param[in]  err_atr_name            Name of attribute that is failed (NULL can be set if it's not require to check. )
+ * @param[in]  attribute_name  Name of the first attribute to set
+ * @param[in]  args_list                       List of attributes and values
+ * @return     This function returns zero on success, or negative value with error code.
+ * @remarks
+ * @see                _mmplayer_set_attribute()
+ *
+ */
+int _mmplayer_get_attribute(MMHandleType handle,  char **err_atr_name, const char *attribute_name, va_list args_list);
+/**
+ * This function get configuration values of attribute.
+ *
+ * @param[in]  handle                  Handle of player.
+ * @param[in]  attribute_name  Name of the first attribute to set
+ * @param[in]  info                            Configuration values
+ * @return     This function returns zero on success, or negative value with error code.
+ * @remarks
+ * @see
+ *
+ */
+int _mmplayer_get_attribute_info(MMHandleType handle,  const char *attribute_name, MMPlayerAttrsInfo *info);
+/**
+ * This function allocates structure of attributes and sets initial values.
+ *
+ * @param[in]  handle          Handle of player.
+ * @return     This function returns allocated structure of attributes.
+ * @remarks
+ * @see                _mmplayer_deconstruct_attribute()
+ *
+ */
+MMHandleType _mmplayer_construct_attribute(MMHandleType handle);
+/**
+ * This function release allocated attributes.
+ *
+ * @param[in]  handle          Handle of player.
+ * @return     This function returns true on success or false on failure.
+ * @remarks
+ * @see                _mmplayer_construct_attribute()
+ *
+ */
+bool _mmplayer_deconstruct_attribute(MMHandleType handle);
+
+#ifdef __cplusplus
+       }
+#endif
+
+#endif /* __MM_PLAYER_ATTRS_H__ */
diff --git a/src/include/mm_player_audioeffect.h b/src/include/mm_player_audioeffect.h
new file mode 100644 (file)
index 0000000..fc03392
--- /dev/null
@@ -0,0 +1,348 @@
+/*
+ * libmm-player
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YeJin Cho <cho.yejin@samsung.com>,
+ * Seungbae Shin <seungbae.shin@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>
+ *
+ * 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 __MM_PLAYER_AUDIOEFFECT_H__
+#define __MM_PLAYER_AUDIOEFFECT_H__
+
+#include <mm_types.h>
+
+#ifdef __cplusplus
+       extern "C" {
+#endif
+
+#define MM_AUDIO_EFFECT_EQ_BAND_NUM_MAX                10
+#define MM_AUDIO_EFFECT_CUSTOM_LEVEL_INIT      0
+
+/**
+       @addtogroup PLAYER_INTERNAL
+
+*/
+
+/**
+ * Enumerations of Audio Effect Preset Type
+ */
+typedef enum {
+       MM_AUDIO_EFFECT_PRESET_AUTO = 0,     /**<  Preset type Auto */
+       MM_AUDIO_EFFECT_PRESET_NORMAL,       /**<  Preset type Normal */
+       MM_AUDIO_EFFECT_PRESET_POP,          /**<  Preset type Pop */
+       MM_AUDIO_EFFECT_PRESET_ROCK,         /**<  Preset type Rock */
+       MM_AUDIO_EFFECT_PRESET_DANCE,        /**<  Preset type Dance */
+       MM_AUDIO_EFFECT_PRESET_JAZZ,         /**<  Preset type Jazz */
+       MM_AUDIO_EFFECT_PRESET_CLASSIC,      /**<  Preset type Classic */
+       MM_AUDIO_EFFECT_PRESET_VOCAL,        /**<  Preset type Vocal */
+       MM_AUDIO_EFFECT_PRESET_BASS_BOOST,   /**<  Preset type Bass Boost */
+       MM_AUDIO_EFFECT_PRESET_TREBLE_BOOST, /**<  Preset type Treble Boost */
+       MM_AUDIO_EFFECT_PRESET_MTHEATER,     /**<  Preset type MTheater */
+       MM_AUDIO_EFFECT_PRESET_EXT,          /**<  Preset type Externalization */
+       MM_AUDIO_EFFECT_PRESET_CAFE,         /**<  Preset type Cafe */
+       MM_AUDIO_EFFECT_PRESET_CONCERT_HALL, /**<  Preset type Concert Hall */
+       MM_AUDIO_EFFECT_PRESET_VOICE,        /**<  Preset type Voice */
+       MM_AUDIO_EFFECT_PRESET_MOVIE,        /**<  Preset type Movie */
+       MM_AUDIO_EFFECT_PRESET_VIRT51,       /**<  Preset type Virtual 5.1 */
+       MM_AUDIO_EFFECT_PRESET_HIPHOP,       /**<  Preset type HipHop */
+       MM_AUDIO_EFFECT_PRESET_RNB,          /**<  Preset type R&B */
+       MM_AUDIO_EFFECT_PRESET_FLAT,         /**<  Preset type Flat */
+       MM_AUDIO_EFFECT_PRESET_NUM,          /**<  Number of Preset type */
+} MMAudioEffectPresetType;
+
+/**
+ * Enumerations of Audio Effect Custom Type
+ */
+typedef enum {
+       MM_AUDIO_EFFECT_CUSTOM_EQ = 0,       /**<  Custom type Equalizer */
+       MM_AUDIO_EFFECT_CUSTOM_3D,           /**<  Custom type 3D */
+       MM_AUDIO_EFFECT_CUSTOM_BASS,         /**<  Custom type Bass */
+       MM_AUDIO_EFFECT_CUSTOM_ROOM_SIZE,    /**<  Custom type Room Size */
+       MM_AUDIO_EFFECT_CUSTOM_REVERB_LEVEL, /**<  Custom type Reverb Level */
+       MM_AUDIO_EFFECT_CUSTOM_CLARITY,      /**<  Custom type Clarity */
+       MM_AUDIO_EFFECT_CUSTOM_NUM,          /**<  Number of Custom type */
+} MMAudioEffectCustomType;
+
+/**
+ * Enumerations of Audio Effect Type
+ */
+typedef enum {
+       MM_AUDIO_EFFECT_TYPE_NONE,
+       MM_AUDIO_EFFECT_TYPE_PRESET,
+       MM_AUDIO_EFFECT_TYPE_CUSTOM,
+} MMAudioEffectType;
+
+
+/**
+ * Enumerations of Output Mode
+ */
+typedef enum {
+       MM_AUDIO_EFFECT_OUTPUT_SPK,    /**< Speaker out */
+       MM_AUDIO_EFFECT_OUTPUT_EAR     /**< Earjack out */
+} MMAudioEffectOutputMode;
+
+
+/**
+ * Structure of AudioEffectInfo
+ */
+typedef struct {
+       MMAudioEffectType effect_type;      /**< effect type, (NONE,PRESET,CUSTOM)*/
+       MMAudioEffectPresetType preset;     /**< for preset type*/
+       int *custom_ext_level_for_plugin;   /**< for custom type, level value list of Extension effects*/
+       int custom_eq_level[MM_AUDIO_EFFECT_EQ_BAND_NUM_MAX];   /**< for custom type, EQ info*/
+       int custom_ext_level[MM_AUDIO_EFFECT_CUSTOM_NUM-1];     /**< for custom type, Extension effect info*/
+} MMAudioEffectInfo;
+
+
+/**
+ * @brief Called to get each supported audio effect.
+ *
+ * @param      effect_type     [in]    Type of effect (preset effect or custom effect).
+ * @param      effect          [in]    Supported audio effect.
+ * @param      user_data       [in]    Pointer of user data.
+ *
+ * @return     True to continue with the next iteration of the loop, False to break out of the loop.
+ * @see                mm_player_get_foreach_present_supported_effect_type()
+ */
+typedef bool (*mmplayer_supported_audio_effect_cb) (int effect_type, int type, void *user_data);
+
+/**
+ * This function is to get supported effect type.
+ *
+ * @param      hplayer         [in]    Handle of player.
+ * @param      effect_type     [in]    Type of effect.
+ * @param      foreach_cb      [in]    Callback function to be passed the result.
+ * @param      user_data       [in]    Pointer of user data.
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ *
+ * @remark
+ * @see
+ * @since
+ */
+int mm_player_get_foreach_present_supported_effect_type(MMHandleType player, MMAudioEffectType effect_type, mmplayer_supported_audio_effect_cb foreach_cb, void *user_data);
+
+/**
+ * This function is to bypass audio effect.
+ *
+ * @param      hplayer         [in]    Handle of player.
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ *
+ * @remark
+ * @see
+ * @since
+ */
+int mm_player_audio_effect_bypass (MMHandleType hplayer);
+
+/**
+ * This function is to apply preset effect.
+ *
+ * @param      hplayer         [in]    Handle of player.
+ * @param      type            [in]    Preset type effect.
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ *
+ * @remark
+ * @see                MMAudioEffectPresetType
+ * @since
+ */
+int mm_player_audio_effect_preset_apply(MMHandleType hplayer, MMAudioEffectPresetType type);
+
+/**
+ * This function is to apply custom effect(Equalizer and Extension effects).
+ *
+ * @param      hplayer         [in]    Handle of player.
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ *
+ * @remark
+ * @see
+ * @since
+ */
+int mm_player_audio_effect_custom_apply(MMHandleType hplayer);
+
+/**
+ * This function is to clear Equalizer custom effect.
+ *
+ * @param      hplayer         [in]    Handle of player.
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ *
+ * @remark
+ * @see
+ * @since
+ */
+int mm_player_audio_effect_custom_clear_eq_all(MMHandleType hplayer);
+
+/**
+ * This function is to clear Extension custom effects.
+ *
+ * @param      hplayer         [in]    Handle of player.
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ *
+ * @remark
+ * @see
+ * @since
+ */
+int mm_player_audio_effect_custom_clear_ext_all(MMHandleType hplayer);
+
+/**
+ * This function is to get the number of equalizer bands.
+ *
+ * @param      hplayer         [in]    Handle of player.
+ * @param      bands           [out]   The number of bands.
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ *
+ * @remark
+ * @see
+ * @since
+ */
+int mm_player_audio_effect_custom_get_eq_bands_number(MMHandleType hplayer, int *bands);
+
+/**
+ * This function is to get width of equalizer band of each index.
+ *
+ * @param      hplayer         [in]    Handle of player.
+ * @param      band_idx        [in]    Index of band.
+ * @param      width           [out]   Value of width.
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ *
+ * @remark
+ * @see
+ * @since
+ */
+int mm_player_audio_effect_custom_get_eq_bands_width(MMHandleType hplayer, int band_idx, int *width);
+
+/**
+ * This function is to get frequency of equalizer band of each index.
+ *
+ * @param      hplayer         [in]    Handle of player.
+ * @param      band_idx        [in]    Index of band.
+ * @param      freq            [out]   Value of frequency.
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ *
+ * @remark
+ * @see
+ * @since
+ */
+int mm_player_audio_effect_custom_get_eq_bands_freq(MMHandleType hplayer, int band_idx, int *freq);
+
+/**
+ * This function is to get the level of the custom effect.
+ *
+ * @param      hplayer         [in]    Handle of player.
+ * @param      type            [in]    Custom type effect.
+ * @param      eq_index        [in]    Equalizer band index. This parameter is available only when the type is MM_AUDIO_EFFECT_CUSTOM_EQ.
+ * @param      level           [out]   The level of the custom effect.
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ *
+ * @remark
+ * @see                MMAudioEffectCustomType
+ * @since
+ */
+int mm_player_audio_effect_custom_get_level(MMHandleType hplayer, MMAudioEffectCustomType type, int eq_index, int *level);
+
+/**
+ * This function is to get range of the level of the custom effect.
+ *
+ * @param      hplayer         [in]    Handle of player.
+ * @param      type            [in]    Custom type effect.
+ * @param      min             [out]   Minimal value of level.
+ * @param      max             [out]   Maximum value of level.
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ *
+ * @remark
+ * @see                MMAudioEffectCustomType
+ * @since
+ */
+int mm_player_audio_effect_custom_get_level_range(MMHandleType hplayer, MMAudioEffectCustomType type, int *min, int *max);
+
+/**
+ * This function is to set the level of the custom effect.
+ *
+ * @param      hplayer         [in]    Handle of player.
+ * @param      type            [in]    Custom type effect.
+ * @param      eq_index        [in]    Equalizer band index. This parameter is available only when the type is MM_AUDIO_EFFECT_CUSTOM_EQ.
+ * @param      level           [in]    The level of the custom effect.
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ *
+ * @remark
+ * @see                MMAudioEffectCustomType
+ * @since
+ */
+int mm_player_audio_effect_custom_set_level(MMHandleType hplayer, MMAudioEffectCustomType effect_custom_type, int eq_index, int level);
+
+/**
+ * This function is to set the bands level of equalizer custom effect using input list.
+ *
+ * @param      hplayer         [in]    Handle of player.
+ * @param      level_list      [in]    list of bands level of equalizer custom audio_effect want to set.
+ * @param      size            [in]    size of level_list.
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ *
+ * @remark
+ * @see
+ * @since
+ */
+int mm_player_audio_effect_custom_set_level_eq_from_list(MMHandleType hplayer, int *level_list, int size);
+
+/**
+ * This function is to decide if the preset type effect is supported or not
+ *
+ * @param      hplayer         [in]    Handle of player.
+ * @param      effect          [in]    Preset type effect.
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ *
+ * @remark
+ * @see
+ * @since
+ */
+int mm_player_is_supported_preset_effect_type(MMHandleType hplayer, MMAudioEffectPresetType effect);
+
+/**
+ * This function is to decide if the custom type effect is supported or not
+ *
+ * @param      hplayer         [in]    Handle of player.
+ * @param      effect          [in]    Custom type effect.
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ *
+ * @remark
+ * @see
+ * @since
+ */
+int mm_player_is_supported_custom_effect_type(MMHandleType hplayer, MMAudioEffectCustomType effect);
+
+/**
+       @}
+ */
+
+#ifdef __cplusplus
+       }
+#endif
+
+#endif /* __MM_PLAYER_AUDIOEFFECT_H__ */
diff --git a/src/include/mm_player_capture.h b/src/include/mm_player_capture.h
new file mode 100755 (executable)
index 0000000..b4349e8
--- /dev/null
@@ -0,0 +1,73 @@
+/*\r
+ * libmm-player\r
+ *\r
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
+ *\r
+ * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YeJin Cho <cho.yejin@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ */\r
+\r
+#ifndef __MM_PLAYER_CAPTURE_H__\r
+#define __MM_PLAYER_CAPTURE_H__\r
+\r
+/*=======================================================================================\r
+| INCLUDE FILES                                                                                |\r
+========================================================================================*/\r
+#include <mm_types.h>\r
+#include "mm_player_priv.h"\r
+\r
+#ifdef __cplusplus\r
+       extern "C" {\r
+#endif\r
+\r
+/*=======================================================================================\r
+| GLOBAL FUNCTION PROTOTYPES                                                           |\r
+========================================================================================*/\r
+/**\r
+ * This function is to initialize video capture\r
+ *\r
+ * @param[in]  handle          Handle of player.\r
+ * @return     This function returns zero on success, or negative value with errors.\r
+ * @remarks\r
+ * @see\r
+ *\r
+ */\r
+int _mmplayer_initialize_video_capture(mm_player_t* player);\r
+/**\r
+ * This function is to release video capture\r
+ *\r
+ * @param[in]  handle          Handle of player.\r
+ * @return     This function returns zero on success, or negative value with errors.\r
+ * @remarks\r
+ * @see\r
+ *\r
+ */\r
+int _mmplayer_release_video_capture(mm_player_t* player);\r
+/**\r
+ * This function is to get video snapshot during playback.\r
+ *\r
+ * @param[in]  handle          Handle of player.\r
+ * @return     This function returns zero on success, or negative value with errors.\r
+ * @remarks\r
+ * @see\r
+ *\r
+ */\r
+int _mmplayer_do_video_capture(MMHandleType hplayer);\r
+\r
+#ifdef __cplusplus\r
+       }\r
+#endif\r
+\r
+#endif\r
diff --git a/src/include/mm_player_ini.h b/src/include/mm_player_ini.h
new file mode 100644 (file)
index 0000000..c8c095e
--- /dev/null
@@ -0,0 +1,256 @@
+/*
+ * libmm-player
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YeJin Cho <cho.yejin@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>
+ *
+ * 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 __MM_PLAYER_INI_H__
+#define __MM_PLAYER_INI_H__
+
+#include <glib.h>
+#include <mm_types.h>
+#include "mm_player_audioeffect.h"
+
+#ifdef __cplusplus
+       extern "C" {
+#endif
+
+
+#define MM_PLAYER_INI_DEFAULT_PATH     "/usr/etc/mmfw_player.ini"
+#define MM_PLAYER_INI_DEFAULT_AUDIOEFFECT_PATH "/usr/etc/mmfw_player_audio_effect.ini"
+
+#define PLAYER_INI() mm_player_ini_get_structure()
+
+#define PLAYER_INI_MAX_STRLEN  100
+#define PLAYER_INI_MAX_PARAM_STRLEN    256
+
+/* NOTE : MMPlayer has no initalizing API for library itself
+ * so we cannot decide when those ini values to be released.
+ * this is the reason of all string items are static array.
+ * make it do with malloc when MMPlayerInitialize() API created
+ * before that time, we should be careful with size limitation
+ * of each string item.
+ */
+
+/* @ mark means the item has tested */
+typedef struct __mm_player_ini
+{
+       /* general */
+       gboolean use_decodebin; // @
+       gchar videosink_element_x[PLAYER_INI_MAX_STRLEN];
+       gchar videosink_element_evas[PLAYER_INI_MAX_STRLEN];
+       gchar videosink_element_fake[PLAYER_INI_MAX_STRLEN];
+       gchar name_of_audiosink[PLAYER_INI_MAX_STRLEN]; // @
+       gchar name_of_drmsrc[PLAYER_INI_MAX_STRLEN]; // @
+       gchar name_of_video_converter[PLAYER_INI_MAX_STRLEN];
+       gboolean skip_rescan; // @
+       gboolean generate_dot; // @
+       gboolean provide_clock; // @
+       gint live_state_change_timeout; // @
+       gint localplayback_state_change_timeout; // @
+       gint delay_before_repeat;
+       gint eos_delay; // @
+       gboolean multiple_codec_supported;
+       
+       gchar gst_param[5][PLAYER_INI_MAX_PARAM_STRLEN]; // @
+       gchar exclude_element_keyword[10][PLAYER_INI_MAX_STRLEN];
+       gboolean async_start;
+       gboolean disable_segtrap;
+
+       /* audio effect */
+       gchar name_of_audio_effect[PLAYER_INI_MAX_STRLEN];
+
+       gboolean use_audio_effect_preset;
+       gboolean audio_effect_preset_list[MM_AUDIO_EFFECT_PRESET_NUM];
+       gboolean audio_effect_preset_earphone_only_list[MM_AUDIO_EFFECT_PRESET_NUM];
+
+       gboolean use_audio_effect_custom;
+       gboolean audio_effect_custom_list[MM_AUDIO_EFFECT_CUSTOM_NUM];
+       gboolean audio_effect_custom_earphone_only_list[MM_AUDIO_EFFECT_CUSTOM_NUM];
+       gint audio_effect_custom_eq_band_num;
+       gint audio_effect_custom_eq_band_width[MM_AUDIO_EFFECT_EQ_BAND_NUM_MAX];
+       gint audio_effect_custom_eq_band_freq[MM_AUDIO_EFFECT_EQ_BAND_NUM_MAX];
+       gint audio_effect_custom_ext_num;
+       gint audio_effect_custom_min_level_list[MM_AUDIO_EFFECT_CUSTOM_NUM];
+       gint audio_effect_custom_max_level_list[MM_AUDIO_EFFECT_CUSTOM_NUM];
+
+       /* http streaming */
+       gchar name_of_httpsrc[PLAYER_INI_MAX_STRLEN]; // @
+       gchar http_file_buffer_path[PLAYER_INI_MAX_STRLEN];
+       gdouble http_buffering_limit;
+       guint http_max_size_bytes;
+       gdouble http_buffering_time;
+       guint http_timeout;
+
+       /* rtsp streaming */
+       gchar name_of_rtspsrc[PLAYER_INI_MAX_STRLEN]; // @
+       guint rtsp_buffering_time;
+       guint rtsp_rebuffering_time;
+       gboolean rtsp_do_typefinding;
+       gboolean rtsp_error_concealment; /* testing purpose */
+} mm_player_ini_t;
+
+/* default values if each values are not specified in inifile */
+/* general */
+#define DEFAULT_USE_DECODEBIN                                                                  FALSE
+#define DEFAULT_AUDIO_EFFECT_ELEMENT                   ""
+#define DEFAULT_USE_AUDIO_EFFECT_PRESET                        FALSE
+#define DEFAULT_AUDIO_EFFECT_PRESET_LIST               ""
+#define DEFAULT_AUDIO_EFFECT_PRESET_LIST_EARPHONE_ONLY ""
+#define DEFAULT_USE_AUDIO_EFFECT_CUSTOM                        FALSE
+#define DEFAULT_AUDIO_EFFECT_CUSTOM_LIST               ""
+#define DEFAULT_AUDIO_EFFECT_CUSTOM_LIST_EARPHONE_ONLY ""
+#define DEFAULT_AUDIO_EFFECT_CUSTOM_EQ_BAND_NUM                0
+#define DEFAULT_AUDIO_EFFECT_CUSTOM_EQ_BAND_WIDTH              ""
+#define DEFAULT_AUDIO_EFFECT_CUSTOM_EQ_BAND_FREQ               ""
+#define DEFAULT_AUDIO_EFFECT_CUSTOM_EQ_MIN             0
+#define DEFAULT_AUDIO_EFFECT_CUSTOM_EQ_MAX             0
+#define DEFAULT_AUDIO_EFFECT_CUSTOM_EXT_NUM            0
+#define DEFAULT_USE_SINK_HANDLER                                                               TRUE
+#define DEFAULT_SKIP_RESCAN                                                                    TRUE
+#define DEFAULT_GENERATE_DOT                                                                   FALSE
+#define DEFAULT_PROVIDE_CLOCK                                                                  TRUE
+#define DEFAULT_DELAY_BEFORE_REPEAT                                                    50 /* msec */
+#define DEFAULT_EOS_DELAY                                                                              150 /* msec */
+#define DEFAULT_DRMSRC                                                                                 "drmsrc"
+#define DEFAULT_VIDEOSINK_X                                                                    "xvimagesink"
+#define DEFAULT_VIDEOSINK_EVAS                                                         "evasimagesink"
+#define DEFAULT_VIDEOSINK_FAKE                                                         "fakesink"
+#define DEFAULT_AUDIOSINK                                                                              "avsysaudiosink"
+#define DEFAULT_GST_PARAM                                                                              ""
+#define DEFAULT_EXCLUDE_KEYWORD                                                                ""
+#define DEFAULT_ASYNC_START                                                                    TRUE
+#define DEFAULT_DISABLE_SEGTRAP                                                                TRUE
+#define DEFAULT_VIDEO_CONVERTER                                                                ""
+#define DEFAULT_MULTIPLE_CODEC_SUPPORTED                                       TRUE
+#define DEFAULT_LIVE_STATE_CHANGE_TIMEOUT                                      30 /* sec */
+#define DEFAULT_LOCALPLAYBACK_STATE_CHANGE_TIMEOUT             10 /* sec */
+/* http streaming */
+#define DEFAULT_HTTPSRC                                                                                "souphttpsrc"
+#define DEFAULT_HTTP_FILE_BUFFER_PATH                                          ""
+#define DEFAULT_HTTP_BUFFERING_LIMIT                                                   99.0            /* percent */
+#define DEFAULT_HTTP_MAX_SIZE_BYTES                                                    1048576         /* bytes : 1 MBytes  */
+#define DEFAULT_HTTP_BUFFERING_TIME                                                    3.0             /* sec */
+#define DEFAULT_HTTP_TIMEOUT                                                           30              /* sec */
+/* rtsp streaming */
+#define DEFAULT_RTSPSRC                                                                                "secrtspsrc"
+#define DEFAULT_RTSP_BUFFERING                                                         5000    /* msec */
+#define DEFAULT_RTSP_REBUFFERING                                                               15000   /* msec */
+#define DEFAULT_RTSP_DO_TYPEFINDING                                                    FALSE
+#define DEFAULT_RTSP_ERROR_CONCEALMENT                                         TRUE
+
+/* NOTE : following content should be same with above default values */
+/* FIXIT : need smarter way to generate default ini file. */
+/* FIXIT : finally, it should be an external file */
+#define MM_PLAYER_DEFAULT_INI \
+"\
+[general] \n\
+\n\
+; if disabled typefind element will used directely \n\
+use decodebin = no ; async state change problem exist \n\
+\n\
+use sink handler = yes \n\
+\n\
+disable segtrap = yes ; same effect with --gst-disable-segtrap \n\
+\n\
+; set default video sink but, it can be replaced with others selected by application\n\
+; 0:v4l2sink, 1:ximagesink, 2:xvimagesink, 3:fakesink 4:evasimagesink 5:glimagesink\n\
+videosink element = 2 \n\
+\n\
+video converter element = \n\
+\n\
+audiosink element = avsysaudiosink \n\
+\n\
+drmsrc element = drmsrc \n\
+\n\
+; if yes. gstreamer will not update registry \n\
+skip rescan = yes \n\
+\n\
+delay before repeat = 50 ; msec\n\
+\n\
+; comma separated list of tocken which elemnts has it in it's name will not be used \n\
+element exclude keyword = \n\
+\n\
+async start = yes \n\
+\n\
+multiple codec supported = yes \n\
+\n\
+; parameters for initializing gstreamer \n\
+gstparam1 = \n\
+gstparam2 = \n\
+gstparam3 = \n\
+gstparam4 = \n\
+gstparam5 = \n\
+\n\
+; generating dot file representing pipeline state \n\
+generate dot = no \n\
+\n\
+; parameter for clock provide in audiosink \n\
+provide clock = yes \n\
+\n\
+; allowed timeout for changing pipeline state \n\
+live state change timeout = 30 ; sec \n\
+localplayback state change timeout = 4 ; sec \n\
+\n\
+; delay in msec for sending EOS \n\
+eos delay = 150 ; msec \n\
+\n\
+\n\
+[http streaming] \n\
+\n\
+httppsrc element = souphttpsrc \n\
+\n\
+; if set, use file or not use memory for buffering\n\
+http file buffer path = /opt/media\n\
+\n\
+http buffering limit = 99 ; percent\n\
+\n\
+http max size bytes = 1048576 ; bytes\n\
+\n\
+http buffering time = 3.0 \n\
+\n\
+http timeout = 30 ; sec \n\
+\n\
+\n\
+[rtsp streaming] \n\
+\n\
+rtspsrc element = secrtspsrc \n\
+\n\
+rtsp buffering time = 5000; msec \n\
+\n\
+rtsp rebuffering time = 15000; msec \n\
+\n\
+rtsp do typefinding = no; if no, caps on rtspsrc:src pad will be used for autoplugging \n\
+\n\
+rtsp error concealment = yes \n\
+\n\
+\n\
+"
+
+int
+mm_player_ini_load(void);
+
+mm_player_ini_t*
+mm_player_ini_get_structure(void);
+
+
+#ifdef __cplusplus
+       }
+#endif
+
+#endif
diff --git a/src/include/mm_player_internal.h b/src/include/mm_player_internal.h
new file mode 100644 (file)
index 0000000..bf8b4c0
--- /dev/null
@@ -0,0 +1,339 @@
+/*
+ * libmm-player
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YeJin Cho <cho.yejin@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>
+ *
+ * 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 __MM_PLAYER_INTERNAL_H__
+#define        __MM_PLAYER_INTERNAL_H__
+
+#include <mm_types.h>
+
+#ifdef __cplusplus
+       extern "C" {
+#endif
+
+/**
+       @addtogroup PLAYER-INTERNAL
+       @{
+
+       @par
+       <div><table>
+       <tr>
+       <td>PROPERTY</td>
+       <td>TYPE</td>
+       <td>VALID TYPE</td>
+       <td>DEFAULT VALUE</td>
+       </tr>
+       <tr>
+       <td>"display_roi_x"</td>
+       <td>int</td>
+       <td>range</td>
+       <td>0</td>
+       </tr>
+       <tr>
+       <td>"display_roi_y"</td>
+       <td>int</td>
+       <td>range</td>
+       <td>0</td>
+       </tr>
+       <tr>
+       <td>"display_roi_width"</td>
+       <td>int</td>
+       <td>range</td>
+       <td>640</td>
+       </tr>
+       <tr>
+       <td>"display_roi_height"</td>
+       <td>int</td>
+       <td>range</td>
+       <td>480</td>
+       </tr>
+       <tr>
+       <td>"display_method"</td>
+       <td>int</td>
+       <td>range</td>
+       <td>MM_DISPLAY_METHOD_LETTER_BOX</td>
+       </tr>
+       <tr>
+       <td>"sound_volume_type"</td>
+       <td>int</td>
+       <td>range</td>
+       <td>MM_SOUND_VOLUME_TYPE_CALL</td>
+       </tr>
+       <tr>
+       <td>"sound_route"</td>
+       <td>int</td>
+       <td>range</td>
+       <td>MM_AUDIOROUTE_USE_EXTERNAL_SETTING</td>
+       </tr>
+       <tr>
+       <td>"sound_stop_when_unplugged"</td>
+       <td>int</td>
+       <td>range</td>
+       </tr>
+       </table></div>
+
+*/
+
+/*
+ * Enumerations of video colorspace
+ */
+typedef enum {
+    MM_PLAYER_COLORSPACE_I420 = 0,             /**< I420 format - planer */
+    MM_PLAYER_COLORSPACE_RGB888,                       /**< RGB888 pixel format */
+    MM_PLAYER_COLORSPACE_NV12_TILED,           /**< Customized color format in s5pc110 */
+}MMPlayerVideoColorspace;
+
+typedef struct
+{
+       unsigned char *data;                                    /* capture image buffer */
+       int size;                                                               /* capture image size */
+       MMPlayerVideoColorspace fmt;                    /* color space type */  
+} MMPlayerVideoCapture;
+
+/**
+ * Buffer need data callback function type.
+ *
+ * @param      size            [in]    size required for the buffer playback
+ * @param      user_param      [in]    User defined parameter which is passed when set
+ *                                                             to need data callback
+ *
+ * @return     This callback function have to return MM_ERROR_NONE.
+ */
+typedef bool   (*mm_player_buffer_need_data_callback) (unsigned int size, void *user_param);
+
+/**
+ * Buffer enough data callback function type.
+ *
+ * @param      user_param      [in]    User defined parameter which is passed when set
+ *                                                             to enough data callback
+ *
+ * @return     This callback function have to return MM_ERROR_NONE.
+ */
+typedef bool   (*mm_player_buffer_enough_data_callback) (void *user_param);
+
+/**
+ * Buffer seek data callback function type.
+ *
+ * @param      offset                  [in]    offset for the buffer playback
+ * @param      user_param              [in]    User defined parameter which is passed when set
+ *                                                                     to seek data callback
+ *
+ * @return     This callback function have to return MM_ERROR_NONE.
+ */
+typedef bool   (*mm_player_buffer_seek_data_callback) (unsigned long long offset, void *user_param);
+
+/**
+ * Video stream callback function type.
+ *
+ * @param      stream          [in]    Reference pointer to video frame data
+ * @param      stream_size     [in]    Size of video frame data
+ * @param      user_param      [in]    User defined parameter which is passed when set
+ *                                                             video stream callback
+ * @param      width           [in]    width of video frame
+ * @param      height          [in]    height of video frame                                                   
+ *
+ * @return     This callback function have to return MM_ERROR_NONE.
+ */
+typedef bool   (*mm_player_video_stream_callback) (void *stream, int stream_size, void *user_param, int width, int height);
+
+/**
+ * Audio stream callback function type.
+ *
+ * @param      stream          [in]    Reference pointer to audio frame data
+ * @param      stream_size     [in]    Size of audio frame data
+ * @param      user_param      [in]    User defined parameter which is passed when set
+ *                                                             audio stream callback
+ *
+ * @return     This callback function have to return MM_ERROR_NONE.
+ */
+typedef bool   (*mm_player_video_capture_callback) (void *stream, int stream_size, void *user_param);
+
+/**
+ * Video frame render error callback function type.
+ *
+ * @param      error_id        [in]    cause of error
+ * @param      user_param      [in]    User defined parameter which is passed when set
+ *                                                             video frame render error callback
+ *
+ * @return     This callback function have to return MM_ERROR_NONE.
+ */
+typedef bool   (*mm_player_video_frame_render_error_callback) (void *error_id, void *user_param);
+
+/**
+ * This function is to set play speed for playback.
+ *
+ * @param      player          [in]    Handle of player.
+ * @param      ratio           [in]    Speed for playback.
+ *
+ * @return     This function returns zero on success, or negative value with error
+ *                     code
+ * @remark     The current supported range is from -64x to 64x. 
+ *             But, the quailty is dependent on codec performance.
+ *             And, the sound is muted under normal speed and more than double speed.  
+ * @see
+ * @since
+ */
+int mm_player_set_play_speed(MMHandleType player, float rate);
+
+/**
+ * This function set callback function for receiving video stream from player.
+ *
+ * @param      player          [in]    Handle of player.
+ * @param      callback        [in]    Video stream callback function.
+ * @param      user_param      [in]    User parameter.
+ *
+ * @return     This function returns zero on success, or negative value with error
+ *                     code.
+ * @remark
+ * @see                mm_player_video_stream_callback mm_player_set_audio_stream_callback
+ * @since
+ */
+int mm_player_set_video_stream_callback(MMHandleType player, mm_player_video_stream_callback callback, void *user_param);
+
+/**
+ * This function set callback function for rendering error information of video render plug-in.
+ *
+ * @param      player          [in]    Handle of player.
+ * @param      callback                [in]    Frame render error callback function.
+ * @param      user_param      [in]    User parameter which is passed to callback function.
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ * @see
+ * @remark     None
+ * @par Example
+ * @code
+ * @endcode
+ */
+int mm_player_set_video_frame_render_error_callback(MMHandleType player, mm_player_video_frame_render_error_callback callback, void *user_param);
+
+/**
+ * This function set callback function for receiving audio stream from player.
+ *
+ * @param       player          [in]    Handle of player.
+ * @param       callback                [in]    Audio buffer callback function.
+ * @param       user_param      [in]    User parameter.
+ *
+ * @return      This function returns zero on success, or negative value with error
+ *                      code.
+ * @remark      It can be used for audio playback only.
+ * @see         mm_player_audio_stream_callback
+ * @since
+ */
+int mm_player_set_audio_buffer_callback(MMHandleType player, mm_player_audio_stream_callback callback, void *user_param);
+
+/**
+ * This function is to capture video frame. 
+ *
+ * @param      player          [in]    Handle of player.
+ *
+ * @return     This function returns zero on success, or negative value with error
+ *                     code.
+ *
+ * @remark     Captured buffer is sent asynchronously through message callback with MM_MESSAGE_VIDEO_CAPTURED. 
+ *                     And, application should free the captured buffer directly. 
+ * @see                MM_MESSAGE_VIDEO_CAPTURED
+ * @since
+ */
+int mm_player_do_video_capture(MMHandleType player);
+
+/**
+ * This function set callback function for receiving need data message from player.
+ *
+ * @param      player          [in]    Handle of player.
+ * @param      callback        [in]    Need data callback function.
+ * @param      user_param      [in]    User parameter.
+ *
+ * @return     This function returns zero on success, or negative value with error
+ *                     code.
+ * @remark
+ * @see                mm_player_set_buffer_enough_data_callback
+ * @since
+ */
+int mm_player_set_buffer_need_data_callback(MMHandleType player, mm_player_buffer_need_data_callback callback , void *user_param);
+
+/**
+ * This function set callback function for receiving enough data message from player.
+ *
+ * @param      player          [in]    Handle of player.
+ * @param      callback        [in]    Enough data callback function.
+ * @param      user_param      [in]    User parameter.
+ *
+ * @return     This function returns zero on success, or negative value with error
+ *                     code.
+ * @remark
+ * @see                mm_player_set_buffer_need_data_callback
+ * @since
+ */
+int mm_player_set_buffer_enough_data_callback(MMHandleType player, mm_player_buffer_enough_data_callback callback, void *user_param);
+
+/**
+ * This function set callback function for receiving seek data message from player.
+ *
+ * @param      player          [in]    Handle of player.
+ * @param      callback        [in]    Seek data callback function.
+ * @param      user_param      [in]    User parameter.
+ *
+ * @return     This function returns zero on success, or negative value with error
+ *                     code.
+ * @remark
+ * @see
+ * @since
+ */
+int mm_player_set_buffer_seek_data_callback(MMHandleType player, mm_player_buffer_seek_data_callback callback, void *user_param);
+
+/**
+ * This function set callback function for putting data into player.
+ *
+ * @param      player          [in]    Handle of player.
+ * @param      buf                     [in]    data to push into player
+ * @param      size                    [in]    buffer size to push
+ *
+ * @return     This function returns zero on success, or negative value with error
+ *                     code.
+ * @remark
+ * @see
+ * @since
+ */
+int mm_player_push_buffer(MMHandleType player, unsigned char *buf, int size);
+
+/**
+ * This function changes the previous videosink plugin for a new one
+ *
+ * @param      player                  [in]    Handle of player.
+ * @param      display_surface_type    [in]    display surface type to set
+ * @param      display_overlay                 [in]    display overlay to set
+ *
+ * @return     This function returns zero on success, or negative value with error
+ *                     code.
+ * @remark     Not supported
+ * @see
+ * @since
+ */
+int mm_player_change_videosink(MMHandleType player, MMDisplaySurfaceType display_surface_type, void *display_overlay);
+
+/**
+       @}
+ */
+
+#ifdef __cplusplus
+       }
+#endif
+
+#endif /* __MM_PLAYER_INTERNAL_H__ */
diff --git a/src/include/mm_player_pd.h b/src/include/mm_player_pd.h
new file mode 100644 (file)
index 0000000..163f65c
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * libmm-player
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, naveen cherukuri <naveen.ch@samsung.com>,
+ * YeJin Cho <cho.yejin@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>
+ *
+ * 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 __MM_PLAYER_PD_H__
+#define        __MM_PLAYER_PD_H__
+
+#include <glib.h>
+#include <gst/gst.h>
+#include <string.h>
+#include <mm_types.h>
+#include <mm_message.h>
+
+#ifdef __cplusplus
+       extern "C" {
+#endif
+
+typedef struct
+{
+       gchar *path_read_from;          // path for download and playback
+       gchar *location_to_save;                // path for saving to local
+       gint64 total_size;                              // size of file to download (bytes)
+
+       GstElement *playback_pipeline_src;  // src element of playback pipeline
+       GstElement *downloader_pipeline;
+       GstElement *downloader_src;
+       GstElement *downloader_queue;
+       GstElement *downloader_sink;
+}mm_player_pd_t;
+
+/**
+ * This function allocates handle of progressive download.
+ *
+ * @return     This function returns allocated handle.
+ * @remarks
+ * @see                _mmplayer_destroy_pd_downloader()
+ *
+ */
+mm_player_pd_t * _mmplayer_create_pd_downloader ();
+/**
+ * This function destroy progressive download.
+ *
+ * @param[in]  handle  Handle of player.
+ * @return     This function returns true on success, or false on failure.
+ * @remarks
+ * @see                _mmplayer_create_pd_downloader()
+ *
+ */
+gboolean _mmplayer_destroy_pd_downloader  (MMHandleType handle);
+/**
+ * This function realize progressive download.
+ *
+ * @param[in]  handle  Handle of player.
+ * @param[in]  src_uri path to download.
+ * @param[in]  dst_uri path to save in local system.
+ * @param[in]  pushsrc source element of playback pipeline
+ * @return     This function returns true on success, or false on failure.
+ * @remarks
+ * @see
+ *
+ */
+gboolean _mmplayer_realize_pd_downloader (MMHandleType handle, gchar *src_uri, gchar *dst_uri, GstElement *pushsrc);
+/**
+ * This function unrealize progressive download.
+ *
+ * @param[in]  handle  Handle of player.
+ * @return     This function returns true on success, or false on failure.
+ * @remarks
+ * @see                _mmplayer_realize_pd_downloader()
+ *
+ */
+gboolean _mmplayer_unrealize_pd_downloader (MMHandleType handle);
+/**
+ * This function start progressive download.
+ *
+ * @param[in]  handle  Handle of player.
+ * @return     This function returns true on success, or false on failure.
+ * @remarks
+ * @see
+ *
+ */
+gboolean _mmplayer_start_pd_downloader (MMHandleType handle);
+/**
+ * This function get pd current status.
+ *
+ * @param[in]  handle  Handle of player.
+ * @param[in]  current_pos     current downloaded size
+ * @param[in]  total_size              total file size to download
+ * @return     This function returns true on success, or false on failure.
+ * @remarks
+ * @see
+ *
+ */
+gboolean _mmplayer_get_pd_downloader_status(MMHandleType handle, guint64 *current_pos, guint64 *total_size);
+/**
+ * This function set message callback of PD downloader.
+ *
+ * @param[in]  handle  Handle of player.
+ * @param[in]  MMMessageCallback       Message callback function
+ * @param[in]  user_param              User parameter which is passed to callback function.
+ * @return     This function returns true on success, or false on failure.
+ * @remarks
+ * @see
+ *
+ */
+gint _mm_player_set_pd_downloader_message_cb(MMHandleType player, MMMessageCallback callback, gpointer user_param);
+
+#ifdef __cplusplus
+       }
+#endif
+
+#endif
diff --git a/src/include/mm_player_priv.h b/src/include/mm_player_priv.h
new file mode 100644 (file)
index 0000000..08f7ba2
--- /dev/null
@@ -0,0 +1,669 @@
+/*
+ * libmm-player
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YeJin Cho <cho.yejin@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>
+ *
+ * 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 __MM_PLAYER_PRIV_H__
+#define        __MM_PLAYER_PRIV_H__
+
+/*===========================================================================================
+|                                                                                                                                                                                      |
+|  INCLUDE FILES                                                                                                                                                       |
+|                                                                                                                                                                                      |
+========================================================================================== */
+#include <glib.h>
+#include <gst/gst.h>
+#include <mm_types.h>
+#include <mm_attrs.h>
+#include <mm_ta.h>
+#include <mm_debug.h>
+
+#include "mm_player.h"
+#include "mm_player_internal.h"
+#include "mm_player_audioeffect.h"
+#include "mm_message.h"
+#include "mm_player_utils.h"
+#include "mm_player_asm.h"
+#include "mm_player_pd.h"
+#include "mm_player_streaming.h"
+
+/*===========================================================================================
+|                                                                                                                                                                                      |
+|  GLOBAL DEFINITIONS AND DECLARATIONS FOR MODULE                                                                                      |
+|                                                                                                                                                                                      |
+========================================================================================== */
+
+/*---------------------------------------------------------------------------
+|    GLOBAL #defines:                                                                                                          |
+---------------------------------------------------------------------------*/
+
+#define MM_PLAYER_IMGB_MPLANE_MAX      4
+#define MM_PLAYER_STREAM_COUNT_MAX     3
+
+#define MM_PLAYER_CAST(x_player)               ((mm_player_t *)(x_player))
+/**
+ * @x_player: MMHandleType of player
+ *
+ * Get the PD downloader of this player.
+ */
+#define MM_PLAYER_GET_PD(x_player)     (MM_PLAYER_CAST(x_player)->pd_downloader)
+/**
+ * @x_player: MMHandleType of player
+ *
+ * Get the attributes handle of this player.
+ */
+#define MM_PLAYER_GET_ATTRS(x_player)  (MM_PLAYER_CAST(x_player)->attrs)
+
+/*---------------------------------------------------------------------------
+|    GLOBAL CONSTANT DEFINITIONS:                                                                                      |
+---------------------------------------------------------------------------*/
+enum tag_info
+{
+       TAG_AUDIO_CODEC = 0x0001,
+       TAG_VIDEO_CODEC = 0x0002,
+       TAG_ARTIST              = 0x0004,
+       TAG_TITLE               = 0x0008,
+       TAG_ALBUM               = 0x0010,
+       TAG_GENRE               = 0x0020,
+       TAG_COPYRIGHT   = 0x0040,
+       TAG_DATE                = 0x0080,
+       TAG_DESCRIPTION = 0x0100,
+       TAG_TRACK_NUMBER = 0x0200
+};
+
+/* async mode makes trouble. alsasink sometimes fails to pause. */
+enum alassink_sync
+{
+       ALSASINK_SYNC,
+       ALSASINK_ASYNC
+};
+
+
+/**
+ * Enumerations of Player Mode
+ */
+enum MMPlayerMode {
+       MM_PLAYER_MODE_NONE,                    /**< Player mode None */
+       MM_PLAYER_MODE_MIDI,                    /**< Player mode Midi */
+       MM_PLAYER_MODE_GST,                     /**< Player mode Gstreamer */
+};
+
+
+/**
+ * Enumerations of Player Uri type
+ */
+enum MMPlayerUriType {
+       MM_PLAYER_URI_TYPE_NONE,                /**< Player URI type None */
+       MM_PLAYER_URI_TYPE_URL_RTSP,    /**< Player URI type RTSP */
+       MM_PLAYER_URI_TYPE_URL_HTTP,/**< Player URI type HTTP */
+       MM_PLAYER_URI_TYPE_URL_MMS,/**< Player URI type MMS */
+       MM_PLAYER_URI_TYPE_MEM,         /**< Player URI type Mem */
+       MM_PLAYER_URI_TYPE_FILE,                /**< Player URI type File */
+       MM_PLAYER_URI_TYPE_URL,                 /**< Player URI type URL */
+       MM_PLAYER_URI_TYPE_BUFF,                /**< Player URI type Buffer */
+       MM_PLAYER_URI_TYPE_HLS,                 /**< Player URI type http live streaming */     
+       MM_PLAYER_URI_TYPE_TEMP,                        /**< Player URI type Temp */
+};
+
+typedef enum _MissingCodec
+{
+       MISSING_PLUGIN_NONE                     = 0x00,
+       MISSING_PLUGIN_AUDIO                    = 0x01,
+       MISSING_PLUGIN_VIDEO                    = 0x02
+}MissingCodec;
+
+
+typedef enum _FoundCodec
+{
+       FOUND_PLUGIN_NONE                       = 0x00,
+       FOUND_PLUGIN_AUDIO                      = 0x01,
+       FOUND_PLUGIN_VIDEO                      = 0x02
+}FoundCodec;
+
+/* main pipeline's element id */
+enum MainElementID
+{
+       MMPLAYER_M_PIPE = 0, /* NOTE : MMPLAYER_M_PIPE should be zero */
+       MMPLAYER_M_SRC,
+       MMPLAYER_M_SUBSRC,
+
+       /* it could be a decodebin or could be a typefind. depends on player ini */
+       MMPLAYER_M_AUTOPLUG,
+
+       /* NOTE : we need two fakesink to autoplug without decodebin.
+        * first one will hold whole pipeline state. and second one will hold state of
+        * a sink-decodebin for an elementary stream. no metter if there's more then one
+        * elementary streams because MSL reuse it.
+        */
+       MMPLAYER_M_SRC_FAKESINK,
+       MMPLAYER_M_SRC_2ND_FAKESINK,
+
+       /* streaming plugin */
+       MMPLAYER_M_S_BUFFER, 
+       MMPLAYER_M_S_ADEC, 
+       MMPLAYER_M_S_VDEC, 
+       
+       /* FIXIT : if there's really no usage for following IDs. remove it */
+       MMPLAYER_M_DEC1,
+       MMPLAYER_M_DEC2,
+       MMPLAYER_M_Q1,
+       MMPLAYER_M_Q2,
+       MMPLAYER_M_DEMUX,
+       MMPLAYER_M_SUBPARSE,
+       MMPLAYER_M_NUM
+};
+
+/* audio pipeline's element id */
+enum AudioElementID
+{
+       MMPLAYER_A_BIN = 0, /* NOTE : MMPLAYER_A_BIN should be zero */
+       MMPLAYER_A_TP,
+       MMPLAYER_A_CONV,
+       MMPLAYER_A_VOL,
+       MMPLAYER_A_FILTER,
+       MMPLAYER_A_CAPS_DEFAULT,
+       MMPLAYER_A_SINK,
+       MMPLAYER_A_RESAMPLER,
+       MMPLAYER_A_NUM
+};
+
+/* video pipeline's element id */
+enum VideoElementID
+{
+       MMPLAYER_V_BIN = 0, /* NOTE : MMPLAYER_V_BIN should be zero */
+       MMPLAYER_V_FLIP,
+       MMPLAYER_V_CONV,
+       MMPLAYER_V_SCALE,
+       MMPLAYER_V_CAPS,
+       MMPLAYER_V_SINK,
+       MMPLAYER_V_NUM
+};
+
+/* text pipeline's element id */
+enum TextElementID
+{
+       MMPLAYER_T_BIN = 0, /* NOTE : MMPLAYER_V_BIN should be zero */
+       MMPLAYER_T_TEXT_QUEUE,
+       MMPLAYER_T_VIDEO_QUEUE,
+       MMPLAYER_T_VIDEO_CONVERTER,
+       MMPLAYER_T_OVERLAY,
+       MMPLAYER_T_SINK,
+       MMPLAYER_T_NUM
+};
+
+/* midi main pipeline's element id */
+enum MidiElementID
+{
+       MMPLAYER_MIDI_PIPE,
+       MMPLAYER_MIDI_PLAYER,
+       MMPLAYER_MIDI_NUM
+};
+
+enum PlayerCommandState
+{
+       MMPLAYER_COMMAND_NONE,
+       MMPLAYER_COMMAND_CREATE,
+       MMPLAYER_COMMAND_DESTROY,
+       MMPLAYER_COMMAND_UNREALIZE,
+       MMPLAYER_COMMAND_START,
+       MMPLAYER_COMMAND_REALIZE,
+       MMPLAYER_COMMAND_STOP,
+       MMPLAYER_COMMAND_PAUSE,
+       MMPLAYER_COMMAND_RESUME,
+       MMPLAYER_COMMAND_NUM
+};
+
+/* Note : StreamingSrcError is error enum for streaming source which post error message
+ *     using custom message made by itself. The enum value must start with zero,
+ *     because the streaming source(secrtspsrc) also does.
+ */
+enum StreamingSrcError
+{
+       MMPLAYER_STREAMING_ERROR_NONE = 0,
+       MMPLAYER_STREAMING_ERROR_UNSUPPORTED_AUDIO,
+       MMPLAYER_STREAMING_ERROR_UNSUPPORTED_VIDEO,
+       MMPLAYER_STREAMING_ERROR_CONNECTION_FAIL,
+       MMPLAYER_STREAMING_ERROR_DNS_FAIL,
+       MMPLAYER_STREAMING_ERROR_SERVER_DISCONNECTED,
+       MMPLAYER_STREAMING_ERROR_BAD_SERVER,
+       MMPLAYER_STREAMING_ERROR_INVALID_PROTOCOL,
+       MMPLAYER_STREAMING_ERROR_INVALID_URL,
+       MMPLAYER_STREAMING_ERROR_UNEXPECTED_MSG,
+       MMPLAYER_STREAMING_ERROR_OUT_OF_MEMORIES,
+       MMPLAYER_STREAMING_ERROR_RTSP_TIMEOUT,
+       MMPLAYER_STREAMING_ERROR_BAD_REQUEST,
+       MMPLAYER_STREAMING_ERROR_NOT_AUTHORIZED,
+       MMPLAYER_STREAMING_ERROR_PAYMENT_REQUIRED,
+       MMPLAYER_STREAMING_ERROR_FORBIDDEN,
+       MMPLAYER_STREAMING_ERROR_CONTENT_NOT_FOUND,
+       MMPLAYER_STREAMING_ERROR_METHOD_NOT_ALLOWED,
+       MMPLAYER_STREAMING_ERROR_NOT_ACCEPTABLE,
+       MMPLAYER_STREAMING_ERROR_PROXY_AUTHENTICATION_REQUIRED,
+       MMPLAYER_STREAMING_ERROR_SERVER_TIMEOUT,
+       MMPLAYER_STREAMING_ERROR_GONE,
+       MMPLAYER_STREAMING_ERROR_LENGTH_REQUIRED,
+       MMPLAYER_STREAMING_ERROR_PRECONDITION_FAILED,
+       MMPLAYER_STREAMING_ERROR_REQUEST_ENTITY_TOO_LARGE,
+       MMPLAYER_STREAMING_ERROR_REQUEST_URI_TOO_LARGE,
+       MMPLAYER_STREAMING_ERROR_UNSUPPORTED_MEDIA_TYPE,
+       MMPLAYER_STREAMING_ERROR_PARAMETER_NOT_UNDERSTOOD,
+       MMPLAYER_STREAMING_ERROR_CONFERENCE_NOT_FOUND,
+       MMPLAYER_STREAMING_ERROR_NOT_ENOUGH_BANDWIDTH,
+       MMPLAYER_STREAMING_ERROR_NO_SESSION_ID,
+       MMPLAYER_STREAMING_ERROR_METHOD_NOT_VALID_IN_THIS_STATE,
+       MMPLAYER_STREAMING_ERROR_HEADER_FIELD_NOT_VALID_FOR_SOURCE,
+       MMPLAYER_STREAMING_ERROR_INVALID_RANGE,
+       MMPLAYER_STREAMING_ERROR_PARAMETER_IS_READONLY,
+       MMPLAYER_STREAMING_ERROR_AGGREGATE_OP_NOT_ALLOWED,
+       MMPLAYER_STREAMING_ERROR_ONLY_AGGREGATE_OP_ALLOWED,
+       MMPLAYER_STREAMING_ERROR_BAD_TRANSPORT,
+       MMPLAYER_STREAMING_ERROR_DESTINATION_UNREACHABLE,
+       MMPLAYER_STREAMING_ERROR_INTERNAL_SERVER_ERROR,
+       MMPLAYER_STREAMING_ERROR_NOT_IMPLEMENTED,
+       MMPLAYER_STREAMING_ERROR_BAD_GATEWAY,
+       MMPLAYER_STREAMING_ERROR_SERVICE_UNAVAILABLE,
+       MMPLAYER_STREAMING_ERROR_GATEWAY_TIME_OUT       ,
+       MMPLAYER_STREAMING_ERROR_RTSP_VERSION_NOT_SUPPORTED,
+       MMPLAYER_STREAMING_ERROR_OPTION_NOT_SUPPORTED,
+};
+
+
+/*---------------------------------------------------------------------------
+|    GLOBAL DATA TYPE DEFINITIONS:                                                                                     |
+---------------------------------------------------------------------------*/
+
+typedef struct
+{
+       int id;
+       GstElement *gst;
+} MMPlayerGstElement;
+
+typedef struct
+{
+       GstTagList                      *tag_list;
+       MMPlayerGstElement      *mainbin;
+       MMPlayerGstElement      *audiobin;
+       MMPlayerGstElement      *videobin;
+       MMPlayerGstElement      *textbin;
+} MMPlayerGstPipelineInfo;
+
+typedef struct
+{
+       char    device[MAX_SOUND_DEVICE_LEN];
+       float volume;
+       int mute;
+       int bluetooth;  /* enable/disable */
+} MMPlayerSoundInfo;
+
+typedef struct {
+       char *buf;
+       int len;
+       int offset;
+
+} tBuffer; /* FIXIT : choose better name */
+
+typedef struct {
+       int uri_type;
+       int     play_mode;
+       void *mem;
+       int     mem_size;
+       char uri[MM_MAX_URL_LEN];
+       char urgent[MM_MAX_FILENAME_LEN];
+} MMPlayerParseProfile;
+
+typedef struct {
+       bool is_pending;
+       MMPlayerPosFormatType format;
+       unsigned long pos;
+}MMPlayerPendingSeek;
+
+typedef struct {
+       GObject* obj;
+       gulong sig;
+} MMPlayerSignalItem;
+
+/* image buffer definition ***************************************************
+
+    +------------------------------------------+ ---
+    |                                          |  ^
+    |     a[], p[]                             |  |
+    |     +---------------------------+ ---    |  |
+    |     |                           |  ^     |  |
+    |     |<---------- w[] ---------->|  |     |  |
+    |     |                           |  |     |  |
+    |     |                           |        |
+    |     |                           |  h[]   |  e[]
+    |     |                           |        |
+    |     |                           |  |     |  |
+    |     |                           |  |     |  |
+    |     |                           |  v     |  |
+    |     +---------------------------+ ---    |  |
+    |                                          |  v
+    +------------------------------------------+ ---
+
+    |<----------------- s[] ------------------>|
+*/
+typedef struct
+{
+       /* width of each image plane */
+       int     w[MM_PLAYER_IMGB_MPLANE_MAX];
+       /* height of each image plane */
+       int     h[MM_PLAYER_IMGB_MPLANE_MAX];
+       /* stride of each image plane */
+       int     s[MM_PLAYER_IMGB_MPLANE_MAX];
+       /* elevation of each image plane */
+       int     e[MM_PLAYER_IMGB_MPLANE_MAX];
+       /* user space address of each image plane */
+       void    *a[MM_PLAYER_IMGB_MPLANE_MAX];
+       /* physical address of each image plane, if needs */
+       void    *p[MM_PLAYER_IMGB_MPLANE_MAX];
+       /* color space type of image */
+       int     cs;
+       /* left postion, if needs */
+       int     x;
+       /* top position, if needs */
+       int     y;
+       /* to align memory */
+       int     __dummy2;
+       /* arbitrary data */
+       int     data[16];
+
+    /* dmabuf fd */
+    int fd[MM_PLAYER_IMGB_MPLANE_MAX];
+
+    /* flag for buffer share */
+    int buf_share_method;
+
+   /*y, cbcr size for bookmark */
+    int y_size;
+    int uv_size;
+} MMPlayerMPlaneImage;
+
+typedef struct {
+       /* STATE */
+       int state;                                      // player current state
+       int prev_state;                         // player previous state
+       int pending_state;                      // player state which is going to now
+       int target_state;                               // player state which user want to go to
+       guint state_change_timeout;     
+
+       gboolean section_repeat;
+       gint section_repeat_start;
+       gint section_repeat_end;
+
+       gchar *album_art;
+
+       int cmd;
+
+       /* command lock */
+       GMutex* cmd_lock;
+
+       /* repeat thread lock */
+       GCond* repeat_thread_cond;
+       GMutex* repeat_thread_mutex;
+       GThread* repeat_thread;
+       gboolean repeat_thread_exit;
+
+       /* capture thread */
+       GThread* capture_thread;
+       gboolean capture_thread_exit;
+       GCond* capture_thread_cond;
+       GMutex* capture_thread_mutex;
+       MMPlayerVideoCapture capture;
+       MMPlayerVideoColorspace video_cs;       
+       MMPlayerMPlaneImage captured;
+       
+       /* fakesink handling lock */
+       GMutex* fsink_lock;
+
+       /* player attributes */
+       MMHandleType attrs;
+
+       /* message callback */
+       MMMessageCallback msg_cb;
+       void* msg_cb_param;
+       GMutex* msg_cb_lock;
+
+       /* progressive download */
+       mm_player_pd_t *pd_downloader;
+       gchar *pd_file_save_path;
+       MMPlayerPDMode pd_mode;
+
+       /* streaming player */
+       mm_player_streaming_t *streamer;
+
+       /* gstreamer pipeline */
+       MMPlayerGstPipelineInfo *pipeline;
+       gboolean pipeline_is_constructed;
+
+       /* buffering support cbs*/
+       mm_player_buffer_need_data_callback need_data_cb;
+       mm_player_buffer_enough_data_callback enough_data_cb;
+       mm_player_buffer_seek_data_callback seek_data_cb;
+
+       void* buffer_cb_user_param;
+
+       /* video stream callback */
+       mm_player_video_stream_callback video_stream_cb;
+       void* video_stream_cb_user_param;
+       int use_video_stream;
+
+       /* audio stram callback */
+       mm_player_audio_stream_callback audio_stream_cb;
+       void* audio_stream_cb_user_param;
+
+       /* audio buffer callback */
+       mm_player_audio_stream_callback audio_buffer_cb;
+       void* audio_buffer_cb_user_param;
+
+       /* video capture callback*/
+       gulong video_capture_cb_probe_id;
+
+       /* video frame render error callback */
+       mm_player_video_frame_render_error_callback video_frame_render_error_cb;
+       void* video_frame_render_error_cb_user_param;
+
+       /* sound info */
+       MMPlayerSoundInfo       sound;
+
+       /* type string */
+       gchar *type;
+
+       /* video stream caps parsed by demuxer */
+       GstCaps* v_stream_caps;
+
+       /* audio effect infomation */
+       MMAudioEffectInfo audio_effect_info;
+       gboolean bypass_audio_effect;
+
+       gulong audio_cb_probe_id;
+
+       /* for appsrc */
+       tBuffer mem_buf;
+
+       /* content profile */
+       MMPlayerParseProfile profile;
+
+       /* streaming service type */
+       MMStreamingType streaming_type;
+
+       /* autoplugging */
+       GList* factories;
+       gboolean have_dynamic_pad;
+       GList* parsers; // list of linked parser name
+       gboolean no_more_pad;
+       gint num_dynamic_pad;
+       gboolean has_many_types;
+
+       /* progress callback timer */
+       /* FIXIT : since duplicated functionality with get_position
+        * this function will be deprecated after fixing all application
+        * which are using it.
+        */
+       guint progress_timer;
+
+       /* timer for sending delayed EOS */
+       guint eos_timer;
+
+       /* last point (msec) that player is paused or seeking */
+       gint64 last_position;
+
+       /* duration */
+       gint64 duration;
+
+       /* data size of http streaming  */
+       guint64 http_content_size;
+
+       /* last error */
+       gchar last_error_msg[1024]; /* FIXIT : should it be dynamic ? */
+
+       gint videodec_linked;
+       gint audiodec_linked;
+       gint videosink_linked;
+       gint audiosink_linked;
+       gint textsink_linked;
+
+       /* missing plugin during autoplugging */
+       MissingCodec not_supported_codec;
+
+       /*unlinked audio/video mime type */
+       gchar *unlinked_video_mime;
+       gchar *unlinked_audio_mime;
+       gchar *unlinked_demuxer_mime;
+
+       /* found codec during autoplugging */
+       FoundCodec can_support_codec;
+
+       gboolean not_found_demuxer;
+
+       /* support seek even though player is not start */
+       MMPlayerPendingSeek pending_seek;
+
+       gboolean doing_seek;
+
+       /* prevent to post msg over and over */
+       gboolean posted_msg;
+
+       /* list of sink elements */
+       GList* sink_elements;
+
+       /* signal notifiers */
+       GList* signals;
+       guint bus_watcher;
+
+       /* NOTE : if sink elements receive flush start event then it's state will be lost.
+        * this can happen when doing buffering in streaming pipeline since all control operation
+        * (play/pause/resume/seek) is requiring server interaction. during 'state lost' situation
+        * _set_state will not work correctely and state transition message will not posted to our
+        * gst_callback.
+        * So. we need to do some special care on the situation.
+        */
+       gboolean state_lost;
+
+       gboolean need_update_content_attrs;
+       gboolean need_update_content_dur;
+
+       gboolean is_sound_extraction;
+
+       gdouble playback_rate;
+       /* player state resumed by fast rewind */
+       gboolean resumed_by_rewind;
+
+       gboolean is_nv12_tiled;
+
+       MMPlayerASM     sm;
+
+       gboolean is_subtitle_off;
+
+       /* contents bitrate for buffering management */
+       guint bitrate[MM_PLAYER_STREAM_COUNT_MAX];
+       guint total_bitrate;
+       guint updated_bitrate_count;
+       guint maximum_bitrate[MM_PLAYER_STREAM_COUNT_MAX];
+       guint total_maximum_bitrate;
+       guint updated_maximum_bitrate_count;
+
+       /* prevent it from posting duplicatly*/
+       gboolean sent_bos;
+
+       /* timeout source for lazy pause */
+       guint lazy_pause_event_id;
+
+       gboolean keep_detecting_vcodec;
+
+       gboolean play_subtitle;
+       gboolean use_textoverlay;
+
+       /* PD downloader message callback and param */
+       MMMessageCallback pd_msg_cb;
+       void* pd_msg_cb_param;
+} mm_player_t;
+
+/*===========================================================================================
+|                                                                                                                                                                                      |
+|  GLOBAL FUNCTION PROTOTYPES                                                                                                                          |
+|                                                                                                                                                                                      |
+========================================================================================== */
+#ifdef __cplusplus
+       extern "C" {
+#endif
+
+int _mmplayer_create_player(MMHandleType hplayer);
+int _mmplayer_destroy(MMHandleType hplayer);
+int _mmplayer_realize(MMHandleType hplayer);
+int _mmplayer_unrealize(MMHandleType hplayer);
+int _mmplayer_get_state(MMHandleType hplayer, int* pstate);
+int _mmplayer_set_volume(MMHandleType hplayer, MMPlayerVolumeType volume);
+int _mmplayer_get_volume(MMHandleType hplayer, MMPlayerVolumeType *volume);
+int _mmplayer_set_mute(MMHandleType hplayer, int mute);
+int _mmplayer_get_mute(MMHandleType hplayer, int* pmute);
+int _mmplayer_start(MMHandleType hplayer);
+int _mmplayer_stop(MMHandleType hplayer);
+int _mmplayer_pause(MMHandleType hplayer);
+int _mmplayer_resume(MMHandleType hplayer);
+int _mmplayer_set_position(MMHandleType hplayer, int format, int pos);
+int _mmplayer_get_position(MMHandleType hplayer, int format, unsigned long *pos);
+int _mmplayer_adjust_subtitle_postion(MMHandleType hplayer, int format,  int pos);
+int _mmplayer_activate_section_repeat(MMHandleType hplayer, unsigned long start, unsigned long end);
+int _mmplayer_deactivate_section_repeat(MMHandleType hplayer);
+int _mmplayer_push_buffer(MMHandleType hplayer, unsigned char *buf, int size);
+int _mmplayer_set_buffer_need_data_cb(MMHandleType hplayer,mm_player_buffer_need_data_callback callback, void *user_param);
+int _mmplayer_set_buffer_enough_data_cb(MMHandleType hplayer,mm_player_buffer_enough_data_callback callback, void *user_param);
+int _mmplayer_set_buffer_seek_data_cb(MMHandleType hplayer,mm_player_buffer_seek_data_callback callback, void *user_param);
+int _mmplayer_set_playspeed(MMHandleType hplayer, gdouble rate);
+int _mmplayer_set_message_callback(MMHandleType hplayer, MMMessageCallback callback, void *user_param);
+int _mmplayer_set_videostream_cb(MMHandleType hplayer,mm_player_video_stream_callback callback, void *user_param);
+int _mmplayer_set_audiostream_cb(MMHandleType hplayer,mm_player_audio_stream_callback callback, void *user_param);
+int _mmplayer_set_videoframe_render_error_cb(MMHandleType hplayer, mm_player_video_frame_render_error_callback callback, void *user_param);
+int _mmplayer_set_subtitle_silent (MMHandleType hplayer, int silent);
+int _mmplayer_get_subtitle_silent (MMHandleType hplayer, int* silent);
+int _mmplayer_get_buffer_position(MMHandleType hplayer, int format, unsigned long* start_pos, unsigned long* stop_pos);
+gboolean       _mmplayer_update_content_attrs(mm_player_t* player);
+/* test API for tuning audio gain. this API should be
+ * deprecated before the day of final release
+ */
+int _mmplayer_set_volume_tune(MMHandleType hplayer, MMPlayerVolumeType volume);
+int _mmplayer_update_video_param(mm_player_t* player);
+int _mmplayer_set_audiobuffer_cb(MMHandleType hplayer, mm_player_audio_stream_callback callback, void *user_param);
+
+#ifdef __cplusplus
+       }
+#endif
+
+#endif /* __MM_PLAYER_PRIV_H__ */
diff --git a/src/include/mm_player_streaming.h b/src/include/mm_player_streaming.h
new file mode 100644 (file)
index 0000000..8766bb3
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * libmm-player
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YeJin Cho <cho.yejin@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>
+ *
+ * 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 __MM_PLAYER_STREAMING_H__
+#define        __MM_PLAYER_STREAMING_H__
+
+#include <glib.h>
+#include <gst/gst.h>
+#include <string.h>
+#include "mm_debug.h"
+
+#define MAX_FILE_BUFFER_NAME_LEN 256
+
+#define MIN_BUFFER_PERCENT 0.0
+#define MAX_BUFFER_PERCENT 100.0
+#define MIN_BUFFERING_TIME 2.0
+#define MAX_BUFFERING_TIME 10.0
+
+#define DEFAULT_BUFFER_SIZE 4194304     // 4 MBytes
+#define DEFAULT_BUFFER_LOW_PERCENT 1.0         // 1%
+#define DEFAULT_BUFFER_HIGH_PERCENT 99.0       // 15%
+#define DEFAULT_BUFFERING_TIME 3.0             // about 3sec
+
+#define DEFAULT_FILE_BUFFER_PATH "/opt/media"
+
+#define STREAMING_USE_FILE_BUFFER
+#define STREAMING_USE_MEMORY_BUFFER
+
+typedef struct
+{
+       GstElement *buffer; /* buffering element of playback pipeline */
+
+       gboolean is_buffering;
+       gint buffering_percent;
+
+       gboolean need_update;
+       guint buffer_size;
+       gdouble buffer_high_percent;
+       gdouble buffer_low_percent;
+       gdouble buffering_time;
+       guint buffer_max_bitrate;
+       guint buffer_avg_bitrate;
+}mm_player_streaming_t;
+
+
+mm_player_streaming_t *__mm_player_streaming_create ();
+void __mm_player_streaming_initialize (mm_player_streaming_t* streaming_player);
+void __mm_player_streaming_deinitialize (mm_player_streaming_t* streaming_player);
+void __mm_player_streaming_destroy(mm_player_streaming_t* streaming_player);
+
+void __mm_player_streaming_set_buffer(mm_player_streaming_t* streaming_player, GstElement * buffer,
+       gboolean use_buffering, guint buffer_size, gdouble low_percent, gdouble high_percent, gdouble buffering_time,
+       gboolean use_file, gchar * file_path, guint64 content_size);
+void __mm_player_streaming_set_content_bitrate(mm_player_streaming_t* streaming_player, guint max_bitrate, guint avg_bitrate);
+void __mm_player_streaming_buffering (mm_player_streaming_t* streaming_player , GstMessage *buffering_msg);
+
+#endif
diff --git a/src/include/mm_player_utils.h b/src/include/mm_player_utils.h
new file mode 100644 (file)
index 0000000..624df44
--- /dev/null
@@ -0,0 +1,278 @@
+/*
+ * libmm-player
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YeJin Cho <cho.yejin@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>
+ *
+ * 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 __MMF_PLAYER_UTILS_H__
+#define __MMF_PLAYER_UTILS_H__
+
+#include <glib.h>
+#include <gst/gst.h>
+#include <mm_player_ini.h>
+#include <mm_types.h>
+#include <mm_error.h>
+#include <mm_message.h>
+
+#ifdef __cplusplus
+       extern "C" {
+#endif
+
+/* general */
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(arr)                (sizeof(arr) / sizeof((arr)[0]))
+#endif
+
+#define MMPLAYER_MAX_INT       (2147483647)
+
+#define MMPLAYER_FREEIF(x) \
+if ( x ) \
+       g_free( x ); \
+x = NULL;
+
+#define MMPLAYER_CMD_LOCK(x_player) \
+do \
+{ \
+       GMutex* cmd_lock = ((mm_player_t *)x_player)->cmd_lock; \
+       if (cmd_lock) \
+               g_mutex_lock(cmd_lock); \
+       else \
+       { \
+               debug_log("don't get command lock"); \
+               return MM_ERROR_PLAYER_NOT_INITIALIZED; \
+       } \
+} while (0);
+
+#define MMPLAYER_CMD_UNLOCK(x_player)  g_mutex_unlock( ((mm_player_t*)x_player)->cmd_lock )
+
+#define MMPLAYER_MSG_POST_LOCK(x_player)       g_mutex_lock( ((mm_player_t*)x_player)->msg_cb_lock )
+#define MMPLAYER_MSG_POST_UNLOCK(x_player)     g_mutex_unlock( ((mm_player_t*)x_player)->msg_cb_lock )
+
+#define MMPLAYER_GET_ATTRS(x_player)           ((mm_player_t*)x_player)->attrs
+
+/* sbs : for bluetooth */
+#define MAX_SOUND_DEVICE_LEN   18      
+
+/* element linking */
+#ifdef GST_EXT_PAD_LINK_UNCHECKED
+#define GST_ELEMENT_LINK_FILTERED      gst_element_link_filtered_unchecked
+#define GST_ELEMENT_LINK_MANY          gst_element_link_many_unchecked
+#define GST_ELEMENT_LINK                       gst_element_link_unchecked
+#define GST_ELEMENT_LINK_PADS          gst_element_link_pads_unchecked
+#define GST_PAD_LINK                           gst_pad_link_unchecked
+#else
+#define GST_ELEMENT_LINK_FILTERED      gst_element_link_filtered
+#define GST_ELEMENT_LINK_MANY          gst_element_link_many
+#define GST_ELEMENT_LINK                       gst_element_link
+#define GST_ELEMENT_UNLINK                     gst_element_unlink
+#define GST_ELEMENT_LINK_PADS          gst_element_link_pads
+#define GST_PAD_LINK                           gst_pad_link
+#endif
+
+/* debug caps string */
+#define MMPLAYER_LOG_GST_CAPS_TYPE(x_caps) \
+do \
+{ \
+       gchar* caps_type = NULL; \
+       caps_type = gst_caps_to_string(x_caps); \
+       debug_log ("caps: %s\n", caps_type ); \
+       MMPLAYER_FREEIF (caps_type) \
+} while (0);
+
+/* message posting */
+#define MMPLAYER_POST_MSG( x_player, x_msgtype, x_msg_param ) \
+debug_log("posting %s to application\n", #x_msgtype); \
+__mmplayer_post_message(x_player, x_msgtype, x_msg_param);
+
+/* setting player state */
+#define MMPLAYER_SET_STATE( x_player, x_state ) \
+debug_log("setting state machine to %d\n", x_state); \
+__mmplayer_set_state(x_player, x_state);
+
+
+#define MMPLAYER_CHECK_STATE_RETURN_IF_FAIL( x_player, x_command ) \
+debug_log("checking player state before doing %s\n", #x_command); \
+switch ( __mmplayer_check_state(x_player, x_command) ) \
+{ \
+       case MM_ERROR_PLAYER_INVALID_STATE: \
+               return MM_ERROR_PLAYER_INVALID_STATE; \
+       break; \
+       /* NOTE : for robustness of player. we won't treat it as an error */ \
+       case MM_ERROR_PLAYER_NO_OP: \
+               return MM_ERROR_NONE; \
+       break; \
+       case MM_ERROR_PLAYER_DOING_SEEK: \
+               return MM_ERROR_PLAYER_DOING_SEEK; \
+       default: \
+       break; \
+}
+
+/* setting element state */ 
+#define MMPLAYER_ELEMENT_SET_STATE( x_element, x_state ) \
+debug_log("setting state [%s:%d] to [%s]\n", #x_state, x_state, GST_ELEMENT_NAME( x_element ) ); \
+if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state ( x_element, x_state) ) \
+{ \
+       debug_error("failed to set state %s to %s\n", #x_state, GST_ELEMENT_NAME( x_element )); \
+       goto STATE_CHANGE_FAILED; \
+}
+
+#define MMPLAYER_CHECK_NULL( x_var ) \
+if ( ! x_var ) \
+{ \
+       debug_error("[%s] is NULL\n", #x_var ); \
+       goto ERROR; \
+}
+
+#define MMPLAYER_CHECK_CMD_IF_EXIT( x_player ) \
+if ( x_player->cmd == MMPLAYER_COMMAND_UNREALIZE || x_player->cmd == MMPLAYER_COMMAND_DESTROY ) \
+{ \
+       debug_log("it's exit state...\n");\
+       goto ERROR;  \
+}
+/* volume */
+/* 
+|----|-------|-------|-------|-------|
+|Res. | HFK(7)  |  BT(7)  |  E.J(7)  | SPK(7) |
+|----|-------|-------|-------|-------|
+*/
+
+/* 090424 Fix me : Currently volume is 0~9, so bt volume can be only 0.0 ~ 0.9 */
+#define GET_VOLUME_BT(volume) (volume/10.)
+
+#if 0
+#define GET_VOLUME_SPK(volume) ((volume) & 0x7F)
+#define GET_VOLUME_EARJACK(volume) ((volume >> 7)& 0x7F)
+#define GET_VOLUME_HFK(volume) ((volume >> 21) & 0x7F)
+
+#define SET_VOLUME_SPK(volume,input) (volume |= (input &0x7F))
+#define SET_VOLUME_EARJACK(volume,input) (volume |= ((input & 0x7F)<<7))
+#define SET_VOLUME_BT(volume,input) (volume |= ((input & 0x7F)<<14))
+#define SET_VOLUME_HFK(volume,input) (volume |= ((input & 0x7F)<<21))
+#endif
+
+
+/* pad probe for pipeilne debugging */
+gboolean __util_gst_pad_probe(GstPad *pad, GstBuffer *buffer, gpointer u_data);
+
+#define MM_PROBE_DEFAULT                       (0)
+#define MM_PROBE_TIMESTAMP                     (1)
+#define MM_PROBE_BUFFERSIZE                    (1 << 1)
+#define MM_PROBE_CAPS                          (1 << 2)
+#define MM_PROBE_BUFFER_DURATION       (1 << 3)
+#define MM_PROBE_DROP_BUFFER           (1 << 4)
+#define MM_PROBE_CLOCK_TIME                    (1 << 5)
+/* ... add more */
+
+/* messages are treated as warnings bcz those code should not be checked in. 
+ * and no error handling will supported for same manner. 
+ */
+#define MMPLAYER_ADD_PROBE(x_pad, x_flag) \
+debug_warning("adding pad probe\n"); \
+if ( ! gst_pad_add_buffer_probe(x_pad, \
+       G_CALLBACK(__util_gst_pad_probe), \
+       (gpointer)x_flag) ) \
+{ \
+       debug_error("failed to add pad probe\n"); \
+}
+
+
+/* generating dot */
+#define MMPLAYER_GENERATE_DOT_IF_ENABLED( x_player, x_name ) \
+if ( PLAYER_INI()->generate_dot ) \
+{ \
+       debug_log("generating dot file(%s)\n", #x_name); \
+       GST_DEBUG_BIN_TO_DOT_FILE (GST_BIN (player->pipeline->mainbin[MMPLAYER_M_PIPE].gst), \
+       GST_DEBUG_GRAPH_SHOW_ALL, x_name); \
+}
+
+/* signal manipulation */
+#define MMPLAYER_SIGNAL_CONNECT( x_player, x_object, x_signal, x_callback, x_arg ) \
+do \
+{ \
+       MMPlayerSignalItem* item = NULL; \
+       item = (MMPlayerSignalItem*) g_malloc( sizeof (MMPlayerSignalItem) ); \
+       if ( ! item ) \
+       { \
+               debug_error("cannot connect signal [%s]\n", x_signal ); \
+       } \
+       else \
+       { \
+               item->obj = G_OBJECT( x_object ); \
+               item->sig = g_signal_connect( G_OBJECT(x_object), x_signal, \
+                                       x_callback, x_arg ); \
+               x_player->signals = g_list_append(x_player->signals, item); \
+       } \
+} while ( 0 );
+
+
+/* state */
+#define        MMPLAYER_PREV_STATE(x_player)           ((mm_player_t*)x_player)->prev_state 
+#define        MMPLAYER_CURRENT_STATE(x_player)                ((mm_player_t*)x_player)->state 
+#define        MMPLAYER_PENDING_STATE(x_player)                ((mm_player_t*)x_player)->pending_state 
+#define        MMPLAYER_TARGET_STATE(x_player)         ((mm_player_t*)x_player)->target_state 
+#define        MMPLAYER_STATE_GET_NAME(state) __get_state_name(state)
+
+#define        MMPLAYER_PRINT_STATE(x_player) \
+debug_log("-----------------------PLAYER STATE-------------------------\n"); \
+debug_log(" prev %s, current %s, pending %s, target %s \n", \
+       MMPLAYER_STATE_GET_NAME(MMPLAYER_PREV_STATE(x_player)), \
+       MMPLAYER_STATE_GET_NAME(MMPLAYER_CURRENT_STATE(x_player)), \
+       MMPLAYER_STATE_GET_NAME(MMPLAYER_PENDING_STATE(x_player)), \
+       MMPLAYER_STATE_GET_NAME(MMPLAYER_TARGET_STATE(x_player))); \
+debug_log("------------------------------------------------------------\n"); 
+
+
+#define        MMPLAYER_STATE_CHANGE_TIMEOUT(x_player )         ((mm_player_t*)x_player)->state_change_timeout 
+
+/* streaming */
+#define MMPLAYER_IS_STREAMING(x_player)                        __is_streaming(x_player)
+#define MMPLAYER_IS_RTSP_STREAMING(x_player)   __is_rtsp_streaming(x_player)
+#define MMPLAYER_IS_HTTP_STREAMING(x_player)   __is_http_streaming(x_player)
+#define MMPLAYER_IS_HTTP_PD(x_player)                  __is_http_progressive_down(x_player)
+#define MMPLAYER_IS_HTTP_LIVE_STREAMING(x_player)  __is_http_live_streaming(x_player)
+#define MMPLAYER_IS_LIVE_STREAMING(x_player)   __is_live_streaming(x_player)
+
+/* etc */
+#define        MMF_PLAYER_FILE_BACKUP_PATH             "/tmp/media_temp."
+#define        MMPLAYER_PT_IS_AUDIO( x_pt )            ( strstr(x_pt, "_97") || strstr(x_pt, "audio") )
+#define        MMPLAYER_PT_IS_VIDEO( x_pt )            ( strstr(x_pt, "_96") || strstr(x_pt, "video") )
+
+bool util_is_sdp_file ( const char *path );
+int64_t uti_get_time ( void );
+int util_get_rank_increase ( const char *factory_class );
+int util_factory_rank_compare(GstPluginFeature *f1, GstPluginFeature *f2); // @
+
+
+bool util_exist_file_path(const char *file_path);
+bool util_write_file_backup(const char *backup_path, char *data_ptr, int data_size);
+bool util_remove_file_backup(const char *backup_path); /* For Midi Player */
+
+int util_is_midi_type_by_mem(void *mem, int size);
+int util_is_midi_type_by_file(const char *file_path);
+
+char** util_get_cookie_list ( const char *cookies );
+bool util_check_valid_url ( const char *proxy );
+
+char* util_get_charset(const char *file_path);
+
+#ifdef __cplusplus
+       }
+#endif
+
+#endif /* __MMF_PLAYER_UTILS_H__ */
+
diff --git a/src/mm_player.c b/src/mm_player.c
new file mode 100644 (file)
index 0000000..e50fefb
--- /dev/null
@@ -0,0 +1,815 @@
+/*
+ * libmm-player
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YeJin Cho <cho.yejin@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>
+ *
+ * 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 <string.h>
+
+#include <mm_types.h>
+#include <mm_message.h>
+
+#include "mm_player.h"
+#include "mm_player_priv.h"
+#include "mm_player_attrs.h"
+#include "mm_player_utils.h"
+#include "mm_player_ini.h"
+#include "mm_debug.h"
+#include "mm_player_capture.h"
+
+int mm_player_create(MMHandleType *player)
+{
+       int result = MM_ERROR_NONE;
+       mm_player_t* new_player = NULL;
+
+       debug_log("\n");
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       if (!g_thread_supported ())
+       g_thread_init (NULL);
+
+       MMTA_INIT();
+
+       __ta__("mm_player_ini_load",
+       result = mm_player_ini_load();
+       )
+       if(result != MM_ERROR_NONE)
+               return result;
+
+       __ta__("mm_player_audio_effect_ini_load",
+       result = mm_player_audio_effect_ini_load();
+       )
+       if(result != MM_ERROR_NONE)
+               return result;
+
+       /* alloc player structure */
+       new_player = g_malloc(sizeof(mm_player_t));
+       if ( ! new_player )
+       {
+               debug_critical("Cannot allocate memory for player\n");
+               goto ERROR;
+       }
+       memset(new_player, 0, sizeof(mm_player_t));
+
+       /* create player lock */
+       new_player->cmd_lock = g_mutex_new();
+
+       if ( ! new_player->cmd_lock )
+       {
+               debug_critical("failed to create player lock\n");
+               goto ERROR;
+       }
+
+       /* create msg callback lock */
+       new_player->msg_cb_lock = g_mutex_new();
+
+       if ( ! new_player->msg_cb_lock )
+       {
+               debug_critical("failed to create msg cb lock\n");
+               goto ERROR;
+       }
+       __ta__("[KPI] create media player service",
+       result = _mmplayer_create_player((MMHandleType)new_player);
+       )
+
+       if(result != MM_ERROR_NONE)
+               goto ERROR;
+
+       *player = (MMHandleType)new_player;
+
+       return result;
+
+ERROR:
+
+       if ( new_player )
+       {
+               if (new_player->cmd_lock)
+               {
+                       g_mutex_free(new_player->cmd_lock);
+                       new_player->cmd_lock = NULL;
+               }
+
+               _mmplayer_destroy( (MMHandleType)new_player );
+               MMPLAYER_FREEIF( new_player );
+       }
+
+       *player = (MMHandleType)0;
+       return MM_ERROR_PLAYER_NO_FREE_SPACE; // are you sure?
+}
+
+int  mm_player_destroy(MMHandleType player)
+{
+       int result = MM_ERROR_NONE;
+
+       debug_log("\n");
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       MMPLAYER_CMD_LOCK( player );
+
+       __ta__("[KPI] destroy media player service",
+       result = _mmplayer_destroy(player);
+       )
+
+       MMPLAYER_CMD_UNLOCK( player );
+
+       if (((mm_player_t*)player)->cmd_lock)
+       {
+               g_mutex_free(((mm_player_t*)player)->cmd_lock);
+               ((mm_player_t*)player)->cmd_lock = NULL;
+       }
+
+       memset( (mm_player_t*)player, 0x00, sizeof(mm_player_t) );
+
+       /* free player */
+       g_free( (void*)player );
+
+       MMTA_ACUM_ITEM_SHOW_RESULT_TO(MMTA_SHOW_FILE);
+
+       MMTA_RELEASE();
+
+       return result;
+}
+
+
+int mm_player_realize(MMHandleType player)
+{
+       int result = MM_ERROR_NONE;
+
+       debug_log("\n");
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       MMPLAYER_CMD_LOCK( player );
+
+       __ta__("[KPI] initialize media player service",
+       result = _mmplayer_realize(player);
+       )
+
+       MMPLAYER_CMD_UNLOCK( player );
+
+       return result;
+}
+
+
+int mm_player_unrealize(MMHandleType player)
+{
+       int result = MM_ERROR_NONE;
+
+       debug_log("\n");
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       MMPLAYER_CMD_LOCK( player );
+
+       __ta__("[KPI] cleanup media player service",
+       result = _mmplayer_unrealize(player);
+       )
+
+       MMPLAYER_CMD_UNLOCK( player );
+
+       return result;
+}
+
+
+int mm_player_set_message_callback(MMHandleType player, MMMessageCallback callback, void *user_param)
+{
+       int result = MM_ERROR_NONE;
+
+       debug_log("\n");
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       MMPLAYER_CMD_LOCK( player );
+
+       result = _mmplayer_set_message_callback(player, callback, user_param);
+
+       MMPLAYER_CMD_UNLOCK( player );
+
+       return result;
+}
+
+int mm_player_set_pd_message_callback(MMHandleType player, MMMessageCallback callback, void *user_param)
+{
+       int result = MM_ERROR_NONE;
+
+       debug_log("\n");
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       result = _mm_player_set_pd_downloader_message_cb(player, callback, user_param);
+
+       return result;
+}
+
+int mm_player_set_audio_stream_callback(MMHandleType player, mm_player_audio_stream_callback callback, void *user_param)
+{
+       int result = MM_ERROR_NONE;
+
+       debug_log("\n");
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       MMPLAYER_CMD_LOCK( player );
+
+       result = _mmplayer_set_audiostream_cb(player, callback, user_param);
+
+       MMPLAYER_CMD_UNLOCK( player );
+
+       return result;
+}
+
+
+int mm_player_set_audio_buffer_callback(MMHandleType player, mm_player_audio_stream_callback callback, void *user_param)
+{
+       int result = MM_ERROR_NONE;
+
+       debug_log("\n");
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       MMPLAYER_CMD_LOCK( player );
+
+       result = _mmplayer_set_audiobuffer_cb(player, callback, user_param);
+
+       MMPLAYER_CMD_UNLOCK( player );
+
+       return result;
+}
+
+int mm_player_set_video_stream_callback(MMHandleType player, mm_player_video_stream_callback callback, void *user_param)
+{
+       int result = MM_ERROR_NONE;
+
+       debug_log("\n");
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       MMPLAYER_CMD_LOCK( player );
+
+    result = _mmplayer_set_videostream_cb(player, callback, user_param);
+
+       MMPLAYER_CMD_UNLOCK( player );
+
+       return result;
+}
+
+int mm_player_set_video_frame_render_error_callback(MMHandleType player, mm_player_video_frame_render_error_callback callback, void *user_param)
+{
+       int result = MM_ERROR_NONE;
+
+       debug_log("\n");
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       MMPLAYER_CMD_LOCK( player );
+
+       result = _mmplayer_set_videoframe_render_error_cb(player, callback, user_param);
+
+       MMPLAYER_CMD_UNLOCK( player );
+
+       return result;
+}
+
+int mm_player_do_video_capture(MMHandleType player)
+{
+       int result = MM_ERROR_NONE;
+
+       debug_log("\n");
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       MMPLAYER_CMD_LOCK( player );
+
+       result = _mmplayer_do_video_capture(player);
+
+       MMPLAYER_CMD_UNLOCK( player );
+
+       return result;
+}
+
+int mm_player_set_buffer_need_data_callback(MMHandleType player, mm_player_buffer_need_data_callback callback, void * user_param)
+{
+       int result = MM_ERROR_NONE;
+
+       debug_log("\n");
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       MMPLAYER_CMD_LOCK( player );
+
+    result = _mmplayer_set_buffer_need_data_cb(player, callback, user_param);
+
+       MMPLAYER_CMD_UNLOCK( player );
+
+       return result;
+}
+
+
+int mm_player_set_buffer_enough_data_callback(MMHandleType player, mm_player_buffer_enough_data_callback callback, void * user_param)
+{
+       int result = MM_ERROR_NONE;
+
+       debug_log("\n");
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       MMPLAYER_CMD_LOCK( player );
+
+    result = _mmplayer_set_buffer_enough_data_cb(player, callback, user_param);
+
+       MMPLAYER_CMD_UNLOCK( player );
+
+       return result;
+}
+
+
+int mm_player_set_buffer_seek_data_callback(MMHandleType player, mm_player_buffer_seek_data_callback callback, void * user_param)
+{
+       int result = MM_ERROR_NONE;
+
+       debug_log("\n");
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       MMPLAYER_CMD_LOCK( player );
+
+    result = _mmplayer_set_buffer_seek_data_cb(player, callback, user_param);
+
+       MMPLAYER_CMD_UNLOCK( player );
+
+       return result;
+}
+
+
+int mm_player_set_volume(MMHandleType player, MMPlayerVolumeType *volume)
+{
+       int result = MM_ERROR_NONE;
+
+       debug_log("\n");
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       return_val_if_fail(volume, MM_ERROR_INVALID_ARGUMENT);
+
+       MMPLAYER_CMD_LOCK( player );
+
+       result = _mmplayer_set_volume(player, *volume);
+
+       MMPLAYER_CMD_UNLOCK( player );
+
+       return result;
+}
+
+
+int mm_player_get_volume(MMHandleType player, MMPlayerVolumeType *volume)
+{
+       int result = MM_ERROR_NONE;
+
+       debug_log("\n");
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       return_val_if_fail(volume, MM_ERROR_INVALID_ARGUMENT);
+
+       MMPLAYER_CMD_LOCK( player );
+
+       result = _mmplayer_get_volume(player, volume);
+
+       MMPLAYER_CMD_UNLOCK( player );
+
+       return result;
+}
+
+
+int mm_player_set_mute(MMHandleType player, int mute)
+{
+       int result = MM_ERROR_NONE;
+
+       debug_log("\n");
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       MMPLAYER_CMD_LOCK( player );
+
+       result = _mmplayer_set_mute(player, mute);
+
+       MMPLAYER_CMD_UNLOCK( player );
+
+       return result;
+}
+
+
+int mm_player_get_mute(MMHandleType player, int *mute)
+{
+       int result = MM_ERROR_NONE;
+
+       debug_log("\n");
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       return_val_if_fail(mute, MM_ERROR_INVALID_ARGUMENT);
+
+       MMPLAYER_CMD_LOCK( player );
+
+       result = _mmplayer_get_mute(player, mute);
+
+       MMPLAYER_CMD_UNLOCK( player );
+
+       return result;
+}
+
+
+int mm_player_get_state(MMHandleType player, MMPlayerStateType *state)
+{
+       int result = MM_ERROR_NONE;
+
+       debug_log("\n");
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       return_val_if_fail(state, MM_ERROR_COMMON_INVALID_ARGUMENT);
+
+       *state = MM_PLAYER_STATE_NULL;
+
+       result = _mmplayer_get_state(player, (int*)state);
+
+       return result;
+}
+
+/* NOTE : Not supported */
+int mm_player_change_videosink(MMHandleType player, MMDisplaySurfaceType display_surface_type, void *display_overlay)
+{
+       int result = MM_ERROR_NONE;
+
+       debug_log("\n");
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       return MM_ERROR_NOT_SUPPORT_API;
+}
+
+int mm_player_push_buffer(MMHandleType player, unsigned char *buf, int size)
+{
+       int result = MM_ERROR_NONE;
+
+       debug_log("\n");
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       //MMPLAYER_CMD_LOCK( player );
+
+       //MMTA_ACUM_ITEM_BEGIN("[KPI] start media player service", false);
+       result = _mmplayer_push_buffer(player, buf, size);
+
+       //MMPLAYER_CMD_UNLOCK( player );
+
+       return result;
+}
+
+
+int mm_player_start(MMHandleType player)
+{
+       int result = MM_ERROR_NONE;
+
+       debug_log("\n");
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       MMPLAYER_CMD_LOCK( player );
+
+       MMTA_ACUM_ITEM_BEGIN("[KPI] start media player service", false);
+       result = _mmplayer_start(player);
+
+       MMPLAYER_CMD_UNLOCK( player );
+
+       return result;
+}
+
+
+int  mm_player_stop(MMHandleType player)
+{
+       int result = MM_ERROR_NONE;
+
+       debug_log("\n");
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       MMPLAYER_CMD_LOCK( player );
+
+       __ta__("[KPI] stop media player service",
+       result = _mmplayer_stop(player);
+       )
+
+       MMPLAYER_CMD_UNLOCK( player );
+
+       return result;
+}
+
+
+int mm_player_pause(MMHandleType player)
+{
+       int result = MM_ERROR_NONE;
+
+       debug_log("\n");
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       MMPLAYER_CMD_LOCK( player );
+
+       __ta__("[KPI] pause media player service",
+       result = _mmplayer_pause(player);
+       )
+
+       MMPLAYER_CMD_UNLOCK( player );
+
+       return result;
+}
+
+
+int mm_player_resume(MMHandleType player)
+{
+       int result = MM_ERROR_NONE;
+
+       debug_log("\n");
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       MMPLAYER_CMD_LOCK( player );
+
+       __ta__("[KPI] resume media player service",
+       result = _mmplayer_resume(player);
+       )
+
+       MMPLAYER_CMD_UNLOCK( player );
+
+       return result;
+}
+
+
+int mm_player_activate_section_repeat(MMHandleType player, int start_pos, int end_pos)
+{
+       int result = MM_ERROR_NONE;
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       MMPLAYER_CMD_LOCK( player );
+
+       result = _mmplayer_activate_section_repeat(player, start_pos, end_pos);
+
+       MMPLAYER_CMD_UNLOCK( player );
+
+       return result;
+}
+
+
+int mm_player_deactivate_section_repeat(MMHandleType player)
+{
+       int result = MM_ERROR_NONE;
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       MMPLAYER_CMD_LOCK( player );
+
+       result = _mmplayer_deactivate_section_repeat(player);
+
+       MMPLAYER_CMD_UNLOCK( player );
+
+       return result;
+}
+
+
+int mm_player_set_play_speed(MMHandleType player, float rate)
+{
+       int result = MM_ERROR_NONE;
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       MMPLAYER_CMD_LOCK( player );
+
+       result = _mmplayer_set_playspeed(player, rate);
+
+       MMPLAYER_CMD_UNLOCK( player );
+
+       return result;
+}
+
+
+int mm_player_set_position(MMHandleType player, MMPlayerPosFormatType format, int pos)
+{
+       int result = MM_ERROR_NONE;
+
+       debug_log("\n");
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       if (format >= MM_PLAYER_POS_FORMAT_NUM)
+       {
+               debug_error("wrong format\n");
+               return MM_ERROR_COMMON_INVALID_ARGUMENT;
+       }
+
+       MMPLAYER_CMD_LOCK( player );
+
+       result = _mmplayer_set_position(player, format, pos);
+
+       MMPLAYER_CMD_UNLOCK( player );
+
+       return result;
+}
+
+
+int mm_player_get_position(MMHandleType player, MMPlayerPosFormatType format, int *pos)
+{
+       int result = MM_ERROR_NONE;
+
+       debug_log("\n");
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       return_val_if_fail(pos, MM_ERROR_COMMON_INVALID_ARGUMENT);
+
+       if (format >= MM_PLAYER_POS_FORMAT_NUM)
+       {
+               debug_error("wrong format\n");
+               return MM_ERROR_COMMON_INVALID_ARGUMENT;
+       }
+
+       MMPLAYER_CMD_LOCK( player );
+
+       result = _mmplayer_get_position(player, (int)format, (unsigned long*)pos);
+
+       MMPLAYER_CMD_UNLOCK( player );
+
+       return result;
+}
+
+int mm_player_get_buffer_position(MMHandleType player, MMPlayerPosFormatType format, int  *start_pos, int  *stop_pos)
+{
+       int result = MM_ERROR_NONE;
+
+       debug_log("\n");
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       return_val_if_fail(start_pos && stop_pos, MM_ERROR_COMMON_INVALID_ARGUMENT);
+
+       MMPLAYER_CMD_LOCK( player );
+
+       result = _mmplayer_get_buffer_position(player, (int)format, (unsigned long*)start_pos, (unsigned long*)stop_pos );
+
+       MMPLAYER_CMD_UNLOCK( player );
+
+       return result;
+}
+
+int mm_player_adjust_subtitle_position(MMHandleType player, MMPlayerPosFormatType format, int pos)
+{
+       int result = MM_ERROR_NONE;
+
+       debug_log("\n");
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       if (format >= MM_PLAYER_POS_FORMAT_NUM)
+       {
+               debug_error("wrong format\n");
+               return MM_ERROR_COMMON_INVALID_ARGUMENT;
+       }
+
+       MMPLAYER_CMD_LOCK( player );
+
+       result = _mmplayer_adjust_subtitle_postion(player, format, pos);
+
+       MMPLAYER_CMD_UNLOCK( player );
+
+       return result;
+}
+
+
+int mm_player_set_subtitle_silent(MMHandleType player, int silent)
+{
+       int result = MM_ERROR_NONE;
+
+       debug_log("\n");
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       MMPLAYER_CMD_LOCK( player );
+
+       result = _mmplayer_set_subtitle_silent(player, silent);
+
+       MMPLAYER_CMD_UNLOCK( player );
+
+       return result;
+}
+
+
+int mm_player_get_subtitle_silent(MMHandleType player, int* silent)
+{
+       int result = MM_ERROR_NONE;
+
+       debug_log("\n");
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       MMPLAYER_CMD_LOCK( player );
+
+       result = _mmplayer_get_subtitle_silent(player, silent);
+
+       MMPLAYER_CMD_UNLOCK( player );
+
+       return result;
+}
+
+
+int mm_player_set_attribute(MMHandleType player,  char **err_attr_name, const char *first_attribute_name, ...)
+{
+       int result = MM_ERROR_NONE;
+       va_list var_args;
+
+       debug_log("\n");
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       return_val_if_fail(first_attribute_name, MM_ERROR_COMMON_INVALID_ARGUMENT);
+
+       va_start (var_args, first_attribute_name);
+       result = _mmplayer_set_attribute(player, err_attr_name, first_attribute_name, var_args);
+       va_end (var_args);
+
+       return result;
+}
+
+
+int mm_player_get_attribute(MMHandleType player,  char **err_attr_name, const char *first_attribute_name, ...)
+{
+       int result = MM_ERROR_NONE;
+       va_list var_args;
+
+       debug_log("\n");
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       return_val_if_fail(first_attribute_name, MM_ERROR_COMMON_INVALID_ARGUMENT);
+
+       va_start (var_args, first_attribute_name);
+       result = _mmplayer_get_attribute(player, err_attr_name, first_attribute_name, var_args);
+       va_end (var_args);
+
+       return result;
+}
+
+
+int mm_player_get_attribute_info(MMHandleType player,  const char *attribute_name, MMPlayerAttrsInfo *info)
+{
+       int result = MM_ERROR_NONE;
+       debug_log("\n");
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       return_val_if_fail(attribute_name, MM_ERROR_COMMON_INVALID_ARGUMENT);
+       return_val_if_fail(info, MM_ERROR_COMMON_INVALID_ARGUMENT);
+
+       result = _mmplayer_get_attributes_info((MMHandleType)player, attribute_name, info);
+
+       return result;
+}
+
+int mm_player_get_pd_status(MMHandleType player, guint64 *current_pos, guint64 *total_size)
+{
+       int result = MM_ERROR_NONE;
+
+       debug_log("\n");
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       return_val_if_fail(current_pos, MM_ERROR_COMMON_INVALID_ARGUMENT);
+       return_val_if_fail(total_size, MM_ERROR_COMMON_INVALID_ARGUMENT);
+
+       result = _mmplayer_get_pd_downloader_status(player, current_pos, total_size);
+
+       return result;
+}
+
+int mm_player_get_track_count(MMHandleType player,  MMPlayerTrackType track_type, int *count)
+{
+       int result = MM_ERROR_NONE;
+
+       debug_log("\n");
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       return_val_if_fail(count, MM_ERROR_COMMON_INVALID_ARGUMENT);
+
+       result = _mmplayer_get_track_count(player, track_type, count);
+
+       return result;
+
+}
diff --git a/src/mm_player_asm.c b/src/mm_player_asm.c
new file mode 100644 (file)
index 0000000..e607806
--- /dev/null
@@ -0,0 +1,247 @@
+/*
+ * libmm-player
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YeJin Cho <cho.yejin@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>
+ *
+ * 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 <glib.h>
+#include <mm_debug.h>
+#include "mm_player_priv.h"
+#include "mm_player_asm.h"
+
+static ASM_sound_events_t __mmplayer_asm_get_event_type(gint type);
+
+gint
+_mmplayer_asm_register(MMPlayerASM* sm, ASM_sound_cb_t callback, void* param)
+{
+       /* read mm-session type */
+       gint sessionType = MM_SESSION_TYPE_SHARE;
+       gint errorcode = MM_ERROR_NONE;
+       gint asm_handle = -1;
+       gint event_type = ASM_EVENT_NONE;
+       gint pid = -1;
+
+       debug_log("\n");
+
+       if ( ! sm )
+       {
+               debug_error("invalid session handle\n");
+               return MM_ERROR_PLAYER_NOT_INITIALIZED;
+       }
+
+       /* check if it's running on the media_server */
+       if ( sm->pid > 0 )
+       {
+               pid = sm->pid;
+               debug_log("mm-player is running on different process. Just faking pid to [%d]. :-p\n", pid);
+       }
+       else
+       {
+               debug_log("no pid has assigned. using default(current) context\n");
+       }
+
+       /* read session type */
+       errorcode = _mm_session_util_read_type(pid, &sessionType);
+       if ( errorcode )
+       {
+               debug_warning("Read MMSession Type failed. use default \"share\" type\n");
+               sessionType = MM_SESSION_TYPE_SHARE;
+
+               /* init session */
+               errorcode = mm_session_init(sessionType);
+               if ( errorcode )
+               {
+                               debug_critical("mm_session_init() failed\n");
+                               return errorcode;
+               }
+       }
+
+       /* check if it's CALL */
+       if ( sessionType == MM_SESSION_TYPE_CALL )
+       {
+               debug_log("session type is CALL\n");
+               sm->event = ASM_EVENT_CALL;
+               return MM_ERROR_NONE;
+       }
+       else if ( sessionType == MM_SESSION_TYPE_VIDEOCALL )
+       {
+               debug_log("session type is VIDEOCALL\n");
+               sm->event = ASM_EVENT_VIDEOCALL;
+               return MM_ERROR_NONE;
+       }
+
+       /* interpret session type */
+       event_type = __mmplayer_asm_get_event_type(sessionType);
+
+
+
+       /* register audio-session-manager callback */
+       if( ! ASM_register_sound(pid, &asm_handle, event_type, ASM_STATE_NONE, callback, (void*)param, ASM_RESOURCE_NONE, &errorcode))
+       {
+               debug_critical("ASM_register_sound() failed\n");
+               return errorcode;
+       }
+
+       /* now succeed to register our callback. take result */
+       sm->handle = asm_handle;
+       sm->state = ASM_STATE_NONE;
+       sm->event = event_type;
+
+       return MM_ERROR_NONE;
+}
+
+gint
+_mmplayer_asm_deregister(MMPlayerASM* sm)
+{
+       gint event_type = ASM_EVENT_NONE;
+       gint errorcode = 0;
+       gint pid = -1;
+
+       if ( ! sm )
+       {
+               debug_error("invalid session handle\n");
+               return MM_ERROR_PLAYER_NOT_INITIALIZED;
+       }
+
+       /* check if it's running on the media_server */
+       if ( sm->pid > 0 )
+       {
+               pid = sm->pid;
+               debug_log("mm-player is running on different process. Just faking pid to [%d]. :-p\n", pid);
+       }
+       else
+       {
+               debug_log("no pid has assigned. using default(current) context\n");
+       }
+
+       /* check if it's CALL */
+       if(sm->event == ASM_EVENT_CALL || sm->event == ASM_EVENT_VIDEOCALL)
+       {
+               debug_log("session type is VOICE or VIDEO CALL (%d)\n", sm->event); 
+               return MM_ERROR_NONE;
+       }
+       event_type = sm->event;
+
+       if( ! ASM_unregister_sound( sm->handle, event_type, &errorcode) )
+       {
+               debug_error("Unregister sound failed 0x%X\n", errorcode);
+               return MM_ERROR_POLICY_INTERNAL;
+       }
+
+       return MM_ERROR_NONE;
+}
+
+gint _mmplayer_asm_set_state(MMHandleType hplayer, ASM_sound_states_t state)
+{
+       gint event_type = ASM_EVENT_NONE;
+       gint pid = -1;
+       ASM_resource_t resource = ASM_RESOURCE_NONE;
+       mm_player_t *player = (mm_player_t *)hplayer;
+       MMPlayerASM* sm  = &player->sm;
+
+       if ( ! sm )
+       {
+               debug_error("invalid session handle\n");
+               return MM_ERROR_PLAYER_NOT_INITIALIZED;
+       }
+
+       /* check if it's running on the media_server */
+       if ( sm->pid > 0 )
+       {
+               pid = sm->pid;
+               debug_log("mm-player is running on different process. Just faking pid to [%d]. :-p\n", pid);
+       }
+       else
+       {
+               debug_log("no pid has assigned. using default(current) context\n");
+       }
+
+       /* check if it's CALL */
+       if(sm->event == ASM_EVENT_CALL || sm->event == ASM_EVENT_VIDEOCALL)
+       {
+               debug_log("session type is VOICE or VIDEO CALL (%d)\n", sm->event); 
+               return MM_ERROR_NONE;
+       }
+
+
+       if ( ! sm->by_asm_cb )//|| sm->state == ASM_STATE_PLAYING )
+       {
+               int ret = 0;
+               event_type = sm->event;
+
+               /* check if there is video */
+               /* NOTE: resource can be set as NONE when it's not occupied or unknown resource is used. */
+               if(ASM_STATE_PLAYING == state || ASM_STATE_PAUSE == state)
+               {
+                       if(player->pipeline && player->pipeline->videobin)
+                               resource = ASM_RESOURCE_VIDEO_OVERLAY | ASM_RESOURCE_HW_DECODER;
+               }
+
+               if( ! ASM_set_sound_state( sm->handle, event_type, state, resource, &ret) )
+               {
+                       debug_error("Set state to [%d] failed 0x%X\n", state, ret);
+                       return MM_ERROR_POLICY_BLOCKED;
+               }
+
+               sm->state = state;
+       }
+       else
+       {
+               sm->by_asm_cb = 0;
+               sm->state = state;
+       }
+
+       return MM_ERROR_NONE;
+}
+
+static ASM_sound_events_t
+__mmplayer_asm_get_event_type(gint type)
+{
+       gint event_type = ASM_EVENT_NONE;
+
+       /* interpret session type */
+               switch(type)
+               {
+                       case MM_SESSION_TYPE_SHARE:
+                               event_type = ASM_EVENT_SHARE_MMPLAYER;
+                       break;
+
+                       case MM_SESSION_TYPE_EXCLUSIVE:
+                               event_type = ASM_EVENT_EXCLUSIVE_MMPLAYER;
+                       break;
+
+                       case MM_SESSION_TYPE_NOTIFY:
+                               event_type = ASM_EVENT_NOTIFY;
+                       break;
+                       
+                       case MM_SESSION_TYPE_ALARM:
+                               event_type = ASM_EVENT_ALARM;
+                       break;
+
+                       case MM_SESSION_TYPE_EMERGENCY:
+                               event_type = ASM_EVENT_EMERGENCY;
+                       break;
+
+                       default:
+                               debug_critical("unexpected case!\n");
+                               event_type = ASM_EVENT_SHARE_MMPLAYER;
+                       break;
+               }
+
+               return event_type;
+}
diff --git a/src/mm_player_attrs.c b/src/mm_player_attrs.c
new file mode 100644 (file)
index 0000000..1d511d5
--- /dev/null
@@ -0,0 +1,1038 @@
+/*
+ * libmm-player
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YeJin Cho <cho.yejin@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>
+ *
+ * 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 FILES                                                                                                                                                       |
+|                                                                                                                                                                                      |
+========================================================================================== */
+#include <vconf.h>
+#include <mm_attrs_private.h>
+#include <mm_attrs.h>
+#include <gst/interfaces/xoverlay.h>
+
+#include "mm_player_priv.h"
+#include "mm_player_attrs.h"
+
+/*===========================================================================================
+|                                                                                                                                                                                      |
+|  LOCAL DEFINITIONS AND DECLARATIONS FOR MODULE                                                                                       |
+|                                                                                                                                                                                      |
+========================================================================================== */
+
+typedef struct{
+       char *name;
+       int value_type;
+       int flags;                              // r, w
+       void *default_value;
+       int valid_type;                 // validity type
+       int value_min;                  //<- set validity value range
+       int value_max;          //->
+}MMPlayerAttrsSpec;
+
+/*---------------------------------------------------------------------------
+|    LOCAL FUNCTION PROTOTYPES:                                                                                                |
+---------------------------------------------------------------------------*/
+int
+__mmplayer_apply_attribute(MMHandleType handle, const char *attribute_name);
+
+/*===========================================================================================
+|                                                                                                                                                                                                              |
+|  FUNCTION DEFINITIONS                                                                                                                                                                        |
+|                                                                                                                                                                                                              |
+========================================================================================== */
+
+int
+_mmplayer_get_attribute(MMHandleType handle,  char **err_attr_name, const char *attribute_name, va_list args_list)
+{
+       int result = MM_ERROR_NONE;
+       MMHandleType attrs = 0;
+
+       debug_fenter();
+
+       /* NOTE : Don't need to check err_attr_name because it can be set NULL */
+       /* if it's not want to know it. */
+       return_val_if_fail(attribute_name, MM_ERROR_COMMON_INVALID_ARGUMENT);
+       return_val_if_fail(handle, MM_ERROR_COMMON_INVALID_ARGUMENT);
+
+       attrs = MM_PLAYER_GET_ATTRS(handle);
+
+       result = mm_attrs_get_valist(attrs, err_attr_name, attribute_name, args_list);
+
+       if ( result != MM_ERROR_NONE)
+               debug_error("failed to get %s attribute\n", attribute_name);
+
+       debug_fleave();
+
+       return result;
+}
+
+int
+_mmplayer_set_attribute(MMHandleType handle,  char **err_attr_name, const char *attribute_name, va_list args_list)
+{
+       int result = MM_ERROR_NONE;
+       MMHandleType attrs = 0;
+
+       debug_fenter();
+
+       /* NOTE : Don't need to check err_attr_name because it can be set NULL */
+       /* if it's not want to know it. */
+       return_val_if_fail(attribute_name, MM_ERROR_COMMON_INVALID_ARGUMENT);
+       return_val_if_fail(handle, MM_ERROR_COMMON_INVALID_ARGUMENT);
+
+       attrs = MM_PLAYER_GET_ATTRS(handle);
+
+       /* set attributes and commit them */
+       result = mm_attrs_set_valist(attrs, err_attr_name, attribute_name, args_list);
+
+       if (result != MM_ERROR_NONE)
+       {
+               debug_error("failed to set %s attribute\n", attribute_name);
+               return result;
+       }
+
+       result = __mmplayer_apply_attribute(handle, attribute_name);
+       if (result != MM_ERROR_NONE)
+       {
+               debug_error("failed to apply attributes\n");
+               return result;
+       }
+
+       debug_fleave();
+
+       return result;
+}
+
+int
+_mmplayer_get_attributes_info(MMHandleType handle,  const char *attribute_name, MMPlayerAttrsInfo *dst_info)
+{
+       int result = MM_ERROR_NONE;
+       MMHandleType attrs = 0;
+       MMAttrsInfo src_info = {0, };
+
+       debug_fenter();
+
+       return_val_if_fail(attribute_name, MM_ERROR_COMMON_INVALID_ARGUMENT);
+       return_val_if_fail(dst_info, MM_ERROR_COMMON_INVALID_ARGUMENT);
+       return_val_if_fail(handle, MM_ERROR_COMMON_INVALID_ARGUMENT);
+
+       attrs = MM_PLAYER_GET_ATTRS(handle);
+
+       result = mm_attrs_get_info_by_name(attrs, attribute_name, &src_info);
+
+       if ( result != MM_ERROR_NONE)
+       {
+               debug_error("failed to get attribute info\n");
+               return result;
+       }
+
+       memset(dst_info, 0x00, sizeof(MMPlayerAttrsInfo));
+
+       dst_info->type = src_info.type;
+       dst_info->flag = src_info.flag;
+       dst_info->validity_type= src_info.validity_type;
+
+       switch(src_info.validity_type)
+       {
+               case MM_ATTRS_VALID_TYPE_INT_ARRAY:
+                       dst_info->int_array.array = src_info.int_array.array;
+                       dst_info->int_array.count = src_info.int_array.count;
+                       dst_info->int_array.d_val = src_info.int_array.dval;
+               break;
+
+               case MM_ATTRS_VALID_TYPE_INT_RANGE:
+                       dst_info->int_range.min = src_info.int_range.min;
+                       dst_info->int_range.max = src_info.int_range.max;
+                       dst_info->int_range.d_val = src_info.int_range.dval;
+               break;
+
+               case MM_ATTRS_VALID_TYPE_DOUBLE_ARRAY:
+                       dst_info->double_array.array = src_info.double_array.array;
+                       dst_info->double_array.count = src_info.double_array.count;
+                       dst_info->double_array.d_val = src_info.double_array.dval;
+               break;
+
+               case MM_ATTRS_VALID_TYPE_DOUBLE_RANGE:
+                       dst_info->double_range.min = src_info.double_range.min;
+                       dst_info->double_range.max = src_info.double_range.max;
+                       dst_info->double_range.d_val = src_info.double_range.dval;
+               break;
+
+               default:
+               break;
+       }
+
+       debug_fleave();
+
+       return result;
+}
+
+int
+__mmplayer_apply_attribute(MMHandleType handle, const char *attribute_name)
+{
+       MMHandleType attrs = 0;
+       mm_player_t* player = 0;
+
+       debug_fenter();
+
+       return_val_if_fail(handle, MM_ERROR_COMMON_INVALID_ARGUMENT);
+       return_val_if_fail(attribute_name, MM_ERROR_COMMON_INVALID_ARGUMENT);
+
+       attrs = MM_PLAYER_GET_ATTRS(handle);
+       player = MM_PLAYER_CAST(handle);
+
+       if ( g_strrstr(attribute_name, "display") )
+       {
+               /* check videosink element is created */
+               if ( !player->pipeline ||
+                        !player->pipeline->videobin ||
+                        !player->pipeline->videobin[MMPLAYER_V_SINK].gst )
+               {
+                       debug_warning("videosink element is not yet ready");
+                       /*
+                        * The attribute should be committed even though videobin is not created yet.
+                        * So, true should be returned here.
+                        * Otherwise, video can be diaplayed abnormal.
+                        */
+                       return MM_ERROR_NONE;
+               }
+
+               if ( MM_ERROR_NONE != _mmplayer_update_video_param( player ) )
+               {
+                       debug_error("failed to update video param");
+                       return MM_ERROR_PLAYER_INTERNAL;
+               }
+       }
+
+       debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+MMHandleType
+_mmplayer_construct_attribute(MMHandleType handle)
+{
+       int idx = 0;
+       MMHandleType attrs = 0;
+       int num_of_attrs = 0;
+       mmf_attrs_construct_info_t *base = NULL;
+       gchar *system_ua = NULL;
+       gchar *system_proxy = NULL;
+
+       debug_fenter();
+
+       return_val_if_fail (handle, 0);
+
+       MMPlayerAttrsSpec player_attrs[] =
+       {
+               {
+                       "profile_uri",                  // name
+                       MM_ATTRS_TYPE_STRING,           // type
+                       MM_ATTRS_FLAG_RW,               // flag
+                       (void *) NULL,                  // default value
+                       MM_ATTRS_VALID_TYPE_NONE,       // validity type
+                       0,                              // validity min value
+                       0                               // validity max value
+               },
+               {
+                       "profile_user_param",
+                       MM_ATTRS_TYPE_DATA,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) NULL,
+                       MM_ATTRS_VALID_TYPE_NONE,
+                       0,
+                       0
+               },
+               {
+                       "profile_play_count",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 1,                     // -1 : repeat continually
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       -1,
+                       MMPLAYER_MAX_INT
+               },
+               {
+                       "profile_prepare_async",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       1
+               },
+               {       /* update registry for downloadable codec */
+                       "profile_update_registry",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       1
+               },
+               {
+                       "streaming_type",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) STREAMING_SERVICE_NONE,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       STREAMING_SERVICE_VOD,
+                       STREAMING_SERVICE_NUM
+               },
+               {
+                       "streaming_udp_timeout",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 10000,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       MMPLAYER_MAX_INT
+               },
+               {
+                       "streaming_user_agent",
+                       MM_ATTRS_TYPE_STRING,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) NULL,
+                       MM_ATTRS_VALID_TYPE_NONE,
+                       0,
+                       0
+               },
+               {
+                       "streaming_wap_profile",
+                       MM_ATTRS_TYPE_STRING,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) NULL,
+                       MM_ATTRS_VALID_TYPE_NONE,
+                       0,
+                       0
+               },
+               {
+                       "streaming_network_bandwidth",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 128000,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       MMPLAYER_MAX_INT
+               },
+               {
+                       "streaming_cookie",
+                       MM_ATTRS_TYPE_STRING,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) NULL,
+                       MM_ATTRS_VALID_TYPE_NONE,
+                       0,
+                       0
+               },
+               {
+                       "streaming_proxy",
+                       MM_ATTRS_TYPE_STRING,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) NULL,
+                       MM_ATTRS_VALID_TYPE_NONE,
+                       0,
+                       0
+               },
+               {
+                       "subtitle_uri",
+                       MM_ATTRS_TYPE_STRING,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) NULL,
+                       MM_ATTRS_VALID_TYPE_NONE,
+                       0,
+                       0
+               },
+               {
+                       "content_duration",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       MMPLAYER_MAX_INT
+               },
+               {
+                       "content_bitrate",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       MMPLAYER_MAX_INT
+               },
+               {
+                       "content_max_bitrate",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       MMPLAYER_MAX_INT
+               },
+               {
+                       "content_video_found",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       1
+               },
+               {
+                       "content_video_codec",
+                       MM_ATTRS_TYPE_STRING,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) NULL,
+                       MM_ATTRS_VALID_TYPE_NONE,
+                       0,
+                       0
+               },
+               {
+                       "content_video_bitrate",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       MMPLAYER_MAX_INT
+               },
+               {
+                       "content_video_fps",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       MMPLAYER_MAX_INT
+               },
+               {
+                       "content_video_width",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       MMPLAYER_MAX_INT
+               },
+               {
+                       "content_video_height",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       MMPLAYER_MAX_INT
+               },
+               {
+                       "content_video_track_num",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       MMPLAYER_MAX_INT
+               },
+               {
+                       "content_audio_found",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       1
+               },
+               {
+                       "content_audio_codec",
+                       MM_ATTRS_TYPE_STRING,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) NULL,
+                       MM_ATTRS_VALID_TYPE_NONE,
+                       0,
+                       0
+               },
+               {
+                       "content_audio_bitrate",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       MMPLAYER_MAX_INT
+               },
+               {
+                       "content_audio_channels",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       MMPLAYER_MAX_INT
+               },
+               {
+                       "content_audio_samplerate",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       MMPLAYER_MAX_INT
+               },
+               {
+                       "content_audio_track_num",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       MMPLAYER_MAX_INT
+               },
+               {
+                       "content_audio_format",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       MMPLAYER_MAX_INT
+               },
+               {
+                       "tag_artist",
+                       MM_ATTRS_TYPE_STRING,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) NULL,
+                       MM_ATTRS_VALID_TYPE_NONE,
+                       0,
+                       0
+               },
+               {
+                       "tag_title",
+                       MM_ATTRS_TYPE_STRING,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) NULL,
+                       MM_ATTRS_VALID_TYPE_NONE,
+                       0,
+                       0
+               },
+               {
+                       "tag_album",
+                       MM_ATTRS_TYPE_STRING,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) NULL
+               },
+               {
+                       "tag_genre",
+                       MM_ATTRS_TYPE_STRING,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) NULL,
+                       MM_ATTRS_VALID_TYPE_NONE,
+                       0,
+                       0
+               },
+               {
+                       "tag_author",
+                       MM_ATTRS_TYPE_STRING,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) NULL,
+                       MM_ATTRS_VALID_TYPE_NONE,
+                       0,
+                       0
+               },
+               {
+                       "tag_copyright",
+                       MM_ATTRS_TYPE_STRING,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) NULL,
+                       MM_ATTRS_VALID_TYPE_NONE,
+                       0,
+                       0
+               },
+               {
+                       "tag_date",
+                       MM_ATTRS_TYPE_STRING,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) NULL,
+                       MM_ATTRS_VALID_TYPE_NONE,
+                       0,
+                       0
+               },
+               {
+                       "tag_description",
+                       MM_ATTRS_TYPE_STRING,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) NULL,
+                       MM_ATTRS_VALID_TYPE_NONE,
+                       0,
+                       0
+               },
+               {
+                       "tag_track_num",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       MMPLAYER_MAX_INT
+               },
+               {
+                       "tag_album_cover",
+                       MM_ATTRS_TYPE_DATA,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) NULL,
+                       MM_ATTRS_VALID_TYPE_NONE,
+                       0,
+                       0
+               },
+               {
+                       "display_roi_x",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       MMPLAYER_MAX_INT
+               },
+               {
+                       "display_roi_y",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       MMPLAYER_MAX_INT
+               },
+               {
+                       "display_roi_width",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 480,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       MMPLAYER_MAX_INT
+               },
+               {
+                       "display_roi_height",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 800,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       MMPLAYER_MAX_INT
+               },
+               {
+                       "display_rotation",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) MM_DISPLAY_ROTATION_NONE,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       MM_DISPLAY_ROTATION_NONE,
+                       MM_DISPLAY_ROTATION_270
+               },
+               {
+                       "display_visible",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) TRUE,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       1
+               },
+               {
+                       "display_method",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) MM_DISPLAY_METHOD_LETTER_BOX,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       MM_DISPLAY_METHOD_LETTER_BOX,
+                       MM_DISPLAY_METHOD_CUSTOM_ROI
+               },
+               {
+                       "display_overlay",
+                       MM_ATTRS_TYPE_DATA,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) NULL,
+                       MM_ATTRS_VALID_TYPE_NONE,
+                       0,
+                       0
+               },
+               {
+                       "display_overlay_user_data",
+                       MM_ATTRS_TYPE_DATA,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) NULL,
+                       MM_ATTRS_VALID_TYPE_NONE,
+                       0,
+                       0
+               },
+               {
+                       "display_zoom",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 1,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       1,
+                       MMPLAYER_MAX_INT
+               },
+               {
+                       "display_surface_type",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) MM_DISPLAY_SURFACE_NULL,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       MM_DISPLAY_SURFACE_X,
+                       MM_DISPLAY_SURFACE_X_EXT
+               },
+               {
+                       "display_evas_surface_sink",
+                       MM_ATTRS_TYPE_STRING,
+                       MM_ATTRS_FLAG_READABLE,
+                       (void *) PLAYER_INI()->videosink_element_evas,
+                       MM_ATTRS_VALID_TYPE_NONE,
+                       0,
+                       0
+               },
+               {
+                       "display_force_aspect_ration",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 1,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       MMPLAYER_MAX_INT
+               },
+               {
+                       "display_width",                // dest width of fimcconvert ouput
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       MMPLAYER_MAX_INT
+               },
+               {
+                       "display_height",               // dest height of fimcconvert ouput
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       MMPLAYER_MAX_INT
+               },
+               {
+                       "display_evas_do_scaling",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) TRUE,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       FALSE,
+                       TRUE
+               },
+               {
+                       "sound_fadeup",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) FALSE,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       FALSE,
+                       TRUE
+               },
+               {
+                       "sound_fadedown",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) FALSE,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       FALSE,
+                       TRUE
+               },
+               {
+                       "sound_volume_type",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) MM_SOUND_VOLUME_TYPE_MEDIA,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       MM_SOUND_VOLUME_TYPE_SYSTEM,
+                       MM_SOUND_VOLUME_TYPE_CALL
+               },
+               {
+                       "sound_route",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) MM_AUDIOROUTE_USE_EXTERNAL_SETTING,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       MM_AUDIOROUTE_USE_EXTERNAL_SETTING,
+                       MM_AUDIOROUTE_CAPTURE_STEREOMIC_ONLY
+               },
+               {
+                       "sound_stop_when_unplugged",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) TRUE,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       FALSE,
+                       TRUE
+               },
+               {
+                       "sound_application_pid",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       MMPLAYER_MAX_INT
+               },
+               {
+                       "sound_spk_out_only",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) FALSE,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       FALSE,
+                       TRUE
+               },
+               {
+                       "sound_priority",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,                     // 0: normal, 1: high 2: high with sound transition
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       2
+               },
+               {
+                       "audio_latency_mode",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 1,                     // 0: low latency, 1: middle latency 2: high latency
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       2
+               },
+               {
+                       "pcm_extraction",               // enable pcm extraction
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) FALSE,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       FALSE,
+                       TRUE
+               },
+               {
+                       "pcm_extraction_samplerate",    // set samplerate for pcm extraction
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 8000,                          // hz
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       MMPLAYER_MAX_INT
+               },
+               {
+                       "pcm_extraction_depth", // set depth for pcm extraction
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 16,                    // bits
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       MMPLAYER_MAX_INT
+               },
+               {
+                       "pcm_extraction_channels",      // set channels for pcm extraction
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 1,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       MMPLAYER_MAX_INT
+               },
+               {
+                       "pcm_extraction_start_msec",    // set start position to extract pcm
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       MMPLAYER_MAX_INT
+               },
+               {
+                       "pcm_extraction_end_msec",      // set end position to extract pcm
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       MMPLAYER_MAX_INT
+               },
+               {
+                       "profile_smooth_repeat",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) FALSE,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       MMPLAYER_MAX_INT
+               },
+               {
+                       "profile_progress_interval",    // will be deprecated
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 500,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       MMPLAYER_MAX_INT
+               },
+               {
+                       "display_x",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       MMPLAYER_MAX_INT
+               },
+               {
+                       "display_y",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       MMPLAYER_MAX_INT
+               },
+               {
+                       "pd_mode",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) MM_PLAYER_PD_MODE_NONE,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       MM_PLAYER_PD_MODE_NONE,
+                       MM_PLAYER_PD_MODE_URI           // not tested yet, because of no fixed scenario
+               },
+               {
+                       "pd_location",                  // location of the file to write
+                       MM_ATTRS_TYPE_STRING,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) NULL,
+                       MM_ATTRS_VALID_TYPE_NONE,
+                       0,
+                       0
+               }
+       };
+
+       num_of_attrs = ARRAY_SIZE(player_attrs);
+
+       base = (mmf_attrs_construct_info_t* )malloc(num_of_attrs * sizeof(mmf_attrs_construct_info_t));
+
+       if ( !base )
+       {
+               debug_error("failed to alloc attrs constructor");
+               return 0;
+       }
+
+       /* initialize values of attributes */
+       for ( idx = 0; idx < num_of_attrs; idx++ )
+       {
+               base[idx].name = player_attrs[idx].name;
+               base[idx].value_type = player_attrs[idx].value_type;
+               base[idx].flags = player_attrs[idx].flags;
+               base[idx].default_value = player_attrs[idx].default_value;
+       }
+
+       attrs = mmf_attrs_new_from_data(
+                                       "mmplayer_attrs",
+                                       base,
+                                       num_of_attrs,
+                                       NULL,
+                                       NULL);
+
+       /* clean */
+       MMPLAYER_FREEIF(base);
+
+       if ( !attrs )
+       {
+               debug_error("failed to create player attrs");
+               return 0;
+       }
+
+       /* set validity type and range */
+       for ( idx = 0; idx < num_of_attrs; idx++ )
+       {
+               switch ( player_attrs[idx].valid_type)
+               {
+                       case MM_ATTRS_VALID_TYPE_INT_RANGE:
+                       {
+                               mmf_attrs_set_valid_type (attrs, idx, MM_ATTRS_VALID_TYPE_INT_RANGE);
+                               mmf_attrs_set_valid_range (attrs, idx,
+                                               player_attrs[idx].value_min,
+                                               player_attrs[idx].value_max,
+                                               player_attrs[idx].default_value);
+                       }
+                       break;
+
+                       case MM_ATTRS_VALID_TYPE_INT_ARRAY:
+                       case MM_ATTRS_VALID_TYPE_DOUBLE_ARRAY:
+                       case MM_ATTRS_VALID_TYPE_DOUBLE_RANGE:
+                       default:
+                       break;
+               }
+       }
+
+       /* set proxy and user agent */
+       system_ua = vconf_get_str(VCONFKEY_ADMIN_UAGENT);
+       system_proxy = vconf_get_str(VCONFKEY_NETWORK_PROXY);
+
+       if (system_ua)
+       {
+                       mm_attrs_set_string_by_name(attrs, "streaming_user_agent", system_ua);
+                       g_free(system_ua);
+       }
+
+       if (system_proxy)
+       {
+                       mm_attrs_set_string_by_name(attrs, "streaming_proxy", system_proxy);
+                       g_free(system_proxy);
+       }
+
+       /* commit */
+       mmf_attrs_commit(attrs);
+
+       debug_fleave();
+
+       return attrs;
+}
+
+bool
+_mmplayer_deconstruct_attribute(MMHandleType handle) // @
+{
+       debug_fenter();
+
+       mm_player_t *player = MM_PLAYER_CAST(handle);
+
+       return_val_if_fail ( player, FALSE );
+
+       if (player->attrs)
+       {
+               mmf_attrs_free (player->attrs);
+               player->attrs = 0;
+       }
+
+       debug_fleave();
+
+       return TRUE;
+}
diff --git a/src/mm_player_audioeffect.c b/src/mm_player_audioeffect.c
new file mode 100644 (file)
index 0000000..6141118
--- /dev/null
@@ -0,0 +1,1044 @@
+/*
+ * libmm-player
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>,YeJin Cho <cho.yejin@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>
+ *
+ * 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 <mm_error.h>
+
+#include "mm_player_audioeffect.h"
+#include "mm_player_ini.h"
+#include "mm_player_priv.h"
+#include <mm_sound.h>
+
+
+int
+mm_player_get_foreach_present_supported_effect_type(MMHandleType player, MMAudioEffectType effect_type, mmplayer_supported_audio_effect_cb foreach_cb, void *user_data)
+{
+       int result = MM_ERROR_NONE;
+       mm_sound_device_in device_in;
+       mm_sound_device_out device_out;
+       int i = 0;
+
+       debug_fenter();
+
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       /* get status if speaker is activated */
+       result = mm_sound_get_active_device(&device_in, &device_out);
+       if ( result ) {
+               debug_fleave();
+               debug_error("mm_sound_get_active_device() failed [%x]!!", result);
+               return result;
+       }
+
+       /* preset */
+       if (effect_type == MM_AUDIO_EFFECT_TYPE_PRESET)
+       {
+               for ( i = 0; i < MM_AUDIO_EFFECT_PRESET_NUM; i++ )
+               {
+                       if (PLAYER_INI()->audio_effect_preset_list[i] )
+                       {
+                               if (device_out == MM_SOUND_DEVICE_OUT_SPEAKER &&
+                                       PLAYER_INI()->audio_effect_preset_earphone_only_list[i])
+                               {
+                                       continue;
+                               }
+                               if (!foreach_cb(effect_type,i, user_data))
+                               {
+                                       goto CALLBACK_ERROR;
+                               }
+                       }
+               }
+       }
+       /* custom */
+       else if (effect_type == MM_AUDIO_EFFECT_TYPE_CUSTOM)
+       {
+               for ( i = 0; i < MM_AUDIO_EFFECT_CUSTOM_NUM; i++ )
+               {
+                       if (PLAYER_INI()->audio_effect_custom_list[i] )
+                       {
+                               if (device_out == MM_SOUND_DEVICE_OUT_SPEAKER &&
+                                       PLAYER_INI()->audio_effect_custom_earphone_only_list[i])
+                               {
+                                       continue;
+                               }
+                               if (!foreach_cb(effect_type,i, user_data))
+                               {
+                                       goto CALLBACK_ERROR;
+                               }
+                       }
+               }
+       }
+       else
+       {
+               debug_error("invalid effect type(%d)", effect_type);
+               result = MM_ERROR_INVALID_ARGUMENT;
+       }
+
+       debug_fleave();
+
+       return result;
+
+CALLBACK_ERROR:
+       debug_error("foreach callback returned error");
+       debug_fleave();
+       return MM_ERROR_PLAYER_INTERNAL;
+}
+
+
+int
+__mmplayer_set_harmony_effect(mm_player_t *player, GstElement *audio_effect_element)
+{
+       gint *ext_effect_level_list = NULL;
+       int count = 1;          /* start from 1, because of excepting eq index */
+       int ext_level_index = 0;
+       int result = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail ( audio_effect_element, MM_ERROR_INVALID_ARGUMENT );
+
+       /* Custom EQ */
+       if( PLAYER_INI()->audio_effect_custom_eq_band_num )
+       {
+               debug_log("pass custom EQ level list to audio effect plugin");
+               /* set custom-equalizer level list */
+               g_object_set(audio_effect_element, "custom-eq", player->audio_effect_info.custom_eq_level, NULL);
+       }
+       else
+       {
+               debug_warning("no custom EQ");
+       }
+
+       /* Custom Extension effects */
+       if( PLAYER_INI()->audio_effect_custom_ext_num )
+       {
+               debug_log("pass custom extension level list to audio effect plugin");
+               ext_effect_level_list = player->audio_effect_info.custom_ext_level_for_plugin;
+               if (!ext_effect_level_list) {
+                       ext_effect_level_list = (gint*) malloc (sizeof(gint)*PLAYER_INI()->audio_effect_custom_ext_num);
+                       if (!ext_effect_level_list)
+                       {
+                               debug_error("memory allocation for extension effect list failed");
+                               return MM_ERROR_OUT_OF_MEMORY;
+                       }
+                       else
+                       {
+                               memset (ext_effect_level_list, 0, PLAYER_INI()->audio_effect_custom_ext_num);
+                       }
+               }
+
+               while ( count < MM_AUDIO_EFFECT_CUSTOM_NUM )
+               {
+                       if ( PLAYER_INI()->audio_effect_custom_list[count] )
+                       {
+                               ext_effect_level_list[ext_level_index] = player->audio_effect_info.custom_ext_level[count-1];
+                               ext_level_index++;
+                               if (ext_level_index == PLAYER_INI()->audio_effect_custom_ext_num)
+                               {
+                                       break;
+                               }
+                       }
+                       count++;
+               }
+
+               /* set custom-extension effects level list */
+               g_object_set(audio_effect_element, "custom-ext", ext_effect_level_list, NULL);
+       }
+       else
+       {
+               debug_warning("no custom extension effect");
+       }
+
+       /* order action to audio effect plugin */
+       g_object_set(audio_effect_element, "filter-action", MM_AUDIO_EFFECT_TYPE_CUSTOM, NULL);
+       debug_log("filter-action = %d", MM_AUDIO_EFFECT_TYPE_CUSTOM);
+
+       debug_fleave();
+
+       return result;
+}
+
+
+gboolean
+__mmplayer_is_earphone_only_effect_type(mm_player_t *player, MMAudioEffectType effect_type, int effect)
+{
+       gboolean result = FALSE;
+       int i = 0;
+
+       debug_fenter();
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       /* preset */
+       if (effect_type == MM_AUDIO_EFFECT_TYPE_PRESET)
+       {
+               if (PLAYER_INI()->audio_effect_preset_earphone_only_list[effect])
+               {
+                       debug_msg("this preset effect(%d) is only available with earphone", effect);
+                       result = TRUE;
+               }
+       }
+       /* custom */
+       else if (effect_type == MM_AUDIO_EFFECT_TYPE_CUSTOM)
+       {
+               for (i = 1; i < MM_AUDIO_EFFECT_CUSTOM_NUM; i++) /* it starts from 1(except testing for EQ) */
+               {
+                       if (PLAYER_INI()->audio_effect_custom_earphone_only_list[i])
+                       {
+                               /* check if the earphone only custom effect was set */
+                               if (player->audio_effect_info.custom_ext_level[i-1])
+                               {
+                                       debug_msg("this custom effect(%d) is only available with earphone", i);
+                                       result = TRUE;
+                               }
+                       }
+               }
+       }
+       else
+       {
+               debug_error("invalid effect type(%d)", effect_type);
+       }
+
+       debug_fleave();
+
+       return result;
+}
+
+
+gboolean
+_mmplayer_is_supported_effect_type(MMAudioEffectType effect_type, int effect)
+{
+       gboolean result = TRUE;
+       mm_sound_device_in device_in;
+       mm_sound_device_out device_out;
+       int ret = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       /* get status if speaker is activated */
+       ret = mm_sound_get_active_device(&device_in, &device_out);
+       if ( ret ) {
+               debug_fleave();
+               debug_error("mm_sound_get_active_device() failed [%x]!!", ret);
+               result = FALSE;
+       }
+       else
+       {
+               /* preset */
+               if (effect_type == MM_AUDIO_EFFECT_TYPE_PRESET)
+               {
+                       if ( effect < MM_AUDIO_EFFECT_PRESET_AUTO || effect >= MM_AUDIO_EFFECT_PRESET_NUM )
+                       {
+                               debug_error("out of range, preset effect(%d)", effect);
+                               result = FALSE;
+                       }
+                       if (!PLAYER_INI()->audio_effect_preset_list[effect])
+                       {
+                               debug_error("this effect(%d) is not supported", effect);
+                               result = FALSE;
+                       }
+                       else
+                       {
+                               if (device_out == MM_SOUND_DEVICE_OUT_SPEAKER &&
+                                               PLAYER_INI()->audio_effect_preset_earphone_only_list[effect])
+                               {
+                                       result = FALSE;
+                               }
+                       }
+               }
+               /* custom */
+               else if (effect_type == MM_AUDIO_EFFECT_TYPE_CUSTOM)
+               {
+                       if ( effect < MM_AUDIO_EFFECT_CUSTOM_EQ || effect >= MM_AUDIO_EFFECT_CUSTOM_NUM )
+                       {
+                               debug_error("out of range, custom effect(%d)", effect);
+                               result = FALSE;
+                       }
+                       if (!PLAYER_INI()->audio_effect_custom_list[effect])
+                       {
+                               debug_error("this custom effect(%d) is not supported", effect);
+                               result = FALSE;
+                       }
+                       else
+                       {
+                               if (device_out == MM_SOUND_DEVICE_OUT_SPEAKER &&
+                                               PLAYER_INI()->audio_effect_custom_earphone_only_list[effect])
+                               {
+                                       result = FALSE;
+                               }
+                       }
+               }
+               else
+               {
+                       debug_error("invalid effect type(%d)", effect_type);
+                       result = FALSE;
+               }
+       }
+
+       debug_fleave();
+
+       return result;
+}
+
+
+int
+_mmplayer_audio_effect_preset_apply(mm_player_t *player, MMAudioEffectPresetType effect_type)
+{
+       GstElement *audio_effect_element = NULL;
+       int result = MM_ERROR_NONE;
+       int output_type = 0;
+       mm_sound_device_in device_in;
+       mm_sound_device_out device_out;
+
+       debug_fenter();
+
+       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       /* Music Player can set audio effect value before Audiobin is created. */
+       if ( !player->pipeline || !player->pipeline->audiobin )
+       {
+               debug_warning("effect element is not created yet.");
+
+               player->bypass_audio_effect = FALSE;
+
+               /* store audio effect setting in order to apply it when audio effect plugin is created */
+               player->audio_effect_info.effect_type = MM_AUDIO_EFFECT_TYPE_PRESET;
+               player->audio_effect_info.preset = effect_type;
+       }
+       else
+       {
+               return_val_if_fail( player->pipeline->audiobin, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+               audio_effect_element = player->pipeline->audiobin[MMPLAYER_A_FILTER].gst;
+
+               /* get status if speaker is activated */
+               result = mm_sound_get_active_device(&device_in, &device_out);
+               if ( result ) {
+                       debug_error("mm_sound_get_active_device() failed [%x]!!", result);
+                       debug_fleave();
+                       return result;
+               }
+
+               /* SPEAKER case */
+               if (device_out == MM_SOUND_DEVICE_OUT_SPEAKER)
+               {
+                       output_type = MM_AUDIO_EFFECT_OUTPUT_SPK;
+                       if (__mmplayer_is_earphone_only_effect_type(player, MM_AUDIO_EFFECT_TYPE_PRESET, effect_type))
+                       {
+                               debug_error("earphone is not equipped, this filter will not be applied");
+                               debug_fleave();
+                               return MM_ERROR_PLAYER_SOUND_EFFECT_INVALID_STATUS;
+                       }
+               }
+               /* Other case, include WIRED_ACCESSORY, BLUETOOTH, DOCK */
+               else
+               {
+                       output_type = MM_AUDIO_EFFECT_OUTPUT_EAR;
+               }
+
+               /* set filter output mode as SPEAKER or EARPHONE */
+               g_object_set(audio_effect_element, "filter-output-mode", output_type, NULL);
+               debug_log("filter-output-mode = %d (0:spk,1:ear)", output_type);
+
+               if (effect_type == MM_AUDIO_EFFECT_PRESET_AUTO) {
+                       /* TODO: Add codes about auto selecting preset mode according to ID3 tag */
+                       /* set effect preset mode */
+                       g_object_set(audio_effect_element, "preset-mode", 0, NULL); /* forced set to 0(normal) temporarily */
+                       debug_log("preset-mode = %d", effect_type);
+
+               } else {
+                       /* set effect preset mode */
+                       g_object_set(audio_effect_element, "preset-mode", effect_type-1, NULL); /* effect_type-1, because of _PRESET_AUTO in MSL/CAPI which does not exist in soundAlive plugin */
+                       debug_log("preset-mode = %d", effect_type);
+               }
+
+               /* order action to audio effect plugin */
+               g_object_set(audio_effect_element, "filter-action", MM_AUDIO_EFFECT_TYPE_PRESET, NULL);
+               debug_log("filter-action = %d", MM_AUDIO_EFFECT_TYPE_PRESET);
+
+       }
+
+       debug_fleave();
+
+       return result;
+}
+
+
+int
+_mmplayer_audio_effect_custom_apply(mm_player_t *player)
+{
+       GstElement *audio_effect_element = NULL;
+       int result = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       /* Music Player can set audio effect value before Audiobin is created. */
+       if ( !player->pipeline || !player->pipeline->audiobin )
+       {
+               debug_warning("effect element is not created yet.");
+
+               player->bypass_audio_effect = FALSE;
+
+               /* store audio effect setting in order to apply it when audio effect plugin is created */
+               player->audio_effect_info.effect_type = MM_AUDIO_EFFECT_TYPE_CUSTOM;
+       }
+       else
+       {
+               int output_type = 0;
+               mm_sound_device_in device_in;
+               mm_sound_device_out device_out;
+
+               return_val_if_fail( player->pipeline->audiobin, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+               audio_effect_element = player->pipeline->audiobin[MMPLAYER_A_FILTER].gst;
+
+               /* get status if speaker is activated */
+               result = mm_sound_get_active_device(&device_in, &device_out);
+               if ( result ) {
+                       debug_error("mm_sound_get_active_device() failed [%x]!!", result);
+                       debug_fleave();
+                       return result;
+               }
+
+               /* SPEAKER case */
+               if (device_out == MM_SOUND_DEVICE_OUT_SPEAKER)
+               {
+                       output_type = MM_AUDIO_EFFECT_OUTPUT_SPK;
+                       if (__mmplayer_is_earphone_only_effect_type(player, MM_AUDIO_EFFECT_TYPE_CUSTOM, 0))
+                       {
+                               debug_error("earphone is not equipped, some custom effect should operate with earphone");
+                               debug_fleave();
+                               return MM_ERROR_PLAYER_SOUND_EFFECT_INVALID_STATUS;
+                       }
+               }
+               /* Other case, include WIRED_ACCESSORY, BLUETOOTH, DOCK */
+               else
+               {
+                       output_type = MM_AUDIO_EFFECT_OUTPUT_EAR;
+               }
+
+               /* set filter output mode as SPEAKER or EARPHONE */
+               g_object_set(audio_effect_element, "filter-output-mode", output_type, NULL);
+               debug_log("filter-output-mode = %d (0:spk,1:ear)", output_type);
+
+               result = __mmplayer_set_harmony_effect(player, audio_effect_element);
+               if ( result )
+               {
+                       debug_error("_set_harmony_effect() failed(%x)", result);
+                       debug_fleave();
+                       return result;
+               }
+       }
+
+       debug_fleave();
+
+       return result;
+}
+
+
+int
+mm_player_audio_effect_custom_clear_eq_all(MMHandleType hplayer)
+{
+       int result = MM_ERROR_NONE;
+       mm_player_t* player = (mm_player_t*)hplayer;
+
+       debug_fenter();
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       /* clear EQ custom effect */
+       memset(player->audio_effect_info.custom_eq_level, MM_AUDIO_EFFECT_CUSTOM_LEVEL_INIT, sizeof(int)*MM_AUDIO_EFFECT_EQ_BAND_NUM_MAX);
+
+       debug_msg("All the EQ bands clearing success");
+
+       debug_fleave();
+
+       return result;
+}
+
+
+int
+mm_player_audio_effect_custom_clear_ext_all(MMHandleType hplayer)
+{
+       int i;
+       int result = MM_ERROR_NONE;
+       mm_player_t* player = (mm_player_t*)hplayer;
+
+       debug_fenter();
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       /* clear ALL custom effects, except EQ */
+       for ( i = 0 ; i < MM_AUDIO_EFFECT_CUSTOM_NUM - 1 ; i++ )
+       {
+               player->audio_effect_info.custom_ext_level[i] = MM_AUDIO_EFFECT_CUSTOM_LEVEL_INIT;
+       }
+
+       debug_msg("All the extension effects clearing success");
+
+       debug_fleave();
+
+       return result;
+}
+
+
+int
+mm_player_is_supported_preset_effect_type(MMHandleType hplayer, MMAudioEffectPresetType effect)
+{
+       mm_player_t* player = (mm_player_t*)hplayer;
+       int result = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       if ( !_mmplayer_is_supported_effect_type( MM_AUDIO_EFFECT_TYPE_PRESET, effect ) )
+       {
+               result = MM_ERROR_PLAYER_SOUND_EFFECT_NOT_SUPPORTED_FILTER;
+       }
+
+       debug_fleave();
+
+       return result;
+}
+
+
+int
+mm_player_is_supported_custom_effect_type(MMHandleType hplayer, MMAudioEffectCustomType effect)
+{
+       mm_player_t* player = (mm_player_t*)hplayer;
+       int result = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       if ( !_mmplayer_is_supported_effect_type( MM_AUDIO_EFFECT_TYPE_CUSTOM, effect ) )
+       {
+               result = MM_ERROR_PLAYER_SOUND_EFFECT_NOT_SUPPORTED_FILTER;
+       }
+
+       debug_fleave();
+
+       return result;
+}
+
+
+int
+mm_player_audio_effect_preset_apply(MMHandleType hplayer, MMAudioEffectPresetType type)
+{
+       mm_player_t* player = (mm_player_t*)hplayer;
+       int result = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       if (!PLAYER_INI()->use_audio_effect_preset)
+       {
+               debug_error("audio effect(preset) is not supported", type);
+               debug_fleave();
+               return MM_ERROR_NOT_SUPPORT_API;
+       }
+
+       if (type < MM_AUDIO_EFFECT_PRESET_AUTO || type >= MM_AUDIO_EFFECT_PRESET_NUM)
+       {
+               debug_error("out of range, type(%d)", type);
+               debug_fleave();
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+
+       /* check if this effect type is supported */
+       if ( !_mmplayer_is_supported_effect_type( MM_AUDIO_EFFECT_TYPE_PRESET, type ) )
+       {
+               debug_fleave();
+               return MM_ERROR_PLAYER_SOUND_EFFECT_NOT_SUPPORTED_FILTER;
+       }
+
+       result = _mmplayer_audio_effect_preset_apply(player, type);
+
+       debug_fleave();
+
+       return result;
+}
+
+
+int
+mm_player_audio_effect_custom_apply(MMHandleType hplayer)
+{
+       mm_player_t* player = (mm_player_t*)hplayer;
+       int result = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       if (!PLAYER_INI()->use_audio_effect_custom)
+       {
+               debug_error("audio effect(custom) is not supported");
+               debug_fleave();
+               return MM_ERROR_NOT_SUPPORT_API;
+       }
+
+       result = _mmplayer_audio_effect_custom_apply(player);
+
+       debug_fleave();
+
+       return result;
+}
+
+
+int
+mm_player_audio_effect_bypass (MMHandleType hplayer)
+{
+       mm_player_t* player = (mm_player_t*)hplayer;
+       int result = MM_ERROR_NONE;
+       GstElement *audio_effect_element = NULL;
+
+       debug_fenter();
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       if ( !PLAYER_INI()->use_audio_effect_preset && !PLAYER_INI()->use_audio_effect_custom )
+       {
+               debug_error("audio effect(preset/custom) is not supported");
+               debug_fleave();
+               return MM_ERROR_NOT_SUPPORT_API;
+       }
+       if ( !player->pipeline || !player->pipeline->audiobin )
+       {
+               debug_warning("effect element is not created yet.");
+       }
+       else
+       {
+               return_val_if_fail( player->pipeline->audiobin, MM_ERROR_PLAYER_NOT_INITIALIZED );
+               audio_effect_element = player->pipeline->audiobin[MMPLAYER_A_FILTER].gst;
+
+               /* order action to audio effect plugin */
+               g_object_set(audio_effect_element, "filter-action", MM_AUDIO_EFFECT_TYPE_NONE, NULL);
+               debug_log("filter-action = %d", MM_AUDIO_EFFECT_TYPE_NONE);
+       }
+
+       debug_fleave();
+
+       return result;
+}
+
+
+int
+_mmplayer_audio_effect_custom_set_level_ext(mm_player_t *player, MMAudioEffectCustomType custom_effect_type, int level)
+{
+       int effect_level_max = 0;
+       int effect_level_min = 0;
+       int count = 1;                  /* start from 1, because of excepting eq index */
+       int ext_level_index = 1;        /* start from 1, because of excepting eq index */
+       int result = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       /* check if EQ is supported */
+       if ( !_mmplayer_is_supported_effect_type( MM_AUDIO_EFFECT_TYPE_CUSTOM, custom_effect_type ) )
+       {
+               debug_fleave();
+               return MM_ERROR_PLAYER_SOUND_EFFECT_NOT_SUPPORTED_FILTER;
+       }
+
+       while ( count < MM_AUDIO_EFFECT_CUSTOM_NUM )
+       {
+               if ( PLAYER_INI()->audio_effect_custom_list[count] )
+               {
+                       if ( count == custom_effect_type )
+                       {
+                               effect_level_min = PLAYER_INI()->audio_effect_custom_min_level_list[ext_level_index];
+                               effect_level_max = PLAYER_INI()->audio_effect_custom_max_level_list[ext_level_index];
+                               debug_msg("level min value(%d), level max value(%d)", effect_level_min, effect_level_max);
+                               break;
+                       }
+                       ext_level_index++;
+                       if (ext_level_index == PLAYER_INI()->audio_effect_custom_ext_num + 1)
+                       {
+                               debug_error("could not find min, max value. maybe effect information in ini file is not proper for audio effect plugin");
+                               break;
+                       }
+               }
+               count++;
+       }
+
+       if ( level < effect_level_min || level > effect_level_max )
+       {
+               debug_error("out of range, level(%d)", level);
+               result = MM_ERROR_INVALID_ARGUMENT;
+       }
+       else
+       {
+               player->audio_effect_info.custom_ext_level[custom_effect_type-1] = level;
+               debug_msg("set ext[%d] = %d", custom_effect_type-1, level);
+       }
+
+       debug_fleave();
+
+       return result;
+}
+
+
+int
+_mmplayer_audio_effect_custom_set_level_eq(mm_player_t *player, int index, int level)
+{
+       gint eq_level_max = 0;
+       gint eq_level_min = 0;
+       int result = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       /* check if EQ is supported */
+       if ( !_mmplayer_is_supported_effect_type( MM_AUDIO_EFFECT_TYPE_CUSTOM, MM_AUDIO_EFFECT_CUSTOM_EQ ) )
+       {
+               debug_fleave();
+               return MM_ERROR_PLAYER_SOUND_EFFECT_NOT_SUPPORTED_FILTER;
+       }
+
+       if ( index < 0 || index > PLAYER_INI()->audio_effect_custom_eq_band_num - 1 )
+       {
+               debug_error("out of range, index(%d)", index);
+               result = MM_ERROR_INVALID_ARGUMENT;
+       }
+       else
+       {
+               eq_level_min = PLAYER_INI()->audio_effect_custom_min_level_list[MM_AUDIO_EFFECT_CUSTOM_EQ];
+               eq_level_max = PLAYER_INI()->audio_effect_custom_max_level_list[MM_AUDIO_EFFECT_CUSTOM_EQ];
+               debug_msg("EQ level min value(%d), EQ level max value(%d)", eq_level_min, eq_level_max);
+
+               if ( level < eq_level_min || level > eq_level_max )
+               {
+                       debug_error("out of range, EQ level(%d)", level);
+                       result =  MM_ERROR_INVALID_ARGUMENT;
+               }
+               else
+               {
+                       player->audio_effect_info.custom_eq_level[index] = level;
+                       debug_msg("set EQ[%d] = %d", index, level);
+               }
+       }
+
+       debug_fleave();
+
+       return result;
+}
+
+
+/* NOTE : parameter eq_index is only used for _set_eq_level() */
+int
+mm_player_audio_effect_custom_set_level(MMHandleType hplayer, MMAudioEffectCustomType effect_custom_type, int eq_index, int level)
+{
+       mm_player_t* player = (mm_player_t*)hplayer;
+       int result = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       /* check if this effect type is supported */
+       if ( !_mmplayer_is_supported_effect_type( MM_AUDIO_EFFECT_TYPE_CUSTOM, effect_custom_type ) )
+       {
+               result = MM_ERROR_PLAYER_SOUND_EFFECT_NOT_SUPPORTED_FILTER;
+       }
+       else
+       {
+               if (effect_custom_type == MM_AUDIO_EFFECT_CUSTOM_EQ)
+               {
+                       result = _mmplayer_audio_effect_custom_set_level_eq(player, eq_index, level);
+               }
+               else if (effect_custom_type > MM_AUDIO_EFFECT_CUSTOM_EQ || effect_custom_type < MM_AUDIO_EFFECT_CUSTOM_NUM)
+               {
+                       result = _mmplayer_audio_effect_custom_set_level_ext(player, effect_custom_type, level);
+               }
+               else
+               {
+                       debug_error("out of range, effect type(%d)", effect_custom_type);
+                       result = MM_ERROR_INVALID_ARGUMENT;
+               }
+       }
+
+       debug_fleave();
+
+       return result;
+}
+
+
+int
+mm_player_audio_effect_custom_get_eq_bands_number(MMHandleType hplayer, int *bands)
+{
+       mm_player_t* player = (mm_player_t*)hplayer;
+       int result = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       /* check if EQ is supported */
+       if ( !_mmplayer_is_supported_effect_type( MM_AUDIO_EFFECT_TYPE_CUSTOM, MM_AUDIO_EFFECT_CUSTOM_EQ ) )
+       {
+               debug_fleave();
+               return MM_ERROR_PLAYER_SOUND_EFFECT_NOT_SUPPORTED_FILTER;
+       }
+
+       *bands = PLAYER_INI()->audio_effect_custom_eq_band_num;
+       debug_log("number of custom EQ band = %d", *bands);
+
+       debug_fleave();
+
+       return result;
+}
+
+
+int
+mm_player_audio_effect_custom_get_eq_bands_width(MMHandleType hplayer, int band_idx, int *width)
+{
+       mm_player_t* player = (mm_player_t*)hplayer;
+       int result = MM_ERROR_NONE;
+       unsigned int eq_num = 0;
+
+       debug_fenter();
+
+       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       /* check if EQ is supported */
+       if ( !_mmplayer_is_supported_effect_type( MM_AUDIO_EFFECT_TYPE_CUSTOM, MM_AUDIO_EFFECT_CUSTOM_EQ ) )
+       {
+               debug_fleave();
+               return MM_ERROR_PLAYER_SOUND_EFFECT_NOT_SUPPORTED_FILTER;
+       }
+
+       return_val_if_fail( player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       eq_num = PLAYER_INI()->audio_effect_custom_eq_band_num;
+       if (band_idx < 0 || band_idx > eq_num-1)
+       {
+               debug_error("out of range, invalid band_idx(%d)", band_idx);
+               result = MM_ERROR_PLAYER_INTERNAL;
+       }
+       else
+       {
+               /* set the width of EQ band */
+               *width = PLAYER_INI()->audio_effect_custom_eq_band_width[band_idx];
+               debug_log("width of band_idx(%d) = %dHz", band_idx, *width);
+       }
+
+       debug_fleave();
+
+       return result;
+}
+
+
+int
+mm_player_audio_effect_custom_get_eq_bands_freq(MMHandleType hplayer, int band_idx, int *freq)
+{
+       mm_player_t* player = (mm_player_t*)hplayer;
+       int result = MM_ERROR_NONE;
+       unsigned int eq_num = 0;
+
+       debug_fenter();
+
+       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       /* check if EQ is supported */
+       if ( !_mmplayer_is_supported_effect_type( MM_AUDIO_EFFECT_TYPE_CUSTOM, MM_AUDIO_EFFECT_CUSTOM_EQ ) )
+       {
+               debug_fleave();
+               return MM_ERROR_PLAYER_SOUND_EFFECT_NOT_SUPPORTED_FILTER;
+       }
+
+       return_val_if_fail( player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       eq_num = PLAYER_INI()->audio_effect_custom_eq_band_num;
+       if (band_idx < 0 || band_idx > eq_num-1)
+       {
+               debug_error("out of range, invalid band_idx(%d)", band_idx);
+               result = MM_ERROR_PLAYER_INTERNAL;
+       }
+       else
+       {
+               /* set the frequency of EQ band */
+               *freq = PLAYER_INI()->audio_effect_custom_eq_band_freq[band_idx];
+               debug_log("frequency of band_idx(%d) = %dHz", band_idx, *freq);
+       }
+
+       debug_fleave();
+
+       return result;
+}
+
+
+int
+mm_player_audio_effect_custom_get_level(MMHandleType hplayer, MMAudioEffectCustomType type, int eq_index, int *level)
+{
+       mm_player_t* player = (mm_player_t*)hplayer;
+       int result = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail( level, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       /* check if this effect type is supported */
+       if ( !_mmplayer_is_supported_effect_type( MM_AUDIO_EFFECT_TYPE_CUSTOM, type ) )
+       {
+               debug_fleave();
+               return MM_ERROR_PLAYER_SOUND_EFFECT_NOT_SUPPORTED_FILTER;
+       }
+
+       if (type == MM_AUDIO_EFFECT_CUSTOM_EQ)
+       {
+               if ( eq_index < 0 || eq_index > PLAYER_INI()->audio_effect_custom_eq_band_num - 1 )
+               {
+                       debug_error("out of range, EQ index(%d)", eq_index);
+                       result = MM_ERROR_INVALID_ARGUMENT;
+               }
+               else
+               {
+                       *level = player->audio_effect_info.custom_eq_level[eq_index];
+                       debug_log("EQ index = %d, level = %d", eq_index, *level);
+               }
+       }
+       else if ( type > MM_AUDIO_EFFECT_CUSTOM_EQ && type < MM_AUDIO_EFFECT_CUSTOM_NUM )
+       {
+               *level = player->audio_effect_info.custom_ext_level[type-1];
+               debug_log("extension effect index = %d, level = %d", type, *level);
+       }
+       else
+       {
+               debug_error("out of range, type(%d)", type);
+               result = MM_ERROR_INVALID_ARGUMENT;
+       }
+
+       debug_fleave();
+
+       return result;
+}
+
+
+int
+mm_player_audio_effect_custom_get_level_range(MMHandleType hplayer, MMAudioEffectCustomType type, int *min, int *max)
+{
+       mm_player_t* player = (mm_player_t*)hplayer;
+       int result = MM_ERROR_NONE;
+       int count = 1;                  /* start from 1, because of excepting eq index */
+       int ext_level_index = 1;        /* start from 1, because of excepting eq index */
+
+       debug_fenter();
+
+       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail( min, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail( max, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       /* check if this effect type is supported */
+       if ( !_mmplayer_is_supported_effect_type( MM_AUDIO_EFFECT_TYPE_CUSTOM, type ) )
+       {
+               debug_fleave();
+               return MM_ERROR_PLAYER_SOUND_EFFECT_NOT_SUPPORTED_FILTER;
+       }
+
+       if ( type == MM_AUDIO_EFFECT_CUSTOM_EQ )
+       {
+               *min = PLAYER_INI()->audio_effect_custom_min_level_list[MM_AUDIO_EFFECT_CUSTOM_EQ];
+               *max = PLAYER_INI()->audio_effect_custom_max_level_list[MM_AUDIO_EFFECT_CUSTOM_EQ];
+               debug_log("EQ min level = %d, max level = %d", *min, *max);
+       }
+       else
+       {
+               while ( count < MM_AUDIO_EFFECT_CUSTOM_NUM )
+               {
+                       if ( PLAYER_INI()->audio_effect_custom_list[count] )
+                       {
+                               if ( count == type )
+                               {
+                                       *min = PLAYER_INI()->audio_effect_custom_min_level_list[ext_level_index];
+                                       *max = PLAYER_INI()->audio_effect_custom_max_level_list[ext_level_index];
+                                       debug_msg("Extension effect(%d) min level = %d, max level = %d", count, *min, *max);
+                                       break;
+                               }
+                               ext_level_index++;
+                               if ( ext_level_index == PLAYER_INI()->audio_effect_custom_ext_num + 1 )
+                               {
+                                       debug_error("could not find min, max value. maybe effect information in ini file is not proper for audio effect plugin");
+                                       break;
+                               }
+                       }
+                       count++;
+               }
+       }
+
+       debug_fleave();
+
+       return result;
+}
+
+
+int
+mm_player_audio_effect_custom_set_level_eq_from_list(MMHandleType hplayer, int *level_list, int size)
+{
+       mm_player_t *player = (mm_player_t*)hplayer;
+       gint i = 0;
+       gint eq_level_min = 0;
+       gint eq_level_max = 0;
+       int result = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       /* check if EQ is supported */
+       if ( !_mmplayer_is_supported_effect_type( MM_AUDIO_EFFECT_TYPE_CUSTOM, MM_AUDIO_EFFECT_CUSTOM_EQ ) )
+       {
+               debug_fleave();
+               return MM_ERROR_PLAYER_SOUND_EFFECT_NOT_SUPPORTED_FILTER;
+       }
+
+       if ( size != PLAYER_INI()->audio_effect_custom_eq_band_num )
+       {
+               debug_error("input size variable(%d) does not match with number of eq band(%d)", size, PLAYER_INI()->audio_effect_custom_eq_band_num);
+               result = MM_ERROR_INVALID_ARGUMENT;
+       }
+       else
+       {
+               eq_level_min = PLAYER_INI()->audio_effect_custom_min_level_list[MM_AUDIO_EFFECT_CUSTOM_EQ];
+               eq_level_max = PLAYER_INI()->audio_effect_custom_max_level_list[MM_AUDIO_EFFECT_CUSTOM_EQ];
+
+               for ( i = 0 ; i < size ; i++ )
+               {
+                       if ( level_list[i] < eq_level_min || level_list[i] > eq_level_max)
+                       {
+                               debug_error("out of range, level[%d]=%d", i, level_list[i]);
+                               result = MM_ERROR_INVALID_ARGUMENT;
+                               break;
+                       }
+                       player->audio_effect_info.custom_eq_level[i] = level_list[i];
+               }
+       }
+       debug_fleave();
+
+       return result;
+}
diff --git a/src/mm_player_capture.c b/src/mm_player_capture.c
new file mode 100755 (executable)
index 0000000..b846e78
--- /dev/null
@@ -0,0 +1,803 @@
+/*\r
+ * libmm-player\r
+ *\r
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
+ *\r
+ * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YeJin Cho <cho.yejin@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ */\r
\r
+/*===========================================================================================\r
+|                                                                                                                                                                                      |\r
+|  INCLUDE FILES                                                                                                                                                       |\r
+|                                                                                                                                                                                      |\r
+========================================================================================== */\r
+#include "mm_player_capture.h"\r
+#include "mm_player_priv.h"\r
+\r
+#include <mm_util_imgp.h>\r
+\r
+/*---------------------------------------------------------------------------\r
+|    LOCAL VARIABLE DEFINITIONS for internal                                                           |\r
+---------------------------------------------------------------------------*/\r
+\r
+/*---------------------------------------------------------------------------\r
+|    LOCAL FUNCTION PROTOTYPES:                                                                                                |\r
+---------------------------------------------------------------------------*/\r
+static gboolean __mmplayer_video_capture_probe (GstPad *pad, GstBuffer *buffer, gpointer u_data);\r
+static int  __mmplayer_get_video_frame_from_buffer(mm_player_t* player, GstBuffer *buffer);\r
+static gpointer __mmplayer_capture_thread(gpointer data);\r
+static void __csc_tiled_to_linear_crop(unsigned char *yuv420_dest, unsigned char *nv12t_src, int yuv420_width, int yuv420_height, int left, int top, int right, int buttom);\r
+static int __tile_4x2_read(int x_size, int y_size, int x_pos, int y_pos);\r
+static int __mm_player_convert_colorspace(mm_player_t* player, unsigned char* src_data, mm_util_img_format src_fmt, unsigned int src_w, unsigned int src_h, mm_util_img_format dst_fmt);\r
+\r
+/*===========================================================================================\r
+|                                                                                                                                                                                      |\r
+|  FUNCTION DEFINITIONS                                                                                                                                                |\r
+|                                                                                                                                                                                      |\r
+========================================================================================== */\r
+int \r
+_mmplayer_initialize_video_capture(mm_player_t* player)\r
+{\r
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );\r
+       /* create capture mutex */\r
+       player->capture_thread_mutex = g_mutex_new();\r
+       if ( ! player->capture_thread_mutex )\r
+       {\r
+               debug_critical("Cannot create capture mutex");\r
+               goto ERROR;\r
+       }\r
+\r
+       /* create capture cond */\r
+       player->capture_thread_cond = g_cond_new();\r
+       if ( ! player->capture_thread_cond )\r
+       {\r
+               debug_critical("Cannot create capture cond");\r
+               goto ERROR;\r
+       }\r
+\r
+       player->capture_thread_exit = FALSE;\r
+\r
+       /* create video capture thread */\r
+       player->capture_thread =\r
+               g_thread_create (__mmplayer_capture_thread, (gpointer)player, TRUE, NULL);\r
+       if ( ! player->capture_thread )\r
+       {\r
+               goto ERROR;\r
+       }\r
+\r
+       return MM_ERROR_NONE;\r
+\r
+ERROR:\r
+       /* capture thread */\r
+       if ( player->capture_thread_mutex )\r
+               g_mutex_free ( player->capture_thread_mutex );\r
+\r
+       if ( player->capture_thread_cond )\r
+               g_cond_free ( player->capture_thread_cond );\r
+\r
+       return MM_ERROR_PLAYER_INTERNAL;\r
+}\r
+\r
+int\r
+_mmplayer_release_video_capture(mm_player_t* player)\r
+{\r
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );\r
+       /* release capture thread */\r
+       if ( player->capture_thread_cond &&\r
+                player->capture_thread_mutex &&\r
+                player->capture_thread )\r
+       {\r
+               g_mutex_lock(player->capture_thread_mutex);\r
+               player->capture_thread_exit = TRUE;\r
+               g_cond_signal( player->capture_thread_cond );\r
+               g_mutex_unlock(player->capture_thread_mutex);\r
+\r
+               debug_log("waitting for capture thread exit");\r
+               g_thread_join ( player->capture_thread );\r
+               g_mutex_free ( player->capture_thread_mutex );\r
+               g_cond_free ( player->capture_thread_cond );\r
+               debug_log("capture thread released");\r
+       }\r
+\r
+       return MM_ERROR_NONE;\r
+}\r
+\r
+int\r
+_mmplayer_do_video_capture(MMHandleType hplayer)\r
+{\r
+       mm_player_t* player = (mm_player_t*) hplayer;\r
+       int ret = MM_ERROR_NONE;\r
+       GstPad *pad = NULL;\r
+\r
+       debug_fenter();\r
+\r
+       return_val_if_fail(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);\r
+\r
+       /* capturing or not */\r
+       if (player->video_capture_cb_probe_id || player->capture.data || player->captured.a[0] || player->captured.a[1])\r
+       {\r
+               debug_warning("capturing... we can't do any more");\r
+               return MM_ERROR_PLAYER_INVALID_STATE;\r
+       }\r
+\r
+       /* check if video pipeline is linked or not */\r
+       if (!player->pipeline->videobin || !player->sent_bos)\r
+       {\r
+               debug_warning("not ready to capture");\r
+               return MM_ERROR_PLAYER_INVALID_STATE;\r
+       }\r
+\r
+       if (player->state != MM_PLAYER_STATE_PLAYING)\r
+       {\r
+               if (player->state == MM_PLAYER_STATE_PAUSED) // get last buffer from video sink\r
+               {\r
+                       GstBuffer *buf = NULL;\r
+                       g_object_get(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "last-buffer", &buf, NULL);\r
+\r
+                       if (buf)\r
+                       {\r
+                               ret = __mmplayer_get_video_frame_from_buffer(player, buf);\r
+                               gst_buffer_unref(buf);\r
+                       }\r
+                       return ret;\r
+               }\r
+               else\r
+               {\r
+                       debug_warning("invalid state(%d) to capture", player->state);\r
+                       return MM_ERROR_PLAYER_INVALID_STATE;\r
+               }\r
+       }\r
+\r
+       pad = gst_element_get_static_pad(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "sink" );\r
+\r
+       /* register probe */\r
+       player->video_capture_cb_probe_id = gst_pad_add_buffer_probe (pad,\r
+               G_CALLBACK (__mmplayer_video_capture_probe), player);\r
+\r
+       gst_object_unref(GST_OBJECT(pad));\r
+       pad = NULL;\r
+\r
+       debug_fleave();\r
+\r
+       return ret;\r
+}\r
+\r
+static gpointer\r
+__mmplayer_capture_thread(gpointer data)\r
+{\r
+       mm_player_t* player = (mm_player_t*) data;\r
+       MMMessageParamType msg = {0, };\r
+       unsigned char * linear_y_plane = NULL;\r
+       unsigned char * linear_uv_plane = NULL;\r
+\r
+       return_if_fail (player);\r
+\r
+       while (!player->capture_thread_exit)\r
+       {\r
+               debug_log("capture thread started. waiting for signal");\r
+\r
+               g_mutex_lock(player->capture_thread_mutex);\r
+               g_cond_wait( player->capture_thread_cond, player->capture_thread_mutex );\r
+\r
+               if ( player->capture_thread_exit )\r
+               {\r
+                       debug_log("exiting capture thread");\r
+                       goto EXIT;\r
+               }\r
+               debug_log("capture thread is recieved signal");\r
+\r
+               /* NOTE: Don't use MMPLAYER_CMD_LOCK() here.\r
+                * Because deadlock can be happened if other player api is used in message callback. \r
+                */\r
+               if (player->video_cs == MM_PLAYER_COLORSPACE_NV12_TILED)\r
+               {\r
+                       /* Colorspace conversion : NV12T-> NV12-> RGB888 */\r
+                       int ret = 0;\r
+                       int linear_y_plane_size;\r
+                       int linear_uv_plane_size;\r
+                       unsigned char * src_buffer = NULL;\r
+\r
+                       debug_log("w[0]=%d, w[1]=%d", player->captured.w[0], player->captured.w[1]);\r
+                       debug_log("h[0]=%d, h[1]=%d", player->captured.h[0], player->captured.h[1]);\r
+                       debug_log("s[0]=%d, s[1]=%d", player->captured.s[0], player->captured.s[1]);\r
+                       debug_log("e[0]=%d, e[1]=%d", player->captured.e[0], player->captured.e[1]);\r
+                       debug_log("a[0]=%p, a[1]=%p", player->captured.a[0], player->captured.a[1]);\r
+\r
+                       #if 0\r
+                       if (mm_attrs_get_int_by_name(player->attrs, "content_video_width", &(player->captured.w[0])) != MM_ERROR_NONE)\r
+                       {\r
+                               debug_error("failed to get content width attribute");\r
+                               goto ERROR;\r
+                       }\r
+\r
+                       if (mm_attrs_get_int_by_name(player->attrs, "content_video_height", &(player->captured.h[0])) != MM_ERROR_NONE)\r
+                       {\r
+                               debug_error("failed to get content height attribute");\r
+                               goto ERROR;\r
+                       }\r
+                       #endif\r
+\r
+                       linear_y_plane_size = (player->captured.w[0] * player->captured.h[0]);\r
+                       linear_uv_plane_size = (player->captured.w[0] * player->captured.h[0]/2);\r
+\r
+                       linear_y_plane = (unsigned char*) g_try_malloc(linear_y_plane_size);\r
+                       if (linear_y_plane == NULL)\r
+                       {\r
+                               msg.code = MM_ERROR_PLAYER_NO_FREE_SPACE;\r
+                               goto ERROR;\r
+                       }\r
+\r
+                       linear_uv_plane = (unsigned char*) g_try_malloc(linear_uv_plane_size);\r
+                       if (linear_uv_plane == NULL)\r
+                       {\r
+                               msg.code = MM_ERROR_PLAYER_NO_FREE_SPACE;\r
+                               goto ERROR;\r
+                       }\r
+                       /* NV12 tiled to linear */\r
+                       __csc_tiled_to_linear_crop(linear_y_plane, player->captured.a[0], player->captured.w[0], player->captured.h[0], 0,0,0,0);\r
+                       __csc_tiled_to_linear_crop(linear_uv_plane, player->captured.a[1], player->captured.w[0], player->captured.h[0]/2, 0,0,0,0);\r
+\r
+                       MMPLAYER_FREEIF(player->captured.a[0]);\r
+                       MMPLAYER_FREEIF(player->captured.a[1]);\r
+\r
+                       src_buffer = (unsigned char*) g_try_malloc(linear_y_plane_size+linear_uv_plane_size);\r
+\r
+                       if (src_buffer == NULL)\r
+                       {\r
+                               msg.code = MM_ERROR_PLAYER_NO_FREE_SPACE;\r
+                               goto ERROR;\r
+                       }\r
+                       memset(src_buffer, 0x00, linear_y_plane_size+linear_uv_plane_size);\r
+                       memcpy(src_buffer, linear_y_plane, linear_y_plane_size);\r
+                       memcpy(src_buffer+linear_y_plane_size, linear_uv_plane, linear_uv_plane_size);\r
+\r
+                       /* NV12 linear to RGB888 */\r
+                       ret = __mm_player_convert_colorspace(player, src_buffer, MM_UTIL_IMG_FMT_NV12,\r
+                               player->captured.w[0], player->captured.h[0], MM_UTIL_IMG_FMT_RGB888);\r
+\r
+                       if (ret != MM_ERROR_NONE)\r
+                       {\r
+                               debug_error("failed to convert nv12 linear");\r
+                               goto ERROR;\r
+                       }\r
+                       /* clean */\r
+                       MMPLAYER_FREEIF(src_buffer);\r
+                       MMPLAYER_FREEIF(linear_y_plane);\r
+                       MMPLAYER_FREEIF(linear_uv_plane);\r
+               }\r
+\r
+               player->capture.fmt = MM_PLAYER_COLORSPACE_RGB888;\r
+               msg.data = &player->capture;\r
+               msg.size = player->capture.size;\r
+\r
+               if (player->cmd >= MMPLAYER_COMMAND_START)\r
+               {\r
+                       MMPLAYER_POST_MSG( player, MM_MESSAGE_VIDEO_CAPTURED, &msg );\r
+                       debug_log("returned from capture message callback");\r
+               }\r
+\r
+               g_mutex_unlock(player->capture_thread_mutex);\r
+\r
+               //MMPLAYER_FREEIF(player->capture.data);\r
+               continue;\r
+ERROR:\r
+               if (player->video_cs == MM_PLAYER_COLORSPACE_NV12_TILED)\r
+               {\r
+                       /* clean */\r
+                       MMPLAYER_FREEIF(linear_y_plane);\r
+                       MMPLAYER_FREEIF(linear_uv_plane);\r
+                       MMPLAYER_FREEIF(player->captured.a[0]);\r
+                       MMPLAYER_FREEIF(player->captured.a[1]);\r
+               }\r
+\r
+               msg.union_type = MM_MSG_UNION_CODE;\r
+\r
+               g_mutex_unlock(player->capture_thread_mutex);\r
+               MMPLAYER_POST_MSG( player, MM_MESSAGE_VIDEO_NOT_CAPTURED, &msg );\r
+       }\r
+       return NULL;\r
+EXIT:\r
+       g_mutex_unlock(player->capture_thread_mutex);\r
+       return NULL;\r
+}\r
+\r
+/**\r
+  * The output is fixed as RGB888\r
+  */\r
+static int\r
+__mmplayer_get_video_frame_from_buffer(mm_player_t* player, GstBuffer *buffer)\r
+{\r
+       gint yplane_size = 0;\r
+       gint uvplane_size = 0;\r
+       gint src_width = 0;\r
+       gint src_height = 0;\r
+       guint32 fourcc = 0;\r
+       GstCaps *caps = NULL;\r
+       GstStructure *structure = NULL;\r
+       mm_util_img_format src_fmt = MM_UTIL_IMG_FMT_YUV420;\r
+       mm_util_img_format dst_fmt = MM_UTIL_IMG_FMT_RGB888; // fixed\r
+\r
+       debug_fenter();\r
+\r
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );\r
+       return_val_if_fail ( buffer, MM_ERROR_INVALID_ARGUMENT );\r
+\r
+       /* get fourcc */\r
+       caps = GST_BUFFER_CAPS(buffer);\r
+\r
+       return_val_if_fail ( caps, MM_ERROR_INVALID_ARGUMENT );\r
+       debug_log("caps to capture: %s\n", gst_caps_to_string(caps));\r
+\r
+       structure = gst_caps_get_structure (caps, 0);\r
+\r
+       return_val_if_fail (structure != NULL, MM_ERROR_PLAYER_INTERNAL);\r
+\r
+       /* init capture image buffer */\r
+       memset(&player->capture, 0x00, sizeof(MMPlayerVideoCapture));\r
+\r
+       gst_structure_get_int (structure, "width", &src_width);\r
+       gst_structure_get_int (structure, "height", &src_height);\r
+\r
+       /* check rgb or yuv */\r
+       if (gst_structure_has_name(structure, "video/x-raw-yuv"))\r
+       {\r
+               gst_structure_get_fourcc (structure, "format", &fourcc);\r
+\r
+               switch(fourcc)\r
+               {\r
+                       /* NV12T */\r
+                       case GST_MAKE_FOURCC ('S', 'T', '1', '2'):\r
+                       {\r
+                               debug_msg ("captured format is ST12\n");\r
+\r
+                               MMPlayerMPlaneImage *proved = NULL;\r
+                               player->video_cs = MM_PLAYER_COLORSPACE_NV12_TILED;\r
+\r
+                               /* get video frame info from proved buffer */\r
+                               proved = (MMPlayerMPlaneImage *)GST_BUFFER_MALLOCDATA(buffer);\r
+\r
+                               if ( !proved || !proved->a[0] || !proved->a[1] )\r
+                                       return MM_ERROR_PLAYER_INTERNAL;\r
+\r
+                               yplane_size = proved->y_size;\r
+                               uvplane_size = proved->uv_size;\r
+\r
+                               debug_msg ("yplane_size=%d, uvplane_size=%d\n",yplane_size,uvplane_size);\r
+                               memset(&player->captured, 0x00, sizeof(MMPlayerMPlaneImage));\r
+                               memcpy(&player->captured, proved, sizeof(MMPlayerMPlaneImage));\r
+\r
+                               player->captured.a[0] = g_try_malloc(yplane_size);\r
+                               if ( !player->captured.a[0] )\r
+                                       return MM_ERROR_SOUND_NO_FREE_SPACE;\r
+\r
+                               player->captured.a[1] = g_try_malloc(uvplane_size);\r
+                               if ( !player->captured.a[1] )\r
+                                       return MM_ERROR_SOUND_NO_FREE_SPACE;\r
+\r
+                               memcpy(player->captured.a[0], proved->a[0], yplane_size);\r
+                               memcpy(player->captured.a[1], proved->a[1], uvplane_size);\r
+                               goto DONE;\r
+                       }\r
+                       break;\r
+\r
+                       case GST_MAKE_FOURCC ('I', '4', '2', '0'):\r
+                       {\r
+                               src_fmt = MM_UTIL_IMG_FMT_I420;\r
+                       }\r
+                       break;\r
+\r
+                       default:\r
+                       {\r
+                               goto UNKNOWN;\r
+                       }\r
+                       break;\r
+               }\r
+       }\r
+       else if (gst_structure_has_name(structure, "video/x-raw-rgb"))\r
+       {\r
+               gint bpp;\r
+               gint depth;\r
+               gint endianess;\r
+               gint blue_mask;\r
+               gboolean bigendian = FALSE;\r
+               gboolean isbluefirst = FALSE;\r
+\r
+            /**\r
+               * The followings will be considered.\r
+               * RGBx, xRGB, BGRx, xBGR\r
+               * RGB888, BGR888\r
+               * RGB565\r
+               *\r
+               */\r
+               gst_structure_get_int (structure, "bpp", &bpp);\r
+               gst_structure_get_int (structure, "depth", &depth);\r
+               gst_structure_get_int (structure, "endianness", &endianess);\r
+               gst_structure_get_int (structure, "blue_mask", &blue_mask);\r
+\r
+               if (endianess == 4321)\r
+                       bigendian = TRUE;\r
+\r
+               if (blue_mask == -16777216)\r
+                       isbluefirst = TRUE;\r
+\r
+               switch(bpp)\r
+               {\r
+                       case 32:\r
+                       {\r
+                               switch(depth)\r
+                               {\r
+                                       case 32:\r
+                                               if (bigendian && isbluefirst)\r
+                                                       src_fmt = MM_UTIL_IMG_FMT_BGRA8888;\r
+                                       case 24:\r
+                                               if (bigendian && isbluefirst)\r
+                                                       src_fmt = MM_UTIL_IMG_FMT_BGRX8888;\r
+                                               break;\r
+                                       default:\r
+                                               goto UNKNOWN;\r
+                                               break;\r
+                               }\r
+                       }\r
+                       break;\r
+\r
+                       case 24:\r
+                       default:\r
+                       {\r
+                               goto UNKNOWN;\r
+                       }\r
+                       break;\r
+               }\r
+       }\r
+       else\r
+       {\r
+               goto UNKNOWN;\r
+       }\r
+       __mm_player_convert_colorspace(player, GST_BUFFER_DATA(buffer), src_fmt, src_width, src_height, dst_fmt);\r
+\r
+DONE:\r
+       /* do convert colorspace */\r
+       g_cond_signal( player->capture_thread_cond );\r
+\r
+       debug_fleave();\r
+\r
+       return MM_ERROR_NONE;\r
+\r
+UNKNOWN:\r
+       debug_error("unknown format to capture\n");\r
+       return MM_ERROR_PLAYER_INTERNAL;\r
+}\r
+\r
+static gboolean\r
+__mmplayer_video_capture_probe (GstPad *pad, GstBuffer *buffer, gpointer u_data)\r
+{\r
+       mm_player_t* player = (mm_player_t*) u_data;\r
+       int ret = MM_ERROR_NONE;\r
+\r
+       return_val_if_fail ( buffer, FALSE);\r
+       debug_fenter();\r
+\r
+       ret = __mmplayer_get_video_frame_from_buffer(player, buffer);\r
+\r
+       if ( ret != MM_ERROR_NONE)\r
+       {\r
+               debug_error("faild to get video frame. %x\n", ret);\r
+               return FALSE;\r
+       }\r
+\r
+       /* remove probe to be called at one time */\r
+       if (player->video_capture_cb_probe_id)\r
+       {\r
+               gst_pad_remove_buffer_probe (pad, player->video_capture_cb_probe_id);\r
+               player->video_capture_cb_probe_id = 0;\r
+       }\r
+\r
+       debug_fleave();\r
+\r
+       return TRUE;\r
+}\r
+\r
+static int\r
+__mm_player_convert_colorspace(mm_player_t* player, unsigned char* src_data, mm_util_img_format src_fmt, unsigned int src_w, unsigned int src_h, mm_util_img_format dst_fmt)\r
+{\r
+       unsigned char *dst_data = NULL;\r
+       unsigned int dst_size;\r
+       int ret = MM_ERROR_NONE;\r
+\r
+       return_val_if_fail(player, MM_ERROR_PLAYER_INTERNAL);\r
+       ret = mm_util_get_image_size(dst_fmt, src_w, src_h, &dst_size);\r
+\r
+       if (ret != MM_ERROR_NONE)\r
+       {\r
+               debug_error("failed to get image size for capture, %d\n", ret);\r
+               return MM_ERROR_PLAYER_INTERNAL;\r
+       }\r
+\r
+       debug_log("width: %d, height: %d to capture, dest size: %d\n", src_w, src_h, dst_size);\r
+\r
+       dst_data = (unsigned char*)g_malloc0(dst_size);\r
+\r
+       if (!dst_data)\r
+       {\r
+               debug_error("no free space to capture\n");\r
+               return MM_ERROR_PLAYER_NO_FREE_SPACE;\r
+       }\r
+\r
+       ret = mm_util_convert_colorspace(src_data, src_w, src_h, src_fmt, dst_data, dst_fmt);\r
+\r
+       if (ret != MM_ERROR_NONE)\r
+       {\r
+               debug_error("failed to convert for capture, %d\n", ret);\r
+               return MM_ERROR_PLAYER_INTERNAL;\r
+       }\r
+\r
+       player->capture.size = dst_size;\r
+       player->capture.data = dst_data;\r
+\r
+       return MM_ERROR_NONE;\r
+}\r
+\r
+/*\r
+ * Get tiled address of position(x,y)\r
+ *\r
+ * @param x_size\r
+ *   width of tiled[in]\r
+ *\r
+ * @param y_size\r
+ *   height of tiled[in]\r
+ *\r
+ * @param x_pos\r
+ *   x position of tield[in]\r
+ *\r
+ * @param src_size\r
+ *   y position of tield[in]\r
+ *\r
+ * @return\r
+ *   address of tiled data\r
+ */\r
+static int\r
+__tile_4x2_read(int x_size, int y_size, int x_pos, int y_pos)\r
+{\r
+    int pixel_x_m1, pixel_y_m1;\r
+    int roundup_x, roundup_y;\r
+    int linear_addr0, linear_addr1, bank_addr ;\r
+    int x_addr;\r
+    int trans_addr;\r
+\r
+    pixel_x_m1 = x_size -1;\r
+    pixel_y_m1 = y_size -1;\r
+\r
+    roundup_x = ((pixel_x_m1 >> 7) + 1);\r
+    roundup_y = ((pixel_x_m1 >> 6) + 1);\r
+\r
+    x_addr = x_pos >> 2;\r
+\r
+    if ((y_size <= y_pos+32) && ( y_pos < y_size) &&\r
+        (((pixel_y_m1 >> 5) & 0x1) == 0) && (((y_pos >> 5) & 0x1) == 0)) {\r
+        linear_addr0 = (((y_pos & 0x1f) <<4) | (x_addr & 0xf));\r
+        linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x + ((x_addr >> 6) & 0x3f));\r
+\r
+        if (((x_addr >> 5) & 0x1) == ((y_pos >> 5) & 0x1))\r
+            bank_addr = ((x_addr >> 4) & 0x1);\r
+        else\r
+            bank_addr = 0x2 | ((x_addr >> 4) & 0x1);\r
+    } else {\r
+        linear_addr0 = (((y_pos & 0x1f) << 4) | (x_addr & 0xf));\r
+        linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x + ((x_addr >> 5) & 0x7f));\r
+\r
+        if (((x_addr >> 5) & 0x1) == ((y_pos >> 5) & 0x1))\r
+            bank_addr = ((x_addr >> 4) & 0x1);\r
+        else\r
+            bank_addr = 0x2 | ((x_addr >> 4) & 0x1);\r
+    }\r
+\r
+    linear_addr0 = linear_addr0 << 2;\r
+    trans_addr = (linear_addr1 <<13) | (bank_addr << 11) | linear_addr0;\r
+\r
+    return trans_addr;\r
+}\r
+\r
+/*\r
+ * Converts tiled data to linear\r
+ * Crops left, top, right, buttom\r
+ * 1. Y of NV12T to Y of YUV420P\r
+ * 2. Y of NV12T to Y of YUV420S\r
+ * 3. UV of NV12T to UV of YUV420S\r
+ *\r
+ * @param yuv420_dest\r
+ *   Y or UV plane address of YUV420[out]\r
+ *\r
+ * @param nv12t_src\r
+ *   Y or UV plane address of NV12T[in]\r
+ *\r
+ * @param yuv420_width\r
+ *   Width of YUV420[in]\r
+ *\r
+ * @param yuv420_height\r
+ *   Y: Height of YUV420, UV: Height/2 of YUV420[in]\r
+ *\r
+ * @param left\r
+ *   Crop size of left\r
+ *\r
+ * @param top\r
+ *   Crop size of top\r
+ *\r
+ * @param right\r
+ *   Crop size of right\r
+ *\r
+ * @param buttom\r
+ *   Crop size of buttom\r
+ */\r
+static void\r
+__csc_tiled_to_linear_crop(unsigned char *yuv420_dest, unsigned char *nv12t_src, int yuv420_width, int yuv420_height,\r
+                                int left, int top, int right, int buttom)\r
+{\r
+    int i, j;\r
+    int tiled_offset = 0, tiled_offset1 = 0;\r
+    int linear_offset = 0;\r
+    int temp1 = 0, temp2 = 0, temp3 = 0, temp4 = 0;\r
+\r
+    temp3 = yuv420_width-right;\r
+    temp1 = temp3-left;\r
+    /* real width is greater than or equal 256 */\r
+    if (temp1 >= 256) {\r
+        for (i=top; i<yuv420_height-buttom; i=i+1) {\r
+            j = left;\r
+            temp3 = (j>>8)<<8;\r
+            temp3 = temp3>>6;\r
+            temp4 = i>>5;\r
+            if (temp4 & 0x1) {\r
+                /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */\r
+                tiled_offset = temp4-1;\r
+                temp1 = ((yuv420_width+127)>>7)<<7;\r
+                tiled_offset = tiled_offset*(temp1>>6);\r
+                tiled_offset = tiled_offset+temp3;\r
+                tiled_offset = tiled_offset+2;\r
+                temp1 = (temp3>>2)<<2;\r
+                tiled_offset = tiled_offset+temp1;\r
+                tiled_offset = tiled_offset<<11;\r
+                tiled_offset1 = tiled_offset+2048*2;\r
+                temp4 = 8;\r
+            } else {\r
+                temp2 = ((yuv420_height+31)>>5)<<5;\r
+                if ((i+32)<temp2) {\r
+                    /* even1 fomula: x+((x+2)>>2)<<2+x_block_num*y */\r
+                    temp1 = temp3+2;\r
+                    temp1 = (temp1>>2)<<2;\r
+                    tiled_offset = temp3+temp1;\r
+                    temp1 = ((yuv420_width+127)>>7)<<7;\r
+                    tiled_offset = tiled_offset+temp4*(temp1>>6);\r
+                    tiled_offset = tiled_offset<<11;\r
+                    tiled_offset1 = tiled_offset+2048*6;\r
+                    temp4 = 8;\r
+                } else {\r
+                    /* even2 fomula: x+x_block_num*y */\r
+                    temp1 = ((yuv420_width+127)>>7)<<7;\r
+                    tiled_offset = temp4*(temp1>>6);\r
+                    tiled_offset = tiled_offset+temp3;\r
+                    tiled_offset = tiled_offset<<11;\r
+                    tiled_offset1 = tiled_offset+2048*2;\r
+                    temp4 = 4;\r
+                }\r
+            }\r
+\r
+            temp1 = i&0x1F;\r
+            tiled_offset = tiled_offset+64*(temp1);\r
+            tiled_offset1 = tiled_offset1+64*(temp1);\r
+            temp2 = yuv420_width-left-right;\r
+            linear_offset = temp2*(i-top);\r
+            temp3 = ((j+256)>>8)<<8;\r
+            temp3 = temp3-j;\r
+            temp1 = left&0x3F;\r
+            if (temp3 > 192) {\r
+                memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset+temp1, 64-temp1);\r
+                temp2 = ((left+63)>>6)<<6;\r
+                temp3 = ((yuv420_width-right)>>6)<<6;\r
+                if (temp2 == temp3) {\r
+                    temp2 = yuv420_width-right-(64-temp1);\r
+                }\r
+                memcpy(yuv420_dest+linear_offset+64-temp1, nv12t_src+tiled_offset+2048, 64);\r
+                memcpy(yuv420_dest+linear_offset+128-temp1, nv12t_src+tiled_offset1, 64);\r
+                memcpy(yuv420_dest+linear_offset+192-temp1, nv12t_src+tiled_offset1+2048, 64);\r
+                linear_offset = linear_offset+256-temp1;\r
+            } else if (temp3 > 128) {\r
+                memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset+2048+temp1, 64-temp1);\r
+                memcpy(yuv420_dest+linear_offset+64-temp1, nv12t_src+tiled_offset1, 64);\r
+                memcpy(yuv420_dest+linear_offset+128-temp1, nv12t_src+tiled_offset1+2048, 64);\r
+                linear_offset = linear_offset+192-temp1;\r
+            } else if (temp3 > 64) {\r
+                memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset1+temp1, 64-temp1);\r
+                memcpy(yuv420_dest+linear_offset+64-temp1, nv12t_src+tiled_offset1+2048, 64);\r
+                linear_offset = linear_offset+128-temp1;\r
+            } else if (temp3 > 0) {\r
+                memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset1+2048+temp1, 64-temp1);\r
+                linear_offset = linear_offset+64-temp1;\r
+            }\r
+\r
+            tiled_offset = tiled_offset+temp4*2048;\r
+            j = (left>>8)<<8;\r
+            j = j + 256;\r
+            temp2 = yuv420_width-right-256;\r
+            for (; j<=temp2; j=j+256) {\r
+                memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);\r
+                tiled_offset1 = tiled_offset1+temp4*2048;\r
+                memcpy(yuv420_dest+linear_offset+64, nv12t_src+tiled_offset+2048, 64);\r
+                memcpy(yuv420_dest+linear_offset+128, nv12t_src+tiled_offset1, 64);\r
+                tiled_offset = tiled_offset+temp4*2048;\r
+                memcpy(yuv420_dest+linear_offset+192, nv12t_src+tiled_offset1+2048, 64);\r
+                linear_offset = linear_offset+256;\r
+            }\r
+\r
+            tiled_offset1 = tiled_offset1+temp4*2048;\r
+            temp2 = yuv420_width-right-j;\r
+            if (temp2 > 192) {\r
+                memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);\r
+                memcpy(yuv420_dest+linear_offset+64, nv12t_src+tiled_offset+2048, 64);\r
+                memcpy(yuv420_dest+linear_offset+128, nv12t_src+tiled_offset1, 64);\r
+                memcpy(yuv420_dest+linear_offset+192, nv12t_src+tiled_offset1+2048, temp2-192);\r
+            } else if (temp2 > 128) {\r
+                memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);\r
+                memcpy(yuv420_dest+linear_offset+64, nv12t_src+tiled_offset+2048, 64);\r
+                memcpy(yuv420_dest+linear_offset+128, nv12t_src+tiled_offset1, temp2-128);\r
+            } else if (temp2 > 64) {\r
+                memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);\r
+                memcpy(yuv420_dest+linear_offset+64, nv12t_src+tiled_offset+2048, temp2-64);\r
+            } else {\r
+                memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, temp2);\r
+            }\r
+        }\r
+    } else if (temp1 >= 64) {\r
+        for (i=top; i<(yuv420_height-buttom); i=i+1) {\r
+            j = left;\r
+            tiled_offset = __tile_4x2_read(yuv420_width, yuv420_height, j, i);\r
+            temp2 = ((j+64)>>6)<<6;\r
+            temp2 = temp2-j;\r
+            linear_offset = temp1*(i-top);\r
+            temp4 = j&0x3;\r
+            tiled_offset = tiled_offset+temp4;\r
+            memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, temp2);\r
+            linear_offset = linear_offset+temp2;\r
+            j = j+temp2;\r
+            if ((j+64) <= temp3) {\r
+                tiled_offset = __tile_4x2_read(yuv420_width, yuv420_height, j, i);\r
+                memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);\r
+                linear_offset = linear_offset+64;\r
+                j = j+64;\r
+            }\r
+            if ((j+64) <= temp3) {\r
+                tiled_offset = __tile_4x2_read(yuv420_width, yuv420_height, j, i);\r
+                memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);\r
+                linear_offset = linear_offset+64;\r
+                j = j+64;\r
+            }\r
+            if (j < temp3) {\r
+                tiled_offset = __tile_4x2_read(yuv420_width, yuv420_height, j, i);\r
+                temp2 = temp3-j;\r
+                memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, temp2);\r
+            }\r
+        }\r
+    } else {\r
+        for (i=top; i<(yuv420_height-buttom); i=i+1) {\r
+            linear_offset = temp1*(i-top);\r
+            for (j=left; j<(yuv420_width-right); j=j+2) {\r
+                tiled_offset = __tile_4x2_read(yuv420_width, yuv420_height, j, i);\r
+                temp4 = j&0x3;\r
+                tiled_offset = tiled_offset+temp4;\r
+                memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 2);\r
+                linear_offset = linear_offset+2;\r
+            }\r
+        }\r
+    }\r
+}\r
diff --git a/src/mm_player_ini.c b/src/mm_player_ini.c
new file mode 100644 (file)
index 0000000..2ce1487
--- /dev/null
@@ -0,0 +1,552 @@
+/*
+ * libmm-player
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YeJin Cho <cho.yejin@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>
+ *
+ * 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 __MM_PLAYER_INI_C__
+#define __MM_PLAYER_INI_C__
+
+/* includes here */
+#include <glib.h>
+#include <stdlib.h>
+#include "iniparser.h"
+#include <mm_player_ini.h>
+#include "mm_debug.h"
+#include <mm_error.h>
+#include <glib/gstdio.h>
+
+/* global variables here */
+static mm_player_ini_t g_player_ini;
+
+/* internal functions, macros here */
+static gboolean        __generate_default_ini(void);
+static void    __get_string_list(gchar** out_list, gchar* str);
+static void __mm_player_ini_check_ini_status(void);
+
+/* macro */
+#define MMPLAYER_INI_GET_STRING( x_dict, x_item, x_ini, x_default ) \
+do \
+{ \
+       gchar* str = iniparser_getstring(x_dict, x_ini, x_default); \
+ \
+       if ( str &&  \
+               ( strlen( str ) > 0 ) && \
+               ( strlen( str ) < PLAYER_INI_MAX_STRLEN ) ) \
+       { \
+               strcpy ( x_item, str ); \
+       } \
+       else \
+       { \
+               strcpy ( x_item, x_default ); \
+       } \
+}while(0)
+
+/* x_ini is the list of index to set TRUE at x_list[index] */
+#define MMPLAYER_INI_GET_BOOLEAN_FROM_LIST( x_dict, x_list, x_list_max, x_ini, x_default ) \
+do \
+{ \
+               int index = 0; \
+               const char *delimiters = " ,"; \
+               char *usr_ptr = NULL; \
+               char *token = NULL; \
+               gchar temp_arr[PLAYER_INI_MAX_STRLEN] = {0}; \
+               MMPLAYER_INI_GET_STRING( x_dict, temp_arr, x_ini, x_default); \
+               token = strtok_r( temp_arr, delimiters, &usr_ptr ); \
+               while (token) \
+               { \
+                       index = atoi(token); \
+                       if (index < 0 || index > x_list_max -1) \
+                       { \
+                               debug_warning("%d is not valid index\n", index); \
+                       } \
+                       else \
+                       { \
+                               x_list[index] = TRUE; \
+                       } \
+                       token = strtok_r( NULL, delimiters, &usr_ptr ); \
+               } \
+}while(0)
+
+/* x_ini is the list of value to be set at x_list[index] */
+#define MMPLAYER_INI_GET_INT_FROM_LIST( x_dict, x_list, x_list_max, x_ini, x_default ) \
+do \
+{ \
+               int index = 0; \
+               int value = 0; \
+               const char *delimiters = " ,"; \
+               char *usr_ptr = NULL; \
+               char *token = NULL; \
+               gchar temp_arr[PLAYER_INI_MAX_STRLEN] = {0}; \
+               MMPLAYER_INI_GET_STRING(x_dict, temp_arr, x_ini, x_default); \
+               token = strtok_r( temp_arr, delimiters, &usr_ptr ); \
+               while (token) \
+               { \
+                       if ( index > x_list_max -1) \
+                       { \
+                               debug_error("%d is not valid index\n", index); \
+                               break; \
+                       } \
+                       else \
+                       { \
+                               value = atoi(token); \
+                               x_list[index] = value; \
+                               index++; \
+                       } \
+                       token = strtok_r( NULL, delimiters, &usr_ptr ); \
+               } \
+}while(0)
+
+int 
+mm_player_ini_load(void)
+{
+       static gboolean loaded = FALSE;
+       dictionary * dict = NULL;
+       gint idx = 0;
+
+       if ( loaded )
+               return MM_ERROR_NONE;
+
+       /* disabling ini parsing for launching */
+#if 1 //debianize
+       /* get player ini status because system will be crashed 
+        * if ini file is corrupted. 
+        */
+       /* FIXIT : the api actually deleting illregular ini. but the function name said it's just checking. */
+       __mm_player_ini_check_ini_status();
+
+       /* first, try to load existing ini file */
+       dict = iniparser_load(MM_PLAYER_INI_DEFAULT_PATH);
+
+       /* if no file exists. create one with set of default values */
+       if ( !dict )
+       {
+               #if 0
+               debug_log("No inifile found. player will create default inifile.\n");
+               if ( FALSE == __generate_default_ini() )
+               {       
+                       debug_warning("Creating default inifile failed. Player will use default values.\n");
+               }
+               else
+               {
+                       /* load default ini */
+                       dict = iniparser_load(MM_PLAYER_INI_DEFAULT_PATH);      
+               }
+               #else
+               debug_log("No inifile found. \n");
+
+               return MM_ERROR_FILE_NOT_FOUND;
+               #endif
+       }
+#endif
+
+       /* get ini values */
+       memset( &g_player_ini, 0, sizeof(mm_player_ini_t) );
+
+       if ( dict ) /* if dict is available */
+       {
+               /* general */
+               g_player_ini.use_decodebin = iniparser_getboolean(dict, "general:use decodebin", DEFAULT_USE_DECODEBIN);
+               g_player_ini.disable_segtrap = iniparser_getboolean(dict, "general:disable segtrap", DEFAULT_DISABLE_SEGTRAP);
+               g_player_ini.skip_rescan = iniparser_getboolean(dict, "general:skip rescan", DEFAULT_SKIP_RESCAN);
+               g_player_ini.generate_dot = iniparser_getboolean(dict, "general:generate dot", DEFAULT_GENERATE_DOT);
+               g_player_ini.provide_clock= iniparser_getboolean(dict, "general:provide clock", DEFAULT_PROVIDE_CLOCK);
+               g_player_ini.live_state_change_timeout = iniparser_getint(dict, "general:live state change timeout", DEFAULT_LIVE_STATE_CHANGE_TIMEOUT);
+               g_player_ini.localplayback_state_change_timeout = iniparser_getint(dict, "general:localplayback state change timeout", DEFAULT_LOCALPLAYBACK_STATE_CHANGE_TIMEOUT);
+               g_player_ini.eos_delay = iniparser_getint(dict, "general:eos delay", DEFAULT_EOS_DELAY);
+               g_player_ini.async_start = iniparser_getboolean(dict, "general:async start", DEFAULT_ASYNC_START);
+               g_player_ini.multiple_codec_supported = iniparser_getboolean(dict, "general:multiple codec supported", DEFAULT_MULTIPLE_CODEC_SUPPORTED);
+
+               g_player_ini.delay_before_repeat = iniparser_getint(dict, "general:delay before repeat", DEFAULT_DELAY_BEFORE_REPEAT);
+
+               MMPLAYER_INI_GET_STRING(dict, g_player_ini.videosink_element_x, "general:videosink element x", DEFAULT_VIDEOSINK_X);
+               MMPLAYER_INI_GET_STRING(dict, g_player_ini.videosink_element_evas, "general:videosink element evas", DEFAULT_VIDEOSINK_EVAS);
+               MMPLAYER_INI_GET_STRING(dict, g_player_ini.videosink_element_fake, "general:videosink element fake", DEFAULT_VIDEOSINK_FAKE);
+               MMPLAYER_INI_GET_STRING(dict, g_player_ini.name_of_drmsrc, "general:drmsrc element", DEFAULT_DRMSRC );
+               MMPLAYER_INI_GET_STRING(dict, g_player_ini.name_of_audiosink, "general:audiosink element", DEFAULT_AUDIOSINK );
+               MMPLAYER_INI_GET_STRING(dict, g_player_ini.name_of_video_converter, "general:video converter element", DEFAULT_VIDEO_CONVERTER );
+
+               __get_string_list( (gchar**) g_player_ini.exclude_element_keyword, 
+                       iniparser_getstring(dict, "general:element exclude keyword", DEFAULT_EXCLUDE_KEYWORD));
+
+               MMPLAYER_INI_GET_STRING(dict, g_player_ini.gst_param[0], "general:gstparam1", DEFAULT_GST_PARAM );
+               MMPLAYER_INI_GET_STRING(dict, g_player_ini.gst_param[1], "general:gstparam2", DEFAULT_GST_PARAM );
+               MMPLAYER_INI_GET_STRING(dict, g_player_ini.gst_param[2], "general:gstparam3", DEFAULT_GST_PARAM );
+               MMPLAYER_INI_GET_STRING(dict, g_player_ini.gst_param[3], "general:gstparam4", DEFAULT_GST_PARAM );
+               MMPLAYER_INI_GET_STRING(dict, g_player_ini.gst_param[4], "general:gstparam5", DEFAULT_GST_PARAM );
+
+               /* http streaming */
+               MMPLAYER_INI_GET_STRING( dict, g_player_ini.name_of_httpsrc, "http streaming:httpsrc element", DEFAULT_HTTPSRC );
+               MMPLAYER_INI_GET_STRING( dict, g_player_ini.http_file_buffer_path, "http streaming:http file buffer path", DEFAULT_HTTP_FILE_BUFFER_PATH );
+               g_player_ini.http_buffering_limit = iniparser_getdouble(dict, "http streaming:http buffering high limit", DEFAULT_HTTP_BUFFERING_LIMIT);
+               g_player_ini.http_max_size_bytes = iniparser_getint(dict, "http streaming:http max size bytes", DEFAULT_HTTP_MAX_SIZE_BYTES);
+               g_player_ini.http_buffering_time = iniparser_getdouble(dict, "http streaming:http buffering time", DEFAULT_HTTP_BUFFERING_TIME);                
+               g_player_ini.http_timeout = iniparser_getint(dict, "http streaming:http timeout", DEFAULT_HTTP_TIMEOUT);
+
+               /* rtsp streaming */
+               MMPLAYER_INI_GET_STRING( dict, g_player_ini.name_of_rtspsrc, "rtsp streaming:rtspsrc element", DEFAULT_RTSPSRC );
+               g_player_ini.rtsp_buffering_time = iniparser_getint(dict, "rtsp streaming:rtsp buffering time", DEFAULT_RTSP_BUFFERING);
+               g_player_ini.rtsp_rebuffering_time = iniparser_getint(dict, "rtsp streaming:rtsp rebuffering time", DEFAULT_RTSP_REBUFFERING);
+               g_player_ini.rtsp_do_typefinding = iniparser_getboolean(dict, "rtsp streaming:rtsp do typefinding", DEFAULT_RTSP_DO_TYPEFINDING);
+               g_player_ini.rtsp_error_concealment = iniparser_getboolean(dict, "rtsp streaming:rtsp error concealment", DEFAULT_RTSP_ERROR_CONCEALMENT);
+       }       
+       else /* if dict is not available just fill the structure with default value */
+       {
+               debug_warning("failed to load ini. using hardcoded default\n");
+
+               /* general */
+               g_player_ini.use_decodebin = DEFAULT_USE_DECODEBIN;
+               g_player_ini.disable_segtrap = DEFAULT_DISABLE_SEGTRAP;
+               g_player_ini.skip_rescan = DEFAULT_SKIP_RESCAN;
+               strncpy( g_player_ini.videosink_element_x, DEFAULT_VIDEOSINK_X, PLAYER_INI_MAX_STRLEN - 1 );
+               strncpy( g_player_ini.videosink_element_evas, DEFAULT_VIDEOSINK_EVAS, PLAYER_INI_MAX_STRLEN - 1 );
+               strncpy( g_player_ini.videosink_element_fake, DEFAULT_VIDEOSINK_FAKE, PLAYER_INI_MAX_STRLEN - 1 );
+               g_player_ini.generate_dot = DEFAULT_GENERATE_DOT;
+               g_player_ini.provide_clock= DEFAULT_PROVIDE_CLOCK;
+               g_player_ini.live_state_change_timeout = DEFAULT_LIVE_STATE_CHANGE_TIMEOUT;
+               g_player_ini.localplayback_state_change_timeout = DEFAULT_LOCALPLAYBACK_STATE_CHANGE_TIMEOUT;
+               g_player_ini.eos_delay = DEFAULT_EOS_DELAY;
+               g_player_ini.multiple_codec_supported = DEFAULT_MULTIPLE_CODEC_SUPPORTED;
+               g_player_ini.async_start = DEFAULT_ASYNC_START;
+               g_player_ini.delay_before_repeat = DEFAULT_DELAY_BEFORE_REPEAT;
+
+
+               strncpy( g_player_ini.name_of_drmsrc, DEFAULT_DRMSRC, PLAYER_INI_MAX_STRLEN - 1 );
+               strncpy( g_player_ini.name_of_audiosink, DEFAULT_AUDIOSINK, PLAYER_INI_MAX_STRLEN -1 );
+               strncpy( g_player_ini.name_of_video_converter, DEFAULT_VIDEO_CONVERTER, PLAYER_INI_MAX_STRLEN -1 );
+
+               {
+                       __get_string_list( (gchar**) g_player_ini.exclude_element_keyword, DEFAULT_EXCLUDE_KEYWORD);
+               }
+
+
+               strncpy( g_player_ini.gst_param[0], DEFAULT_GST_PARAM, PLAYER_INI_MAX_PARAM_STRLEN - 1 );
+               strncpy( g_player_ini.gst_param[1], DEFAULT_GST_PARAM, PLAYER_INI_MAX_PARAM_STRLEN - 1 );
+               strncpy( g_player_ini.gst_param[2], DEFAULT_GST_PARAM, PLAYER_INI_MAX_PARAM_STRLEN - 1 );
+               strncpy( g_player_ini.gst_param[3], DEFAULT_GST_PARAM, PLAYER_INI_MAX_PARAM_STRLEN - 1 );
+               strncpy( g_player_ini.gst_param[4], DEFAULT_GST_PARAM, PLAYER_INI_MAX_PARAM_STRLEN - 1 );
+
+               /* http streaming */
+               strncpy( g_player_ini.name_of_httpsrc, DEFAULT_HTTPSRC, PLAYER_INI_MAX_STRLEN - 1 );
+               strncpy( g_player_ini.http_file_buffer_path, DEFAULT_HTTP_FILE_BUFFER_PATH, PLAYER_INI_MAX_STRLEN - 1 );
+               g_player_ini.http_buffering_limit = DEFAULT_HTTP_BUFFERING_LIMIT;
+               g_player_ini.http_max_size_bytes = DEFAULT_HTTP_MAX_SIZE_BYTES;
+               g_player_ini.http_buffering_time = DEFAULT_HTTP_BUFFERING_TIME;         
+               g_player_ini.http_timeout = DEFAULT_HTTP_TIMEOUT;
+               
+               /* rtsp streaming */
+               strncpy( g_player_ini.name_of_rtspsrc, DEFAULT_RTSPSRC, PLAYER_INI_MAX_STRLEN - 1 );
+               g_player_ini.rtsp_buffering_time = DEFAULT_RTSP_BUFFERING;
+               g_player_ini.rtsp_rebuffering_time = DEFAULT_RTSP_REBUFFERING;
+               g_player_ini.rtsp_do_typefinding = DEFAULT_RTSP_DO_TYPEFINDING;
+               g_player_ini.rtsp_error_concealment = DEFAULT_RTSP_ERROR_CONCEALMENT;
+       }
+
+       /* free dict as we got our own structure */
+       iniparser_freedict (dict);
+
+       loaded = TRUE;
+
+       /* dump structure */
+       debug_log("player settings -----------------------------------\n");
+
+       /* general */
+       debug_log("use_decodebin : %d\n", g_player_ini.use_decodebin);
+       debug_log("disable_segtrap : %d\n", g_player_ini.disable_segtrap);
+       debug_log("skip rescan : %d\n", g_player_ini.skip_rescan);
+       debug_log("videosink element x: %s\n", g_player_ini.videosink_element_x);
+       debug_log("videosink element evas: %s\n", g_player_ini.videosink_element_evas);
+       debug_log("videosink element fake: %s\n", g_player_ini.videosink_element_fake);
+       debug_log("generate_dot : %d\n", g_player_ini.generate_dot);
+       debug_log("provide_clock : %d\n", g_player_ini.provide_clock);
+       debug_log("live_state_change_timeout(sec) : %d\n", g_player_ini.live_state_change_timeout);
+       debug_log("localplayback_state_change_timeout(sec) : %d\n", g_player_ini.localplayback_state_change_timeout);   
+       debug_log("eos_delay(msec) : %d\n", g_player_ini.eos_delay);
+       debug_log("delay_before_repeat(msec) : %d\n", g_player_ini.delay_before_repeat);
+       debug_log("name_of_drmsrc : %s\n", g_player_ini.name_of_drmsrc);
+       debug_log("name_of_audiosink : %s\n", g_player_ini.name_of_audiosink);
+       debug_log("name_of_video_converter : %s\n", g_player_ini.name_of_video_converter);
+       debug_log("async_start : %d\n", g_player_ini.async_start);
+       debug_log("multiple_codec_supported : %d\n", g_player_ini.multiple_codec_supported);    
+
+       debug_log("gst_param1 : %s\n", g_player_ini.gst_param[0]);
+       debug_log("gst_param2 : %s\n", g_player_ini.gst_param[1]);
+       debug_log("gst_param3 : %s\n", g_player_ini.gst_param[2]);
+       debug_log("gst_param4 : %s\n", g_player_ini.gst_param[3]);
+       debug_log("gst_param5 : %s\n", g_player_ini.gst_param[4]);
+
+       for ( idx = 0; g_player_ini.exclude_element_keyword[idx][0] != '\0'; idx++ )
+       {
+               debug_log("exclude_element_keyword [%d] : %s\n", idx, g_player_ini.exclude_element_keyword[idx]);
+       }
+       
+       /* http streaming */
+       debug_log("name_of_httpsrc : %s\n", g_player_ini.name_of_httpsrc);
+       debug_log("http_file_buffer_path : %s \n", g_player_ini.http_file_buffer_path);
+       debug_log("http_buffering_limit : %f \n", g_player_ini.http_buffering_limit);
+       debug_log("http_max_size_bytes : %d \n", g_player_ini.http_max_size_bytes);
+       debug_log("http_buffering_time : %f \n", g_player_ini.http_buffering_time);
+       debug_log("http_timeout : %d \n", g_player_ini.http_timeout);
+       
+       /* rtsp streaming */
+       debug_log("name_of_rtspsrc : %s\n", g_player_ini.name_of_rtspsrc);
+       debug_log("rtsp_buffering_time(msec) : %d\n", g_player_ini.rtsp_buffering_time);
+       debug_log("rtsp_rebuffering_time(msec) : %d\n", g_player_ini.rtsp_rebuffering_time);
+       debug_log("rtsp_do_typefinding : %d \n", g_player_ini.rtsp_do_typefinding);
+       debug_log("rtsp_error_concealment : %d \n", g_player_ini.rtsp_error_concealment);
+
+       debug_log("---------------------------------------------------\n");     
+
+       return MM_ERROR_NONE;
+}
+
+
+int
+mm_player_audio_effect_ini_load(void)
+{
+       static gboolean loaded_audioeffect = FALSE;
+       dictionary * dict_audioeffect = NULL;
+
+       if ( loaded_audioeffect )
+               return MM_ERROR_NONE;
+
+       dict_audioeffect = iniparser_load(MM_PLAYER_INI_DEFAULT_AUDIOEFFECT_PATH);
+       if ( !dict_audioeffect )
+       {
+               debug_warning("No audio effect ini file found. \n");
+               //return MM_ERROR_FILE_NOT_FOUND;
+       }
+
+       /* audio effect element name */
+       MMPLAYER_INI_GET_STRING( dict_audioeffect, g_player_ini.name_of_audio_effect, "audio effect:audio effect element", DEFAULT_AUDIO_EFFECT_ELEMENT );
+       if (!g_player_ini.name_of_audio_effect)
+       {
+               debug_error("could not parse name of audio effect. \n");
+               iniparser_freedict (dict_audioeffect);
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       /* audio effect (Preset)*/
+       g_player_ini.use_audio_effect_preset = iniparser_getboolean(dict_audioeffect, "audio effect:audio effect preset", DEFAULT_USE_AUDIO_EFFECT_PRESET);
+       if (g_player_ini.use_audio_effect_preset)
+       {
+               MMPLAYER_INI_GET_BOOLEAN_FROM_LIST( dict_audioeffect, g_player_ini.audio_effect_preset_list, MM_AUDIO_EFFECT_PRESET_NUM,
+                               "audio effect:audio effect preset list", DEFAULT_AUDIO_EFFECT_PRESET_LIST );
+               MMPLAYER_INI_GET_BOOLEAN_FROM_LIST( dict_audioeffect, g_player_ini.audio_effect_preset_earphone_only_list, MM_AUDIO_EFFECT_PRESET_NUM,
+                               "audio effect:audio effect preset earphone only", DEFAULT_AUDIO_EFFECT_PRESET_LIST_EARPHONE_ONLY );
+       }
+
+       /* audio effect custom (EQ / Extension effects) */
+       g_player_ini.use_audio_effect_custom = iniparser_getboolean(dict_audioeffect, "audio effect:audio effect custom", DEFAULT_USE_AUDIO_EFFECT_CUSTOM);
+       if (g_player_ini.use_audio_effect_custom)
+       {
+               MMPLAYER_INI_GET_BOOLEAN_FROM_LIST( dict_audioeffect, g_player_ini.audio_effect_custom_list, MM_AUDIO_EFFECT_CUSTOM_NUM,
+                               "audio effect:audio effect custom list", DEFAULT_AUDIO_EFFECT_CUSTOM_LIST );
+               MMPLAYER_INI_GET_BOOLEAN_FROM_LIST( dict_audioeffect, g_player_ini.audio_effect_custom_earphone_only_list, MM_AUDIO_EFFECT_CUSTOM_NUM,
+                               "audio effect:audio effect custom earphone only", DEFAULT_AUDIO_EFFECT_CUSTOM_LIST_EARPHONE_ONLY );
+
+               /* audio effect custom : EQ */
+               if (g_player_ini.audio_effect_custom_list[MM_AUDIO_EFFECT_CUSTOM_EQ])
+               {
+                       g_player_ini.audio_effect_custom_eq_band_num = iniparser_getint(dict_audioeffect, "audio effect:audio effect custom eq band num",
+                                       DEFAULT_AUDIO_EFFECT_CUSTOM_EQ_BAND_NUM);
+                       if (g_player_ini.audio_effect_custom_eq_band_num < DEFAULT_AUDIO_EFFECT_CUSTOM_EQ_BAND_NUM ||
+                                       g_player_ini.audio_effect_custom_eq_band_num > MM_AUDIO_EFFECT_EQ_BAND_NUM_MAX)
+                       {
+                               debug_error("audio_effect_custom_eq_band_num(%d) is not valid range(%d - %d), set the value %d",
+                                       g_player_ini.audio_effect_custom_eq_band_num, DEFAULT_AUDIO_EFFECT_CUSTOM_EQ_BAND_NUM, MM_AUDIO_EFFECT_EQ_BAND_NUM_MAX, DEFAULT_AUDIO_EFFECT_CUSTOM_EQ_BAND_NUM);
+                               g_player_ini.audio_effect_custom_eq_band_num = DEFAULT_AUDIO_EFFECT_CUSTOM_EQ_BAND_NUM;
+
+                               iniparser_freedict (dict_audioeffect);
+                               return MM_ERROR_PLAYER_INTERNAL;
+                       }
+                       else
+                       {
+                               if (g_player_ini.audio_effect_custom_eq_band_num)
+                               {
+                                       MMPLAYER_INI_GET_INT_FROM_LIST( dict_audioeffect, g_player_ini.audio_effect_custom_eq_band_width, MM_AUDIO_EFFECT_EQ_BAND_NUM_MAX,
+                                                       "audio effect:audio effect custom eq band width", DEFAULT_AUDIO_EFFECT_CUSTOM_EQ_BAND_WIDTH );
+                                       MMPLAYER_INI_GET_INT_FROM_LIST( dict_audioeffect, g_player_ini.audio_effect_custom_eq_band_freq, MM_AUDIO_EFFECT_EQ_BAND_NUM_MAX,
+                                                       "audio effect:audio effect custom eq band freq", DEFAULT_AUDIO_EFFECT_CUSTOM_EQ_BAND_FREQ );
+                               }
+                       }
+               }
+
+               /* audio effect custom : Extension effects */
+               g_player_ini.audio_effect_custom_ext_num = iniparser_getint(dict_audioeffect, "audio effect:audio effect custom ext num",
+                               DEFAULT_AUDIO_EFFECT_CUSTOM_EXT_NUM);
+
+               /* Min/Max value list of EQ / Extension effects */
+               if (g_player_ini.audio_effect_custom_eq_band_num || g_player_ini.audio_effect_custom_ext_num)
+               {
+
+                       MMPLAYER_INI_GET_INT_FROM_LIST( dict_audioeffect, g_player_ini.audio_effect_custom_min_level_list, MM_AUDIO_EFFECT_CUSTOM_NUM,
+                                       "audio effect:audio effect custom min list", DEFAULT_AUDIO_EFFECT_CUSTOM_LIST );
+                       MMPLAYER_INI_GET_INT_FROM_LIST( dict_audioeffect, g_player_ini.audio_effect_custom_max_level_list, MM_AUDIO_EFFECT_CUSTOM_NUM,
+                                       "audio effect:audio effect custom max list", DEFAULT_AUDIO_EFFECT_CUSTOM_LIST );
+               }
+       }
+
+       /* dump structure */
+       debug_log("player audio-effect settings ----------------------\n");
+       debug_log("name_of_audio_effect : %s\n", g_player_ini.name_of_audio_effect);
+       debug_log("use_audio_effect_preset : %d\n", g_player_ini.use_audio_effect_preset);
+       debug_log("use_audio_effect_custom : %d\n", g_player_ini.use_audio_effect_custom);
+#if 0
+       int i;
+       for (i=0; i<MM_AUDIO_EFFECT_PRESET_NUM; i++)
+       {
+               debug_log("audio_effect_preset_list: %d (is it for earphone only?(%d))\n", g_player_ini.audio_effect_preset_list[i], g_player_ini.audio_effect_preset_earphone_only_list[i]);
+       }
+       for (i=0; i<MM_AUDIO_EFFECT_CUSTOM_NUM; i++)
+       {
+               debug_log("audio_effect_custom_list : %d (is it for earphone only?(%d))\n", g_player_ini.audio_effect_custom_list[i], g_player_ini.audio_effect_custom_earphone_only_list[i]);
+       }
+       debug_log("audio_effect_custom : eq_band_num(%d), ext_num(%d)\n", g_player_ini.audio_effect_custom_eq_band_num, g_player_ini.audio_effect_custom_ext_num );
+       debug_log("audio_effect_custom_EQ : width(Hz) / central frequency(Hz)");
+       for (i=0; i<g_player_ini.audio_effect_custom_eq_band_num; i++)
+       {
+               debug_log("     EQ band index(%d) :  %8d / %8d", i, g_player_ini.audio_effect_custom_eq_band_width[i], g_player_ini.audio_effect_custom_eq_band_freq[i]);
+       }
+       for (i=0; i<MM_AUDIO_EFFECT_CUSTOM_NUM; i++)
+       {
+               debug_log("audio_effect_custom_level_min_max(idx:%d) : Min(%d), Max(%d)\n", i, g_player_ini.audio_effect_custom_min_level_list[i], g_player_ini.audio_effect_custom_max_level_list[i]);
+       }
+#endif
+       debug_log("---------------------------------------------------\n");
+
+       iniparser_freedict (dict_audioeffect);
+
+       loaded_audioeffect = TRUE;
+
+       return MM_ERROR_NONE;
+
+}
+
+
+static
+void __mm_player_ini_check_ini_status(void)
+{
+       struct stat ini_buff;
+       
+       if ( g_stat(MM_PLAYER_INI_DEFAULT_PATH, &ini_buff) < 0 )
+       {
+               debug_warning("failed to get player ini status\n");
+       }
+       else
+       {
+               if ( ini_buff.st_size < 5 )
+               {
+                       debug_warning("player.ini file size=%d, Corrupted! So, Removed\n", (int)ini_buff.st_size);
+                       
+                       if ( g_remove( MM_PLAYER_INI_DEFAULT_PATH ) == -1)
+                       {
+                               debug_error("failed to delete corrupted ini");
+                       }
+               }
+       }
+}
+
+mm_player_ini_t* 
+mm_player_ini_get_structure(void)
+{
+       return &g_player_ini;
+}
+
+static 
+gboolean __generate_default_ini(void)
+{
+       FILE* fp = NULL;
+       gchar* default_ini = MM_PLAYER_DEFAULT_INI;
+
+
+       /* create new file */
+       fp = fopen(MM_PLAYER_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;
+}
+
+static 
+void   __get_string_list(gchar** out_list, gchar* str)
+{
+       gchar** list = NULL;
+       gchar** walk = NULL;
+       gint i = 0;
+       gchar* strtmp = NULL;
+
+
+       if ( ! str )
+               return;
+
+       if ( strlen( str ) < 1 )
+               return;
+
+       strtmp = g_strdup (str);
+
+       /* trimming. it works inplace */
+       g_strstrip( strtmp );
+
+
+       /* split */
+       list = g_strsplit( strtmp, ",", 10 );
+
+       if ( !list )
+       {
+               if (strtmp)
+                       g_free(strtmp);
+
+               return;
+       }
+
+       /* copy list */
+       for( walk = list; *walk; walk++ )
+       {
+               strncpy( g_player_ini.exclude_element_keyword[i], *walk, (PLAYER_INI_MAX_STRLEN - 1) );
+
+               g_strstrip( g_player_ini.exclude_element_keyword[i] );
+
+               g_player_ini.exclude_element_keyword[i][PLAYER_INI_MAX_STRLEN - 1] = '\0';
+
+               i++;
+       }
+
+       /* mark last item to NULL */
+       g_player_ini.exclude_element_keyword[i][0] = '\0';
+
+       g_strfreev( list );
+       if (strtmp)
+               g_free (strtmp);
+}
+
+#endif
+
+
+
diff --git a/src/mm_player_pd.c b/src/mm_player_pd.c
new file mode 100644 (file)
index 0000000..1961e65
--- /dev/null
@@ -0,0 +1,467 @@
+/*
+ * libmm-player
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, naveen cherukuri <naveen.ch@samsung.com>,
+ * YeJin Cho <cho.yejin@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>
+ *
+ * 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 <mm_debug.h>
+#include <mm_error.h>
+#include "mm_player_pd.h"
+#include "mm_player_utils.h"
+#include "mm_player_priv.h"
+
+/*---------------------------------------------------------------------------------------
+|    LOCAL FUNCTION PROTOTYPES:                                                                                                                        |
+---------------------------------------------------------------------------------------*/
+
+/* It's callback to process whenever there is some changes in PD downloader. */
+static gboolean __pd_downloader_callback(GstBus *bus, GstMessage *msg, gpointer data);
+
+/* This function posts messages to application. */
+/* Currently, MM_MESSAGE_PD_DOWNLOADER_START and MM_MESSAGE_PD_DOWNLOADER_END are used. */
+static gboolean __pd_downloader_post_message(mm_player_t * player, enum MMMessageType msgtype, MMMessageParamType* param);
+
+/*=======================================================================================
+|  FUNCTION DEFINITIONS                                                                                                                                                              |
+=======================================================================================*/
+static gboolean
+__pd_downloader_callback(GstBus *bus, GstMessage *msg, gpointer data)
+{
+       mm_player_t * player = NULL;
+       mm_player_pd_t *pd = NULL;
+       gboolean bret = TRUE;
+       
+       debug_fenter();
+
+       /* chech player handle */
+       return_val_if_fail ( data, MM_ERROR_INVALID_ARGUMENT );
+
+       player = MM_PLAYER_CAST((MMHandleType)data);
+
+       /* get PD downloader handle */
+       pd = MM_PLAYER_GET_PD((MMHandleType)data);
+
+       return_val_if_fail ( pd, MM_ERROR_INVALID_ARGUMENT );
+
+//     g_print("%s\n", GST_MESSAGE_TYPE_NAME(msg));
+
+       switch ( GST_MESSAGE_TYPE( msg ) )
+       {
+               case GST_MESSAGE_EOS:
+                       {
+                               debug_log("PD Downloader EOS received....\n");
+
+                               g_object_set (G_OBJECT (pd->playback_pipeline_src), "eos", TRUE, NULL);
+
+                               /* notify application that download is completed */
+                               __pd_downloader_post_message(player, MM_MESSAGE_PD_DOWNLOADER_END, NULL);
+
+                               #ifdef PD_SELF_DOWNLOAD
+                               _mmplayer_unrealize_pd_downloader ((MMHandleType)data);
+                               #endif
+                       }
+                       break;
+
+               case GST_MESSAGE_ERROR:
+                       {
+                               gboolean ret = FALSE;
+                               GError *error = NULL;
+                               gchar* debug = NULL;
+                               GstMessage *new_msg = NULL;
+                               
+                               /* get error code */
+                               gst_message_parse_error( msg, &error, &debug );
+                               debug_error ("GST_MESSAGE_ERROR = %s\n", debug);
+                               
+                               new_msg = gst_message_new_error (GST_OBJECT_CAST (pd->playback_pipeline_src), error, debug);
+
+                               /* notify application that pd has any error */
+                               ret = gst_element_post_message (pd->playback_pipeline_src, new_msg);
+
+                               _mmplayer_unrealize_pd_downloader ((MMHandleType)data);
+                       }
+                       break;
+
+               case GST_MESSAGE_WARNING:
+                       {
+                               char* debug = NULL;
+                               GError* error = NULL;
+
+                               gst_message_parse_warning(msg, &error, &debug);
+                               debug_warning("warning : %s\n", error->message);
+                               debug_warning("debug : %s\n", debug);
+
+                               MMPLAYER_FREEIF(debug);
+                               g_error_free( error);
+                       }
+                       break;
+
+               case GST_MESSAGE_STATE_CHANGED:
+               {
+                       GstState old_state, new_state;
+                       gchar *src_name;
+
+                       /* get old and new state */
+                       gst_message_parse_state_changed (msg, &old_state, &new_state, NULL);
+
+                       if (old_state == new_state)
+                               break;
+
+                       /* we only care about pipeline state changes */
+                       if (GST_MESSAGE_SRC (msg) != GST_OBJECT (pd->downloader_pipeline))
+                               break;
+
+                       src_name = gst_object_get_name (msg->src);
+                       debug_log ("%s changed state from %s to %s", src_name,
+                               gst_element_state_get_name (old_state),
+                               gst_element_state_get_name (new_state));
+                       g_free (src_name);
+
+                       switch(new_state)
+                       {
+                               case GST_STATE_VOID_PENDING:
+                               case GST_STATE_NULL:
+                               case GST_STATE_READY:
+                               case GST_STATE_PAUSED:
+                                       break;
+
+                               case GST_STATE_PLAYING:
+                                       /* notify application that download is stated */
+                                       __pd_downloader_post_message(player, MM_MESSAGE_PD_DOWNLOADER_START, NULL);
+                                       break;
+
+                               default:
+                                       break;
+                       }
+               }
+               break;
+
+               case GST_MESSAGE_DURATION:
+               {
+                       GstFormat fmt= GST_FORMAT_BYTES;
+
+                       gint64 size = 0LL;
+
+                       /* get total size  of download file, (bytes) */
+                       if ( ! gst_element_query_duration( pd->downloader_pipeline, &fmt, &size ) )
+                       {
+                               GError *err = NULL;
+                               GstMessage *new_msg = NULL;
+
+                               err = g_error_new (GST_STREAM_ERROR, GST_STREAM_ERROR_FAILED, "can't get total size");
+                               new_msg = gst_message_new_error (GST_OBJECT_CAST (pd->playback_pipeline_src), err, NULL);
+                               gst_element_post_message (pd->playback_pipeline_src, new_msg);
+
+                               g_error_free (err);
+
+                               // TODO: check if playback pipeline is closed well or not
+                               g_object_set (G_OBJECT (pd->playback_pipeline_src), "eos", TRUE, NULL);
+
+                               _mmplayer_unrealize_pd_downloader ((MMHandleType)data);
+
+                               debug_error("failed to query total size for download\n");
+                               break;
+                       }
+
+                       pd->total_size = size;
+
+                       debug_log("PD total size : %lld bytes\n", size);
+               }
+               break;
+
+               default:
+                       debug_warning("unhandled message\n");
+                       break;
+       }
+
+       debug_fleave();
+
+       return bret;
+}
+
+
+gboolean __pd_downloader_post_message(mm_player_t * player, enum MMMessageType msgtype, MMMessageParamType* param)
+{
+       debug_fenter();
+
+       return_val_if_fail( player, FALSE );
+
+       if ( !player->pd_msg_cb )
+       {
+               debug_warning("no msg callback. can't post\n");
+               return FALSE;
+       }
+
+       player->pd_msg_cb(msgtype, param, player->pd_msg_cb_param);
+
+       debug_fleave();
+
+       return TRUE;
+}
+
+
+gboolean _mmplayer_get_pd_downloader_status(MMHandleType handle, guint64 *current_pos, guint64 *total_size)
+{
+       debug_fenter();
+
+       mm_player_pd_t * pd = NULL;
+       guint64 bytes = 0;
+
+       return_val_if_fail(handle, MM_ERROR_INVALID_ARGUMENT);
+
+       pd = MM_PLAYER_GET_PD(handle);
+
+       return_val_if_fail(pd, MM_ERROR_INVALID_ARGUMENT);
+       return_val_if_fail(pd->downloader_pipeline, MM_ERROR_INVALID_ARGUMENT);
+
+       if ( !pd->total_size )
+       {
+               debug_warning("not ready to get total size\n");
+               return FALSE;
+       }
+
+       g_object_get(pd->downloader_sink, "current-bytes", &bytes, NULL);
+
+       debug_log("PD status : %lld / %lld\n", bytes, pd->total_size);
+
+       *current_pos = bytes;
+       *total_size = pd->total_size;
+
+       debug_fleave();
+
+       return TRUE;
+}
+
+
+mm_player_pd_t * _mmplayer_create_pd_downloader()
+{
+       debug_fenter();
+
+       mm_player_pd_t * pd = NULL;
+
+       /* create PD handle */
+       pd = (mm_player_pd_t *) malloc (sizeof (mm_player_pd_t));
+       if ( !pd )
+       {
+               debug_error ("Failed to create pd downloader handle...\n");
+               return FALSE;
+       }
+
+       debug_fleave();
+
+       return pd;
+}
+
+
+gboolean _mmplayer_destroy_pd_downloader (MMHandleType handle)
+{
+       debug_fenter();
+
+       mm_player_pd_t * pd = NULL;
+
+       return_val_if_fail ( handle, MM_ERROR_INVALID_ARGUMENT );
+
+       pd = MM_PLAYER_GET_PD(handle);
+
+       if ( pd && pd->downloader_pipeline)
+               _mmplayer_unrealize_pd_downloader (handle);
+
+       /* release PD handle */
+       MMPLAYER_FREEIF(pd);
+
+       debug_fleave();
+
+       return TRUE;
+}
+
+
+gboolean _mmplayer_realize_pd_downloader (MMHandleType handle, gchar *src_uri, gchar *dst_uri, GstElement *pushsrc)
+{
+       debug_fenter();
+
+       mm_player_pd_t * pd = NULL;
+
+       return_val_if_fail ( handle, MM_ERROR_INVALID_ARGUMENT );
+       return_val_if_fail ( src_uri, MM_ERROR_INVALID_ARGUMENT );
+       return_val_if_fail ( dst_uri, MM_ERROR_INVALID_ARGUMENT );
+       return_val_if_fail ( pushsrc, MM_ERROR_INVALID_ARGUMENT );
+
+       pd = MM_PLAYER_GET_PD(handle);
+
+       /* initialize */
+       pd->path_read_from = g_strdup (src_uri);
+       pd->location_to_save = g_strdup (dst_uri);
+       pd->playback_pipeline_src = pushsrc;
+       pd->total_size = 0LL;
+
+       debug_fleave();
+       
+       return TRUE;
+}
+
+
+gboolean _mmplayer_start_pd_downloader (MMHandleType handle)
+{
+       GstBus* bus = NULL;
+       gboolean bret = FALSE;
+       GstStateChangeReturn sret = GST_STATE_CHANGE_SUCCESS;
+       GstState cur_state;
+       GstState pending_state;
+
+       debug_fenter();
+
+       mm_player_pd_t * pd = NULL;
+
+       return_val_if_fail ( handle, MM_ERROR_INVALID_ARGUMENT );
+
+       pd = MM_PLAYER_GET_PD(handle);
+
+       /* pipeline */
+       pd->downloader_pipeline = gst_pipeline_new ("PD Downloader");
+       if (NULL == pd->downloader_pipeline)
+       {
+               debug_error ("Can't create PD download pipeline...");
+               return FALSE;
+       }
+
+       /* source */
+       pd->downloader_src = gst_element_factory_make ("souphttpsrc", "PD HTTP download source");
+       if (NULL == pd->downloader_src)
+       {
+               debug_error ("Can't create PD download src...");
+               return FALSE;
+       }
+
+       /* queue */
+       pd->downloader_queue = gst_element_factory_make ("queue", "PD download queue");
+       if (NULL == pd->downloader_queue)
+       {
+               debug_error ("Can't create PD download queue...");
+               return FALSE;
+       }
+
+       /* filesink */
+       pd->downloader_sink = gst_element_factory_make ("filesink", "PD download sink");
+       if (NULL == pd->downloader_sink)
+       {
+               debug_error ("Can't create PD download sink...");
+               return FALSE;
+       }
+
+       g_object_set(pd->downloader_sink, "sync", FALSE, NULL);
+       
+       /* Add to bin and link */
+       gst_bin_add_many (GST_BIN (pd->downloader_pipeline),
+                                       pd->downloader_src, pd->downloader_queue, pd->downloader_sink,
+                                       NULL);
+       
+       bret = gst_element_link_many (pd->downloader_src, pd->downloader_queue, pd->downloader_sink, NULL);
+       if (FALSE == bret)
+       {
+               debug_error ("Can't link elements src and sink...");
+               return FALSE;
+       }
+       
+       /* Get Bus and set callback to watch */
+       bus = gst_pipeline_get_bus (GST_PIPELINE (pd->downloader_pipeline));
+       gst_bus_add_watch (bus, __pd_downloader_callback, (gpointer)handle);
+       gst_object_unref (bus);
+       
+       /* Set URI on HTTP source */
+       g_object_set (G_OBJECT (pd->downloader_src), "location", pd->path_read_from, NULL);
+
+       /* set file download location on filesink*/
+       g_object_set (G_OBJECT (pd->downloader_sink), "location", pd->location_to_save, NULL);
+
+       debug_log ("src location = %s, save location = %s\n", pd->path_read_from, pd->location_to_save);
+
+       /* Start to download */
+       sret = gst_element_set_state (pd->downloader_pipeline, GST_STATE_PLAYING);
+       if (GST_STATE_CHANGE_FAILURE == sret)
+       {
+               debug_error ("PD download pipeline failed to go to PLAYING state...");
+               return FALSE;
+       }
+
+       debug_log ("set_state :: sret = %d\n", sret);
+
+       sret = gst_element_get_state (pd->downloader_pipeline, &cur_state, &pending_state, GST_CLOCK_TIME_NONE);
+       if (GST_STATE_CHANGE_FAILURE == sret)
+       {
+               debug_error ("PD download pipeline failed to do get_state...");
+               return FALSE;
+       }
+
+       debug_log ("get-state :: sret = %d\n", sret);
+
+       debug_fleave();
+
+       return TRUE;
+}
+
+
+gboolean _mmplayer_unrealize_pd_downloader (MMHandleType handle)
+{
+       debug_fenter();
+
+       mm_player_pd_t * pd = NULL;
+
+       return_val_if_fail ( handle, FALSE );
+
+       pd = MM_PLAYER_GET_PD(handle);
+
+       return_val_if_fail ( pd && pd->downloader_pipeline, FALSE );
+
+       gst_element_set_state (pd->downloader_pipeline, GST_STATE_NULL);
+       gst_element_get_state (pd->downloader_pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
+
+       gst_object_unref (G_OBJECT (pd->downloader_pipeline));
+       pd->downloader_pipeline = NULL;
+
+       /* free */
+       MMPLAYER_FREEIF(pd->path_read_from);
+       MMPLAYER_FREEIF(pd->location_to_save);
+
+       debug_fleave();
+
+       return TRUE;
+}
+
+
+gint _mm_player_set_pd_downloader_message_cb(MMHandleType handle, MMMessageCallback callback, gpointer user_param)
+{
+       debug_fenter();
+
+       mm_player_t * player = NULL;
+
+       return_val_if_fail ( handle, MM_ERROR_INVALID_ARGUMENT );
+
+       player = MM_PLAYER_CAST((MMHandleType)handle);
+
+       /* PD callback can be set as soon as player handle is created.
+         * So, player handle must have it.
+         */
+       player->pd_msg_cb = callback;
+       player->pd_msg_cb_param = user_param;
+
+       debug_log("msg_cb : 0x%x     msg_cb_param : 0x%x\n", (guint)callback, (guint)user_param);
+
+       debug_fleave();
+
+       return MM_ERROR_NONE;
+}
diff --git a/src/mm_player_priv.c b/src/mm_player_priv.c
new file mode 100644 (file)
index 0000000..d918e87
--- /dev/null
@@ -0,0 +1,10252 @@
+/*
+ * libmm-player
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YeJin Cho <cho.yejin@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>
+ *
+ * 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 FILES                                                                                                                                                       |
+|                                                                                                                                                                                      |
+========================================================================================== */
+#include <glib.h>
+#include <gst/gst.h>
+#include <gst/app/gstappsrc.h>
+#include <gst/interfaces/xoverlay.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/time.h>
+#include <stdlib.h>
+
+#include <mm_error.h>
+#include <mm_attrs.h>
+#include <mm_attrs_private.h>
+#include <mm_debug.h>
+
+#include "mm_player_priv.h"
+#include "mm_player_ini.h"
+#include "mm_player_attrs.h"
+#include "mm_player_capture.h"
+
+/*===========================================================================================
+|                                                                                                                                                                                      |
+|  LOCAL DEFINITIONS AND DECLARATIONS FOR MODULE                                                                                       |
+|                                                                                                                                                                                      |
+========================================================================================== */
+
+/*---------------------------------------------------------------------------
+|    GLOBAL CONSTANT DEFINITIONS:                                                                                      |
+---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+|    IMPORTED VARIABLE DECLARATIONS:                                                                           |
+---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+|    IMPORTED FUNCTION DECLARATIONS:                                                                           |
+---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+|    LOCAL #defines:                                                                                                           |
+---------------------------------------------------------------------------*/
+#define TRICK_PLAY_MUTE_THRESHOLD_MAX  2.0
+#define TRICK_PLAY_MUTE_THRESHOLD_MIN  0.0
+
+#define MM_VOLUME_FACTOR_DEFAULT               1.0
+#define MM_VOLUME_FACTOR_MIN                           0
+#define MM_VOLUME_FACTOR_MAX                           1.0
+
+#define MM_PLAYER_FADEOUT_TIME_DEFAULT 700000 // 700 msec
+
+#define MM_PLAYER_MPEG_VNAME                           "mpegversion"
+#define MM_PLAYER_DIVX_VNAME                           "divxversion"
+#define MM_PLAYER_WMV_VNAME                            "wmvversion"
+#define MM_PLAYER_WMA_VNAME                            "wmaversion"
+
+#define DEFAULT_PLAYBACK_RATE                  1.0
+
+#define GST_QUEUE_DEFAULT_TIME                 8
+#define GST_QUEUE_HLS_TIME                             8
+
+/* video capture callback*/
+gulong ahs_appsrc_cb_probe_id = 0;
+
+#define MMPLAYER_USE_FILE_FOR_BUFFERING(player) (((player)->profile.uri_type != MM_PLAYER_URI_TYPE_HLS) && (PLAYER_INI()->http_file_buffer_path) && (strlen(PLAYER_INI()->http_file_buffer_path) > 0) )
+
+#define        LAZY_PAUSE_TIMEOUT_MSEC 700     
+
+/*---------------------------------------------------------------------------
+|    LOCAL CONSTANT DEFINITIONS:                                                                                       |
+---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+|    LOCAL DATA TYPE DEFINITIONS:                                                                                      |
+---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+|    GLOBAL VARIABLE DEFINITIONS:                                                                                      |
+---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+|    LOCAL VARIABLE DEFINITIONS:                                                                                       |
+---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+|    LOCAL FUNCTION PROTOTYPES:                                                                                                |
+---------------------------------------------------------------------------*/
+static gboolean __mmplayer_set_state(mm_player_t* player, int state);
+static int             __mmplayer_get_state(mm_player_t* player);
+static int             __mmplayer_gst_create_video_pipeline(mm_player_t* player, GstCaps *caps, MMDisplaySurfaceType surface_type);
+static int             __mmplayer_gst_create_audio_pipeline(mm_player_t* player);
+static int             __mmplayer_gst_create_text_pipeline(mm_player_t* player);
+static int             __mmplayer_gst_create_subtitle_src(mm_player_t* player);
+static int             __mmplayer_gst_create_pipeline(mm_player_t* player);
+static int             __mmplayer_gst_destroy_pipeline(mm_player_t* player);
+static int             __mmplayer_gst_element_link_bucket(GList* element_bucket);
+
+static gboolean __mmplayer_gst_callback(GstBus *bus, GstMessage *msg, gpointer data);
+static void    __mmplayer_gst_decode_callback(GstElement *decodebin, GstPad *pad, gboolean last, gpointer data);
+
+static void    __mmplayer_typefind_have_type(  GstElement *tf, guint probability, GstCaps *caps, gpointer data);
+static gboolean __mmplayer_try_to_plug(mm_player_t* player, GstPad *pad, const GstCaps *caps);
+static void    __mmplayer_pipeline_complete(GstElement *decodebin,  gpointer data);
+static gboolean __mmplayer_is_midi_type(gchar* str_caps);
+static gboolean __mmplayer_is_amr_type (gchar *str_caps);
+static gboolean __mmplayer_is_only_mp3_type (gchar *str_caps);
+
+static gboolean        __mmplayer_close_link(mm_player_t* player, GstPad *srcpad, GstElement *sinkelement, const char *padname, const GList *templlist);
+static gboolean __mmplayer_feature_filter(GstPluginFeature *feature, gpointer data);
+static void    __mmplayer_add_new_pad(GstElement *element, GstPad *pad, gpointer data);
+
+static void            __mmplayer_gst_rtp_no_more_pads (GstElement *element,  gpointer data);
+static void            __mmplayer_gst_rtp_dynamic_pad (GstElement *element, GstPad *pad, gpointer data);
+static gboolean        __mmplayer_update_stream_service_type( mm_player_t* player );
+static gboolean        __mmplayer_update_subtitle( GstElement* object, GstBuffer *buffer, GstPad *pad, gpointer data);
+
+
+static void    __mmplayer_init_factories(mm_player_t* player);
+static void    __mmplayer_release_factories(mm_player_t* player);
+static void    __mmplayer_release_misc(mm_player_t* player);
+static gboolean        __mmplayer_gstreamer_init(void);
+
+static int             __mmplayer_gst_set_state (mm_player_t* player, GstElement * pipeline,  GstState state, gboolean async, gint timeout );
+gboolean __mmplayer_post_message(mm_player_t* player, enum MMMessageType msgtype, MMMessageParamType* param);
+static gboolean        __mmplayer_gst_extract_tag_from_msg(mm_player_t* player, GstMessage *msg);
+int            __mmplayer_switch_audio_sink (mm_player_t* player);
+static gboolean __mmplayer_gst_remove_fakesink(mm_player_t* player, MMPlayerGstElement* fakesink);
+static int             __mmplayer_check_state(mm_player_t* player, enum PlayerCommandState command);
+static gboolean __mmplayer_audio_stream_probe (GstPad *pad, GstBuffer *buffer, gpointer u_data);
+
+static gboolean __mmplayer_dump_pipeline_state( mm_player_t* player );
+static gboolean __mmplayer_check_subtitle( mm_player_t* player );
+static gboolean __mmplayer_handle_gst_error ( mm_player_t* player, GstMessage * message, GError* error );
+static gboolean __mmplayer_handle_streaming_error  ( mm_player_t* player, GstMessage * message );
+static void            __mmplayer_post_delayed_eos( mm_player_t* player, int delay_in_ms );
+static void    __mmplayer_cancel_delayed_eos( mm_player_t* player );
+static gboolean        __mmplayer_eos_timer_cb(gpointer u_data);
+static gboolean __mmplayer_link_decoder( mm_player_t* player,GstPad *srcpad);
+static gboolean __mmplayer_link_sink( mm_player_t* player,GstPad *srcpad);
+static int     __mmplayer_post_missed_plugin(mm_player_t* player);
+static int             __mmplayer_check_not_supported_codec(mm_player_t* player, gchar* mime);
+static gboolean __mmplayer_configure_audio_callback(mm_player_t* player);
+static void    __mmplayer_add_sink( mm_player_t* player, GstElement* sink);
+static void    __mmplayer_del_sink( mm_player_t* player, GstElement* sink);
+static void            __mmplayer_release_signal_connection(mm_player_t* player);
+static void __mmplayer_set_antishock( mm_player_t* player, gboolean disable_by_force);
+static gpointer __mmplayer_repeat_thread(gpointer data);
+int _mmplayer_get_track_count(MMHandleType hplayer,  MMPlayerTrackType track_type, int *count);
+
+static int             __gst_realize(mm_player_t* player);
+static int             __gst_unrealize(mm_player_t* player);
+static int             __gst_start(mm_player_t* player);
+static int             __gst_stop(mm_player_t* player);
+static int             __gst_pause(mm_player_t* player, gboolean async);
+static int             __gst_resume(mm_player_t* player, gboolean async);
+static gboolean        __gst_seek(mm_player_t* player, GstElement * element, gdouble rate,
+                                       GstFormat format, GstSeekFlags flags, GstSeekType cur_type,
+                                       gint64 cur, GstSeekType stop_type, gint64 stop );
+static int __gst_pending_seek ( mm_player_t* player );
+
+static int             __gst_set_position(mm_player_t* player, int format, unsigned long position, gboolean internal_called);
+static int             __gst_get_position(mm_player_t* player, int format, unsigned long *position);
+static int             __gst_get_buffer_position(mm_player_t* player, int format, unsigned long* start_pos, unsigned long* stop_pos);
+static int             __gst_adjust_subtitle_position(mm_player_t* player, int format, int position);
+static int             __gst_set_message_callback(mm_player_t* player, MMMessageCallback callback, gpointer user_param);
+static void    __gst_set_async_state_change(mm_player_t* player, gboolean async);
+
+static gint    __gst_handle_core_error( mm_player_t* player, int code );
+static gint    __gst_handle_library_error( mm_player_t* player, int code );
+static gint    __gst_handle_resource_error( mm_player_t* player, int code );
+static gint    __gst_handle_stream_error( mm_player_t* player, GError* error, GstMessage * message );
+static gint            __gst_transform_gsterror( mm_player_t* player, GstMessage * message, GError* error);
+static gboolean __gst_send_event_to_sink( mm_player_t* player, GstEvent* event );
+
+static int __mmplayer_set_pcm_extraction(mm_player_t* player);
+static gboolean __mmplayer_can_extract_pcm( mm_player_t* player );
+
+/*fadeout */
+static void __mmplayer_do_sound_fadedown(mm_player_t* player, unsigned int time);
+static void __mmplayer_undo_sound_fadedown(mm_player_t* player);
+
+static void    __mmplayer_add_new_caps(GstPad* pad, GParamSpec* unused, gpointer data);
+static void __mmplayer_set_unlinked_mime_type(mm_player_t* player, GstCaps *caps);
+
+/* util */
+const gchar * __get_state_name ( int state );
+static gboolean __is_streaming( mm_player_t* player );
+static gboolean __is_rtsp_streaming( mm_player_t* player );
+static gboolean __is_live_streaming ( mm_player_t* player );
+static gboolean __is_http_streaming( mm_player_t* player );
+static gboolean __is_http_live_streaming( mm_player_t* player );
+static gboolean __is_http_progressive_down(mm_player_t* player);
+
+static gboolean __mmplayer_warm_up_video_codec( mm_player_t* player,  GstElementFactory *factory);
+static GstBusSyncReply __mmplayer_bus_sync_callback (GstBus * bus, GstMessage * message, gpointer data);
+
+static int  __mmplayer_realize_streaming_ext(mm_player_t* player);
+static int __mmplayer_unrealize_streaming_ext(mm_player_t *player);
+static int __mmplayer_start_streaming_ext(mm_player_t *player);
+static int __mmplayer_destroy_streaming_ext(mm_player_t* player);
+
+
+/*===========================================================================================
+|                                                                                                                                                                                      |
+|  FUNCTION DEFINITIONS                                                                                                                                                |
+|                                                                                                                                                                                      |
+========================================================================================== */
+
+/* implementing player FSM */
+/* FIXIT : We need to handle state transition also at here since start api is no more sync */
+static int
+__mmplayer_check_state(mm_player_t* player, enum PlayerCommandState command)
+{
+       MMPlayerStateType current_state = MM_PLAYER_STATE_NUM;
+       MMPlayerStateType pending_state = MM_PLAYER_STATE_NUM;
+       MMPlayerStateType target_state = MM_PLAYER_STATE_NUM;
+       MMPlayerStateType prev_state = MM_PLAYER_STATE_NUM;
+
+       debug_fenter();
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       //debug_log("incomming command : %d \n", command );
+
+       current_state = MMPLAYER_CURRENT_STATE(player);
+       pending_state = MMPLAYER_PENDING_STATE(player);
+       target_state = MMPLAYER_TARGET_STATE(player);
+       prev_state = MMPLAYER_PREV_STATE(player);
+
+       MMPLAYER_PRINT_STATE(player);
+
+       switch( command )
+       {
+               case MMPLAYER_COMMAND_CREATE:
+               {
+                       MMPLAYER_TARGET_STATE(player) = MM_PLAYER_STATE_NULL;
+                       
+                       if ( current_state == MM_PLAYER_STATE_NULL ||
+                               current_state == MM_PLAYER_STATE_READY ||
+                               current_state == MM_PLAYER_STATE_PAUSED ||
+                               current_state == MM_PLAYER_STATE_PLAYING )
+                               goto NO_OP;
+               }
+               break;
+
+               case MMPLAYER_COMMAND_DESTROY:
+               {
+                       /* destroy can called anytime */
+
+                       MMPLAYER_TARGET_STATE(player) = MM_PLAYER_STATE_NONE;
+               }
+               break;
+
+               case MMPLAYER_COMMAND_REALIZE:
+               {
+                       MMPLAYER_TARGET_STATE(player) = MM_PLAYER_STATE_READY;
+
+                       if ( pending_state != MM_PLAYER_STATE_NONE )
+                       {
+                               goto INVALID_STATE;
+                       }
+                       else
+                       {
+                               /* need ready state to realize */
+                               if ( current_state == MM_PLAYER_STATE_READY )
+                                       goto NO_OP;
+
+                               if ( current_state != MM_PLAYER_STATE_NULL )
+                                       goto INVALID_STATE;
+                       }
+               }
+               break;
+
+               case MMPLAYER_COMMAND_UNREALIZE:
+               {
+                       MMPLAYER_TARGET_STATE(player) = MM_PLAYER_STATE_NULL;
+
+                       if ( current_state == MM_PLAYER_STATE_NULL )
+                               goto NO_OP;
+               }
+               break;
+
+               case MMPLAYER_COMMAND_START:
+               {
+                       MMPLAYER_TARGET_STATE(player) = MM_PLAYER_STATE_PLAYING;
+
+                       if ( pending_state == MM_PLAYER_STATE_NONE )
+                       {
+                               if ( current_state == MM_PLAYER_STATE_PLAYING )
+                                       goto NO_OP;
+                               else if ( current_state  != MM_PLAYER_STATE_READY &&
+                                       current_state != MM_PLAYER_STATE_PAUSED )
+                                       goto INVALID_STATE;
+                       }
+                       else if ( pending_state == MM_PLAYER_STATE_PLAYING )
+                       {
+                               goto ALREADY_GOING;
+                       }
+                       else if ( pending_state == MM_PLAYER_STATE_PAUSED )
+                       {
+                               debug_log("player is going to paused state, just change the pending state as playing");
+                       }
+                       else
+                       {
+                               goto INVALID_STATE;
+                       }
+               }
+               break;
+
+               case MMPLAYER_COMMAND_STOP:
+               {
+                       MMPLAYER_TARGET_STATE(player) = MM_PLAYER_STATE_READY;
+
+                       if ( current_state == MM_PLAYER_STATE_READY )
+                               goto NO_OP;
+                       
+                       /* need playing/paused state to stop */
+                       if ( current_state != MM_PLAYER_STATE_PLAYING &&
+                                current_state != MM_PLAYER_STATE_PAUSED )
+                               goto INVALID_STATE;
+               }
+               break;
+
+               case MMPLAYER_COMMAND_PAUSE:
+               {
+                       if ( MMPLAYER_IS_LIVE_STREAMING( player ) )
+                               goto NO_OP;
+
+                       if (player->doing_seek)
+                               goto NOT_COMPLETED_SEEK;
+
+                       MMPLAYER_TARGET_STATE(player) = MM_PLAYER_STATE_PAUSED;
+
+                       if ( pending_state == MM_PLAYER_STATE_NONE )
+                       {
+                               if ( current_state == MM_PLAYER_STATE_PAUSED )
+                                       goto NO_OP;
+                               else if ( current_state != MM_PLAYER_STATE_PLAYING && current_state != MM_PLAYER_STATE_READY ) // support loading state of broswer
+                                       goto INVALID_STATE;
+                       }
+                       else if ( pending_state == MM_PLAYER_STATE_PAUSED )
+                       {
+                               goto ALREADY_GOING;
+                       }
+                       else if ( pending_state == MM_PLAYER_STATE_PLAYING )
+                       {
+                               if ( current_state == MM_PLAYER_STATE_PAUSED ) {
+                                       debug_log("player is PAUSED going to PLAYING, just change the pending state as PAUSED");
+                               } else {
+                                       goto INVALID_STATE;
+                               }
+                       }
+               }
+               break;
+
+               case MMPLAYER_COMMAND_RESUME:
+               {
+                       if ( MMPLAYER_IS_LIVE_STREAMING(player) )
+                               goto NO_OP;
+
+                       if (player->doing_seek)
+                               goto NOT_COMPLETED_SEEK;
+
+                       MMPLAYER_TARGET_STATE(player) = MM_PLAYER_STATE_PLAYING;
+
+                       if ( pending_state == MM_PLAYER_STATE_NONE )
+                       {
+                               if ( current_state == MM_PLAYER_STATE_PLAYING )
+                                       goto NO_OP;
+                               else if (  current_state != MM_PLAYER_STATE_PAUSED )
+                                       goto INVALID_STATE;
+                       }
+                       else if ( pending_state == MM_PLAYER_STATE_PLAYING )
+                       {
+                               goto ALREADY_GOING;
+                       }
+                       else if ( pending_state == MM_PLAYER_STATE_PAUSED )
+                       {
+                               debug_log("player is going to paused state, just change the pending state as playing");
+                       }
+                       else
+                       {
+                               goto INVALID_STATE;
+                       }
+               }
+               break;
+
+               default:
+               break;
+       }
+       player->cmd = command;
+
+       debug_fleave();
+       return MM_ERROR_NONE;
+
+INVALID_STATE:
+       debug_warning("since player is in wrong state(%s). it's not able to apply the command(%d)",
+               MMPLAYER_STATE_GET_NAME(current_state), command);
+       return MM_ERROR_PLAYER_INVALID_STATE;
+
+NOT_COMPLETED_SEEK:
+       debug_warning("not completed seek");
+       return MM_ERROR_PLAYER_DOING_SEEK;
+
+NO_OP:
+       debug_warning("player is in the desired state(%s). doing noting", MMPLAYER_STATE_GET_NAME(current_state));
+       return MM_ERROR_PLAYER_NO_OP;
+
+ALREADY_GOING:
+       debug_warning("player is already going to %s, doing nothing", MMPLAYER_STATE_GET_NAME(pending_state));
+       return MM_ERROR_PLAYER_NO_OP;
+}
+
+int
+__mmplayer_gst_set_state (mm_player_t* player, GstElement * element,  GstState state, gboolean async, gint timeout) // @
+{
+       GstState element_state = GST_STATE_VOID_PENDING;
+       GstState element_pending_state = GST_STATE_VOID_PENDING;
+       GstStateChangeReturn ret = GST_STATE_CHANGE_FAILURE;
+
+       debug_fenter();
+       
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail ( element, MM_ERROR_INVALID_ARGUMENT );
+
+       debug_log("setting [%s] element state to : %d\n", GST_ELEMENT_NAME(element),  state);
+
+       /* set state */
+       ret = gst_element_set_state(element, state);
+
+       if ( ret == GST_STATE_CHANGE_FAILURE )
+       {
+               debug_error("failed to set  [%s] state to [%d]\n", GST_ELEMENT_NAME(element), state);
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+       
+       /* return here so state transition to be done in async mode */
+       if ( async )
+       {
+               debug_log("async state transition. not waiting for state complete.\n");
+               return MM_ERROR_NONE;
+       }
+
+       /* wait for state transition */
+       ret = gst_element_get_state( element, &element_state, &element_pending_state, timeout * GST_SECOND );
+
+       if ( ret == GST_STATE_CHANGE_FAILURE || ( state != element_state ) )
+       {
+               debug_error("failed to change [%s] element state to [%s] within %d sec\n",
+                       GST_ELEMENT_NAME(element), 
+                       gst_element_state_get_name(state), timeout );
+               
+               debug_error(" [%s] state : %s   pending : %s \n", 
+                       GST_ELEMENT_NAME(element), 
+                       gst_element_state_get_name(element_state), 
+                       gst_element_state_get_name(element_pending_state) );
+
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       debug_log("[%s] element state has changed to %s \n",
+               GST_ELEMENT_NAME(element), 
+               gst_element_state_get_name(element_state));
+
+       debug_fleave();
+       
+       return MM_ERROR_NONE;
+}
+
+static void
+__mmplayer_videostream_cb(GstElement *element, void *stream,
+int width, int height, gpointer data) // @
+{
+       mm_player_t* player = (mm_player_t*)data;
+       int length = 0;
+
+       return_if_fail ( player );
+
+       debug_fenter();
+
+       if (player->video_stream_cb )
+       {
+               length = width * height * 4; // for rgb 32bit
+               player->video_stream_cb(stream, length, player->video_stream_cb_user_param, width, height);
+       }
+
+       debug_fleave();
+}
+
+static void
+__mmplayer_videoframe_render_error_cb(GstElement *element, void *error_id, gpointer data)
+{
+       mm_player_t* player = (mm_player_t*)data;
+
+       return_if_fail ( player );
+
+       debug_fenter();
+
+       if (player->video_frame_render_error_cb )
+       {
+               if (player->attrs)
+               {
+                       int surface_type = 0;
+                       mm_attrs_get_int_by_name (player->attrs, "display_surface_type", &surface_type);
+                       switch (surface_type)
+                       {
+                       case MM_DISPLAY_SURFACE_X_EXT:
+                               player->video_frame_render_error_cb((unsigned int*)error_id, player->video_frame_render_error_cb_user_param);
+                               debug_log("display surface type(X_EXT) : render error callback(%p) is finished", player->video_frame_render_error_cb);
+                               break;
+                       default:
+                               debug_error("video_frame_render_error_cb was set, but this surface type(%d) is not supported", surface_type);
+                               break;
+                       }
+               }
+               else
+               {
+                       debug_error("could not get surface type");
+               }
+       }
+       else
+       {
+               debug_warning("video_frame_render_error_cb was not set");
+       }
+
+       debug_fleave();
+}
+
+gboolean
+_mmplayer_update_content_attrs(mm_player_t* player) // @
+{
+       GstFormat fmt  = GST_FORMAT_TIME;
+       gint64 dur_nsec = 0;
+       GstStructure* p = NULL;
+       MMHandleType attrs = 0;
+       gint retry_count = 0;
+       gint retry_count_max = 10;
+       gchar *path = NULL;
+       struct stat sb;
+
+       return_val_if_fail ( player, FALSE );
+
+       if ( ! player->need_update_content_attrs )
+       {
+               debug_log("content attributes are already updated");
+               return TRUE;
+       }
+
+       /* get content attribute first */
+       attrs = MMPLAYER_GET_ATTRS(player);
+       if ( !attrs )
+       {
+               debug_error("cannot get content attribute");
+               return FALSE;
+       }
+
+       /* update duration
+        * NOTE : we need to wait for a while until is possible to get duration from pipeline
+        * as getting duration timing is depends on behavier of demuxers ( or etc ).
+        * we set timeout 100ms * 10 as initial value. fix it if needed.
+        */
+       if ( player->need_update_content_dur  )
+       {
+               while ( retry_count <  retry_count_max)
+               {
+                       if ( FALSE == gst_element_query_duration( player->pipeline->mainbin[MMPLAYER_M_PIPE].gst,
+                               &fmt, &dur_nsec ) )
+                       {
+                               /* retry if failed */
+                               debug_warning("failed to get duraton. waiting 100ms and then retrying...");
+                               usleep(100000);
+                               retry_count++;
+                               continue;
+                       }
+
+                       if ( dur_nsec == 0 && ( !MMPLAYER_IS_LIVE_STREAMING( player ) ) )
+                       {
+                               /* retry if duration is zero in case of not live stream */
+                               debug_warning("returned duration is zero. but it's not an live stream. retrying...");
+                               usleep(100000);
+                               retry_count++;
+                               continue;
+                       }
+
+                       break;
+               }
+
+               player->duration = dur_nsec;
+               debug_log("duration : %lld msec", GST_TIME_AS_MSECONDS(dur_nsec));
+
+               /* try to get streaming service type */
+               __mmplayer_update_stream_service_type( player );
+
+               /* check duration is OK */
+               if ( dur_nsec == 0 && !MMPLAYER_IS_LIVE_STREAMING( player ) )
+               {
+                       /* FIXIT : find another way to get duration here. */
+                       debug_error("finally it's failed to get duration from pipeline. progressbar will not work correctely!");
+               }
+               else
+               {
+                       player->need_update_content_dur = FALSE;
+               }
+
+               /*update duration */
+               mm_attrs_set_int_by_name(attrs, "content_duration", GST_TIME_AS_MSECONDS(dur_nsec));
+       }
+       else
+       {
+               debug_log("not ready to get duration or already updated");
+       }
+
+       /* update rate, channels */
+       if ( player->pipeline->audiobin &&
+                player->pipeline->audiobin[MMPLAYER_A_SINK].gst )
+       {
+               GstCaps *caps_a = NULL;
+               GstPad* pad = NULL;
+               gint samplerate = 0, channels = 0;
+
+               pad = gst_element_get_static_pad(
+                               player->pipeline->audiobin[MMPLAYER_A_CONV].gst, "sink" );
+
+               if ( pad )
+               {
+                       caps_a = gst_pad_get_negotiated_caps( pad );
+
+                       if ( caps_a )
+                       {
+                               p = gst_caps_get_structure (caps_a, 0);
+
+                               mm_attrs_get_int_by_name(attrs, "content_audio_samplerate", &samplerate);
+                               if ( ! samplerate ) // check if update already or not
+                               {
+                                       gst_structure_get_int (p, "rate", &samplerate);
+                                       mm_attrs_set_int_by_name(attrs, "content_audio_samplerate", samplerate);
+
+                                       gst_structure_get_int (p, "channels", &channels);
+                                       mm_attrs_set_int_by_name(attrs, "content_audio_channels", channels);
+
+                                       debug_log("samplerate : %d      channels : %d", samplerate, channels);
+                               }
+                               gst_caps_unref( caps_a );
+                               caps_a = NULL;
+                       }
+                       else
+                       {
+                               debug_warning("not ready to get audio caps");
+                       }
+
+                       gst_object_unref( pad );
+               }
+               else
+               {
+                       debug_warning("failed to get pad from audiosink");
+               }
+       }
+
+       /* update width, height, framerate */
+       if ( player->pipeline->videobin &&
+                player->pipeline->videobin[MMPLAYER_V_SINK].gst )
+       {
+               GstCaps *caps_v = NULL;
+               GstPad* pad = NULL;
+               gint tmpNu, tmpDe;
+               gint width, height;
+
+               pad = gst_element_get_static_pad( player->pipeline->videobin[MMPLAYER_V_SINK].gst, "sink" );
+               if ( pad )
+               {
+                       caps_v = gst_pad_get_negotiated_caps( pad );
+                       if (caps_v)
+                       {
+                               p = gst_caps_get_structure (caps_v, 0);
+                               gst_structure_get_int (p, "width", &width);
+                               mm_attrs_set_int_by_name(attrs, "content_video_width", width);
+
+                               gst_structure_get_int (p, "height", &height);
+                               mm_attrs_set_int_by_name(attrs, "content_video_height", height);
+
+                               gst_structure_get_fraction (p, "framerate", &tmpNu, &tmpDe);
+
+                               debug_log("width : %d     height : %d", width, height );
+
+                               gst_caps_unref( caps_v );
+                               caps_v = NULL;
+
+                               if (tmpDe > 0)
+                               {
+                                       mm_attrs_set_int_by_name(attrs, "content_video_fps", tmpNu / tmpDe);
+                                       debug_log("fps : %d", tmpNu / tmpDe);
+                               }
+                       }
+                       else
+                       {
+                               debug_warning("failed to get negitiated caps from videosink");
+                       }
+                       gst_object_unref( pad );
+                       pad = NULL;
+               }
+               else
+               {
+                       debug_warning("failed to get pad from videosink");
+               }
+       }
+
+       if (player->duration)
+       {
+               guint64 data_size = 0;
+
+               if (!MMPLAYER_IS_STREAMING(player) && (player->can_support_codec & FOUND_PLUGIN_VIDEO))
+               {
+                       mm_attrs_get_string_by_name(attrs, "profile_uri", &path);
+
+                       if (stat(path, &sb) == 0)
+                       {
+                               data_size = (guint64)sb.st_size;
+                       }
+               }
+               else if (MMPLAYER_IS_HTTP_STREAMING(player))
+               {
+                       data_size = player->http_content_size;
+               }
+
+               if (data_size)
+               {
+                       guint64 bitrate = 0;
+                       guint64 msec_dur = 0;
+
+                       msec_dur = GST_TIME_AS_MSECONDS(player->duration);
+                       bitrate = data_size * 8 * 1000 / msec_dur;
+                       debug_log("file size : %u, video bitrate = %llu", data_size, bitrate);
+                       mm_attrs_set_int_by_name(attrs, "content_video_bitrate", bitrate);
+               }
+       }
+
+
+       /* validate all */
+       if (  mmf_attrs_commit ( attrs ) )
+       {
+               debug_error("failed to update attributes\n");
+               return FALSE;
+       }
+
+       player->need_update_content_attrs = FALSE;
+
+       return TRUE;
+}
+
+gboolean __mmplayer_update_stream_service_type( mm_player_t* player )
+{
+       MMHandleType attrs = 0;
+       gint streaming_type = STREAMING_SERVICE_NONE;
+
+       debug_fenter();
+
+       return_val_if_fail ( player &&
+                                       player->pipeline &&
+                                       player->pipeline->mainbin &&
+                                       player->pipeline->mainbin[MMPLAYER_M_SRC].gst,
+                                       FALSE );
+
+       /* streaming service type if streaming */
+       if ( ! MMPLAYER_IS_STREAMING(player) );
+               return FALSE;
+
+       if (MMPLAYER_IS_RTSP_STREAMING(player))
+       {
+               /* get property from rtspsrc element */
+               g_object_get(G_OBJECT(player->pipeline->mainbin[MMPLAYER_M_SRC].gst), "service_type", &streaming_type, NULL);
+       }
+       else if (MMPLAYER_IS_HTTP_STREAMING(player))
+       {
+               if ( player->duration == 0)
+                       streaming_type = STREAMING_SERVICE_LIVE;
+               else
+                       streaming_type = STREAMING_SERVICE_VOD;                 
+       }
+               
+       player->streaming_type = streaming_type;
+
+       if ( player->streaming_type == STREAMING_SERVICE_LIVE)
+       {
+               debug_log("It's live streaming. pause/resume/seek are not working.\n");
+       }
+       else if (player->streaming_type == STREAMING_SERVICE_LIVE)
+       {
+               debug_log("It's vod streaming. pause/resume/seek are working.\n");
+       }
+       else
+       {
+               debug_warning("fail to determine streaming type. pause/resume/seek may not working properly if stream is live stream\n");
+       }
+
+       /* get profile attribute */
+       attrs = MMPLAYER_GET_ATTRS(player);
+       if ( !attrs )
+       {
+               debug_error("cannot get content attribute\n");
+               return FALSE;
+       }
+
+       mm_attrs_set_int_by_name ( attrs, "streaming_type", streaming_type );
+       /* validate all */
+       if (  mmf_attrs_commit ( attrs ) )
+       {
+               debug_warning("updating streaming service type failed. pause/resume/seek may not working properly if stream is live stream\n");
+               return FALSE;
+       }
+
+       debug_fleave();
+
+       return TRUE;
+}
+
+
+/* this function sets the player state and also report
+ * it to applicaton by calling callback function
+ */
+static gboolean
+__mmplayer_set_state(mm_player_t* player, int state) // @
+{
+       MMMessageParamType msg = {0, };
+       int asm_result = MM_ERROR_NONE;
+
+       debug_fenter();
+       return_val_if_fail ( player, FALSE );
+
+       if ( MMPLAYER_CURRENT_STATE(player) == state )
+       {
+               debug_warning("already same state(%s)\n", MMPLAYER_STATE_GET_NAME(state));
+               MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_NONE;
+               return TRUE;
+       }
+
+       /* post message to application */
+       if (MMPLAYER_TARGET_STATE(player) == state)
+       {
+               /* fill the message with state of player */
+               msg.state.previous = MMPLAYER_CURRENT_STATE(player);
+               msg.state.current = state;
+
+               /* state changed by asm callback */
+               if ( player->sm.by_asm_cb )
+               {
+                       msg.union_type = MM_MSG_UNION_CODE;
+                       msg.code = player->sm.event_src;
+                       MMPLAYER_POST_MSG( player, MM_MESSAGE_STATE_INTERRUPTED, &msg );
+               }
+               /* state changed by usecase */
+               else
+               {
+                       MMPLAYER_POST_MSG( player, MM_MESSAGE_STATE_CHANGED, &msg );
+               }
+
+               debug_log ("player reach the target state, then do something in each state(%s).\n", 
+                       MMPLAYER_STATE_GET_NAME(MMPLAYER_TARGET_STATE(player)));
+       }
+       else
+       {
+               debug_log ("intermediate state, do nothing.\n");
+               MMPLAYER_PRINT_STATE(player);
+
+               return TRUE;
+       }
+
+       /* update player states */
+       MMPLAYER_PREV_STATE(player) = MMPLAYER_CURRENT_STATE(player);
+       MMPLAYER_CURRENT_STATE(player) = state;
+       if ( MMPLAYER_CURRENT_STATE(player) == MMPLAYER_PENDING_STATE(player) )
+               MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_NONE;
+
+       /* print state */
+       MMPLAYER_PRINT_STATE(player);
+       
+       switch ( MMPLAYER_TARGET_STATE(player) )
+       {
+               case MM_PLAYER_STATE_NULL:      
+               case MM_PLAYER_STATE_READY:
+               {
+                       if (player->cmd == MMPLAYER_COMMAND_STOP)
+                       {
+                               asm_result = _mmplayer_asm_set_state((MMHandleType)player, ASM_STATE_STOP);
+                               if ( asm_result != MM_ERROR_NONE )
+                               {
+                                       debug_error("failed to set asm state to stop\n");
+                                       return FALSE;
+                               }
+                       }
+               }
+               break;
+                       
+               case MM_PLAYER_STATE_PAUSED:
+               {
+                       /* special care for local playback. normaly we can get some content attribute
+                        * when the demuxer is changed to PAUSED. so we are trying it. it will be tried again
+                        * when PLAYING state has signalled if failed.
+                        * note that this is only happening pause command has come before the state of pipeline
+                        * reach to the PLAYING.
+                        */
+                        if ( ! player->sent_bos )
+                        {
+                               player->need_update_content_attrs = TRUE;
+                               player->need_update_content_dur = TRUE;
+                               _mmplayer_update_content_attrs( player );
+                        }
+
+                       /* add audio callback probe if condition is satisfied */
+                       if ( ! player->audio_cb_probe_id && player->is_sound_extraction )
+                               __mmplayer_configure_audio_callback(player);
+
+                       asm_result = _mmplayer_asm_set_state((MMHandleType)player, ASM_STATE_PAUSE);
+                       if ( asm_result )
+                       {
+                               debug_error("failed to set asm state to PAUSE\n");
+                               return FALSE;
+                       }
+               }
+               break;
+
+               case MM_PLAYER_STATE_PLAYING:
+               {
+                       /* non-managed prepare case, should be updated */
+                       if ( ! player->need_update_content_dur)
+                       {
+                               player->need_update_content_dur = TRUE;
+                               _mmplayer_update_content_attrs ( player );
+                       }
+                       if (MMPLAYER_IS_STREAMING(player))
+                       {
+                               /* force setting value to TRUE for streaming */
+                               player->need_update_content_attrs = TRUE;
+                               _mmplayer_update_content_attrs ( player );
+                       }
+
+                       if ( player->cmd == MMPLAYER_COMMAND_START  && !player->sent_bos )
+                       {
+                               __mmplayer_post_missed_plugin ( player );
+
+                               /* update video resource status */
+                               if ( ( player->can_support_codec & 0x02) == FOUND_PLUGIN_VIDEO )
+                               {
+                                       asm_result = _mmplayer_asm_set_state((MMHandleType)player, ASM_STATE_PLAYING);
+                                       if ( asm_result )
+                                       {
+                                               MMMessageParamType msg = {0, };
+                                                               
+                                               debug_error("failed to go ahead because of video conflict\n");
+                                                                                                       
+                                               msg.union_type = MM_MSG_UNION_CODE;
+                                               msg.code = MM_ERROR_POLICY_INTERRUPTED;
+                                               MMPLAYER_POST_MSG( player, MM_MESSAGE_STATE_INTERRUPTED, &msg);
+
+                                               _mmplayer_unrealize((MMHandleType)player);
+                                                                                                               
+                                               return FALSE;                                                           
+                                       }
+                               }
+                       }
+
+                       if ( player->resumed_by_rewind && player->playback_rate < 0.0 )
+                       {
+                               /* initialize because auto resume is done well. */
+                               player->resumed_by_rewind = FALSE;
+                               player->playback_rate = 1.0;
+                       }
+
+                       if ( !player->sent_bos )
+                       {
+                               /* check audio codec field is set or not
+                                * we can get it from typefinder or codec's caps.
+                                */
+                               gchar *audio_codec = NULL;
+                               mm_attrs_get_string_by_name(player->attrs, "content_audio_codec", &audio_codec);
+
+                               /* The codec format can't be sent for audio only case like amr, mid etc.
+                                * Because, parser don't make related TAG.
+                                * So, if it's not set yet, fill it with found data.
+                                */
+                               if ( ! audio_codec )
+                               {
+                                       if ( g_strrstr(player->type, "audio/midi"))
+                                       {
+                                               audio_codec = g_strdup("MIDI");
+
+                                       }
+                                       else if ( g_strrstr(player->type, "audio/x-amr"))
+                                       {
+                                               audio_codec = g_strdup("AMR");
+                                       }
+                                       else if ( g_strrstr(player->type, "audio/mpeg") && !g_strrstr(player->type, "mpegversion=(int)1"))
+                                       {
+                                               audio_codec = g_strdup("AAC");
+                                       }
+                                       else
+                                       {
+                                               audio_codec = g_strdup("unknown");
+                                       }
+                                       mm_attrs_set_string_by_name(player->attrs, "content_audio_codec", audio_codec);
+
+                                       MMPLAYER_FREEIF(audio_codec);
+                                       mmf_attrs_commit(player->attrs);
+                                       debug_log("set audio codec type with caps\n");
+                               }
+
+                               MMTA_ACUM_ITEM_END("[KPI] start media player service", FALSE);
+                               MMTA_ACUM_ITEM_END("[KPI] media player service create->playing", FALSE);
+
+                               MMPLAYER_POST_MSG ( player, MM_MESSAGE_BEGIN_OF_STREAM, NULL );
+                               player->sent_bos = TRUE;
+                       }
+               }
+               break;
+
+               case MM_PLAYER_STATE_NONE:
+               default:
+                       debug_warning("invalid target state, there is nothing to do.\n");
+                       break;
+       }
+
+       debug_fleave();
+
+       return TRUE;
+}
+
+
+gboolean
+__mmplayer_post_message(mm_player_t* player, enum MMMessageType msgtype, MMMessageParamType* param) // @
+{
+       return_val_if_fail( player, FALSE );
+
+       debug_fenter();
+
+       if ( !player->msg_cb )
+       {
+               debug_warning("no msg callback. can't post\n");
+               return FALSE;
+       }
+
+       //debug_log("Message (type : %d)  will be posted using msg-cb(%p). \n", msgtype, player->msg_cb);
+
+       player->msg_cb(msgtype, param, player->msg_cb_param);
+
+       debug_fleave();
+
+       return TRUE;
+}
+
+
+static int
+__mmplayer_get_state(mm_player_t* player) // @
+{
+       int state = MM_PLAYER_STATE_NONE;
+
+       debug_fenter();
+       
+       return_val_if_fail ( player, MM_PLAYER_STATE_NONE );
+
+       state = MMPLAYER_CURRENT_STATE(player);
+
+       debug_log("player state is %s.\n", MMPLAYER_STATE_GET_NAME(state));
+
+       debug_fleave();
+       
+       return state;
+}
+
+static void
+__gst_set_async_state_change(mm_player_t* player, gboolean async)
+{
+       //debug_fenter();
+       return_if_fail( player && player->pipeline && player->pipeline->mainbin );
+
+       /* need only when we are using decodebin */
+       if ( ! PLAYER_INI()->use_decodebin )
+               return;
+
+       /* audio sink */
+       if ( player->pipeline->audiobin &&
+                player->pipeline->audiobin[MMPLAYER_A_SINK].gst )
+       {
+               debug_log("audiosink async : %d\n", async);
+               g_object_set (G_OBJECT (player->pipeline->audiobin[MMPLAYER_A_SINK].gst), "async", async, NULL);
+       }
+
+       /* video sink */
+       if ( player->pipeline->videobin &&
+                player->pipeline->videobin[MMPLAYER_V_SINK].gst )
+       {
+               debug_log("videosink async : %d\n", async);
+               g_object_set (G_OBJECT (player->pipeline->videobin[MMPLAYER_V_SINK].gst), "async", async, NULL);
+       }
+
+       /* decodebin if enabled */
+       if ( PLAYER_INI()->use_decodebin )
+       {
+               debug_log("decodebin async : %d\n", async);
+               g_object_set (G_OBJECT (player->pipeline->mainbin[MMPLAYER_M_AUTOPLUG].gst), "async-handling", async, NULL);
+       }
+
+       //debug_fleave();
+}
+
+static gpointer __mmplayer_repeat_thread(gpointer data)
+{
+       mm_player_t* player = (mm_player_t*) data;
+       gboolean ret_value = FALSE;
+       MMHandleType attrs = 0;
+       gint count = 0;
+
+       return_val_if_fail ( player, NULL );
+
+       while ( ! player->repeat_thread_exit )
+       {
+               debug_log("repeat thread started. waiting for signal.\n");
+               g_cond_wait( player->repeat_thread_cond, player->repeat_thread_mutex );
+
+               if ( player->repeat_thread_exit )
+               {
+                       debug_log("exiting repeat thread\n");
+                       break;
+               }
+
+               if ( !player->cmd_lock )
+               {
+                       debug_log("can't get cmd lock\n");
+                       return NULL;
+               }
+
+               /* lock */
+               g_mutex_lock(player->cmd_lock); 
+
+               attrs = MMPLAYER_GET_ATTRS(player);
+
+               if (mm_attrs_get_int_by_name(attrs, "profile_play_count", &count) != MM_ERROR_NONE)
+               {
+                       debug_error("can not get play count\n");
+                       break;
+               }
+
+               if ( player->section_repeat )
+               {
+                       ret_value = _mmplayer_activate_section_repeat((MMHandleType)player, player->section_repeat_start, player->section_repeat_end);
+               }
+               else
+               {
+                       if ( player->playback_rate < 0.0 )
+                       {
+                               player->resumed_by_rewind = TRUE;
+                               _mmplayer_set_mute((MMHandleType)player, 0);
+                               MMPLAYER_POST_MSG( player, MM_MESSAGE_RESUMED_BY_REW, NULL );
+                       }
+
+                       ret_value = __gst_seek( player, player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, 1.0,
+                               GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET,
+                               0, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
+
+                       /* initialize */
+                       player->sent_bos = FALSE;
+               }
+
+               if ( ! ret_value )
+               {
+                       debug_error("failed to set position to zero for rewind\n");
+                       continue;
+               }
+
+               /* decrease play count */
+               if ( count > 1 )
+               {
+                       /* we successeded to rewind. update play count and then wait for next EOS */
+                       count--;
+
+                       mm_attrs_set_int_by_name(attrs, "profile_play_count", count);
+
+                       /* commit attribute */
+                       if ( mmf_attrs_commit ( attrs ) )
+                       {
+                               debug_error("failed to commit attribute\n");
+                       }
+               }
+
+               /* unlock */
+               g_mutex_unlock(player->cmd_lock);
+       }
+
+       return NULL;
+}
+
+static void
+__mmplayer_handle_buffering_message ( mm_player_t* player )
+{
+       MMPlayerStateType prev_state = MM_PLAYER_STATE_NONE;
+       MMPlayerStateType current_state = MM_PLAYER_STATE_NONE;
+       MMPlayerStateType target_state = MM_PLAYER_STATE_NONE;
+       MMPlayerStateType pending_state = MM_PLAYER_STATE_NONE;
+
+       return_if_fail ( player );
+
+       prev_state = MMPLAYER_PREV_STATE(player),
+       current_state = MMPLAYER_CURRENT_STATE(player);
+       target_state = MMPLAYER_TARGET_STATE(player);
+       pending_state = MMPLAYER_PENDING_STATE(player);
+
+       if ( MMPLAYER_IS_RTSP_STREAMING(player) )
+               return;
+
+       if ( !player->streamer->is_buffering )
+       {
+               debug_log( "player state : prev %s, current %s, pending %s, target %s \n",
+                       MMPLAYER_STATE_GET_NAME(prev_state),
+                       MMPLAYER_STATE_GET_NAME(current_state),
+                       MMPLAYER_STATE_GET_NAME(pending_state),
+                       MMPLAYER_STATE_GET_NAME(target_state));
+
+               /* NOTE : if buffering has done, player has to go to target state. */
+               switch ( target_state )
+               {
+                       case MM_PLAYER_STATE_PAUSED :
+                       {
+                               switch ( pending_state )
+                               {
+                                       case MM_PLAYER_STATE_PLAYING:
+                                       {
+                                               __gst_pause ( player, TRUE );
+                                       }
+                                       break;
+
+                                       case MM_PLAYER_STATE_PAUSED:
+                                       {
+                                                debug_log("player is already going to paused state, there is nothing to do.\n");
+                                       }
+                                       break;
+
+                                       case MM_PLAYER_STATE_NONE:
+                                       case MM_PLAYER_STATE_NULL:
+                                       case MM_PLAYER_STATE_READY:
+                                       default :
+                                       {
+                                               debug_warning("invalid pending state [%s].\n", MMPLAYER_STATE_GET_NAME(pending_state) );
+                                       }
+                                               break;
+                               }
+                       }
+                       break;
+
+                       case MM_PLAYER_STATE_PLAYING :
+                       {
+                               switch ( pending_state )
+                               {
+                                       case MM_PLAYER_STATE_NONE:
+                                       {
+                                               if (current_state != MM_PLAYER_STATE_PLAYING)
+                                                       __gst_resume ( player, TRUE );
+                                       }
+                                       break;
+
+                                       case MM_PLAYER_STATE_PAUSED:
+                                       {
+                                               /* NOTE: It should be worked as asynchronously.
+                                                * Because, buffering can be completed during autoplugging when pipeline would try to go playing state directly.
+                                                */
+                                               __gst_resume ( player, TRUE );
+                                       }
+                                       break;
+
+                                       case MM_PLAYER_STATE_PLAYING:
+                                       {
+                                                debug_log("player is already going to playing state, there is nothing to do.\n");
+                                       }
+                                       break;
+
+                                       case MM_PLAYER_STATE_NULL:
+                                       case MM_PLAYER_STATE_READY:
+                                       default :
+                                       {
+                                               debug_warning("invalid pending state [%s].\n", MMPLAYER_STATE_GET_NAME(pending_state) );
+                                       }
+                                               break;
+                               }
+                       }
+                       break;
+
+                       case MM_PLAYER_STATE_NULL :
+                       case MM_PLAYER_STATE_READY :
+                       case MM_PLAYER_STATE_NONE :
+                       default:
+                       {
+                               debug_warning("invalid target state [%s].\n", MMPLAYER_STATE_GET_NAME(target_state) );
+                       }
+                               break;
+               }
+       }
+       else
+       {
+               /* NOTE : during the buffering, pause the player for stopping pipeline clock.
+                *      it's for stopping the pipeline clock to prevent dropping the data in sink element.
+                */
+               switch ( pending_state )
+               {
+                       case MM_PLAYER_STATE_NONE:
+                       {
+                               if (current_state != MM_PLAYER_STATE_PAUSED)
+                                       __gst_pause ( player, TRUE );
+                       }
+                       break;
+
+                       case MM_PLAYER_STATE_PLAYING:
+                       {
+                               __gst_pause ( player, TRUE );
+                       }
+                       break;
+
+                       case MM_PLAYER_STATE_PAUSED:
+                       {
+                                debug_log("player is already going to paused state, there is nothing to do.\n");
+                       }
+                       break;
+
+                       case MM_PLAYER_STATE_NULL:
+                       case MM_PLAYER_STATE_READY:
+                       default :
+                       {
+                               debug_warning("invalid pending state [%s].\n", MMPLAYER_STATE_GET_NAME(pending_state) );
+                       }
+                               break;
+               }
+       }
+}
+
+static gboolean
+__mmplayer_gst_callback(GstBus *bus, GstMessage *msg, gpointer data) // @
+{
+       mm_player_t* player = (mm_player_t*) data;
+       gboolean ret = TRUE;
+       static gboolean async_done = FALSE;
+
+       return_val_if_fail ( player, FALSE );
+       return_val_if_fail ( msg && GST_IS_MESSAGE(msg), FALSE );
+
+       switch ( GST_MESSAGE_TYPE( msg ) )
+       {
+               case GST_MESSAGE_UNKNOWN:
+                       debug_warning("unknown message received\n");
+               break;
+
+               case GST_MESSAGE_EOS:
+               {
+                       MMHandleType attrs = 0;
+                       gint count = 0;
+
+                       debug_log("GST_MESSAGE_EOS received\n");
+
+                       /* NOTE : EOS event is comming multiple time. watch out it */
+                       /* check state. we only process EOS when pipeline state goes to PLAYING */
+                       if ( ! (player->cmd == MMPLAYER_COMMAND_START || player->cmd == MMPLAYER_COMMAND_RESUME) )
+                       {
+                               debug_warning("EOS received on non-playing state. ignoring it\n");
+                               break;
+                       }
+
+                       if ( (player->audio_stream_cb) && (player->is_sound_extraction) )
+                       {
+                               GstPad *pad = NULL;
+       
+                               pad = gst_element_get_static_pad (player->pipeline->audiobin[MMPLAYER_A_SINK].gst, "sink");
+
+                               debug_error("release audio callback\n");
+                               
+                               /* release audio callback */
+                               gst_pad_remove_buffer_probe (pad, player->audio_cb_probe_id);
+                               player->audio_cb_probe_id = 0;
+                               /* audio callback should be free because it can be called even though probe remove.*/
+                               player->audio_stream_cb = NULL;
+                               player->audio_stream_cb_user_param = NULL;
+
+                       }
+
+                       /* rewind if repeat count is greater then zero */
+                       /* get play count */
+                       attrs = MMPLAYER_GET_ATTRS(player);
+
+                       if ( attrs )
+                       {
+                               gboolean smooth_repeat = FALSE;
+
+                               mm_attrs_get_int_by_name(attrs, "profile_play_count", &count);
+                               mm_attrs_get_int_by_name(attrs, "profile_smooth_repeat", &smooth_repeat);
+
+                               debug_log("remaining play count: %d, playback rate: %f\n", count, player->playback_rate);
+
+                               if ( count > 1 || count == -1 || player->playback_rate < 0.0 ) /* default value is 1 */
+                               {
+                                       if ( smooth_repeat )
+                                       {
+                                               debug_log("smooth repeat enabled. seeking operation will be excuted in new thread\n");
+
+                                               g_cond_signal( player->repeat_thread_cond );
+
+                                               break;
+                                       }
+                                       else
+                                       {
+                                               gint ret_value = 0;
+
+                                               if ( player->section_repeat )
+                                               {
+                                                       ret_value = _mmplayer_activate_section_repeat((MMHandleType)player, player->section_repeat_start, player->section_repeat_end);
+                                               }
+                                               else
+                                               {
+
+                                                       if ( player->playback_rate < 0.0 )
+                                                       {
+                                                       player->resumed_by_rewind = TRUE;
+                                                               _mmplayer_set_mute((MMHandleType)player, 0);
+                                                               MMPLAYER_POST_MSG( player, MM_MESSAGE_RESUMED_BY_REW, NULL );
+                                                       }
+
+                                                       ret_value = __gst_set_position( player, MM_PLAYER_POS_FORMAT_TIME, 0, TRUE);
+
+                                                       /* initialize */
+                                                       player->sent_bos = FALSE;
+                                               }
+
+                                               if ( MM_ERROR_NONE != ret_value )
+                                               {
+                                                       debug_error("failed to set position to zero for rewind\n");
+                                               }
+                                               else
+                                               {
+                                                       if ( count > 1 )
+                                                       {
+                                                               /* we successeded to rewind. update play count and then wait for next EOS */
+                                                               count--;
+
+                                                               mm_attrs_set_int_by_name(attrs, "profile_play_count", count);
+
+                                                               if ( mmf_attrs_commit ( attrs ) )
+                                                                       debug_error("failed to commit attrs\n");
+                                                       }
+                                               }
+
+                                               break;
+                                       }
+                               }
+                       }
+
+                       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-eos" );
+
+                       /* post eos message to application */
+                       __mmplayer_post_delayed_eos( player, PLAYER_INI()->eos_delay );
+
+                       /* reset last position */
+                       player->last_position = 0;
+               }
+               break;
+
+               case GST_MESSAGE_ERROR:
+               {
+                       GError *error = NULL;
+                       gchar* debug = NULL;
+                       gchar *msg_src_element = NULL;
+
+                       /* generating debug info before returning error */
+                       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-error" );
+
+                       /* get error code */
+                       gst_message_parse_error( msg, &error, &debug );
+
+                       msg_src_element = GST_ELEMENT_NAME( GST_ELEMENT_CAST( msg->src ) );
+                       if ( gst_structure_has_name ( msg->structure, "streaming_error" ) )
+                       {
+                               /* Note : the streaming error from the streaming source is handled
+                                *   using __mmplayer_handle_streaming_error.
+                                */
+                               __mmplayer_handle_streaming_error ( player, msg );
+
+                               /* dump state of all element */
+                               __mmplayer_dump_pipeline_state( player );
+                       }
+                       else
+                       {
+                               /* traslate gst error code to msl error code. then post it
+                                * to application if needed
+                                */
+                               __mmplayer_handle_gst_error( player, msg, error );
+
+                               /* dump state of all element */
+                               __mmplayer_dump_pipeline_state( player );
+
+                       }
+
+                       if (MMPLAYER_IS_HTTP_PD(player))
+                       {       
+                               _mmplayer_unrealize_pd_downloader ((MMHandleType)player);
+                       }
+                       
+                       MMPLAYER_FREEIF( debug );
+                       g_error_free( error );
+               }
+               break;
+
+               case GST_MESSAGE_WARNING:
+               {
+                       char* debug = NULL;
+                       GError* error = NULL;
+
+                       gst_message_parse_warning(msg, &error, &debug);
+
+                       debug_warning("warning : %s\n", error->message);
+                       debug_warning("debug : %s\n", debug);
+
+                       MMPLAYER_POST_MSG( player, MM_MESSAGE_WARNING, NULL );
+
+                       MMPLAYER_FREEIF( debug );
+                       g_error_free( error );
+               }
+               break;
+
+               case GST_MESSAGE_INFO:                          debug_log("GST_MESSAGE_STATE_DIRTY\n"); break;
+
+               case GST_MESSAGE_TAG:
+               {
+                       debug_log("GST_MESSAGE_TAG\n");
+                       if ( ! __mmplayer_gst_extract_tag_from_msg( player, msg ) )
+                       {
+                               debug_warning("failed to extract tags from gstmessage\n");
+                       }
+               }
+               break;
+
+               case GST_MESSAGE_BUFFERING:
+               {
+                       MMMessageParamType msg_param = {0, };
+                       gboolean update_buffering_percent = TRUE;
+
+                       if ( !MMPLAYER_IS_STREAMING(player) || (player->profile.uri_type == MM_PLAYER_URI_TYPE_HLS) ) // pure hlsdemux case, don't consider buffering of msl currently
+                               break;
+
+                       __mm_player_streaming_buffering (player->streamer, msg);
+
+                       __mmplayer_handle_buffering_message ( player );
+
+                       update_buffering_percent = (player->pipeline_is_constructed || MMPLAYER_IS_RTSP_STREAMING(player) );
+                       if (update_buffering_percent)
+                       {
+                               msg_param.connection.buffering = player->streamer->buffering_percent;
+                               MMPLAYER_POST_MSG ( player, MM_MESSAGE_BUFFERING, &msg_param );
+                       }
+               }
+               break;
+
+               case GST_MESSAGE_STATE_CHANGED:
+               {
+                       MMPlayerGstElement *mainbin;
+                       const GValue *voldstate, *vnewstate, *vpending;
+                       GstState oldstate, newstate, pending;
+
+                       if ( ! ( player->pipeline && player->pipeline->mainbin ) )
+                       {
+                               debug_error("player pipeline handle is null");
+
+                               break;
+                       }
+
+                       mainbin = player->pipeline->mainbin;
+
+                       /* get state info from msg */
+                       voldstate = gst_structure_get_value (msg->structure, "old-state");
+                       vnewstate = gst_structure_get_value (msg->structure, "new-state");
+                       vpending = gst_structure_get_value (msg->structure, "pending-state");
+
+                       oldstate = (GstState)voldstate->data[0].v_int;
+                       newstate = (GstState)vnewstate->data[0].v_int;
+                       pending = (GstState)vpending->data[0].v_int;
+
+                       if (oldstate == newstate)
+                               break;
+
+                       debug_log("state changed [%s] : %s ---> %s     final : %s\n",
+                               GST_OBJECT_NAME(GST_MESSAGE_SRC(msg)),
+                               gst_element_state_get_name( (GstState)oldstate ),
+                               gst_element_state_get_name( (GstState)newstate ),
+                               gst_element_state_get_name( (GstState)pending ) );
+
+                       /* we only handle messages from pipeline */
+                       if( msg->src != (GstObject *)mainbin[MMPLAYER_M_PIPE].gst )
+                               break;
+
+                       switch(newstate)
+                       {
+                               case GST_STATE_VOID_PENDING:
+                               break;
+
+                               case GST_STATE_NULL:
+                               break;
+
+                               case GST_STATE_READY:
+                               break;
+
+                               case GST_STATE_PAUSED:
+                               {
+                                       gboolean prepare_async = FALSE;
+
+                                       player->need_update_content_dur = TRUE;
+
+                                       if ( ! player->audio_cb_probe_id && player->is_sound_extraction )
+                                               __mmplayer_configure_audio_callback(player);
+
+                                       if ( ! player->sent_bos && oldstate == GST_STATE_READY) // managed prepare async case
+                                       {
+                                               mm_attrs_get_int_by_name(player->attrs, "profile_prepare_async", &prepare_async);
+                                               debug_log("checking prepare mode for async transition - %d", prepare_async);
+                                       }
+
+                                       if ( MMPLAYER_IS_STREAMING(player) || prepare_async )
+                                       {
+                                               MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_PAUSED );
+
+                                               if (player->streamer)
+                                                       __mm_player_streaming_set_content_bitrate(player->streamer, player->total_maximum_bitrate, player->total_bitrate);
+                                       }
+                               }                                       
+                               break;
+
+                               case GST_STATE_PLAYING:
+                               {
+                                       if (player->doing_seek && async_done)
+                                       {
+                                               player->doing_seek = FALSE;
+                                               async_done = FALSE;
+                                               MMPLAYER_POST_MSG ( player, MM_MESSAGE_SEEK_COMPLETED, NULL );
+                                       }
+
+                                       if ( MMPLAYER_IS_STREAMING(player) ) // managed prepare async case when buffering is completed
+                                       {
+                                               // pending state should be reset oyherwise, it's still playing even though it's resumed after bufferging.
+                                               MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_PLAYING);
+                                       }
+                               }
+                               break;
+
+                               default:
+                               break;
+                       }
+               }
+               break;
+
+               case GST_MESSAGE_STATE_DIRTY:           debug_log("GST_MESSAGE_STATE_DIRTY\n"); break;
+               case GST_MESSAGE_STEP_DONE:                     debug_log("GST_MESSAGE_STEP_DONE\n"); break;
+               case GST_MESSAGE_CLOCK_PROVIDE:         debug_log("GST_MESSAGE_CLOCK_PROVIDE\n"); break;
+               
+               case GST_MESSAGE_CLOCK_LOST:
+                       {
+                               GstClock *clock = NULL;
+                               gst_message_parse_clock_lost (msg, &clock);
+                               debug_log("GST_MESSAGE_CLOCK_LOST : %s\n", (clock ? GST_OBJECT_NAME (clock) : "NULL"));
+                               g_print ("GST_MESSAGE_CLOCK_LOST : %s\n", (clock ? GST_OBJECT_NAME (clock) : "NULL"));
+
+                               if (PLAYER_INI()->provide_clock)
+                               {
+                                       debug_log ("Provide clock is TRUE, do pause->resume\n");
+                                       __gst_pause(player, FALSE);
+                                       __gst_resume(player, FALSE);
+                               }
+                       }
+                       break;
+                       
+               case GST_MESSAGE_NEW_CLOCK:
+                       {
+                               GstClock *clock = NULL;
+                               gst_message_parse_new_clock (msg, &clock);
+                               debug_log("GST_MESSAGE_NEW_CLOCK : %s\n", (clock ? GST_OBJECT_NAME (clock) : "NULL"));
+                       }
+                       break;
+
+               case GST_MESSAGE_STRUCTURE_CHANGE:      debug_log("GST_MESSAGE_STRUCTURE_CHANGE\n"); break;
+               case GST_MESSAGE_STREAM_STATUS:         debug_log("GST_MESSAGE_STREAM_STATUS\n"); break;
+               case GST_MESSAGE_APPLICATION:           debug_log("GST_MESSAGE_APPLICATION\n"); break;
+
+               case GST_MESSAGE_ELEMENT:
+               {
+                       debug_log("GST_MESSAGE_ELEMENT\n");
+               }
+               break;
+               
+               case GST_MESSAGE_SEGMENT_START:         debug_log("GST_MESSAGE_SEGMENT_START\n"); break;
+               case GST_MESSAGE_SEGMENT_DONE:          debug_log("GST_MESSAGE_SEGMENT_DONE\n"); break;
+               
+               case GST_MESSAGE_DURATION:
+               {
+                       debug_log("GST_MESSAGE_DURATION\n");
+
+                       if (MMPLAYER_IS_STREAMING(player))
+                       {
+                               GstFormat format;
+                               gint64 bytes = 0;
+
+                               gst_message_parse_duration (msg, &format, &bytes);
+                               if (format == GST_FORMAT_BYTES)
+                               {
+                                       debug_log("data total size of http content: %lld", bytes);
+                                       player->http_content_size = bytes;
+                               }
+                       }
+
+                       player->need_update_content_attrs = TRUE;
+                       player->need_update_content_dur = TRUE;
+                       _mmplayer_update_content_attrs(player);
+               }
+               break;
+
+               case GST_MESSAGE_LATENCY:                               debug_log("GST_MESSAGE_LATENCY\n"); break;
+               case GST_MESSAGE_ASYNC_START:           debug_log("GST_MESSAGE_ASYNC_DONE : %s\n", gst_element_get_name(GST_MESSAGE_SRC(msg))); break;
+               
+               case GST_MESSAGE_ASYNC_DONE:    
+               {
+                       debug_log("GST_MESSAGE_ASYNC_DONE : %s\n", gst_element_get_name(GST_MESSAGE_SRC(msg)));
+
+                       if (player->doing_seek)
+                       {
+                               if (MMPLAYER_TARGET_STATE(player) == MM_PLAYER_STATE_PAUSED)
+                               {
+                                       player->doing_seek = FALSE;
+                                       MMPLAYER_POST_MSG ( player, MM_MESSAGE_SEEK_COMPLETED, NULL );
+                               }
+                               else if (MMPLAYER_TARGET_STATE(player) == MM_PLAYER_STATE_PLAYING)
+                               {
+                                       async_done = TRUE;
+                               }
+                       }
+               }
+               break;
+               
+               case GST_MESSAGE_REQUEST_STATE:         debug_log("GST_MESSAGE_REQUEST_STATE\n"); break;
+               case GST_MESSAGE_STEP_START:            debug_log("GST_MESSAGE_STEP_START\n"); break;
+               case GST_MESSAGE_QOS:                                   debug_log("GST_MESSAGE_QOS\n"); break;
+               case GST_MESSAGE_PROGRESS:                      debug_log("GST_MESSAGE_PROGRESS\n"); break;
+               case GST_MESSAGE_ANY:                           debug_log("GST_MESSAGE_ANY\n"); break;
+
+               default:
+                       debug_warning("unhandled message\n");
+               break;
+       }
+
+       /* FIXIT : this cause so many warnings/errors from glib/gstreamer. we should not call it since
+        * gst_element_post_message api takes ownership of the message.
+        */
+       //gst_message_unref( msg );
+
+       return ret;
+}
+
+static gboolean
+__mmplayer_gst_extract_tag_from_msg(mm_player_t* player, GstMessage* msg) // @
+{
+
+/* macro for better code readability */
+#define MMPLAYER_UPDATE_TAG_STRING(gsttag, attribute, playertag) \
+if (gst_tag_list_get_string(tag_list, gsttag, &string)) \
+{\
+       if (string != NULL)\
+       {\
+               debug_log ( "update tag string : %s\n", string); \
+               mm_attrs_set_string_by_name(attribute, playertag, string); \
+               g_free(string);\
+               string = NULL;\
+       }\
+}
+
+#define MMPLAYER_UPDATE_TAG_IMAGE(gsttag, attribute, playertag) \
+value = gst_tag_list_get_value_index(tag_list, gsttag, index); \
+if (value) \
+{\
+       buffer = gst_value_get_buffer (value); \
+       debug_log ( "update album cover data : %p, size : %d\n", GST_BUFFER_DATA(buffer), GST_BUFFER_SIZE(buffer)); \
+       player->album_art = (gchar *)g_malloc(GST_BUFFER_SIZE(buffer)); \
+       if (player->album_art); \
+       { \
+               memcpy(player->album_art, GST_BUFFER_DATA(buffer), GST_BUFFER_SIZE(buffer)); \
+               mm_attrs_set_data_by_name(attribute, playertag, (void *)player->album_art, GST_BUFFER_SIZE(buffer)); \
+       } \
+}
+
+#define MMPLAYER_UPDATE_TAG_UINT(gsttag, attribute, playertag) \
+if (gst_tag_list_get_uint(tag_list, gsttag, &v_uint))\
+{\
+       if(v_uint)\
+       {\
+               if(gsttag==GST_TAG_BITRATE)\
+               {\
+                       if (player->updated_bitrate_count == 0) \
+                               mm_attrs_set_int_by_name(attribute, "content_audio_bitrate", v_uint); \
+                       if (player->updated_bitrate_count<MM_PLAYER_STREAM_COUNT_MAX) \
+                       {\
+                               player->bitrate[player->updated_bitrate_count] = v_uint;\
+                               player->total_bitrate += player->bitrate[player->updated_maximum_bitrate_count]; \
+                               player->updated_bitrate_count++; \
+                               mm_attrs_set_int_by_name(attribute, playertag, player->total_bitrate);\
+                               debug_log ( "update bitrate %d[bps] of stream #%d.\n", v_uint, player->updated_bitrate_count);\
+                       }\
+               }\
+               else if (gsttag==GST_TAG_MAXIMUM_BITRATE)\
+               {\
+                       if (player->updated_maximum_bitrate_count<MM_PLAYER_STREAM_COUNT_MAX) \
+                       {\
+                               player->maximum_bitrate[player->updated_maximum_bitrate_count] = v_uint;\
+                               player->total_maximum_bitrate += player->maximum_bitrate[player->updated_maximum_bitrate_count]; \
+                               player->updated_maximum_bitrate_count++; \
+                               mm_attrs_set_int_by_name(attribute, playertag, player->total_maximum_bitrate); \
+                               debug_log ( "update maximum bitrate %d[bps] of stream #%d\n", v_uint, player->updated_maximum_bitrate_count);\
+                       }\
+               }\
+               else\
+               {\
+                       mm_attrs_set_int_by_name(attribute, playertag, v_uint); \
+               }\
+               v_uint = 0;\
+       }\
+}
+
+#define MMPLAYER_UPDATE_TAG_DATE(gsttag, attribute, playertag) \
+if (gst_tag_list_get_date(tag_list, gsttag, &date))\
+{\
+       if (date != NULL)\
+       {\
+               string = g_strdup_printf("%d", g_date_get_year(date));\
+               mm_attrs_set_string_by_name(attribute, playertag, string);\
+               debug_log ( "metainfo year : %s\n", string);\
+               MMPLAYER_FREEIF(string);\
+               g_date_free(date);\
+       }\
+}
+
+#define MMPLAYER_UPDATE_TAG_UINT64(gsttag, attribute, playertag) \
+if(gst_tag_list_get_uint64(tag_list, gsttag, &v_uint64))\
+{\
+       if(v_uint64)\
+       {\
+               /* FIXIT : don't know how to store date */\
+               g_assert(1);\
+               v_uint64 = 0;\
+       }\
+}
+
+#define MMPLAYER_UPDATE_TAG_DOUBLE(gsttag, attribute, playertag) \
+if(gst_tag_list_get_double(tag_list, gsttag, &v_double))\
+{\
+       if(v_double)\
+       {\
+               /* FIXIT : don't know how to store date */\
+               g_assert(1);\
+               v_double = 0;\
+       }\
+}
+
+       /* function start */
+       GstTagList* tag_list = NULL;
+
+       MMHandleType attrs = 0;
+
+       char *string = NULL;
+       guint v_uint = 0;
+       GDate *date = NULL;
+       /* album cover */
+       GstBuffer *buffer = NULL;
+       gint index = 0;
+       const GValue *value;
+
+       /* currently not used. but those are needed for above macro */
+       //guint64 v_uint64 = 0;
+       //gdouble v_double = 0;
+
+       return_val_if_fail( player && msg, FALSE );
+
+       attrs = MMPLAYER_GET_ATTRS(player);
+
+       return_val_if_fail( attrs, FALSE );
+
+       /* get tag list from gst message */
+       gst_message_parse_tag(msg, &tag_list);
+
+       /* store tags to player attributes */
+       MMPLAYER_UPDATE_TAG_STRING(GST_TAG_TITLE, attrs, "tag_title");
+       /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_TITLE_SORTNAME, ?, ?); */
+       MMPLAYER_UPDATE_TAG_STRING(GST_TAG_ARTIST, attrs, "tag_artist");
+       /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_ARTIST_SORTNAME, ?, ?); */
+       MMPLAYER_UPDATE_TAG_STRING(GST_TAG_ALBUM, attrs, "tag_album");
+       /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_ALBUM_SORTNAME, ?, ?); */
+       MMPLAYER_UPDATE_TAG_STRING(GST_TAG_COMPOSER, attrs, "tag_author");
+       MMPLAYER_UPDATE_TAG_DATE(GST_TAG_DATE, attrs, "tag_date");
+       MMPLAYER_UPDATE_TAG_STRING(GST_TAG_GENRE, attrs, "tag_genre");
+       /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_COMMENT, ?, ?); */
+       /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_EXTENDED_COMMENT, ?, ?); */
+       MMPLAYER_UPDATE_TAG_UINT(GST_TAG_TRACK_NUMBER, attrs, "tag_track_num");
+       /* MMPLAYER_UPDATE_TAG_UINT(GST_TAG_TRACK_COUNT, ?, ?); */
+       /* MMPLAYER_UPDATE_TAG_UINT(GST_TAG_ALBUM_VOLUME_NUMBER, ?, ?); */
+       /* MMPLAYER_UPDATE_TAG_UINT(GST_TAG_ALBUM_VOLUME_COUNT, ?, ?); */
+       /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_LOCATION, ?, ?); */
+       MMPLAYER_UPDATE_TAG_STRING(GST_TAG_DESCRIPTION, attrs, "tag_description");
+       /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_VERSION, ?, ?); */
+       /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_ISRC, ?, ?); */
+       /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_ORGANIZATION, ?, ?); */
+       MMPLAYER_UPDATE_TAG_STRING(GST_TAG_COPYRIGHT, attrs, "tag_copyright");
+       /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_COPYRIGHT_URI, ?, ?); */
+       /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_CONTACT, ?, ?); */
+       /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_LICENSE, ?, ?); */
+       /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_LICENSE_URI, ?, ?); */
+       /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_PERFORMER, ?, ?); */
+       /* MMPLAYER_UPDATE_TAG_UINT64(GST_TAG_DURATION, ?, ?); */
+       /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_CODEC, ?, ?); */
+       MMPLAYER_UPDATE_TAG_STRING(GST_TAG_VIDEO_CODEC, attrs, "content_video_codec");
+       MMPLAYER_UPDATE_TAG_STRING(GST_TAG_AUDIO_CODEC, attrs, "content_audio_codec");
+       MMPLAYER_UPDATE_TAG_UINT(GST_TAG_BITRATE, attrs, "content_bitrate");
+       MMPLAYER_UPDATE_TAG_UINT(GST_TAG_MAXIMUM_BITRATE, attrs, "content_max_bitrate");
+       MMPLAYER_UPDATE_TAG_IMAGE(GST_TAG_IMAGE, attrs, "tag_album_cover");
+       /* MMPLAYER_UPDATE_TAG_UINT(GST_TAG_NOMINAL_BITRATE, ?, ?); */
+       /* MMPLAYER_UPDATE_TAG_UINT(GST_TAG_MINIMUM_BITRATE, ?, ?); */
+       /* MMPLAYER_UPDATE_TAG_UINT(GST_TAG_SERIAL, ?, ?); */
+       /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_ENCODER, ?, ?); */
+       /* MMPLAYER_UPDATE_TAG_UINT(GST_TAG_ENCODER_VERSION, ?, ?); */
+       /* MMPLAYER_UPDATE_TAG_DOUBLE(GST_TAG_TRACK_GAIN, ?, ?); */
+       /* MMPLAYER_UPDATE_TAG_DOUBLE(GST_TAG_TRACK_PEAK, ?, ?); */
+       /* MMPLAYER_UPDATE_TAG_DOUBLE(GST_TAG_ALBUM_GAIN, ?, ?); */
+       /* MMPLAYER_UPDATE_TAG_DOUBLE(GST_TAG_ALBUM_PEAK, ?, ?); */
+       /* MMPLAYER_UPDATE_TAG_DOUBLE(GST_TAG_REFERENCE_LEVEL, ?, ?); */
+       /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_LANGUAGE_CODE, ?, ?); */
+       /* MMPLAYER_UPDATE_TAG_DOUBLE(GST_TAG_BEATS_PER_MINUTE, ?, ?); */
+
+       if ( mmf_attrs_commit ( attrs ) )
+               debug_error("failed to commit.\n");
+
+       gst_tag_list_free(tag_list);
+
+       return TRUE;
+}
+
+static void
+__mmplayer_gst_rtp_no_more_pads (GstElement *element,  gpointer data)  // @
+{
+       mm_player_t* player = (mm_player_t*) data;
+
+       debug_fenter();
+
+       /* NOTE : we can remove fakesink here if there's no rtp_dynamic_pad. because whenever
+         * we connect autoplugging element to the pad which is just added to rtspsrc, we increase
+         * num_dynamic_pad. and this is no-more-pad situation which means mo more pad will be added.
+         * So we can say this. if num_dynamic_pad is zero, it must be one of followings
+
+         * [1] audio and video will be dumped with filesink.
+         * [2] autoplugging is done by just using pad caps.
+         * [3] typefinding has happend in audio but audiosink is created already before no-more-pad signal
+         * and the video will be dumped via filesink.
+         */
+       if ( player->num_dynamic_pad == 0 )
+       {
+               debug_log("it seems pad caps is directely used for autoplugging. removing fakesink now\n");
+
+               if ( ! __mmplayer_gst_remove_fakesink( player,
+                       &player->pipeline->mainbin[MMPLAYER_M_SRC_FAKESINK]) )
+               {
+                       /* NOTE : __mmplayer_pipeline_complete() can be called several time. because
+                        * signaling mechanism ( pad-added, no-more-pad, new-decoded-pad ) from various
+                        * source element are not same. To overcome this situation, this function will called
+                        * several places and several times. Therefore, this is not an error case.
+                        */
+                       return;
+               }
+       }
+
+       /* create dot before error-return. for debugging */
+       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-no-more-pad" );
+
+       /* NOTE : if rtspsrc goes to PLAYING before adding it's src pads, a/v sink elements will
+        * not goes to PLAYING. they will just remain in PAUSED state. simply we are giving
+        * PLAYING state again.
+        */
+       __mmplayer_gst_set_state(player,
+               player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_PLAYING, TRUE, 5000 );
+
+       player->no_more_pad = TRUE;
+
+       debug_fleave();
+}
+
+static gboolean
+__mmplayer_gst_remove_fakesink(mm_player_t* player, MMPlayerGstElement* fakesink) // @
+{
+       GstElement* parent = NULL;
+
+       return_val_if_fail(player && player->pipeline && fakesink, FALSE);
+
+       /* lock */
+       g_mutex_lock( player->fsink_lock );
+
+       if ( ! fakesink->gst )
+       {
+               goto ERROR;
+       }
+
+       /* get parent of fakesink */
+       parent = (GstElement*)gst_object_get_parent( (GstObject*)fakesink->gst );
+       if ( ! parent )
+       {
+               debug_log("fakesink already removed\n");
+               goto ERROR;
+       }
+
+       gst_element_set_locked_state( fakesink->gst, TRUE );
+
+       /* setting the state to NULL never returns async
+        * so no need to wait for completion of state transiton
+        */
+       if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state (fakesink->gst, GST_STATE_NULL) )
+       {
+               debug_error("fakesink state change failure!\n");
+
+               /* FIXIT : should I return here? or try to proceed to next? */
+               /* return FALSE; */
+       }
+
+       /* remove fakesink from it's parent */
+       if ( ! gst_bin_remove( GST_BIN( parent ), fakesink->gst ) )
+       {
+               debug_error("failed to remove fakesink\n");
+
+               gst_object_unref( parent );
+
+               goto ERROR;
+       }
+
+       gst_object_unref( parent );
+
+       /* FIXIT : releasing fakesink takes too much time (around 700ms)
+        * we need to figure out the reason why. just for now, fakesink will be released
+        * in __mmplayer_gst_destroy_pipeline()
+        */
+       //      gst_object_unref ( fakesink->gst );
+       //      fakesink->gst = NULL;
+
+       debug_log("state-holder removed\n");
+
+       gst_element_set_locked_state( fakesink->gst, FALSE );
+
+       g_mutex_unlock( player->fsink_lock );
+       return TRUE;
+
+ERROR:
+       if ( fakesink->gst )
+       {
+               gst_element_set_locked_state( fakesink->gst, FALSE );
+       }
+
+       g_mutex_unlock( player->fsink_lock );
+       return FALSE;
+}
+
+
+static void
+__mmplayer_gst_rtp_dynamic_pad (GstElement *element, GstPad *pad, gpointer data) // @
+{
+       GstPad *sinkpad = NULL;
+       GstCaps* caps = NULL;
+       GstElement* new_element = NULL;
+
+       mm_player_t* player = (mm_player_t*) data;
+
+       debug_fenter();
+
+       return_if_fail( element && pad );
+       return_if_fail( player &&
+                                       player->pipeline &&
+                                       player->pipeline->mainbin );
+
+
+       /* payload type is recognizable. increase num_dynamic and wait for sinkbin creation.
+        * num_dynamic_pad will decreased after creating a sinkbin.
+        */
+       player->num_dynamic_pad++;
+       debug_log("stream count inc : %d\n", player->num_dynamic_pad);
+
+       /* perform autoplugging if dump is disabled */
+       if ( PLAYER_INI()->rtsp_do_typefinding )
+       {
+               /* create typefind */
+               new_element = gst_element_factory_make( "typefind", NULL );
+               if ( ! new_element )
+               {
+                       debug_error("failed to create typefind\n");
+                       goto ERROR;
+               }
+
+               MMPLAYER_SIGNAL_CONNECT(        player,
+                                                                       G_OBJECT(new_element),
+                                                                       "have-type",
+                                                                       G_CALLBACK(__mmplayer_typefind_have_type),
+                                                                       (gpointer)player);
+
+               /* FIXIT : try to remove it */
+               player->have_dynamic_pad = FALSE;
+       }
+       else  /* NOTE : use pad's caps directely. if enabled. what I am assuming is there's no elemnt has dynamic pad */
+       {
+               debug_log("using pad caps to autopluging instead of doing typefind\n");
+
+               caps = gst_pad_get_caps( pad );
+
+               MMPLAYER_CHECK_NULL( caps );
+
+               /* clear  previous result*/
+               player->have_dynamic_pad = FALSE;
+
+               if ( ! __mmplayer_try_to_plug( player, pad, caps ) )
+               {
+                       debug_error("failed to autoplug for caps : %s\n", gst_caps_to_string( caps ) );
+                       goto ERROR;
+               }
+
+               /* check if there's dynamic pad*/
+               if( player->have_dynamic_pad )
+               {
+                       debug_error("using pad caps assums there's no dynamic pad !\n");
+                       debug_error("try with enalbing rtsp_do_typefinding\n");
+                       goto ERROR;
+               }
+
+               gst_caps_unref( caps );
+               caps = NULL;
+       }
+
+       /* excute new_element if created*/
+       if ( new_element )
+       {
+               debug_log("adding new element to pipeline\n");
+
+               /* set state to READY before add to bin */
+               MMPLAYER_ELEMENT_SET_STATE( new_element, GST_STATE_READY );
+
+               /* add new element to the pipeline */
+               if ( FALSE == gst_bin_add( GST_BIN(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst), new_element)  )
+               {
+                       debug_error("failed to add autoplug element to bin\n");
+                       goto ERROR;
+               }
+
+               /* get pad from element */
+               sinkpad = gst_element_get_static_pad ( GST_ELEMENT(new_element), "sink" );
+               if ( !sinkpad )
+               {
+                       debug_error("failed to get sinkpad from autoplug element\n");
+                       goto ERROR;
+               }
+
+               /* link it */
+               if ( GST_PAD_LINK_OK != GST_PAD_LINK(pad, sinkpad) )
+               {
+                       debug_error("failed to link autoplug element\n");
+                       goto ERROR;
+               }
+
+               gst_object_unref (sinkpad);
+               sinkpad = NULL;
+
+               /* run. setting PLAYING here since streamming source is live source */
+               MMPLAYER_ELEMENT_SET_STATE( new_element, GST_STATE_PLAYING );
+       }
+
+       debug_fleave();
+
+       return;
+
+STATE_CHANGE_FAILED:
+ERROR:
+       /* FIXIT : take care if new_element has already added to pipeline */
+       if ( new_element )
+               gst_object_unref(GST_OBJECT(new_element));
+
+       if ( sinkpad )
+               gst_object_unref(GST_OBJECT(sinkpad));
+
+       if ( caps )
+               gst_object_unref(GST_OBJECT(caps));
+
+       /* FIXIT : how to inform this error to MSL ????? */
+       /* FIXIT : I think we'd better to use g_idle_add() to destroy pipeline and
+        * then post an error to application
+        */
+}
+
+
+static void
+__mmplayer_gst_decode_callback(GstElement *decodebin, GstPad *pad, gboolean last, gpointer data) // @
+{
+       mm_player_t* player = NULL;
+       MMHandleType attrs = 0;
+       GstElement* pipeline = NULL;
+       GstCaps* caps = NULL;
+       GstStructure* str = NULL;
+       const gchar* name = NULL;
+       GstPad* sinkpad = NULL;
+       GstElement* sinkbin = NULL;
+
+       /* check handles */
+       player = (mm_player_t*) data;
+
+       return_if_fail( decodebin && pad );
+       return_if_fail(player && player->pipeline && player->pipeline->mainbin);
+
+       pipeline = player->pipeline->mainbin[MMPLAYER_M_PIPE].gst;
+
+       attrs = MMPLAYER_GET_ATTRS(player);
+       if ( !attrs )
+       {
+               debug_error("cannot get content attribute\n");
+               goto ERROR;
+       }
+
+       /* get mimetype from caps */
+       caps = gst_pad_get_caps( pad );
+       if ( !caps )
+       {
+               debug_error("cannot get caps from pad.\n");
+               goto ERROR;
+       }
+
+       str = gst_caps_get_structure( caps, 0 );
+       if ( ! str )
+       {
+               debug_error("cannot get structure from capse.\n");
+               goto ERROR;
+       }
+
+       name = gst_structure_get_name(str);
+       if ( ! name )
+       {
+               debug_error("cannot get mimetype from structure.\n");
+               goto ERROR;
+       }
+
+       debug_log("detected mimetype : %s\n", name);
+
+       if (strstr(name, "audio"))
+       {
+               if (player->pipeline->audiobin == NULL)
+               {
+                       __ta__("__mmplayer_gst_create_audio_pipeline",
+                               if (MM_ERROR_NONE !=  __mmplayer_gst_create_audio_pipeline(player))
+                               {
+                                       debug_error("failed to create audiobin. continuing without audio\n");
+                                       goto ERROR;
+                               }
+                       )
+
+                       sinkbin = player->pipeline->audiobin[MMPLAYER_A_BIN].gst;
+                       debug_log("creating audiosink bin success\n");
+               }
+               else
+               {
+                       sinkbin = player->pipeline->audiobin[MMPLAYER_A_BIN].gst;
+                       debug_log("re-using audiobin\n");
+               }
+
+               /* FIXIT : track number shouldn't be hardcoded */
+               mm_attrs_set_int_by_name(attrs, "content_audio_track_num", 1);
+
+               player->audiosink_linked  = 1;
+               debug_msg("player->audsink_linked set to 1\n");
+
+               sinkpad = gst_element_get_static_pad( GST_ELEMENT(sinkbin), "sink" );
+               if ( !sinkpad )
+               {
+                       debug_error("failed to get pad from sinkbin\n");
+                       goto ERROR;
+               }
+       }
+       else if (strstr(name, "video"))
+       {
+               if (player->pipeline->videobin == NULL)
+               {
+                       /*      NOTE : not make videobin because application dose not want to play it even though file has video stream.
+                       */
+
+                       /* get video surface type */
+                       int surface_type = 0;
+                       mm_attrs_get_int_by_name (player->attrs, "display_surface_type", &surface_type);
+
+                       if (surface_type == MM_DISPLAY_SURFACE_NULL)
+                       {
+                               debug_log("not make videobin because it dose not want\n");
+                               goto ERROR;
+                       }
+
+                       __ta__("__mmplayer_gst_create_video_pipeline",
+                       if (MM_ERROR_NONE !=  __mmplayer_gst_create_video_pipeline(player, caps, surface_type) )
+                       {
+                               debug_error("failed to create videobin. continuing without video\n");
+                               goto ERROR;
+                       }
+                       )
+
+                       sinkbin = player->pipeline->videobin[MMPLAYER_V_BIN].gst;
+                       debug_log("creating videosink bin success\n");
+               }
+               else
+               {
+                       sinkbin = player->pipeline->videobin[MMPLAYER_V_BIN].gst;
+                       debug_log("re-using videobin\n");
+               }
+
+               /* FIXIT : track number shouldn't be hardcoded */
+               mm_attrs_set_int_by_name(attrs, "content_video_track_num", 1);
+
+               player->videosink_linked  = 1;
+               debug_msg("player->videosink_linked set to 1\n");
+
+               sinkpad = gst_element_get_static_pad( GST_ELEMENT(sinkbin), "sink" );
+               if ( !sinkpad )
+               {
+                       debug_error("failed to get pad from sinkbin\n");
+                       goto ERROR;
+               }
+       }
+       else if (strstr(name, "text"))
+       {
+               if (player->pipeline->textbin == NULL)
+               {
+                       __ta__("__mmplayer_gst_create_text_pipeline",
+                               if (MM_ERROR_NONE !=  __mmplayer_gst_create_text_pipeline(player))
+                               {
+                                       debug_error("failed to create textbin. continuing without text\n");
+                                       goto ERROR;
+                               }
+                       )
+
+                       sinkbin = player->pipeline->textbin[MMPLAYER_T_BIN].gst;
+                       debug_log("creating textink bin success\n");
+               }
+               else
+               {
+                       sinkbin = player->pipeline->textbin[MMPLAYER_T_BIN].gst;
+                       debug_log("re-using textbin\n");
+               }
+
+               /* FIXIT : track number shouldn't be hardcoded */
+               mm_attrs_set_int_by_name(attrs, "content_text_track_num", 1);
+
+               player->textsink_linked  = 1;
+               debug_msg("player->textsink_linked set to 1\n");
+
+               sinkpad = gst_element_get_static_pad( GST_ELEMENT(sinkbin), "text_sink" );
+               if ( !sinkpad )
+               {
+                       debug_error("failed to get pad from sinkbin\n");
+                       goto ERROR;
+               }
+       }
+       else
+       {
+               debug_warning("unknown type of elementary stream! ignoring it...\n");
+               goto ERROR;
+       }
+
+       if ( sinkbin )
+       {
+               /* warm up */
+               if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state( sinkbin, GST_STATE_READY ) )
+               {
+                       debug_error("failed to set state(READY) to sinkbin\n");
+                       goto ERROR;
+               }
+
+               /* add */
+               if ( FALSE == gst_bin_add( GST_BIN(pipeline), sinkbin ) )
+               {
+                       debug_error("failed to add sinkbin to pipeline\n");
+                       goto ERROR;
+               }
+
+               /* link */
+               if ( GST_PAD_LINK_OK != GST_PAD_LINK(pad, sinkpad) )
+               {
+                       debug_error("failed to get pad from sinkbin\n");
+                       goto ERROR;
+               }
+
+               /* run */
+               if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state( sinkbin, GST_STATE_PAUSED ) )
+               {
+                       debug_error("failed to set state(PLAYING) to sinkbin\n");
+                       goto ERROR;
+               }
+
+               gst_object_unref( sinkpad );
+               sinkpad = NULL;
+       }
+
+       /* update track number attributes */
+       if ( mmf_attrs_commit ( attrs ) )
+               debug_error("failed to commit attrs\n");
+
+       debug_log("linking sink bin success\n");
+
+       /* FIXIT : we cannot hold callback for 'no-more-pad' signal because signal was emitted in
+        * streaming task. if the task blocked, then buffer will not flow to the next element
+        * ( autoplugging element ). so this is special hack for streaming. please try to remove it
+        */
+       /* dec stream count. we can remove fakesink if it's zero */
+       player->num_dynamic_pad--;
+
+       debug_log("stream count dec : %d (num of dynamic pad)\n", player->num_dynamic_pad);
+
+       if ( ( player->no_more_pad ) && ( player->num_dynamic_pad == 0 ) )
+       {
+               __mmplayer_pipeline_complete( NULL, player );
+       }
+
+ERROR:
+       if ( caps )
+               gst_caps_unref( caps );
+
+       if ( sinkpad )
+               gst_object_unref(GST_OBJECT(sinkpad));
+
+       return;
+}
+
+static gboolean
+__mmplayer_get_property_value_for_rotation(mm_player_t* player, int rotation_angle, int *value)
+{
+       int pro_value = 0; // in the case of expection, default will be returned.
+       int dest_angle = rotation_angle;
+       char *element_name = NULL;
+       int rotation_using_type = -1;
+       #define ROTATION_USING_X        0
+       #define ROTATION_USING_FLIP     1
+
+       return_val_if_fail(player, FALSE);
+       return_val_if_fail(value, FALSE);
+       return_val_if_fail(rotation_angle >= 0, FALSE);
+
+       if (rotation_angle >= 360)
+       {
+               dest_angle = rotation_angle - 360;
+       }
+
+       /* chech if supported or not */
+       if ( dest_angle % 90 )
+       {
+               debug_log("not supported rotation angle = %d", rotation_angle);
+               return FALSE;
+       }
+
+       if (player->use_video_stream)
+       {
+               rotation_using_type = ROTATION_USING_FLIP;
+       }
+       else
+       {
+               int surface_type = 0;
+               mm_attrs_get_int_by_name(player->attrs, "display_surface_type", &surface_type);
+               debug_log("check display surface type for rotation: %d", surface_type);
+
+               switch (surface_type)
+               {
+                       case MM_DISPLAY_SURFACE_X:
+                               rotation_using_type = ROTATION_USING_X;
+                               break;
+                       case MM_DISPLAY_SURFACE_EVAS:
+                       default:
+                               rotation_using_type = ROTATION_USING_FLIP;
+                               break;
+               }
+       }
+
+       debug_log("using %d type for rotation", rotation_using_type);
+
+       /* get property value for setting */
+       switch(rotation_using_type)
+       {
+               case ROTATION_USING_X: // xvimagesink
+                       {
+                               switch (dest_angle)
+                               {
+                                       case 0:
+                                               break;
+                                       case 90:
+                                               pro_value = 3; // clockwise 90
+                                               break;
+                                       case 180:
+                                               pro_value = 2;
+                                               break;
+                                       case 270:
+                                               pro_value = 1; // counter-clockwise 90
+                                               break;
+                               }
+                       }
+                       break;
+               case ROTATION_USING_FLIP: // videoflip
+                       {
+                                       switch (dest_angle)
+                                       {
+
+                                               case 0:
+                                                       break;
+                                               case 90:
+                                                       pro_value = 1; // clockwise 90
+                                                       break;
+                                               case 180:
+                                                       pro_value = 2;
+                                                       break;
+                                               case 270:
+                                                       pro_value = 3; // counter-clockwise 90
+                                                       break;
+                                       }
+                       }
+                       break;
+       }
+
+       debug_log("setting rotation property value : %d", pro_value);
+
+       *value = pro_value;
+
+       return TRUE;
+}
+
+int
+_mmplayer_update_video_param(mm_player_t* player) // @
+{
+       MMHandleType attrs = 0;
+       int surface_type = 0;
+       int org_angle = 0; // current supported angle values are 0, 90, 180, 270
+       int user_angle = 0;
+       int user_angle_type= 0;
+       int rotation_value = 0;
+
+       debug_fenter();
+
+       /* check video sinkbin is created */
+       return_val_if_fail ( player && 
+               player->pipeline &&
+               player->pipeline->videobin &&
+               player->pipeline->videobin[MMPLAYER_V_BIN].gst &&
+               player->pipeline->videobin[MMPLAYER_V_SINK].gst, 
+               MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       attrs = MMPLAYER_GET_ATTRS(player);
+       if ( !attrs )
+       {
+               debug_error("cannot get content attribute");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       /* update user roation */
+       mm_attrs_get_int_by_name(attrs, "display_rotation", &user_angle_type);
+
+       /* get angle with user type */
+       switch(user_angle_type)
+       {
+               case MM_DISPLAY_ROTATION_NONE:
+                       user_angle = 0;
+                       break;
+               case MM_DISPLAY_ROTATION_90: // counter-clockwise 90
+                       user_angle = 270;
+                       break;
+               case MM_DISPLAY_ROTATION_180:
+                       user_angle = 180;
+                       break;
+               case MM_DISPLAY_ROTATION_270: // clockwise 90
+                       user_angle = 90;
+                       break;
+       }
+
+       /* get original orientation */
+       if (player->v_stream_caps)
+       {
+               GstStructure *str = NULL;
+
+               str = gst_caps_get_structure (player->v_stream_caps, 0);
+               if ( !gst_structure_get_int (str, "orientation", &org_angle))
+               {
+                       debug_log ("missing 'orientation' field in video caps");
+               }
+               else
+               {
+                       debug_log("origianl video orientation = %d", org_angle);
+               }
+       }
+
+       debug_log("check user angle: %d, org angle: %d", user_angle, org_angle);
+
+       /* get rotation value to set */
+       __mmplayer_get_property_value_for_rotation(player, org_angle+user_angle, &rotation_value);
+
+       /* check video stream callback is used */
+       if( player->use_video_stream )
+       {
+               debug_log("using video stream callback with memsink. player handle : [%p]", player);
+
+               /* apply roate */
+               g_object_set(player->pipeline->videobin[MMPLAYER_V_FLIP].gst, "method", rotation_value, NULL);
+
+               return MM_ERROR_NONE;
+       }
+
+       /* update display surface */
+       mm_attrs_get_int_by_name(attrs, "display_surface_type", &surface_type);
+       debug_log("check display surface type attribute: %d", surface_type);
+
+       /* configuring display */
+       switch ( surface_type )
+       {
+               case MM_DISPLAY_SURFACE_X:
+               {
+                       /* ximagesink or xvimagesink */
+                       void *xid = NULL;
+                       int zoom = 0;
+                       int display_method = 0;
+                       int roi_x = 0;
+                       int roi_y = 0;
+                       int roi_w = 0;
+                       int roi_h = 0;
+                       int force_aspect_ratio = 0;
+                       gboolean visible = TRUE;
+
+                       /* common case if using x surface */
+                       mm_attrs_get_data_by_name(attrs, "display_overlay", &xid);
+                       if ( xid )
+                       {
+                               debug_log("set video param : xid %d", *(int*)xid);
+                               gst_x_overlay_set_xwindow_id( GST_X_OVERLAY( player->pipeline->videobin[MMPLAYER_V_SINK].gst ), *(int*)xid );
+                       }
+                       else
+                       {
+                               /* FIXIT : is it error case? */
+                               debug_warning("still we don't have xid on player attribute. create it's own surface.");
+                       }
+
+                       /* if xvimagesink */
+                       if (!strcmp(PLAYER_INI()->videosink_element_x,"xvimagesink"))
+                       {
+                               mm_attrs_get_int_by_name(attrs, "display_force_aspect_ration", &force_aspect_ratio);
+                               mm_attrs_get_int_by_name(attrs, "display_zoom", &zoom);
+                               mm_attrs_get_int_by_name(attrs, "display_method", &display_method);
+                               mm_attrs_get_int_by_name(attrs, "display_roi_x", &roi_x);
+                               mm_attrs_get_int_by_name(attrs, "display_roi_y", &roi_y);
+                               mm_attrs_get_int_by_name(attrs, "display_roi_width", &roi_w);
+                               mm_attrs_get_int_by_name(attrs, "display_roi_height", &roi_h);
+                               mm_attrs_get_int_by_name(attrs, "display_visible", &visible);
+
+                               g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst,
+                                       "force-aspect-ratio", force_aspect_ratio,
+                                       "zoom", zoom,
+                                       "rotate", rotation_value,
+                                       "handle-events", TRUE,
+                                       "display-geometry-method", display_method,
+                                       "draw-borders", FALSE,
+                                       "dst-roi-x", roi_x,
+                                       "dst-roi-y", roi_y,
+                                       "dst-roi-w", roi_w,
+                                       "dst-roi-h", roi_h,
+                                       "visible", visible,
+                                       NULL );
+
+                               debug_log("set video param : zoom %d", zoom);
+                               debug_log("set video param : rotate %d", rotation_value);
+                               debug_log("set video param : method %d", display_method);
+                               debug_log("set video param : dst-roi-x: %d, dst-roi-y: %d, dst-roi-w: %d, dst-roi-h: %d",
+                                                               roi_x, roi_y, roi_w, roi_h );
+                               debug_log("set video param : visible %d", visible);
+                               debug_log("set video param : force aspect ratio %d", force_aspect_ratio);
+                       }
+               }
+               break;
+               case MM_DISPLAY_SURFACE_EVAS:
+               {
+                       void *object = NULL;
+                       int scaling = 0;
+                       gboolean visible = TRUE;
+
+                       /* common case if using evas surface */
+                       mm_attrs_get_data_by_name(attrs, "display_overlay", &object);
+                       mm_attrs_get_int_by_name(attrs, "display_visible", &visible);
+                       mm_attrs_get_int_by_name(attrs, "display_evas_do_scaling", &scaling);
+                       if (object)
+                       {
+                               g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst,
+                                               "evas-object", object,
+                                               "visible", visible,
+                                               NULL);
+                               debug_log("set video param : evas-object %x", object);
+                               debug_log("set video param : visible %d", visible);
+                       }
+                       else
+                       {
+                               debug_error("no evas object");
+                               return MM_ERROR_PLAYER_INTERNAL;
+                       }
+
+                       /* if evaspixmapsink */
+                       if (!strcmp(PLAYER_INI()->videosink_element_evas,"evaspixmapsink"))
+                       {
+                               int display_method = 0;
+                               int roi_x = 0;
+                               int roi_y = 0;
+                               int roi_w = 0;
+                               int roi_h = 0;
+                               int force_aspect_ratio = 0;
+                               int origin_size = !scaling;
+
+                               mm_attrs_get_int_by_name(attrs, "display_force_aspect_ration", &force_aspect_ratio);
+                               mm_attrs_get_int_by_name(attrs, "display_method", &display_method);
+                               mm_attrs_get_int_by_name(attrs, "display_roi_x", &roi_x);
+                               mm_attrs_get_int_by_name(attrs, "display_roi_y", &roi_y);
+                               mm_attrs_get_int_by_name(attrs, "display_roi_width", &roi_w);
+                               mm_attrs_get_int_by_name(attrs, "display_roi_height", &roi_h);
+
+                               g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst,
+                                       "force-aspect-ratio", force_aspect_ratio,
+                                       "origin-size", origin_size,
+                                       "dst-roi-x", roi_x,
+                                       "dst-roi-y", roi_y,
+                                       "dst-roi-w", roi_w,
+                                       "dst-roi-h", roi_h,
+                                       "display-geometry-method", display_method,
+                                       NULL );
+
+                               debug_log("set video param : method %d", display_method);
+                               debug_log("set video param : dst-roi-x: %d, dst-roi-y: %d, dst-roi-w: %d, dst-roi-h: %d",
+                                                               roi_x, roi_y, roi_w, roi_h );
+                               debug_log("set video param : force aspect ratio %d", force_aspect_ratio);
+                               debug_log("set video param : display_evas_do_scaling %d (origin-size %d)", scaling, origin_size);
+                       }
+                       g_object_set(player->pipeline->videobin[MMPLAYER_V_FLIP].gst, "method", rotation_value, NULL);
+               }
+               break;
+               case MM_DISPLAY_SURFACE_X_EXT:  /* NOTE : this surface type is used for the videoTexture(canvasTexture) overlay */
+               {
+                       void *pixmap_id_cb = NULL;
+                       void *pixmap_id_cb_user_data = NULL;
+                       int display_method = 0;
+                       gboolean visible = TRUE;
+
+                       /* if xvimagesink */
+                       if (strcmp(PLAYER_INI()->videosink_element_x,"xvimagesink"))
+                       {
+                               debug_error("videosink is not xvimagesink");
+                               return MM_ERROR_PLAYER_INTERNAL;
+                       }
+
+                       /* get information from attributes */
+                       mm_attrs_get_data_by_name(attrs, "display_overlay", &pixmap_id_cb);
+                       mm_attrs_get_data_by_name(attrs, "display_overlay_user_data", &pixmap_id_cb_user_data);
+                       mm_attrs_get_int_by_name(attrs, "display_method", &display_method);
+
+                       if ( pixmap_id_cb )
+                       {
+                               debug_log("set video param : display_overlay(0x%x)", pixmap_id_cb);
+                               if (pixmap_id_cb_user_data)
+                               {
+                                       debug_log("set video param : display_overlay_user_data(0x%x)", pixmap_id_cb_user_data);
+                               }
+                       }
+                       else
+                       {
+                               debug_error("failed to set pixmap-id-callback");
+                               return MM_ERROR_PLAYER_INTERNAL;
+                       }
+                       debug_log("set video param : method %d", display_method);
+                       debug_log("set video param : visible %d", visible);
+
+                       /* set properties of videosink plugin */
+                       g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst,
+                               "display-geometry-method", display_method,
+                               "draw-borders", FALSE,
+                               "visible", visible,
+                               "pixmap-id-callback", pixmap_id_cb,
+                               "pixmap-id-callback-userdata", pixmap_id_cb_user_data,
+                               NULL );
+               }
+               break;
+               case MM_DISPLAY_SURFACE_NULL:
+               {
+                       /* do nothing */
+               }
+               break;
+       }
+
+       debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+static int
+__mmplayer_gst_element_link_bucket(GList* element_bucket) // @
+{
+       GList* bucket = element_bucket;
+       MMPlayerGstElement* element = NULL;
+       MMPlayerGstElement* prv_element = NULL;
+       gint successful_link_count = 0;
+
+       debug_fenter();
+
+       return_val_if_fail(element_bucket, -1);
+
+       prv_element = (MMPlayerGstElement*)bucket->data;
+       bucket = bucket->next;
+
+       for ( ; bucket; bucket = bucket->next )
+       {
+               element = (MMPlayerGstElement*)bucket->data;
+
+               if ( element && element->gst )
+               {
+                       if ( GST_ELEMENT_LINK(GST_ELEMENT(prv_element->gst), GST_ELEMENT(element->gst)) )
+                       {
+                               debug_log("linking [%s] to [%s] success\n",
+                                       GST_ELEMENT_NAME(GST_ELEMENT(prv_element->gst)),
+                                       GST_ELEMENT_NAME(GST_ELEMENT(element->gst)) );
+                               successful_link_count ++;
+                       }
+                       else
+                       {
+                               debug_log("linking [%s] to [%s] failed\n",
+                                       GST_ELEMENT_NAME(GST_ELEMENT(prv_element->gst)),
+                                       GST_ELEMENT_NAME(GST_ELEMENT(element->gst)) );
+                               return -1;
+                       }
+               }
+
+               prv_element = element;
+       }
+
+       debug_fleave();
+
+       return successful_link_count;
+}
+
+static int
+__mmplayer_gst_element_add_bucket_to_bin(GstBin* bin, GList* element_bucket) // @
+{
+       GList* bucket = element_bucket;
+       MMPlayerGstElement* element = NULL;
+       int successful_add_count = 0;
+
+       debug_fenter();
+
+       return_val_if_fail(element_bucket, 0);
+       return_val_if_fail(bin, 0);
+
+       for ( ; bucket; bucket = bucket->next )
+       {
+               element = (MMPlayerGstElement*)bucket->data;
+
+               if ( element && element->gst )
+               {
+                       if( !gst_bin_add(bin, GST_ELEMENT(element->gst)) )
+                       {
+                               debug_log("__mmplayer_gst_element_link_bucket : Adding element [%s]  to bin [%s] failed\n",
+                                       GST_ELEMENT_NAME(GST_ELEMENT(element->gst)),
+                                       GST_ELEMENT_NAME(GST_ELEMENT(bin) ) );
+                               return 0;
+                       }
+                       successful_add_count ++;
+               }
+       }
+
+       debug_fleave();
+
+       return successful_add_count;
+}
+
+
+
+/**
+ * This function is to create audio pipeline for playing.
+ *
+ * @param      player          [in]    handle of player
+ *
+ * @return     This function returns zero on success.
+ * @remark
+ * @see                __mmplayer_gst_create_midi_pipeline, __mmplayer_gst_create_video_pipeline
+ */
+#define MMPLAYER_CREATEONLY_ELEMENT(x_bin, x_id, x_factory, x_name) \
+x_bin[x_id].id = x_id;\
+x_bin[x_id].gst = gst_element_factory_make(x_factory, x_name);\
+if ( ! x_bin[x_id].gst )\
+{\
+       debug_critical("failed to create %s \n", x_factory);\
+       goto ERROR;\
+}\
+
+#define MMPLAYER_CREATE_ELEMENT_ADD_BIN(x_bin, x_id, x_factory, x_name, y_bin) \
+x_bin[x_id].id = x_id;\
+x_bin[x_id].gst = gst_element_factory_make(x_factory, x_name);\
+if ( ! x_bin[x_id].gst )\
+{\
+       debug_critical("failed to create %s \n", x_factory);\
+       goto ERROR;\
+}\
+if( !gst_bin_add(GST_BIN(y_bin), GST_ELEMENT(x_bin[x_id].gst)))\
+{\
+       debug_log("__mmplayer_gst_element_link_bucket : Adding element [%s]  to bin [%s] failed\n",\
+               GST_ELEMENT_NAME(GST_ELEMENT(x_bin[x_id].gst)),\
+               GST_ELEMENT_NAME(GST_ELEMENT(y_bin) ) );\
+       goto ERROR;\
+}\
+
+/* macro for code readability. just for sinkbin-creation functions */
+#define MMPLAYER_CREATE_ELEMENT(x_bin, x_id, x_factory, x_name, x_add_bucket) \
+do \
+{ \
+       x_bin[x_id].id = x_id;\
+       x_bin[x_id].gst = gst_element_factory_make(x_factory, x_name);\
+       if ( ! x_bin[x_id].gst )\
+       {\
+               debug_critical("failed to create %s \n", x_factory);\
+               goto ERROR;\
+       }\
+       if ( x_add_bucket )\
+               element_bucket = g_list_append(element_bucket, &x_bin[x_id]);\
+} while(0);
+
+
+/**
+  * AUDIO PIPELINE 
+  * - Local playback   : audioconvert !volume ! capsfilter ! audioeq ! audiosink
+  * - Streaming                : audioconvert !volume ! audiosink
+  * - PCM extraction   : audioconvert ! audioresample ! capsfilter ! fakesink 
+  */
+static int
+__mmplayer_gst_create_audio_pipeline(mm_player_t* player)
+{
+       MMPlayerGstElement* first_element = NULL;
+       MMPlayerGstElement* audiobin = NULL;
+       MMHandleType attrs = 0;
+       GstPad *pad = NULL;
+       GstPad *ghostpad = NULL;
+       GList* element_bucket = NULL;
+       char *device_name = NULL;
+       gboolean link_audio_sink_now = TRUE;
+       int i =0;
+
+       debug_fenter();
+
+       return_val_if_fail( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       /* alloc handles */
+       audiobin = (MMPlayerGstElement*)g_malloc0(sizeof(MMPlayerGstElement) * MMPLAYER_A_NUM);
+
+       if ( ! audiobin )
+       {
+               debug_error("failed to allocate memory for audiobin\n");
+               return MM_ERROR_PLAYER_NO_FREE_SPACE;
+       }
+
+       attrs = MMPLAYER_GET_ATTRS(player);
+
+       /* create bin */
+       audiobin[MMPLAYER_A_BIN].id = MMPLAYER_A_BIN;
+       audiobin[MMPLAYER_A_BIN].gst = gst_bin_new("audiobin");
+       if ( !audiobin[MMPLAYER_A_BIN].gst )
+       {
+               debug_critical("failed to create audiobin\n");
+               goto ERROR;
+       }
+
+       /* take it */
+       player->pipeline->audiobin = audiobin;
+
+       player->is_sound_extraction = __mmplayer_can_extract_pcm(player);
+
+       /* Adding audiotp plugin for reverse trickplay feature */
+       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_TP, "audiotp", "audiotrickplay", TRUE);
+
+       /* converter */
+       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CONV, "audioconvert", "audioconverter", TRUE);
+
+       if ( ! player->is_sound_extraction )
+       {
+               GstCaps* caps = NULL;
+               guint channels = 0;
+
+               /* for logical volume control */
+               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_VOL, "volume", "volume", TRUE);
+               g_object_set(G_OBJECT (audiobin[MMPLAYER_A_VOL].gst), "volume", player->sound.volume, NULL);
+
+               if (player->sound.mute)
+               {
+                       debug_log("mute enabled\n");
+                       g_object_set(G_OBJECT (audiobin[MMPLAYER_A_VOL].gst), "mute", player->sound.mute, NULL);
+               }
+
+               /*capsfilter */
+               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CAPS_DEFAULT, "capsfilter", "audiocapsfilter", TRUE);
+
+               caps = gst_caps_from_string(            "audio/x-raw-int, "
+                                                                               "endianness = (int) LITTLE_ENDIAN, "
+                                                                               "signed = (boolean) true, "
+                                                                               "width = (int) 16, "
+                                                                               "depth = (int) 16"      );
+               g_object_set (GST_ELEMENT(audiobin[MMPLAYER_A_CAPS_DEFAULT].gst), "caps", caps, NULL );
+
+               gst_caps_unref( caps );
+
+               /* chech if multi-chennels */
+               if (player->pipeline->mainbin && player->pipeline->mainbin[MMPLAYER_M_DEMUX].gst)
+               {
+                       GstPad *srcpad = NULL;
+                       GstCaps *caps = NULL;
+
+                       if (srcpad = gst_element_get_static_pad(player->pipeline->mainbin[MMPLAYER_M_DEMUX].gst, "src"))
+                       {
+                               if (caps = gst_pad_get_caps(srcpad))
+                               {
+                                       MMPLAYER_LOG_GST_CAPS_TYPE(caps);
+                                       GstStructure *str = gst_caps_get_structure(caps, 0);
+                                       if (str)
+                                               gst_structure_get_int (str, "channels", &channels);
+                                       gst_caps_unref(caps);
+                               }
+                               gst_object_unref(srcpad);
+                       }
+               }
+
+               /* audio effect element. if audio effect is enabled */
+               if ( channels <= 2 && (PLAYER_INI()->use_audio_effect_preset || PLAYER_INI()->use_audio_effect_custom) )
+               {
+                       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_FILTER, PLAYER_INI()->name_of_audio_effect, "audiofilter", TRUE);
+               }
+
+               /* create audio sink */
+               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_SINK, PLAYER_INI()->name_of_audiosink,
+                       "audiosink", link_audio_sink_now);
+
+               /* sync on */
+               if (MMPLAYER_IS_RTSP_STREAMING(player))
+                       g_object_set (G_OBJECT (audiobin[MMPLAYER_A_SINK].gst), "sync", FALSE, NULL);   /* sync off */
+               else
+                       g_object_set (G_OBJECT (audiobin[MMPLAYER_A_SINK].gst), "sync", TRUE, NULL);    /* sync on */
+
+               /* qos on */
+               g_object_set (G_OBJECT (audiobin[MMPLAYER_A_SINK].gst), "qos", TRUE, NULL);     /* qos on */
+
+               /* FIXIT : using system clock. isn't there another way? */
+               g_object_set (G_OBJECT (audiobin[MMPLAYER_A_SINK].gst), "provide-clock", PLAYER_INI()->provide_clock,  NULL);
+
+               __mmplayer_add_sink( player, audiobin[MMPLAYER_A_SINK].gst );
+
+               if(player->audio_buffer_cb)
+               {
+                   g_object_set(audiobin[MMPLAYER_A_SINK].gst, "audio-handle", player->audio_buffer_cb_user_param, NULL);
+                   g_object_set(audiobin[MMPLAYER_A_SINK].gst, "audio-callback", player->audio_buffer_cb, NULL);
+               }
+
+               if ( g_strrstr(PLAYER_INI()->name_of_audiosink, "avsysaudiosink") )
+               {
+                       gint volume_type = 0;
+                       gint audio_route = 0;
+                       gint sound_priority = FALSE;
+                       gint is_spk_out_only = 0;
+                       gint latency_mode = 0;
+
+                       /* set volume table
+                        * It should be set after player creation through attribute.
+                        * But, it can not be changed during playing.
+                        */
+                       mm_attrs_get_int_by_name(attrs, "sound_volume_type", &volume_type);
+                       mm_attrs_get_int_by_name(attrs, "sound_route", &audio_route);
+                       mm_attrs_get_int_by_name(attrs, "sound_priority", &sound_priority);
+                       mm_attrs_get_int_by_name(attrs, "sound_spk_out_only", &is_spk_out_only);
+                       mm_attrs_get_int_by_name(attrs, "audio_latency_mode", &latency_mode);
+
+                       /* hook sound_type if emergency case */
+                       if ( player->sm.event == ASM_EVENT_EMERGENCY)
+                       {
+                               debug_log ("This is emergency session, hook sound_type from [%d] to [%d]\n", volume_type, MM_SOUND_VOLUME_TYPE_EMERGENCY);
+                               volume_type = MM_SOUND_VOLUME_TYPE_EMERGENCY;
+                       }
+
+                       g_object_set(audiobin[MMPLAYER_A_SINK].gst,
+                                                               "volumetype", volume_type,
+                                                               "audio-route", audio_route,
+                                                               "priority", sound_priority,
+                                                               "user-route", is_spk_out_only,
+                                                               "latency", latency_mode,
+                                                               NULL);
+
+                       debug_log("audiosink property status...volume type:%d, route:%d, priority=%d, user-route=%d, latency=%d\n",
+                               volume_type, audio_route, sound_priority, is_spk_out_only, latency_mode);
+               }
+
+               /* Antishock can be enabled when player is resumed by soundCM.
+                * But, it's not used in MMS, setting and etc.
+                * Because, player start seems like late.
+                */
+               __mmplayer_set_antishock( player , FALSE );
+       }
+       else // pcm extraction only and no sound output 
+       {
+               int dst_samplerate = 0;
+               int dst_channels = 0;
+               int dst_depth = 0;
+               char *caps_type = NULL;
+               GstCaps* caps = NULL;
+
+               /* resampler */
+               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_RESAMPLER, "audioresample", "resampler", TRUE);
+
+               /* get conf. values */
+               mm_attrs_multiple_get(player->attrs, 
+                                               NULL,
+                                               "pcm_extraction_samplerate", &dst_samplerate,
+                                               "pcm_extraction_channels", &dst_channels,
+                                               "pcm_extraction_depth", &dst_depth,
+                                               NULL);
+               /* capsfilter */
+               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CAPS_DEFAULT, "capsfilter", "audiocapsfilter", TRUE);
+
+               caps = gst_caps_new_simple ("audio/x-raw-int",
+                                              "rate", G_TYPE_INT, dst_samplerate,
+                                              "channels", G_TYPE_INT, dst_channels,
+                                              "depth", G_TYPE_INT, dst_depth,
+                                               NULL);
+
+               caps_type = gst_caps_to_string(caps);
+               debug_log("resampler new caps : %s\n", caps_type);
+
+                       g_object_set (GST_ELEMENT(audiobin[MMPLAYER_A_CAPS_DEFAULT].gst), "caps", caps, NULL );
+
+                       /* clean */
+                       gst_caps_unref( caps );
+                       MMPLAYER_FREEIF( caps_type );
+
+               /* fake sink */
+               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_SINK, "fakesink", "fakesink", TRUE);
+
+               /* set sync */
+               g_object_set (G_OBJECT (audiobin[MMPLAYER_A_SINK].gst), "sync", FALSE, NULL);
+
+               __mmplayer_add_sink( player, audiobin[MMPLAYER_A_SINK].gst );
+       }
+
+       /* adding created elements to bin */
+       debug_log("adding created elements to bin\n");
+       if( !__mmplayer_gst_element_add_bucket_to_bin( GST_BIN(audiobin[MMPLAYER_A_BIN].gst), element_bucket ))
+       {
+               debug_error("failed to add elements\n");
+               goto ERROR;
+       }
+
+       /* linking elements in the bucket by added order. */
+       debug_log("Linking elements in the bucket by added order.\n");
+       if ( __mmplayer_gst_element_link_bucket(element_bucket) == -1 )
+       {
+               debug_error("failed to link elements\n");
+               goto ERROR;
+       }
+
+       /* get first element's sinkpad for creating ghostpad */
+       first_element = (MMPlayerGstElement *)element_bucket->data;
+
+       pad = gst_element_get_static_pad(GST_ELEMENT(first_element->gst), "sink");
+       if ( ! pad )
+       {
+               debug_error("failed to get pad from first element of audiobin\n");
+               goto ERROR;
+       }
+
+       ghostpad = gst_ghost_pad_new("sink", pad);
+       if ( ! ghostpad )
+       {
+               debug_error("failed to create ghostpad\n");
+               goto ERROR;
+       }
+
+       if ( FALSE == gst_element_add_pad(audiobin[MMPLAYER_A_BIN].gst, ghostpad) )
+       {
+               debug_error("failed to add ghostpad to audiobin\n");
+               goto ERROR;
+       }
+
+       gst_object_unref(pad);
+
+       if ( !player->bypass_audio_effect && (PLAYER_INI()->use_audio_effect_preset || PLAYER_INI()->use_audio_effect_custom) )
+       {
+               if ( player->audio_effect_info.effect_type == MM_AUDIO_EFFECT_TYPE_PRESET )
+               {
+                       if (!_mmplayer_audio_effect_preset_apply(player, player->audio_effect_info.preset))
+                       {
+                               debug_msg("apply audio effect(preset:%d) setting success\n",player->audio_effect_info.preset);
+                       }
+               }
+               else if ( player->audio_effect_info.effect_type == MM_AUDIO_EFFECT_TYPE_CUSTOM )
+               {
+                       if (!_mmplayer_audio_effect_custom_apply(player))
+                       {
+                               debug_msg("apply audio effect(custom) setting success\n");
+                       }
+               }
+       }
+
+       /* done. free allocated variables */
+       MMPLAYER_FREEIF( device_name );
+       g_list_free(element_bucket);
+
+       mm_attrs_set_int_by_name(attrs, "content_audio_found", TRUE);
+       if ( mmf_attrs_commit ( attrs ) ) /* return -1 if error */
+               debug_error("failed to commit attribute ""content_audio_found"".\n");
+
+       debug_fleave();
+
+       return MM_ERROR_NONE;
+
+ERROR:
+
+       debug_log("ERROR : releasing audiobin\n");
+
+       MMPLAYER_FREEIF( device_name );
+
+       if ( pad )
+               gst_object_unref(GST_OBJECT(pad));
+
+       if ( ghostpad )
+               gst_object_unref(GST_OBJECT(ghostpad));
+
+       g_list_free( element_bucket );
+
+
+       /* release element which are not added to bin */
+       for ( i = 1; i < MMPLAYER_A_NUM; i++ )  /* NOTE : skip bin */
+       {
+               if ( audiobin[i].gst )
+               {
+                       GstObject* parent = NULL;
+                       parent = gst_element_get_parent( audiobin[i].gst );
+
+                       if ( !parent )
+                       {
+                               gst_object_unref(GST_OBJECT(audiobin[i].gst));
+                               audiobin[i].gst = NULL;
+                       }
+                       else
+                       {
+                               gst_object_unref(GST_OBJECT(parent));
+                       }
+               }
+       }
+
+       /* release audiobin with it's childs */
+       if ( audiobin[MMPLAYER_A_BIN].gst )
+       {
+               gst_object_unref(GST_OBJECT(audiobin[MMPLAYER_A_BIN].gst));
+       }
+
+       MMPLAYER_FREEIF( audiobin );
+
+       player->pipeline->audiobin = NULL;
+
+       return MM_ERROR_PLAYER_INTERNAL;
+}
+
+static gboolean
+__mmplayer_audio_stream_probe (GstPad *pad, GstBuffer *buffer, gpointer u_data)
+{
+       mm_player_t* player = (mm_player_t*) u_data;
+       gint size;
+       guint8 *data;
+
+       data = GST_BUFFER_DATA(buffer);
+       size = GST_BUFFER_SIZE(buffer);
+
+       if (player->audio_stream_cb && size && data)
+               player->audio_stream_cb((void *)data, size, player->audio_stream_cb_user_param);
+
+       return TRUE;
+}
+
+/**
+ * This function is to create video pipeline.
+ *
+ * @param      player          [in]    handle of player
+ *             caps            [in]    src caps of decoder
+ *             surface_type    [in]    surface type for video rendering
+ *
+ * @return     This function returns zero on success.
+ * @remark
+ * @see                __mmplayer_gst_create_audio_pipeline, __mmplayer_gst_create_midi_pipeline
+ */
+/**
+  * VIDEO PIPELINE
+  * - x surface (arm/x86) : videoflip ! xvimagesink
+  * - evas surface  (arm) : ffmpegcolorspace ! videoflip ! evasimagesink
+  * - evas surface  (x86) : videoconvertor ! videoflip ! evasimagesink
+  */
+static int
+__mmplayer_gst_create_video_pipeline(mm_player_t* player, GstCaps* caps, MMDisplaySurfaceType surface_type)
+{
+       GstPad *pad = NULL;
+       MMHandleType attrs;
+       GList*element_bucket = NULL;
+       MMPlayerGstElement* first_element = NULL;
+       MMPlayerGstElement* videobin = NULL;
+       gchar* vconv_factory = NULL;
+       gchar *videosink_element = NULL;
+
+       debug_fenter();
+
+       return_val_if_fail(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       /* alloc handles */
+       videobin = (MMPlayerGstElement*)g_malloc0(sizeof(MMPlayerGstElement) * MMPLAYER_V_NUM);
+       if ( !videobin )
+       {
+               return MM_ERROR_PLAYER_NO_FREE_SPACE;
+       }
+
+       player->pipeline->videobin = videobin;
+
+       attrs = MMPLAYER_GET_ATTRS(player);
+       if ( !attrs )
+       {
+               debug_error("cannot get content attribute");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       /* create bin */
+       videobin[MMPLAYER_V_BIN].id = MMPLAYER_V_BIN;
+       videobin[MMPLAYER_V_BIN].gst = gst_bin_new("videobin");
+       if ( !videobin[MMPLAYER_V_BIN].gst )
+       {
+               debug_critical("failed to create videobin");
+               goto ERROR;
+       }
+
+       if( player->use_video_stream ) // video stream callback, so send raw video data to application
+       {
+               GstStructure *str = NULL;
+               guint32 fourcc = 0;
+               gint ret = 0;
+               gint width = 0;         //width of video
+               gint height = 0;                //height of video
+               GstCaps* video_caps = NULL;
+
+               debug_log("using memsink\n");
+
+               /* first, create colorspace convert */
+               if (strlen(PLAYER_INI()->name_of_video_converter) > 0)
+               {
+                               vconv_factory = PLAYER_INI()->name_of_video_converter;
+               }
+
+               if (vconv_factory)
+               {
+                       MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_CONV, vconv_factory, "video converter", TRUE);
+               }
+
+               /* rotator, scaler and capsfilter */
+               MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_FLIP, "videoflip", "video rotator", TRUE);
+               MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_SCALE, "videoscale", "video scaler", TRUE);
+               MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_CAPS, "capsfilter", "videocapsfilter", TRUE);
+
+               /* get video stream caps parsed by demuxer */
+               str = gst_caps_get_structure (player->v_stream_caps, 0);
+               if ( !str )
+               {
+                       debug_error("cannot get structure");
+                       goto ERROR;
+               }
+
+               mm_attrs_get_int_by_name(attrs, "display_width", &width);
+               mm_attrs_get_int_by_name(attrs, "display_height", &height);
+               if (!width || !height)
+               {
+                       /* we set width/height of original media's size  to capsfilter for scaling video */
+                       ret = gst_structure_get_int (str, "width", &width);
+                       if ( !ret )
+                       {
+                               debug_error("cannot get width");
+                               goto ERROR;
+                       }
+
+                       ret = gst_structure_get_int(str, "height", &height);
+                       if ( !ret )
+                       {
+                               debug_error("cannot get height");
+                               goto ERROR;
+                       }
+               }
+
+               video_caps = gst_caps_new_simple( "video/x-raw-rgb",
+                                                                               "width", G_TYPE_INT, width,
+                                                                               "height", G_TYPE_INT, height,
+                                                                               NULL);
+
+               g_object_set (GST_ELEMENT(videobin[MMPLAYER_V_CAPS].gst), "caps", video_caps, NULL );
+
+               gst_caps_unref( video_caps );
+
+               /* finally, create video sink. output will be BGRA8888. */
+               MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_SINK, "avsysmemsink", "videosink", TRUE);
+
+               MMPLAYER_SIGNAL_CONNECT( player,
+                                                                        videobin[MMPLAYER_V_SINK].gst,
+                                                                        "video-stream",
+                                                                        G_CALLBACK(__mmplayer_videostream_cb),
+                                                                        player );
+       }
+       else // render video data using sink plugin like xvimagesink
+       {
+               debug_log("using videosink");
+               
+               /* set video converter */
+               if (strlen(PLAYER_INI()->name_of_video_converter) > 0)
+               {
+                       vconv_factory = PLAYER_INI()->name_of_video_converter;
+                       if (vconv_factory)
+                       {
+                               MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_CONV, vconv_factory, "video converter", TRUE);
+                               debug_log("using video converter: %s", vconv_factory);
+                       }
+               }
+
+               /* set video rotator */
+               MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_FLIP, "videoflip", "video rotator", TRUE);
+
+               /* videoscaler */
+               #if !defined(__arm__)
+               MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_SCALE, "videoscale", "videoscaler", TRUE);
+               #endif
+
+               /* set video sink */
+               switch (surface_type)
+               {
+               case MM_DISPLAY_SURFACE_X:
+                       if (strlen(PLAYER_INI()->videosink_element_x) > 0)
+                               videosink_element = PLAYER_INI()->videosink_element_x;
+                       else
+                               goto ERROR;
+                       break;
+               case MM_DISPLAY_SURFACE_EVAS:
+                       if (strlen(PLAYER_INI()->videosink_element_evas) > 0)
+                               videosink_element = PLAYER_INI()->videosink_element_evas;
+                       else
+                               goto ERROR;
+                       break;
+               case MM_DISPLAY_SURFACE_X_EXT:
+               {
+                       void *pixmap_id_cb = NULL;
+                       mm_attrs_get_data_by_name(attrs, "display_overlay", &pixmap_id_cb);
+                       if (pixmap_id_cb) /* this is used for the videoTextue(canvasTexture) overlay */
+                       {
+                               videosink_element = PLAYER_INI()->videosink_element_x;
+                               debug_warning("video texture usage");
+                       }
+                       else
+                       {
+                               debug_error("something wrong.. callback function for getting pixmap id is null");
+                               goto ERROR;
+                       }
+                       break;
+               }
+               case MM_DISPLAY_SURFACE_NULL:
+                       if (strlen(PLAYER_INI()->videosink_element_fake) > 0)
+                               videosink_element = PLAYER_INI()->videosink_element_fake;
+                       else
+                               goto ERROR;
+                       break;
+               default:
+                       debug_error("unidentified surface type");
+                       goto ERROR;
+               }
+
+               MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_SINK, videosink_element, videosink_element, TRUE);
+               debug_log("selected videosink name: %s", videosink_element);
+
+               /* connect signal handlers for sink plug-in */
+               switch (surface_type) {
+               case MM_DISPLAY_SURFACE_X_EXT:
+                       MMPLAYER_SIGNAL_CONNECT( player,
+                                                                       player->pipeline->videobin[MMPLAYER_V_SINK].gst,
+                                                                       "frame-render-error",
+                                                                       G_CALLBACK(__mmplayer_videoframe_render_error_cb),
+                                                                       player );
+                       debug_log("videoTexture usage, connect a signal handler for pixmap rendering error");
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       if ( _mmplayer_update_video_param(player) != MM_ERROR_NONE)
+               goto ERROR;
+
+       /* qos on */
+       g_object_set (G_OBJECT (videobin[MMPLAYER_V_SINK].gst), "qos", TRUE, NULL);
+
+       /* store it as it's sink element */
+       __mmplayer_add_sink( player, videobin[MMPLAYER_V_SINK].gst );
+
+       /* adding created elements to bin */
+       if( ! __mmplayer_gst_element_add_bucket_to_bin(GST_BIN(videobin[MMPLAYER_V_BIN].gst), element_bucket) )
+       {
+               debug_error("failed to add elements\n");
+               goto ERROR;
+       }
+
+       /* Linking elements in the bucket by added order */
+       if ( __mmplayer_gst_element_link_bucket(element_bucket) == -1 )
+       {
+               debug_error("failed to link elements\n");
+               goto ERROR;
+       }
+
+       /* get first element's sinkpad for creating ghostpad */
+       first_element = (MMPlayerGstElement *)element_bucket->data;
+       if ( !first_element )
+       {
+               debug_error("failed to get first element from bucket\n");
+               goto ERROR;
+       }
+
+       pad = gst_element_get_static_pad(GST_ELEMENT(first_element->gst), "sink");
+       if ( !pad )
+       {
+               debug_error("failed to get pad from first element\n");
+               goto ERROR;
+       }
+
+       /* create ghostpad */
+       if (FALSE == gst_element_add_pad(videobin[MMPLAYER_V_BIN].gst, gst_ghost_pad_new("sink", pad)))
+       {
+               debug_error("failed to add ghostpad to videobin\n");
+               goto ERROR;
+       }
+       gst_object_unref(pad);
+
+       /* done. free allocated variables */
+       g_list_free(element_bucket);
+
+       mm_attrs_set_int_by_name(attrs, "content_video_found", TRUE);
+       if ( mmf_attrs_commit ( attrs ) ) /* return -1 if error */
+               debug_error("failed to commit attribute ""content_video_found"".\n");
+
+       debug_fleave();
+
+       return MM_ERROR_NONE;
+
+ERROR:
+       debug_error("ERROR : releasing videobin\n");
+
+       g_list_free( element_bucket );
+
+       if (pad)
+               gst_object_unref(GST_OBJECT(pad));
+
+       /* release videobin with it's childs */
+       if ( videobin[MMPLAYER_V_BIN].gst )
+       {
+               gst_object_unref(GST_OBJECT(videobin[MMPLAYER_V_BIN].gst));
+       }
+
+
+       MMPLAYER_FREEIF( videobin );
+
+       player->pipeline->videobin = NULL;
+
+       return MM_ERROR_PLAYER_INTERNAL;
+}
+
+static int             __mmplayer_gst_create_text_pipeline(mm_player_t* player)
+{
+       MMPlayerGstElement* first_element = NULL;
+       MMPlayerGstElement* textbin = NULL;
+       GList* element_bucket = NULL;
+       GstPad *pad = NULL;
+       GstPad *ghostpad = NULL;
+       gint i = 0;
+
+       debug_fenter();
+
+       return_val_if_fail( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       /* alloc handles */
+       textbin = (MMPlayerGstElement*)g_malloc0(sizeof(MMPlayerGstElement) * MMPLAYER_T_NUM);
+       if ( ! textbin )
+       {
+               debug_error("failed to allocate memory for textbin\n");
+               return MM_ERROR_PLAYER_NO_FREE_SPACE;
+       }
+
+       /* create bin */
+       textbin[MMPLAYER_T_BIN].id = MMPLAYER_T_BIN;
+       textbin[MMPLAYER_T_BIN].gst = gst_bin_new("textbin");
+       if ( !textbin[MMPLAYER_T_BIN].gst )
+       {
+               debug_critical("failed to create textbin\n");
+               goto ERROR;
+       }
+
+       /* take it */
+       player->pipeline->textbin = textbin;
+
+       /* fakesink */
+       if (player->use_textoverlay)
+       {
+               debug_log ("use textoverlay for displaying \n");
+
+               MMPLAYER_CREATE_ELEMENT_ADD_BIN(textbin, MMPLAYER_T_TEXT_QUEUE, "queue", "text_t_queue", textbin[MMPLAYER_T_BIN].gst);
+
+               MMPLAYER_CREATE_ELEMENT_ADD_BIN(textbin, MMPLAYER_T_VIDEO_QUEUE, "queue", "text_v_queue", textbin[MMPLAYER_T_BIN].gst);
+
+               MMPLAYER_CREATE_ELEMENT_ADD_BIN(textbin, MMPLAYER_T_VIDEO_CONVERTER, "fimcconvert", "text_v_converter", textbin[MMPLAYER_T_BIN].gst);
+
+               MMPLAYER_CREATE_ELEMENT_ADD_BIN(textbin, MMPLAYER_T_OVERLAY, "textoverlay", "text_overlay", textbin[MMPLAYER_T_BIN].gst);
+
+               if (!gst_element_link_pads (textbin[MMPLAYER_T_VIDEO_QUEUE].gst, "src", textbin[MMPLAYER_T_VIDEO_CONVERTER].gst, "sink"))
+               {
+                       debug_error("failed to link queue and converter\n");
+                       goto ERROR;
+               }
+
+               if (!gst_element_link_pads (textbin[MMPLAYER_T_VIDEO_CONVERTER].gst, "src", textbin[MMPLAYER_T_OVERLAY].gst, "video_sink"))
+               {
+                       debug_error("failed to link queue and textoverlay\n");
+                       goto ERROR;
+               }
+
+               if (!gst_element_link_pads (textbin[MMPLAYER_T_TEXT_QUEUE].gst, "src", textbin[MMPLAYER_T_OVERLAY].gst, "text_sink"))
+               {
+                       debug_error("failed to link queue and textoverlay\n");
+                       goto ERROR;
+               }
+
+       }
+       else
+       {
+               debug_log ("use subtitle message for displaying \n");
+
+               MMPLAYER_CREATE_ELEMENT(textbin, MMPLAYER_T_TEXT_QUEUE, "queue", "text_queue", TRUE);
+
+               MMPLAYER_CREATE_ELEMENT(textbin, MMPLAYER_T_SINK, "fakesink", "text_sink", TRUE);
+
+               g_object_set (G_OBJECT (textbin[MMPLAYER_T_SINK].gst), "sync", TRUE, NULL);
+               g_object_set (G_OBJECT (textbin[MMPLAYER_T_SINK].gst), "async", FALSE, NULL);
+               g_object_set (G_OBJECT (textbin[MMPLAYER_T_SINK].gst), "signal-handoffs", TRUE, NULL);
+
+               MMPLAYER_SIGNAL_CONNECT( player,
+                                                               G_OBJECT(textbin[MMPLAYER_T_SINK].gst),
+                                                               "handoff",
+                                                               G_CALLBACK(__mmplayer_update_subtitle),
+                                                               (gpointer)player );
+
+               if (!player->play_subtitle)
+               {
+                       debug_log ("add textbin sink as sink element of whole pipeline.\n");
+                       __mmplayer_add_sink (player, GST_ELEMENT(textbin[MMPLAYER_T_SINK].gst));
+               }
+
+               /* adding created elements to bin */
+               debug_log("adding created elements to bin\n");
+               if( !__mmplayer_gst_element_add_bucket_to_bin( GST_BIN(textbin[MMPLAYER_T_BIN].gst), element_bucket ))
+               {
+                       debug_error("failed to add elements\n");
+                       goto ERROR;
+               }
+
+               /* linking elements in the bucket by added order. */
+               debug_log("Linking elements in the bucket by added order.\n");
+               if ( __mmplayer_gst_element_link_bucket(element_bucket) == -1 )
+               {
+                       debug_error("failed to link elements\n");
+                       goto ERROR;
+               }
+
+               /* done. free allocated variables */
+               g_list_free(element_bucket);
+       }
+
+       if (textbin[MMPLAYER_T_TEXT_QUEUE].gst)
+       {
+               pad = gst_element_get_static_pad(GST_ELEMENT(textbin[MMPLAYER_T_TEXT_QUEUE].gst), "sink");
+               if (!pad)
+               {
+                       debug_error("failed to get text pad of textbin\n");
+                       goto ERROR;
+               }
+
+               ghostpad = gst_ghost_pad_new("text_sink", pad);
+               if (!ghostpad)
+               {
+                       debug_error("failed to create ghostpad of textbin\n");
+                       goto ERROR;
+               }
+
+               if ( FALSE == gst_element_add_pad(textbin[MMPLAYER_T_BIN].gst, ghostpad) )
+               {
+                       debug_error("failed to add ghostpad to textbin\n");
+                       goto ERROR;
+               }
+       }
+
+       if (textbin[MMPLAYER_T_VIDEO_QUEUE].gst)
+       {
+               pad = gst_element_get_static_pad(GST_ELEMENT(textbin[MMPLAYER_T_VIDEO_QUEUE].gst), "sink");
+               if (!pad)
+               {
+                       debug_error("failed to get video pad of textbin\n");
+                       goto ERROR;
+               }
+
+               ghostpad = gst_ghost_pad_new("video_sink", pad);
+               if (!ghostpad)
+               {
+                       debug_error("failed to create ghostpad of textbin\n");
+                       goto ERROR;
+               }
+
+               if (!gst_element_add_pad(textbin[MMPLAYER_T_BIN].gst, ghostpad))
+               {
+                       debug_error("failed to add ghostpad to textbin\n");
+                       goto ERROR;
+               }
+       }
+
+       if (textbin[MMPLAYER_T_OVERLAY].gst)
+       {
+               pad = gst_element_get_static_pad(GST_ELEMENT(textbin[MMPLAYER_T_OVERLAY].gst), "src");
+               if (!pad)
+               {
+                       debug_error("failed to get src pad of textbin\n");
+                       goto ERROR;
+               }
+
+               ghostpad = gst_ghost_pad_new("src", pad);
+               if (!ghostpad)
+               {
+                       debug_error("failed to create ghostpad of textbin\n");
+                       goto ERROR;
+               }
+
+               if (!gst_element_add_pad(textbin[MMPLAYER_T_BIN].gst, ghostpad))
+               {
+                       debug_error("failed to add ghostpad to textbin\n");
+                       goto ERROR;
+               }
+       }
+
+       gst_object_unref(pad);
+
+       debug_fleave();
+
+       return MM_ERROR_NONE;
+
+ERROR:
+
+       debug_log("ERROR : releasing textbin\n");
+
+       if ( pad )
+               gst_object_unref(GST_OBJECT(pad));
+
+       if ( ghostpad )
+               gst_object_unref(GST_OBJECT(ghostpad));
+
+       g_list_free( element_bucket );
+
+
+       /* release element which are not added to bin */
+       for ( i = 1; i < MMPLAYER_T_NUM; i++ )  /* NOTE : skip bin */
+       {
+               if ( textbin[i].gst )
+               {
+                       GstObject* parent = NULL;
+                       parent = gst_element_get_parent( textbin[i].gst );
+
+                       if ( !parent )
+                       {
+                               gst_object_unref(GST_OBJECT(textbin[i].gst));
+                               textbin[i].gst = NULL;
+                       }
+                       else
+                       {
+                               gst_object_unref(GST_OBJECT(parent));
+                       }
+               }
+       }
+
+       /* release textbin with it's childs */
+       if ( textbin[MMPLAYER_T_BIN].gst )
+       {
+               gst_object_unref(GST_OBJECT(textbin[MMPLAYER_T_BIN].gst));
+       }
+
+       MMPLAYER_FREEIF( textbin );
+
+       player->pipeline->textbin = NULL;
+
+       return MM_ERROR_PLAYER_INTERNAL;
+}
+
+
+static int
+__mmplayer_gst_create_subtitle_src(mm_player_t* player)
+{
+       MMPlayerGstElement* mainbin = NULL;
+       MMHandleType attrs = 0;
+       GstElement * pipeline = NULL;
+       GstElement *subsrc = NULL;
+       GstElement *subparse = NULL;
+       GstPad *sinkpad = NULL;
+       gchar *subtitle_uri =NULL;
+       gchar *charset = NULL;
+
+       debug_fenter();
+
+       /* get mainbin */
+       return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       pipeline = player->pipeline->mainbin[MMPLAYER_M_PIPE].gst;
+       mainbin = player->pipeline->mainbin;
+
+       attrs = MMPLAYER_GET_ATTRS(player);
+       if ( !attrs )
+       {
+               debug_error("cannot get content attribute\n");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       mm_attrs_get_string_by_name ( attrs, "subtitle_uri", &subtitle_uri );
+       if ( !subtitle_uri || strlen(subtitle_uri) < 1)
+       {
+               debug_error("subtitle uri is not proper filepath.\n");
+               return MM_ERROR_PLAYER_INVALID_URI;     
+       }
+       debug_log("subtitle file path is [%s].\n", subtitle_uri);
+
+
+       /* create the subtitle source */
+       subsrc = gst_element_factory_make("filesrc", "subtitle_source");
+       if ( !subsrc )
+       {
+               debug_error ( "failed to create filesrc element\n" );
+               goto ERROR;
+       }
+       g_object_set(G_OBJECT (subsrc), "location", subtitle_uri, NULL);
+
+       mainbin[MMPLAYER_M_SUBSRC].id = MMPLAYER_M_SUBSRC;
+       mainbin[MMPLAYER_M_SUBSRC].gst = subsrc;
+
+       if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), subsrc))
+       {
+               debug_warning("failed to add queue\n");
+               goto ERROR;
+       }
+
+       /* subparse */
+       subparse = gst_element_factory_make("subparse", "subtitle_parser");
+       if ( !subparse )
+       {
+               debug_error ( "failed to create subparse element\n" );
+               goto ERROR;
+       }
+
+       charset = util_get_charset(subtitle_uri);
+       if (charset)
+       {
+               debug_log ("detected charset is %s\n", charset );
+               g_object_set (G_OBJECT (subparse), "subtitle-encoding", charset, NULL);
+       }
+
+       mainbin[MMPLAYER_M_SUBPARSE].id = MMPLAYER_M_SUBPARSE;
+       mainbin[MMPLAYER_M_SUBPARSE].gst = subparse;
+
+       if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), subparse))
+       {
+               debug_warning("failed to add subparse\n");
+               goto ERROR;
+       }
+
+       if (!gst_element_link_pads (subsrc, "src", subparse, "sink"))
+       {
+               debug_warning("failed to link subsrc and subparse\n");
+               goto ERROR;
+       }
+
+       player->play_subtitle = TRUE;
+       debug_log ("play subtitle using subtitle file\n");
+
+       if (MM_ERROR_NONE !=  __mmplayer_gst_create_text_pipeline(player))
+       {
+               debug_error("failed to create textbin. continuing without text\n");
+               goto ERROR;
+       }
+
+       if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), GST_ELEMENT(player->pipeline->textbin[MMPLAYER_T_BIN].gst)))
+       {
+               debug_warning("failed to add textbin\n");
+               goto ERROR;
+       }
+
+       if (!gst_element_link_pads (subparse, "src", player->pipeline->textbin[MMPLAYER_T_BIN].gst, "text_sink"))
+       {
+               debug_warning("failed to link subparse and textbin\n");
+               goto ERROR;
+       }
+
+       debug_fleave();
+       
+       return MM_ERROR_NONE;
+
+
+ERROR:
+       return MM_ERROR_PLAYER_INTERNAL;
+}
+
+gboolean
+__mmplayer_update_subtitle( GstElement* object, GstBuffer *buffer, GstPad *pad, gpointer data)
+{
+       mm_player_t* player = (mm_player_t*) data;
+       MMMessageParamType msg = {0, };
+       GstClockTime duration = 0;
+       guint8 *text = NULL;
+       gboolean ret = TRUE;
+
+       debug_fenter();
+
+       return_val_if_fail ( player, FALSE );
+       return_val_if_fail ( buffer, FALSE );
+
+       text = GST_BUFFER_DATA(buffer);
+       duration = GST_BUFFER_DURATION(buffer);
+
+       if ( player->is_subtitle_off )
+       {
+               debug_log("subtitle is OFF.\n" );
+               return TRUE;
+       }
+
+       if ( !text )
+       {
+               debug_log("There is no subtitle to be displayed.\n" );
+               return TRUE;
+       }
+
+       msg.data = (void *) text;
+       msg.subtitle.duration = GST_TIME_AS_MSECONDS(duration);
+
+       debug_warning("update subtitle : [%ld msec] %s\n'", msg.subtitle.duration, (char*)msg.data );
+
+       MMPLAYER_POST_MSG( player, MM_MESSAGE_UPDATE_SUBTITLE, &msg );
+
+       debug_fleave();
+
+       return ret;
+}
+
+static int     __gst_adjust_subtitle_position(mm_player_t* player, int format, int position)
+{
+       GstEvent* event = NULL;
+       gint64 current_pos = 0;
+       gint64 adusted_pos = 0;
+       gboolean ret = TRUE;
+
+       debug_fenter();
+
+       /* check player and subtitlebin are created */
+       return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail ( player->play_subtitle, MM_ERROR_NOT_SUPPORT_API );
+
+       if (position == 0)
+       {
+               debug_log ("nothing to do\n");
+               return MM_ERROR_NONE;
+       }
+
+       switch (format)
+       {
+               case MM_PLAYER_POS_FORMAT_TIME:
+               {
+                       /* check current postion */
+                       if (__gst_get_position(player, MM_PLAYER_POS_FORMAT_TIME, &current_pos ))
+                       {
+                               debug_error("failed to get position");
+                               return MM_ERROR_PLAYER_INTERNAL;
+                       }
+
+                       adusted_pos = (gint64)current_pos + ((gint64)position * G_GINT64_CONSTANT(1000000));
+                       if (adusted_pos < 0)
+                               adusted_pos = G_GUINT64_CONSTANT(0);
+                       debug_log("adjust subtitle postion : %lu -> %lu [msec]\n", GST_TIME_AS_MSECONDS(current_pos), GST_TIME_AS_MSECONDS(adusted_pos));
+
+                       event = gst_event_new_seek (1.0,        GST_FORMAT_TIME,
+                               ( GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE ),
+                               GST_SEEK_TYPE_SET, adusted_pos,
+                               GST_SEEK_TYPE_SET, -1);
+               }
+               break;
+
+               default:
+               {
+                       debug_warning("invalid format.\n");
+                       return MM_ERROR_INVALID_ARGUMENT;
+               }
+       }
+
+       /* keep ref to the event */
+       gst_event_ref (event);
+
+       debug_log("sending event[%s] to subparse element [%s]\n",
+                       GST_EVENT_TYPE_NAME(event), GST_ELEMENT_NAME(player->pipeline->mainbin[MMPLAYER_M_SUBPARSE].gst) );
+
+       if (gst_element_send_event (player->pipeline->mainbin[MMPLAYER_M_SUBPARSE].gst, event))
+       {
+               debug_log("sending event[%s] to subparse element [%s] success!\n",
+                       GST_EVENT_TYPE_NAME(event), GST_ELEMENT_NAME(player->pipeline->mainbin[MMPLAYER_M_SUBPARSE].gst) );
+       }
+
+       /* unref to the event */
+       gst_event_unref (event);
+
+       debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+static void
+__gst_appsrc_feed_data_mem(GstElement *element, guint size, gpointer user_data) // @
+{
+       GstElement *appsrc = element;
+       tBuffer *buf = (tBuffer *)user_data;
+       GstBuffer *buffer = NULL;
+       GstFlowReturn ret = GST_FLOW_OK;
+       gint len = size;
+
+       return_if_fail ( element );
+       return_if_fail ( buf );
+
+       buffer = gst_buffer_new ();
+
+       if (buf->offset >= buf->len)
+       {
+               debug_log("call eos appsrc\n");
+              g_signal_emit_by_name (appsrc, "end-of-stream", &ret);
+              return;
+       }
+
+       if ( buf->len - buf->offset < size)
+       {
+               len = buf->len - buf->offset + buf->offset;
+       }
+
+       GST_BUFFER_DATA(buffer) = (guint8*)(buf->buf + buf->offset);
+       GST_BUFFER_SIZE(buffer) = len;
+       GST_BUFFER_OFFSET(buffer) = buf->offset;
+       GST_BUFFER_OFFSET_END(buffer) = buf->offset + len;
+
+       debug_log("feed buffer %p, offset %u-%u length %u\n", buffer, buf->offset, buf->len,len);
+       g_signal_emit_by_name (appsrc, "push-buffer", buffer, &ret);
+
+       buf->offset += len;
+}
+
+static gboolean
+__gst_appsrc_seek_data_mem(GstElement *element, guint64 size, gpointer user_data) // @
+{
+       tBuffer *buf = (tBuffer *)user_data;
+
+       return_val_if_fail ( buf, FALSE );
+
+       buf->offset  = (int)size;
+
+       return TRUE;
+}
+
+static void
+__gst_appsrc_feed_data(GstElement *element, guint size, gpointer user_data) // @
+{
+       mm_player_t *player  = (mm_player_t*)user_data;
+
+       return_if_fail ( player );
+
+       debug_msg("app-src: feed data\n");
+            
+       if(player->need_data_cb)
+               player->need_data_cb(size, player->buffer_cb_user_param);
+}
+
+static gboolean
+__gst_appsrc_seek_data(GstElement *element, guint64 offset, gpointer user_data) // @
+{
+       mm_player_t *player  = (mm_player_t*)user_data;
+
+       return_val_if_fail ( player, FALSE );
+
+       debug_msg("app-src: seek data\n");
+
+       if(player->seek_data_cb)
+               player->seek_data_cb(offset, player->buffer_cb_user_param);
+
+       return TRUE;
+}
+
+
+static gboolean
+__gst_appsrc_enough_data(GstElement *element, gpointer user_data) // @
+{
+       mm_player_t *player  = (mm_player_t*)user_data;
+
+       return_val_if_fail ( player, FALSE );
+
+       debug_msg("app-src: enough data:%p\n", player->enough_data_cb);
+       
+       if(player->enough_data_cb)
+               player->enough_data_cb(player->buffer_cb_user_param);
+
+       return TRUE;
+}
+
+int
+_mmplayer_push_buffer(MMHandleType hplayer, unsigned char *buf, int size) // @
+{
+       mm_player_t* player = (mm_player_t*)hplayer;
+       GstBuffer *buffer = NULL;
+       GstFlowReturn gst_ret = GST_FLOW_OK;
+       int ret = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       /* check current state */
+//     MMPLAYER_CHECK_STATE_RETURN_IF_FAIL( player, MMPLAYER_COMMAND_START );
+
+
+       /* NOTE : we should check and create pipeline again if not created as we destroy
+        * whole pipeline when stopping in streamming playback
+        */
+       if ( ! player->pipeline )
+       {
+               if ( MM_ERROR_NONE != __gst_realize( player ) )
+               {
+                       debug_error("failed to realize before starting. only in streamming\n");
+                       return MM_ERROR_PLAYER_INTERNAL;
+               }
+       }
+
+       debug_msg("app-src: pushing data\n");
+
+       if ( buf == NULL )
+       {
+               debug_error("buf is null\n");
+               return MM_ERROR_NONE;
+       }
+
+       buffer = gst_buffer_new ();
+
+       if (size <= 0)
+       {
+               debug_log("call eos appsrc\n");
+               g_signal_emit_by_name (player->pipeline->mainbin[MMPLAYER_M_SRC].gst, "end-of-stream", &gst_ret);
+               return MM_ERROR_NONE;
+       }
+
+       GST_BUFFER_DATA(buffer) = (guint8*)(buf);
+       GST_BUFFER_SIZE(buffer) = size;
+
+       debug_log("feed buffer %p, length %u\n", buf, size);
+       g_signal_emit_by_name (player->pipeline->mainbin[MMPLAYER_M_SRC].gst, "push-buffer", buffer, &gst_ret);
+
+       debug_fleave();
+
+       return ret;
+}
+
+static GstBusSyncReply
+__mmplayer_bus_sync_callback (GstBus * bus, GstMessage * message, gpointer data)
+{
+       mm_player_t *player = (mm_player_t *)data;
+
+       switch (GST_MESSAGE_TYPE (message))
+       {
+               case GST_MESSAGE_TAG:
+                       __mmplayer_gst_extract_tag_from_msg(player, message);
+                       break;
+
+               default:
+                       return GST_BUS_PASS;
+       }
+       gst_message_unref (message);
+
+       return GST_BUS_DROP;
+}
+
+/**
+ * This function is to create  audio or video pipeline for playing.
+ *
+ * @param      player          [in]    handle of player
+ *
+ * @return     This function returns zero on success.
+ * @remark
+ * @see
+ */
+static int
+__mmplayer_gst_create_pipeline(mm_player_t* player) // @
+{
+       GstBus  *bus = NULL;
+       MMPlayerGstElement *mainbin = NULL;
+       MMHandleType attrs = 0;
+       GstElement* element = NULL;
+       GList* element_bucket = NULL;
+       gboolean need_state_holder = TRUE;
+       gint i = 0;
+
+       debug_fenter();
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       /* get profile attribute */
+       attrs = MMPLAYER_GET_ATTRS(player);
+       if ( !attrs )
+       {
+               debug_error("cannot get content attribute\n");
+               goto INIT_ERROR;
+       }
+
+       /* create pipeline handles */
+       if ( player->pipeline )
+       {
+               debug_warning("pipeline should be released before create new one\n");
+               goto INIT_ERROR;
+       }
+
+       player->pipeline = (MMPlayerGstPipelineInfo*) g_malloc0( sizeof(MMPlayerGstPipelineInfo) );
+       if (player->pipeline == NULL)
+               goto INIT_ERROR;
+
+       memset( player->pipeline, 0, sizeof(MMPlayerGstPipelineInfo) );
+
+
+       /* create mainbin */
+       mainbin = (MMPlayerGstElement*) g_malloc0( sizeof(MMPlayerGstElement) * MMPLAYER_M_NUM );
+       if (mainbin == NULL)
+               goto INIT_ERROR;
+
+       memset( mainbin, 0, sizeof(MMPlayerGstElement) * MMPLAYER_M_NUM);
+
+
+       /* create pipeline */
+       mainbin[MMPLAYER_M_PIPE].id = MMPLAYER_M_PIPE;
+       mainbin[MMPLAYER_M_PIPE].gst = gst_pipeline_new("player");
+       if ( ! mainbin[MMPLAYER_M_PIPE].gst )
+       {
+               debug_error("failed to create pipeline\n");
+               goto INIT_ERROR;
+       }
+
+
+       /* create source element */
+       switch ( player->profile.uri_type )
+       {
+               /* rtsp streamming */
+               case MM_PLAYER_URI_TYPE_URL_RTSP:
+               {
+                       gint network_bandwidth;
+                       gchar *user_agent, *wap_profile;
+
+                       element = gst_element_factory_make(PLAYER_INI()->name_of_rtspsrc, "streaming_source");
+
+                       if ( !element )
+                       {
+                               debug_critical("failed to create streaming source element\n");
+                               break;
+                       }
+
+                       debug_log("using streamming source [%s].\n", PLAYER_INI()->name_of_rtspsrc);
+
+                       /* make it zero */
+                       network_bandwidth = 0;
+                       user_agent = wap_profile = NULL;
+
+                       /* get attribute */
+                       mm_attrs_get_string_by_name ( attrs, "streaming_user_agent", &user_agent );
+                       mm_attrs_get_string_by_name ( attrs,"streaming_wap_profile", &wap_profile );
+                       mm_attrs_get_int_by_name ( attrs, "streaming_network_bandwidth", &network_bandwidth );
+
+                       debug_log("setting streaming source ----------------\n");
+                       debug_log("user_agent : %s\n", user_agent);
+                       debug_log("wap_profile : %s\n", wap_profile);
+                       debug_log("network_bandwidth : %d\n", network_bandwidth);
+                       debug_log("buffering time : %d\n", PLAYER_INI()->rtsp_buffering_time);
+                       debug_log("rebuffering time : %d\n", PLAYER_INI()->rtsp_rebuffering_time);
+                       debug_log("-----------------------------------------\n");
+
+                       /* setting property to streaming source */
+                       g_object_set(G_OBJECT(element), "location", player->profile.uri, NULL);
+                       g_object_set(G_OBJECT(element), "bandwidth", network_bandwidth, NULL);
+                       g_object_set(G_OBJECT(element), "buffering_time", PLAYER_INI()->rtsp_buffering_time, NULL);
+                       g_object_set(G_OBJECT(element), "rebuffering_time", PLAYER_INI()->rtsp_rebuffering_time, NULL);
+                       if ( user_agent )
+                               g_object_set(G_OBJECT(element), "user_agent", user_agent, NULL);
+                       if ( wap_profile )
+                               g_object_set(G_OBJECT(element), "wap_profile", wap_profile, NULL);
+
+                       MMPLAYER_SIGNAL_CONNECT ( player, G_OBJECT(element), "pad-added",
+                               G_CALLBACK (__mmplayer_gst_rtp_dynamic_pad), player );
+                       MMPLAYER_SIGNAL_CONNECT ( player, G_OBJECT(element), "no-more-pads",
+                               G_CALLBACK (__mmplayer_gst_rtp_no_more_pads), player );
+
+                       player->no_more_pad = FALSE;
+                       player->num_dynamic_pad = 0;
+
+                       /* NOTE : we cannot determine it yet. this filed will be filled by
+                        * _mmplayer_update_content_attrs() after START.
+                        */
+                       player->streaming_type = STREAMING_SERVICE_NONE;
+               }
+               break;
+
+               /* http streaming*/
+               case MM_PLAYER_URI_TYPE_URL_HTTP:
+               {
+                       gchar *user_agent, *proxy, *cookies, **cookie_list;
+                       user_agent = proxy = cookies = NULL;
+                       cookie_list = NULL;
+                       gint mode = MM_PLAYER_PD_MODE_NONE;
+
+                       mm_attrs_get_int_by_name ( attrs, "pd_mode", &mode );
+
+                       player->pd_mode = mode;
+
+                       debug_log("http playback, PD mode : %d\n", player->pd_mode);
+
+                       if ( ! MMPLAYER_IS_HTTP_PD(player) )
+                       {
+                               element = gst_element_factory_make(PLAYER_INI()->name_of_httpsrc, "http_streaming_source");
+                               if ( !element )
+                               {
+                                       debug_critical("failed to create http streaming source element[%s].\n", PLAYER_INI()->name_of_httpsrc);
+                                       break;
+                               }
+                               debug_log("using http streamming source [%s].\n", PLAYER_INI()->name_of_httpsrc);
+
+                               /* get attribute */
+                               mm_attrs_get_string_by_name ( attrs, "streaming_cookie", &cookies );
+                               mm_attrs_get_string_by_name ( attrs, "streaming_user_agent", &user_agent );
+                               mm_attrs_get_string_by_name ( attrs, "streaming_proxy", &proxy );
+                               
+                               /* get attribute */
+                               debug_log("setting http streaming source ----------------\n");
+                               debug_log("location : %s\n", player->profile.uri);
+                               debug_log("cookies : %s\n", cookies);
+                               debug_log("proxy : %s\n", proxy);
+                               debug_log("user_agent :  %s\n",  user_agent);
+                               debug_log("timeout : %d\n",  PLAYER_INI()->http_timeout);
+                               debug_log("-----------------------------------------\n");
+
+                               /* setting property to streaming source */
+                               g_object_set(G_OBJECT(element), "location", player->profile.uri, NULL);
+                               g_object_set(G_OBJECT(element), "timeout", PLAYER_INI()->http_timeout, NULL);
+                               /* check if prosy is vailid or not */
+                               if ( util_check_valid_url ( proxy ) )
+                                       g_object_set(G_OBJECT(element), "proxy", proxy, NULL);
+                               /* parsing cookies */
+                               if ( ( cookie_list = util_get_cookie_list ((const char*)cookies) ) )
+                                       g_object_set(G_OBJECT(element), "cookies", cookie_list, NULL);
+                               if ( user_agent )
+                                       g_object_set(G_OBJECT(element), "user_agent", user_agent, NULL);
+                       }
+                       else // progressive download 
+                       {
+                               if (player->pd_mode == MM_PLAYER_PD_MODE_URI)
+                               {
+                                       gchar *path = NULL;
+                                       
+                                       mm_attrs_get_string_by_name ( attrs, "pd_location", &path );
+                                       
+                                       MMPLAYER_FREEIF(player->pd_file_save_path);
+
+                                       debug_log("PD Location : %s\n", path);
+
+                                       if ( path )
+                                       {
+                                               player->pd_file_save_path = g_strdup(path);
+                                       }
+                                       else
+                                       {
+                                               debug_error("can't find pd location so, it should be set \n");
+                                               return MM_ERROR_PLAYER_FILE_NOT_FOUND;  
+                                       }
+                               }
+
+                               element = gst_element_factory_make("pdpushsrc", "PD pushsrc");
+                               if ( !element )
+                               {
+                                       debug_critical("failed to create PD push source element[%s].\n", "pdpushsrc");
+                                       break;
+                               }
+
+                               g_object_set(G_OBJECT(element), "location", player->pd_file_save_path, NULL);
+                       }
+                       
+                       player->streaming_type = STREAMING_SERVICE_NONE;
+               }
+               break;
+
+               /* file source */
+               case MM_PLAYER_URI_TYPE_FILE:
+               {
+                       char* drmsrc = PLAYER_INI()->name_of_drmsrc;
+
+                       debug_log("using [%s] for 'file://' handler.\n", drmsrc);
+
+                       element = gst_element_factory_make(drmsrc, "source");
+                       if ( !element )
+                       {
+                               debug_critical("failed to create %s\n", drmsrc);
+                               break;
+                       }
+
+                       g_object_set(G_OBJECT(element), "location", (player->profile.uri)+7, NULL);     /* uri+7 -> remove "file:// */
+                       //g_object_set(G_OBJECT(element), "use-mmap", TRUE, NULL);
+               }
+               break;
+
+               /* appsrc */
+               case MM_PLAYER_URI_TYPE_BUFF:
+               {
+                       guint64 stream_type = GST_APP_STREAM_TYPE_STREAM;
+
+                       debug_log("mem src is selected\n");
+
+                       element = gst_element_factory_make("appsrc", "buff-source");
+                       if ( !element )
+                       {
+                               debug_critical("failed to create appsrc element\n");
+                               break;
+                       }
+
+                       g_object_set( element, "stream-type", stream_type, NULL );
+                       //g_object_set( element, "size", player->mem_buf.len, NULL );
+                       //g_object_set( element, "blocksize", (guint64)20480, NULL );
+
+                       MMPLAYER_SIGNAL_CONNECT( player, element, "seek-data",
+                               G_CALLBACK(__gst_appsrc_seek_data), player);
+                       MMPLAYER_SIGNAL_CONNECT( player, element, "need-data",
+                               G_CALLBACK(__gst_appsrc_feed_data), player);
+                       MMPLAYER_SIGNAL_CONNECT( player, element, "enough-data",
+                               G_CALLBACK(__gst_appsrc_enough_data), player);
+               }
+               break;
+
+               /* appsrc */
+               case MM_PLAYER_URI_TYPE_MEM:
+               {
+                       guint64 stream_type = GST_APP_STREAM_TYPE_RANDOM_ACCESS;
+
+                       debug_log("mem src is selected\n");
+
+                       element = gst_element_factory_make("appsrc", "mem-source");
+                       if ( !element )
+                       {
+                               debug_critical("failed to create appsrc element\n");
+                               break;
+                       }
+
+                       g_object_set( element, "stream-type", stream_type, NULL );
+                       g_object_set( element, "size", player->mem_buf.len, NULL );
+                       g_object_set( element, "blocksize", (guint64)20480, NULL );
+
+                       MMPLAYER_SIGNAL_CONNECT( player, element, "seek-data",
+                               G_CALLBACK(__gst_appsrc_seek_data_mem), &player->mem_buf );
+                       MMPLAYER_SIGNAL_CONNECT( player, element, "need-data",
+                               G_CALLBACK(__gst_appsrc_feed_data_mem), &player->mem_buf );
+               }
+               break;
+               case MM_PLAYER_URI_TYPE_URL:
+               break;
+
+               case MM_PLAYER_URI_TYPE_TEMP:
+               break;
+
+               case MM_PLAYER_URI_TYPE_NONE:
+               default:
+               break;
+       }
+
+       /* check source element is OK */
+       if ( ! element )
+       {
+               debug_critical("no source element was created.\n");
+               goto INIT_ERROR;
+       }
+
+       /* take source element */
+       mainbin[MMPLAYER_M_SRC].id = MMPLAYER_M_SRC;
+       mainbin[MMPLAYER_M_SRC].gst = element;
+       element_bucket = g_list_append(element_bucket, &mainbin[MMPLAYER_M_SRC]);
+
+       if (MMPLAYER_IS_STREAMING(player))
+       {
+               player->streamer = __mm_player_streaming_create();
+               __mm_player_streaming_initialize(player->streamer);
+       }
+
+       if ( MMPLAYER_IS_HTTP_PD(player) )
+       {       
+              debug_log ("Picked queue2 element....\n");
+               element = gst_element_factory_make("queue2", "hls_stream_buffer");
+               if ( !element )
+               {
+                       debug_critical ( "failed to create http streaming buffer element\n" );
+                       goto INIT_ERROR;
+               }
+                       
+               /* take it */
+               mainbin[MMPLAYER_M_S_BUFFER].id = MMPLAYER_M_S_BUFFER;
+               mainbin[MMPLAYER_M_S_BUFFER].gst = element;
+               element_bucket = g_list_append(element_bucket, &mainbin[MMPLAYER_M_S_BUFFER]);
+
+               __mm_player_streaming_set_buffer(player->streamer,
+                               element,
+                               TRUE,
+                               PLAYER_INI()->http_max_size_bytes,
+                               1.0,
+                               PLAYER_INI()->http_buffering_limit,
+                               PLAYER_INI()->http_buffering_time,
+                               FALSE,
+                               NULL,
+                               0);
+       }
+
+       /* create autoplugging element if src element is not a streamming src */
+       if ( player->profile.uri_type != MM_PLAYER_URI_TYPE_URL_RTSP )
+       {
+               element = NULL;
+
+               if( PLAYER_INI()->use_decodebin )
+               {
+                       /* create decodebin */
+                       element = gst_element_factory_make("decodebin", "decodebin");
+
+                       g_object_set(G_OBJECT(element), "async-handling", TRUE, NULL);
+
+                       /* set signal handler */
+                       MMPLAYER_SIGNAL_CONNECT( player, G_OBJECT(element), "new-decoded-pad",
+                                       G_CALLBACK(__mmplayer_gst_decode_callback), player);
+
+                       /* we don't need state holder, bcz decodebin is doing well by itself */
+                       need_state_holder = FALSE;
+               }
+               else
+               {
+                       element = gst_element_factory_make("typefind", "typefinder");
+                       MMPLAYER_SIGNAL_CONNECT( player, element, "have-type",
+                               G_CALLBACK(__mmplayer_typefind_have_type), (gpointer)player );
+               }
+
+               /* check autoplug element is OK */
+               if ( ! element )
+               {
+                       debug_critical("can not create autoplug element\n");
+                       goto INIT_ERROR;
+               }
+
+               mainbin[MMPLAYER_M_AUTOPLUG].id = MMPLAYER_M_AUTOPLUG;
+               mainbin[MMPLAYER_M_AUTOPLUG].gst = element;
+
+               element_bucket = g_list_append(element_bucket, &mainbin[MMPLAYER_M_AUTOPLUG]);
+       }
+
+
+       /* add elements to pipeline */
+       if( !__mmplayer_gst_element_add_bucket_to_bin(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), element_bucket))
+       {
+               debug_error("Failed to add elements to pipeline\n");
+               goto INIT_ERROR;
+       }
+
+
+       /* linking elements in the bucket by added order. */
+       if ( __mmplayer_gst_element_link_bucket(element_bucket) == -1 )
+       {
+               debug_error("Failed to link some elements\n");
+               goto INIT_ERROR;
+       }
+
+
+       /* create fakesink element for keeping the pipeline state PAUSED. if needed */
+       if ( need_state_holder )
+       {
+               /* create */
+               mainbin[MMPLAYER_M_SRC_FAKESINK].id = MMPLAYER_M_SRC_FAKESINK;
+               mainbin[MMPLAYER_M_SRC_FAKESINK].gst = gst_element_factory_make ("fakesink", "state-holder");
+
+               if (!mainbin[MMPLAYER_M_SRC_FAKESINK].gst)
+               {
+                       debug_error ("fakesink element could not be created\n");
+                       goto INIT_ERROR;
+               }
+               GST_OBJECT_FLAG_UNSET (mainbin[MMPLAYER_M_SRC_FAKESINK].gst, GST_ELEMENT_IS_SINK);
+
+               /* take ownership of fakesink. we are reusing it */
+               gst_object_ref( mainbin[MMPLAYER_M_SRC_FAKESINK].gst );
+
+               /* add */
+               if ( FALSE == gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst),
+                       mainbin[MMPLAYER_M_SRC_FAKESINK].gst) )
+               {
+                       debug_error("failed to add fakesink to bin\n");
+                       goto INIT_ERROR;
+               }
+       }
+
+       /* now we have completed mainbin. take it */
+       player->pipeline->mainbin = mainbin;
+
+       /* connect bus callback */
+       bus = gst_pipeline_get_bus(GST_PIPELINE(mainbin[MMPLAYER_M_PIPE].gst));
+       if ( !bus )
+       {
+               debug_error ("cannot get bus from pipeline.\n");
+               goto INIT_ERROR;
+       }
+       player->bus_watcher = gst_bus_add_watch(bus, (GstBusFunc)__mmplayer_gst_callback, player);
+
+       /* Note : check whether subtitle atrribute uri is set. If uri is set, then tyr to play subtitle file */
+       if ( __mmplayer_check_subtitle ( player ) )
+       {
+               if ( MM_ERROR_NONE != __mmplayer_gst_create_subtitle_src(player) )
+                       debug_error("fail to create subtitle src\n")
+       }
+
+       /* set sync handler to get tag synchronously */
+       gst_bus_set_sync_handler(bus, __mmplayer_bus_sync_callback, player);
+
+       /* finished */
+       gst_object_unref(GST_OBJECT(bus));
+       g_list_free(element_bucket);
+
+       debug_fleave();
+
+       return MM_ERROR_NONE;
+
+INIT_ERROR:
+
+       __mmplayer_gst_destroy_pipeline(player);
+       g_list_free(element_bucket);
+
+       /* release element which are not added to bin */
+       for ( i = 1; i < MMPLAYER_M_NUM; i++ )  /* NOTE : skip pipeline */
+       {
+               if ( mainbin[i].gst )
+               {
+                       GstObject* parent = NULL;
+                       parent = gst_element_get_parent( mainbin[i].gst );
+
+                       if ( !parent )
+                       {
+                               gst_object_unref(GST_OBJECT(mainbin[i].gst));
+                               mainbin[i].gst = NULL;
+                       }
+                       else
+                       {
+                               gst_object_unref(GST_OBJECT(parent));
+                       }
+               }
+       }
+
+       /* release pipeline with it's childs */
+       if ( mainbin[MMPLAYER_M_PIPE].gst )
+       {
+               gst_object_unref(GST_OBJECT(mainbin[MMPLAYER_M_PIPE].gst));
+       }
+
+       MMPLAYER_FREEIF( player->pipeline );
+       MMPLAYER_FREEIF( mainbin );
+
+       return MM_ERROR_PLAYER_INTERNAL;
+}
+
+
+static int
+__mmplayer_gst_destroy_pipeline(mm_player_t* player) // @
+{
+       gint timeout = 0;
+       int ret = MM_ERROR_NONE;
+
+       debug_fenter();
+       
+       return_val_if_fail ( player, MM_ERROR_INVALID_HANDLE );
+
+       /* cleanup stuffs */
+       MMPLAYER_FREEIF(player->type);
+       player->have_dynamic_pad = FALSE;
+       player->no_more_pad = FALSE;
+       player->num_dynamic_pad = 0;
+
+       if (player->v_stream_caps)
+       {
+               gst_caps_unref(player->v_stream_caps);
+               player->v_stream_caps = NULL;
+       }
+
+       if (ahs_appsrc_cb_probe_id )
+       {
+               GstPad *pad = NULL;
+               pad = gst_element_get_static_pad(player->pipeline->mainbin[MMPLAYER_M_SRC].gst, "src" );
+
+               gst_pad_remove_buffer_probe (pad, ahs_appsrc_cb_probe_id);
+               gst_object_unref(pad);
+               pad = NULL;
+               ahs_appsrc_cb_probe_id = 0;
+       }
+
+       if ( player->sink_elements )
+               g_list_free ( player->sink_elements );
+       player->sink_elements = NULL;
+
+       /* cleanup unlinked mime type */
+       MMPLAYER_FREEIF(player->unlinked_audio_mime);
+       MMPLAYER_FREEIF(player->unlinked_video_mime);
+       MMPLAYER_FREEIF(player->unlinked_demuxer_mime); 
+
+       /* cleanup running stuffs */
+       __mmplayer_cancel_delayed_eos( player );
+
+       /* cleanup gst stuffs */
+       if ( player->pipeline )
+       {
+               MMPlayerGstElement* mainbin = player->pipeline->mainbin;
+               GstTagList* tag_list = player->pipeline->tag_list;
+
+               /* first we need to disconnect all signal hander */
+               __mmplayer_release_signal_connection( player );
+
+               /* disconnecting bus watch */
+               if ( player->bus_watcher )
+                       g_source_remove( player->bus_watcher );
+               player->bus_watcher = 0;
+
+               if ( mainbin )
+               {
+                       MMPlayerGstElement* audiobin = player->pipeline->audiobin;
+                       MMPlayerGstElement* videobin = player->pipeline->videobin;
+                       MMPlayerGstElement* textbin = player->pipeline->textbin;
+                       GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (mainbin[MMPLAYER_M_PIPE].gst));
+                       gst_bus_set_sync_handler (bus, NULL, NULL);
+
+                       debug_log("pipeline status before set state to NULL\n");
+                       __mmplayer_dump_pipeline_state( player );
+
+                       timeout = MMPLAYER_STATE_CHANGE_TIMEOUT(player);
+                       ret = __mmplayer_gst_set_state ( player, mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_NULL, FALSE, timeout );
+                       if ( ret != MM_ERROR_NONE )
+                       {
+                               debug_error("fail to change state to NULL\n");
+                               return MM_ERROR_PLAYER_INTERNAL;
+                       }
+
+                       debug_log("pipeline status before unrefering pipeline\n");
+                       __mmplayer_dump_pipeline_state( player );
+
+                       gst_object_unref(GST_OBJECT(mainbin[MMPLAYER_M_PIPE].gst));
+
+                       /* free fakesink */
+                       if ( mainbin[MMPLAYER_M_SRC_FAKESINK].gst )
+                               gst_object_unref(GST_OBJECT(mainbin[MMPLAYER_M_SRC_FAKESINK].gst));
+
+                       /* free avsysaudiosink
+                          avsysaudiosink should be unref when destory pipeline just after start play with BT.
+                          Because audiosink is created but never added to bin, and therefore it will not be unref when pipeline is destroyed.
+                       */
+                       MMPLAYER_FREEIF( audiobin );
+                       MMPLAYER_FREEIF( videobin );
+                       MMPLAYER_FREEIF( textbin );
+                       MMPLAYER_FREEIF( mainbin );
+               }
+
+               if ( tag_list )
+                       gst_tag_list_free(tag_list);
+
+               MMPLAYER_FREEIF( player->pipeline );
+       }
+
+       player->pipeline_is_constructed = FALSE;
+       
+       debug_fleave();
+
+       return ret;
+}
+
+static int __gst_realize(mm_player_t* player) // @
+{
+       gint timeout = 0;
+       int ret = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_READY;
+
+       __ta__("__mmplayer_gst_create_pipeline",
+               ret = __mmplayer_gst_create_pipeline(player);
+               if ( ret )
+               {
+                       debug_critical("failed to create pipeline\n");
+                       return ret;
+               }
+       )
+
+       /* set pipeline state to READY */
+       /* NOTE : state change to READY must be performed sync. */
+       timeout = MMPLAYER_STATE_CHANGE_TIMEOUT(player);
+       ret = __mmplayer_gst_set_state(player,
+                               player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_READY, FALSE, timeout);
+
+       if ( ret != MM_ERROR_NONE )
+       {
+               /* return error if failed to set state */
+               debug_error("failed to set state PAUSED (live : READY).\n");
+
+               /* dump state of all element */
+               __mmplayer_dump_pipeline_state( player );
+
+               return ret;
+       }
+       else 
+       {
+               MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_READY );
+       }
+
+       /* create dot before error-return. for debugging */
+       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-realize" );
+
+       debug_fleave();
+
+       return ret;
+}
+
+static int __gst_unrealize(mm_player_t* player) // @
+{
+       int ret = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_NULL;
+       MMPLAYER_PRINT_STATE(player);   
+
+       /* release miscellaneous information */
+       __mmplayer_release_misc( player );
+
+       /* destroy pipeline */
+       ret = __mmplayer_gst_destroy_pipeline( player );
+       if ( ret != MM_ERROR_NONE )
+       {
+               debug_error("failed to destory pipeline\n");
+               return ret;
+       }
+
+       MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_NULL );
+
+       debug_fleave();
+
+       return ret;
+}
+
+static int __gst_pending_seek ( mm_player_t* player )
+{
+       MMPlayerStateType current_state = MM_PLAYER_STATE_NONE;
+       MMPlayerStateType pending_state = MM_PLAYER_STATE_NONE;
+       int ret = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       if ( !player->pending_seek.is_pending )
+       {
+               debug_log("pending seek is not reserved. nothing to do.\n" );
+               return ret;
+       }
+
+       /* check player state if player could pending seek or not. */
+       current_state = MMPLAYER_CURRENT_STATE(player);
+       pending_state = MMPLAYER_PENDING_STATE(player);
+
+       if ( current_state != MM_PLAYER_STATE_PAUSED && current_state != MM_PLAYER_STATE_PLAYING  )
+       {
+               debug_warning("try to pending seek in %s state, try next time. \n",
+                       MMPLAYER_STATE_GET_NAME(current_state));
+               return ret;
+       }
+       
+       debug_log("trying to play from (%lu) pending position\n", player->pending_seek.pos);
+       
+       ret = __gst_set_position ( player, player->pending_seek.format, player->pending_seek.pos, FALSE );
+       
+       if ( MM_ERROR_NONE != ret )
+               debug_error("failed to seek pending postion. just keep staying current position.\n");
+
+       player->pending_seek.is_pending = FALSE;
+
+       debug_fleave();
+
+       return ret;
+}
+
+static int __gst_start(mm_player_t* player) // @
+{
+       gboolean sound_extraction = 0;
+       int ret = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       /* get sound_extraction property */
+       mm_attrs_get_int_by_name(player->attrs, "pcm_extraction", &sound_extraction);
+
+       /* NOTE : if SetPosition was called before Start. do it now */
+       /* streaming doesn't support it. so it should be always sync */
+       /* !! create one more api to check if there is pending seek rather than checking variables */
+       if ( (player->pending_seek.is_pending || sound_extraction) && !MMPLAYER_IS_STREAMING(player))
+       {
+               MMPLAYER_TARGET_STATE(player) = MM_PLAYER_STATE_PAUSED;
+               ret = __gst_pause(player, FALSE);
+               if ( ret != MM_ERROR_NONE )
+               {
+                       debug_error("failed to set state to PAUSED for pending seek\n");
+                       return ret;
+               }
+
+               MMPLAYER_TARGET_STATE(player) = MM_PLAYER_STATE_PLAYING;
+
+               if ( sound_extraction )
+               {
+                       debug_log("setting pcm extraction\n");
+
+                       ret = __mmplayer_set_pcm_extraction(player);
+                       if ( MM_ERROR_NONE != ret )
+                       {
+                               debug_warning("failed to set pcm extraction\n");
+                               return ret;
+                       }
+               }
+               else
+               {                       
+                       if ( MM_ERROR_NONE != __gst_pending_seek(player) )
+                       {
+                               debug_warning("failed to seek pending postion. starting from the begin of content.\n");
+                       }
+               }
+       }
+
+       debug_log("current state before doing transition");
+       MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_PLAYING;
+       MMPLAYER_PRINT_STATE(player);
+
+       /* set pipeline state to PLAYING  */
+       ret = __mmplayer_gst_set_state(player,
+               player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_PLAYING, FALSE, MMPLAYER_STATE_CHANGE_TIMEOUT(player) );
+       if (ret == MM_ERROR_NONE)
+       {
+               MMPLAYER_SET_STATE(player, MM_PLAYER_STATE_PLAYING);
+       }
+       else
+       {
+               debug_error("failed to set state to PLAYING");
+
+               /* dump state of all element */
+               __mmplayer_dump_pipeline_state( player );
+
+               return ret;
+       }
+
+       /* FIXIT : analyze so called "async problem" */
+       /* set async off */
+       __gst_set_async_state_change( player, FALSE );
+
+       /* generating debug info before returning error */
+       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-start" );
+
+       debug_fleave();
+
+       return ret;
+}
+
+static void __mmplayer_do_sound_fadedown(mm_player_t* player, unsigned int time)
+{
+       debug_fenter();
+       
+       return_if_fail(player 
+               && player->pipeline
+               && player->pipeline->audiobin
+               && player->pipeline->audiobin[MMPLAYER_A_SINK].gst);
+
+       g_object_set(G_OBJECT(player->pipeline->audiobin[MMPLAYER_A_SINK].gst), "mute", 2, NULL);
+       
+       usleep(time);
+
+       debug_fleave();
+}
+
+static void __mmplayer_undo_sound_fadedown(mm_player_t* player)
+{
+       debug_fenter();
+       
+       return_if_fail(player 
+               && player->pipeline
+               && player->pipeline->audiobin
+               && player->pipeline->audiobin[MMPLAYER_A_SINK].gst);
+       
+       g_object_set(G_OBJECT(player->pipeline->audiobin[MMPLAYER_A_SINK].gst), "mute", 0, NULL);       
+
+       debug_fleave();
+}
+
+static int __gst_stop(mm_player_t* player) // @
+{
+       GstStateChangeReturn change_ret = GST_STATE_CHANGE_SUCCESS;
+       MMHandleType attrs = 0;
+       gboolean fadewown = FALSE;
+       gboolean rewind = FALSE;
+       gint timeout = 0;
+       int ret = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       debug_log("current state before doing transition");
+       MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_READY;
+       MMPLAYER_PRINT_STATE(player);   
+
+       attrs = MMPLAYER_GET_ATTRS(player);
+       if ( !attrs )
+       {
+               debug_error("cannot get content attribute\n");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       mm_attrs_get_int_by_name(attrs,"sound_fadedown", &fadewown);
+
+       /* enable fadedown */
+       if (fadewown)
+               __mmplayer_do_sound_fadedown(player, MM_PLAYER_FADEOUT_TIME_DEFAULT);
+
+       /* Just set state to PAUESED and the rewind. it's usual player behavior. */
+       timeout = MMPLAYER_STATE_CHANGE_TIMEOUT ( player );
+       if  ( player->profile.uri_type == MM_PLAYER_URI_TYPE_BUFF || player->profile.uri_type == MM_PLAYER_URI_TYPE_HLS)
+       {
+               ret = __mmplayer_gst_set_state(player, 
+                       player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_READY, FALSE, timeout );
+       }
+       else
+       {
+               ret = __mmplayer_gst_set_state( player,
+                       player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_PAUSED, FALSE, timeout );
+
+               if ( !MMPLAYER_IS_STREAMING(player))
+                       rewind = TRUE;
+       }
+
+       /* disable fadeout */
+       if (fadewown)
+               __mmplayer_undo_sound_fadedown(player);
+
+
+       /* return if set_state has failed */
+       if ( ret != MM_ERROR_NONE )
+       {
+               debug_error("failed to set state.\n");
+
+               /* dump state of all element. don't care it success or not */
+               __mmplayer_dump_pipeline_state( player );
+
+               return ret;
+       }
+
+       /* rewind */
+       if ( rewind )
+       {
+               if ( ! __gst_seek( player, player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, 1.0,
+                               GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, 0,
+                               GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE) )
+               {
+                       debug_warning("failed to rewind\n");
+                       ret = MM_ERROR_PLAYER_SEEK;
+               }
+       }
+
+       /* initialize */
+       player->sent_bos = FALSE;
+
+       /* wait for seek to complete */
+       change_ret = gst_element_get_state (player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, NULL, NULL, timeout * GST_SECOND);
+       if ( change_ret == GST_STATE_CHANGE_SUCCESS || change_ret == GST_STATE_CHANGE_NO_PREROLL )
+       {
+               MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_READY );
+       }
+       else
+       {
+               debug_error("fail to stop player.\n");
+               ret = MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       /* generate dot file if enabled */
+       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-stop" );
+
+       debug_fleave(); 
+
+       return ret;
+}
+
+int __gst_pause(mm_player_t* player, gboolean async) // @
+{
+       int ret = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       return_val_if_fail(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       debug_log("current state before doing transition");
+       MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_PAUSED;
+       MMPLAYER_PRINT_STATE(player);   
+
+       /* set pipeline status to PAUSED */
+       ret = __mmplayer_gst_set_state(player,
+               player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_PAUSED, async, MMPLAYER_STATE_CHANGE_TIMEOUT(player));
+
+       if ( ret != MM_ERROR_NONE )
+       {
+               debug_error("failed to set state to PAUSED\n");
+
+               /* dump state of all element */
+               __mmplayer_dump_pipeline_state( player );
+
+               return ret;
+       }
+       else
+       {       
+               if ( async == FALSE ) 
+               {
+                       MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_PAUSED );
+               }
+       } 
+
+       /* FIXIT : analyze so called "async problem" */
+       /* set async off */
+       __gst_set_async_state_change( player, TRUE);
+
+       /* generate dot file before returning error */
+       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-pause" );
+
+       debug_fleave();
+
+       return ret;
+}
+
+int __gst_resume(mm_player_t* player, gboolean async) // @
+{
+       int ret = MM_ERROR_NONE;
+       gint timeout = 0;
+
+       debug_fenter();
+
+       return_val_if_fail(player && player->pipeline,
+               MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       debug_log("current state before doing transition");
+       MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_PLAYING;
+       MMPLAYER_PRINT_STATE(player);   
+
+       /* generate dot file before returning error */
+       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-resume" );
+
+       __mmplayer_set_antishock( player , FALSE );
+
+       if ( async )
+               debug_log("do async state transition to PLAYING.\n");
+
+       /* set pipeline state to PLAYING */
+       timeout = MMPLAYER_STATE_CHANGE_TIMEOUT(player);
+       ret = __mmplayer_gst_set_state(player,
+               player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_PLAYING, async, timeout );
+       if (ret != MM_ERROR_NONE)
+       {
+               debug_error("failed to set state to PLAYING\n");
+
+               /* dump state of all element */
+               __mmplayer_dump_pipeline_state( player );
+
+               return ret;
+       }
+       else
+       {
+               if (async == FALSE)
+               {
+                       MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_PLAYING );
+               }
+       }
+       
+       /* FIXIT : analyze so called "async problem" */
+       /* set async off */
+       __gst_set_async_state_change( player, FALSE );
+
+       /* generate dot file before returning error */
+       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-resume" );
+
+       debug_fleave();
+
+       return ret;
+}
+
+static int
+__gst_set_position(mm_player_t* player, int format, unsigned long position, gboolean internal_called) // @
+{
+       GstFormat fmt  = GST_FORMAT_TIME;
+       unsigned long dur_msec = 0;
+       gint64 dur_nsec = 0;
+       gint64 pos_nsec = 0;
+       gboolean ret = TRUE;
+
+       debug_fenter();
+       return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail ( !MMPLAYER_IS_LIVE_STREAMING(player), MM_ERROR_PLAYER_NO_OP );
+
+       if ( MMPLAYER_CURRENT_STATE(player) != MM_PLAYER_STATE_PLAYING
+               && MMPLAYER_CURRENT_STATE(player) != MM_PLAYER_STATE_PAUSED )
+               goto PENDING;
+
+       /* check duration */
+       /* NOTE : duration cannot be zero except live streaming.
+        *              Since some element could have some timing problemn with quering duration, try again.
+        */
+       if ( !player->duration )
+       {
+               if ( !gst_element_query_duration( player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, &fmt, &dur_nsec ))
+               {
+                       goto SEEK_ERROR;
+               }
+               player->duration = dur_nsec;
+       }
+
+       if ( player->duration )
+       {
+               dur_msec = GST_TIME_AS_MSECONDS(player->duration);
+       }
+       else
+       {
+               debug_error("could not get the duration. fail to seek.\n");
+               goto SEEK_ERROR;
+       }
+
+       debug_log("playback rate: %f\n", player->playback_rate);
+
+       /* do seek */
+       switch ( format )
+       {
+               case MM_PLAYER_POS_FORMAT_TIME:
+               {
+                       /* check position is valid or not */
+                       if ( position > dur_msec )
+                               goto INVALID_ARGS;
+
+                       debug_log("seeking to (%lu) msec, duration is %d msec\n", position, dur_msec);
+
+                       if (player->doing_seek)
+                       {
+                               debug_log("not completed seek");
+                               return MM_ERROR_PLAYER_DOING_SEEK;
+                       }
+
+                       if ( !internal_called)
+                               player->doing_seek = TRUE;
+
+                       pos_nsec = position * G_GINT64_CONSTANT(1000000);
+                       ret = __gst_seek ( player, player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, 1.0,
+                                                       GST_FORMAT_TIME, ( GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE ),
+                                                       GST_SEEK_TYPE_SET, pos_nsec, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE );
+                       if ( !ret  )
+                       {
+                               debug_error("failed to set position. dur[%lu]  pos[%lu]  pos_msec[%llu]\n", dur_msec, position, pos_nsec);
+                               goto SEEK_ERROR;
+                       }
+               }
+               break;
+
+               case MM_PLAYER_POS_FORMAT_PERCENT:
+               {
+                       debug_log("seeking to (%lu)%% \n", position);
+
+                       if (player->doing_seek)
+                       {
+                               debug_log("not completed seek");
+                               return MM_ERROR_PLAYER_DOING_SEEK;
+                       }
+
+                       if ( !internal_called)
+                               player->doing_seek = TRUE;
+
+                       /* FIXIT : why don't we use 'GST_FORMAT_PERCENT' */
+                       pos_nsec = (gint64) ( ( position * player->duration ) / 100 );
+                       ret = __gst_seek ( player, player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, 1.0,
+                                                       GST_FORMAT_TIME, ( GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE ),
+                                                       GST_SEEK_TYPE_SET, pos_nsec, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE );
+                       if ( !ret  )
+                       {
+                               debug_error("failed to set position. dur[%lud]  pos[%lud]  pos_msec[%llud]\n", dur_msec, position, pos_nsec);
+                               goto SEEK_ERROR;
+                       }
+               }
+               break;
+
+               default:
+                       goto INVALID_ARGS;
+                       
+       }
+
+       /* NOTE : store last seeking point to overcome some bad operation 
+         *      ( returning zero when getting current position ) of some elements 
+         */
+       player->last_position = pos_nsec;
+
+       /* MSL should guarante playback rate when seek is selected during trick play of fast forward. */
+       if ( player->playback_rate > 1.0 )
+               _mmplayer_set_playspeed ( (MMHandleType)player, player->playback_rate );
+
+       debug_fleave();
+       return MM_ERROR_NONE;
+
+PENDING:
+       player->pending_seek.is_pending = TRUE;
+       player->pending_seek.format = format;
+       player->pending_seek.pos = position;
+       
+       debug_warning("player current-state : %s, pending-state : %s, just preserve pending position(%lu).\n", 
+               MMPLAYER_STATE_GET_NAME(MMPLAYER_CURRENT_STATE(player)), MMPLAYER_STATE_GET_NAME(MMPLAYER_PENDING_STATE(player)), player->pending_seek.pos);
+       
+       return MM_ERROR_NONE;
+       
+INVALID_ARGS:  
+       debug_error("invalid arguments, position : %ld  dur : %ld format : %d \n", position, dur_msec, format);
+       return MM_ERROR_INVALID_ARGUMENT;
+
+SEEK_ERROR:
+       player->doing_seek = FALSE;
+       return MM_ERROR_PLAYER_SEEK;
+}
+
+#define TRICKPLAY_OFFSET GST_MSECOND
+
+static int
+__gst_get_position(mm_player_t* player, int format, unsigned long* position) // @
+{
+       MMPlayerStateType current_state = MM_PLAYER_STATE_NONE;
+       GstFormat fmt = GST_FORMAT_TIME;
+       signed long long pos_msec = 0;
+       gboolean ret = TRUE;
+
+       return_val_if_fail( player && position && player->pipeline && player->pipeline->mainbin,
+               MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       current_state = MMPLAYER_CURRENT_STATE(player);
+
+       /* NOTE : query position except paused state to overcome some bad operation
+        * please refer to below comments in details
+        */
+       if ( current_state != MM_PLAYER_STATE_PAUSED )
+       {
+               ret = gst_element_query_position(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, &fmt, &pos_msec);
+       }
+
+       /* NOTE : get last point to overcome some bad operation of some elements
+        * ( returning zero when getting current position in paused state
+        * and when failed to get postion during seeking
+        */
+       if ( ( current_state == MM_PLAYER_STATE_PAUSED )
+               || ( ! ret ))
+               //|| ( player->last_position != 0 && pos_msec == 0 ) )
+       {
+               debug_warning ("pos_msec = %"GST_TIME_FORMAT" and ret = %d and state = %d", GST_TIME_ARGS (pos_msec), ret, current_state);
+
+               if(player->playback_rate < 0.0)
+                       pos_msec = player->last_position - TRICKPLAY_OFFSET;
+               else
+                       pos_msec = player->last_position;
+
+               if (!ret)
+                       pos_msec = player->last_position;
+               else
+                       player->last_position = pos_msec;
+
+               debug_warning("returning last point : %"GST_TIME_FORMAT, GST_TIME_ARGS(pos_msec));
+
+       }
+       else
+       {
+               player->last_position = pos_msec;
+       }
+
+       switch (format) {
+               case MM_PLAYER_POS_FORMAT_TIME:
+                       *position = GST_TIME_AS_MSECONDS(pos_msec);
+                       break;
+
+               case MM_PLAYER_POS_FORMAT_PERCENT:
+               {
+                       int dur = 0;
+                       int pos = 0;
+
+                       dur = player->duration / GST_SECOND;
+                       if (dur <= 0)
+                       {
+                               debug_log ("duration is [%d], so returning position 0\n",dur);
+                               *position = 0;
+                       }
+                       else
+                       {
+                               pos = pos_msec / GST_SECOND;
+                               *position = pos * 100 / dur;
+                       }
+                       break;
+               }
+               default:
+                       return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       debug_log("current position : %lu\n", *position);
+
+       
+       return MM_ERROR_NONE;
+}
+
+
+static int     __gst_get_buffer_position(mm_player_t* player, int format, unsigned long* start_pos, unsigned long* stop_pos)
+{
+       GstElement *element = NULL;
+       GstQuery *query = NULL;
+
+       return_val_if_fail( player && 
+               player->pipeline && 
+               player->pipeline->mainbin,
+               MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       return_val_if_fail( start_pos && stop_pos, MM_ERROR_INVALID_ARGUMENT );
+
+       if ( MMPLAYER_IS_HTTP_STREAMING ( player ))
+       {
+               /* Note : In case of http streaming or HLS, the buffering queue [ queue2 ] could handle buffering query. */
+               element = GST_ELEMENT ( player->pipeline->mainbin[MMPLAYER_M_S_BUFFER].gst );
+       }
+       else if ( MMPLAYER_IS_RTSP_STREAMING ( player ) )
+       {
+               debug_warning ( "it's not supported yet.\n" );
+               return MM_ERROR_NONE;
+       }
+       else
+       {
+               debug_warning ( "it's only used for streaming case.\n" );
+               return MM_ERROR_NONE;   
+       }
+
+       *start_pos = 0;
+       *stop_pos = 0;
+       
+       switch ( format )
+       {
+               case MM_PLAYER_POS_FORMAT_PERCENT :
+               {
+                               query = gst_query_new_buffering ( GST_FORMAT_PERCENT );
+                               if ( gst_element_query ( element, query ) ) 
+                               {
+                                       gint64 start, stop;
+                                       GstFormat format;
+                                       gboolean busy;
+                                       gint percent;
+
+                                       gst_query_parse_buffering_percent ( query, &busy, &percent);
+                                       gst_query_parse_buffering_range ( query, &format, &start, &stop, NULL );
+
+                                       debug_log ( "buffering start %" G_GINT64_FORMAT ", stop %" G_GINT64_FORMAT "\n",  start, stop);
+
+                                       if ( start != -1)
+                                               *start_pos = 100 * start / GST_FORMAT_PERCENT_MAX;
+                                       else
+                                               *start_pos = 0;
+
+                                       if ( stop != -1)
+                                               *stop_pos = 100 * stop / GST_FORMAT_PERCENT_MAX;
+                                       else
+                                               *stop_pos = 0;
+                               }
+                               gst_query_unref (query);
+               }
+               break;
+
+               case MM_PLAYER_POS_FORMAT_TIME :
+                       debug_warning ( "Time format is not supported yet.\n" );
+                       break;
+                       
+               default :
+                       break;
+       }
+
+       debug_log("current buffer position : %lu~%lu \n", *start_pos, *stop_pos );
+
+       return MM_ERROR_NONE;
+}
+
+static int
+__gst_set_message_callback(mm_player_t* player, MMMessageCallback callback, gpointer user_param) // @
+{
+       debug_fenter();
+
+       if ( !player )
+       {
+               debug_warning("set_message_callback is called with invalid player handle\n");
+               return MM_ERROR_PLAYER_NOT_INITIALIZED;
+       }
+
+       player->msg_cb = callback;
+       player->msg_cb_param = user_param;
+
+       debug_log("msg_cb : 0x%x     msg_cb_param : 0x%x\n", (guint)callback, (guint)user_param);
+
+       debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+static gboolean __mmfplayer_parse_profile(const char *uri, void *param, MMPlayerParseProfile* data) // @
+{
+       gboolean ret = FALSE;
+       char *path = NULL;
+
+       debug_fenter();
+
+       return_val_if_fail ( uri , FALSE);
+       return_val_if_fail ( data , FALSE);
+       return_val_if_fail ( ( strlen(uri) <= MM_MAX_URL_LEN ), FALSE );
+
+       memset(data, 0, sizeof(MMPlayerParseProfile));
+
+       if ((path = strstr(uri, "file://")))
+       {
+               if (util_exist_file_path(path + 7)) {
+                       strncpy(data->uri, path, MM_MAX_URL_LEN-1);                     
+
+                       if ( util_is_sdp_file ( path ) )
+                       {
+                               debug_log("uri is actually a file but it's sdp file. giving it to rtspsrc\n");
+                               data->uri_type = MM_PLAYER_URI_TYPE_URL_RTSP;
+                       }
+                       else
+                       {
+                       data->uri_type = MM_PLAYER_URI_TYPE_FILE;
+                       }
+                       ret = TRUE;
+               }
+               else
+               {
+                       debug_warning("could  access %s.\n", path);
+               }
+       }
+       else if ((path = strstr(uri, "buff://")))
+       {
+                       data->uri_type = MM_PLAYER_URI_TYPE_BUFF;
+                       ret = TRUE;
+       }
+       else if ((path = strstr(uri, "rtsp://")))
+       {
+               if (strlen(path)) {
+                       strcpy(data->uri, uri);
+                       data->uri_type = MM_PLAYER_URI_TYPE_URL_RTSP;
+                       ret = TRUE;
+               }
+       }
+       else if ((path = strstr(uri, "http://")))
+       {
+               if (strlen(path)) {
+                       strcpy(data->uri, uri);
+                               data->uri_type = MM_PLAYER_URI_TYPE_URL_HTTP;
+
+                       ret = TRUE;
+               }
+       }
+       else if ((path = strstr(uri, "https://")))
+       {
+               if (strlen(path)) {
+                       strcpy(data->uri, uri);
+                               data->uri_type = MM_PLAYER_URI_TYPE_URL_HTTP;
+                       
+                       ret = TRUE;
+               }
+       }
+       else if ((path = strstr(uri, "rtspu://")))
+       {
+               if (strlen(path)) {
+                       strcpy(data->uri, uri);
+                       data->uri_type = MM_PLAYER_URI_TYPE_URL_RTSP;
+                       ret = TRUE;
+               }
+       }
+       else if ((path = strstr(uri, "rtspr://")))
+       {
+               strcpy(data->uri, path);
+               char *separater =strstr(path, "*");
+
+               if (separater) {
+                       int urgent_len = 0;
+                       char *urgent = separater + strlen("*");
+
+                       if ((urgent_len = strlen(urgent))) {
+                               data->uri[strlen(path) - urgent_len - strlen("*")] = '\0';
+                               strcpy(data->urgent, urgent);
+                               data->uri_type = MM_PLAYER_URI_TYPE_URL_RTSP;
+                               ret = TRUE;
+                       }
+               }
+       }
+       else if ((path = strstr(uri, "mms://")))
+       {
+               if (strlen(path)) {
+                       strcpy(data->uri, uri);
+                       data->uri_type = MM_PLAYER_URI_TYPE_URL_MMS;
+                       ret = TRUE;
+               }
+       }
+       else if ((path = strstr(uri, "mem://")))
+       {
+               if (strlen(path)) {
+                       int mem_size = 0;
+                       char *buffer = NULL;
+                       char *seperator = strchr(path, ',');
+                       char ext[100] = {0,}, size[100] = {0,};
+
+                       if (seperator) {
+                               if ((buffer = strstr(path, "ext="))) {
+                                       buffer += strlen("ext=");
+
+                                       if (strlen(buffer)) {
+                                               strcpy(ext, buffer);
+
+                                               if ((seperator = strchr(ext, ','))
+                                                       || (seperator = strchr(ext, ' '))
+                                                       || (seperator = strchr(ext, '\0'))) {
+                                                       seperator[0] = '\0';
+                                               }
+                                       }
+                               }
+
+                               if ((buffer = strstr(path, "size="))) {
+                                       buffer += strlen("size=");
+
+                                       if (strlen(buffer) > 0) {
+                                               strcpy(size, buffer);
+
+                                               if ((seperator = strchr(size, ','))
+                                                       || (seperator = strchr(size, ' '))
+                                                       || (seperator = strchr(size, '\0'))) {
+                                                       seperator[0] = '\0';
+                                               }
+
+                                               mem_size = atoi(size);
+                                       }
+                               }
+                       }
+
+                       debug_log("ext: %s, mem_size: %d, mmap(param): %p\n", ext, mem_size, param);
+                       if ( mem_size && param) {
+                                       data->mem = param;
+                                       data->mem_size = mem_size;
+                               data->uri_type = MM_PLAYER_URI_TYPE_MEM;
+                               ret = TRUE;
+                       }
+               }
+       }
+       else
+       {
+               /* if no protocol prefix exist. check file existence and then give file:// as it's prefix */
+               if (util_exist_file_path(uri))
+               {
+                       debug_warning("uri has no protocol-prefix. giving 'file://' by default.\n");
+                       g_snprintf(data->uri,  MM_MAX_URL_LEN, "file://%s", uri);
+
+                       if ( util_is_sdp_file( (char*)uri ) )
+                       {
+                               debug_log("uri is actually a file but it's sdp file. giving it to rtspsrc\n");
+                               data->uri_type = MM_PLAYER_URI_TYPE_URL_RTSP;
+                       }
+                       else
+                       {
+                               data->uri_type = MM_PLAYER_URI_TYPE_FILE;
+                       }
+                       ret = TRUE;
+               }
+               else
+               {
+                       debug_error ("invalid uri, could not play..\n");
+                       data->uri_type = MM_PLAYER_URI_TYPE_NONE;
+               }
+       }
+       
+       if (data->uri_type == MM_PLAYER_URI_TYPE_NONE) {
+               ret = FALSE;
+       }
+
+       /* dump parse result */
+       debug_log("profile parsing result ---\n");
+       debug_warning("incomming uri : %s\n", uri);
+       debug_log("uri : %s\n", data->uri);
+       debug_log("uri_type : %d\n", data->uri_type);
+       debug_log("play_mode : %d\n", data->play_mode);
+       debug_log("mem : 0x%x\n", (guint)data->mem);
+       debug_log("mem_size : %d\n", data->mem_size);
+       debug_log("urgent : %s\n", data->urgent);
+       debug_log("--------------------------\n");
+
+       debug_fleave();
+
+       return ret;
+}
+
+gboolean _asm_postmsg(gpointer *data)
+{
+       mm_player_t* player = (mm_player_t*)data;
+       MMMessageParamType msg = {0, };
+
+       debug_fenter();
+
+       return_val_if_fail ( player, FALSE );
+
+       msg.union_type = MM_MSG_UNION_CODE;
+       msg.code = player->sm.event_src;
+       
+       MMPLAYER_POST_MSG( player, MM_MESSAGE_READY_TO_RESUME, &msg);
+       
+       return FALSE;
+}
+gboolean _asm_lazy_pause(gpointer *data)
+{
+       mm_player_t* player = (mm_player_t*)data;
+       int ret = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       return_val_if_fail ( player, FALSE );
+
+       if (MMPLAYER_CURRENT_STATE(player) == MM_PLAYER_STATE_PLAYING)
+       {
+               debug_log ("Ready to proceed lazy pause\n");
+               ret = _mmplayer_pause((MMHandleType)player);
+               if(MM_ERROR_NONE != ret)
+               {
+                       debug_error("MMPlayer pause failed in ASM callback lazy pause\n");
+               }       
+       }
+       else
+       {
+               debug_log ("Invalid state to proceed lazy pause\n");
+       }
+
+       /* unset mute */
+       if (player->pipeline && player->pipeline->audiobin)
+               g_object_set(G_OBJECT(player->pipeline->audiobin[MMPLAYER_A_SINK].gst), "mute", 0, NULL);
+
+       player->sm.by_asm_cb = 0; //should be reset here
+
+       debug_fleave();
+
+       return FALSE;
+}
+ASM_cb_result_t
+__mmplayer_asm_callback(int handle, ASM_event_sources_t event_src, ASM_sound_commands_t command, unsigned int sound_status, void* cb_data)
+{
+       mm_player_t* player = (mm_player_t*) cb_data;
+       ASM_cb_result_t cb_res = ASM_CB_RES_IGNORE;
+       int result = MM_ERROR_NONE;
+       gboolean lazy_pause = FALSE;
+
+       debug_fenter();
+
+       return_val_if_fail ( player && player->pipeline, ASM_CB_RES_IGNORE );
+       return_val_if_fail ( player->attrs, MM_ERROR_PLAYER_INTERNAL );
+
+       if (player->is_sound_extraction)
+       {
+               debug_log("sound extraction is working...so, asm command is ignored.\n");
+               return result;
+       }
+       
+       player->sm.by_asm_cb = 1; // it should be enabled for player state transition with called application command
+       player->sm.event_src = event_src;
+
+       if(event_src == ASM_EVENT_SOURCE_EARJACK_UNPLUG )
+       {
+               int stop_by_asm = 0;
+
+               mm_attrs_get_int_by_name(player->attrs, "sound_stop_when_unplugged", &stop_by_asm);
+               if (!stop_by_asm)
+                       return cb_res;
+       }
+       else if (event_src == ASM_EVENT_SOURCE_RESOURCE_CONFLICT)
+       {
+               /* can use video overlay simultaneously */
+               /* video resource conflict */
+               if(player->pipeline->videobin) 
+               {
+                       if (PLAYER_INI()->multiple_codec_supported)
+                       {
+                               debug_log("video conflict but, can support to use video overlay simultaneously");
+                               result = _mmplayer_pause((MMHandleType)player);
+                               cb_res = ASM_CB_RES_PAUSE;
+                       }
+                       else
+                       {
+                               debug_log("video conflict, can't support for multiple codec instance");
+                               result = _mmplayer_unrealize((MMHandleType)player);
+                               cb_res = ASM_CB_RES_STOP;
+                       }
+               }
+               return cb_res;
+       }
+
+       switch(command)
+       {
+               case ASM_COMMAND_PLAY:
+                       debug_warning ("Got unexpected asm command (%d)", command);
+               break;
+
+               case ASM_COMMAND_STOP: // notification case
+               {
+                       debug_log("Got msg from asm to stop");
+
+                       result = _mmplayer_stop((MMHandleType)player);
+                       if (result != MM_ERROR_NONE)
+                       {
+                               debug_warning("fail to set stop state by asm");
+                               cb_res = ASM_CB_RES_IGNORE;
+                       }
+                       else
+                       {
+                               cb_res = ASM_CB_RES_STOP;
+                       }
+                       player->sm.by_asm_cb = 0; // reset because no message any more from asm
+               }
+               break;
+                       
+               case ASM_COMMAND_PAUSE:
+               {
+                       debug_log("Got msg from asm to Pause");
+                       
+                       if(event_src == ASM_EVENT_SOURCE_CALL_START
+                               || event_src == ASM_EVENT_SOURCE_ALARM_START
+                               || event_src == ASM_EVENT_SOURCE_MEDIA)
+                       {
+                               //hold 0.7 second to excute "fadedown mute" effect
+                               debug_log ("do fade down->pause->undo fade down");
+                                       
+                               __mmplayer_do_sound_fadedown(player, MM_PLAYER_FADEOUT_TIME_DEFAULT);
+                                       
+                               result = _mmplayer_pause((MMHandleType)player);
+                               if (result != MM_ERROR_NONE)
+                               {
+                                       debug_warning("fail to set Pause state by asm");
+                                       cb_res = ASM_CB_RES_IGNORE;
+                                       break;
+                               }
+                               __mmplayer_undo_sound_fadedown(player);
+                       }
+                       else if(event_src == ASM_EVENT_SOURCE_OTHER_PLAYER_APP)
+                       {
+                               lazy_pause = TRUE; // return as soon as possible, for fast start of other app
+
+                               if ( player->pipeline->audiobin && player->pipeline->audiobin[MMPLAYER_A_SINK].gst )
+                                       g_object_set( player->pipeline->audiobin[MMPLAYER_A_SINK].gst, "mute", 2, NULL);
+
+                               player->lazy_pause_event_id = g_timeout_add(LAZY_PAUSE_TIMEOUT_MSEC, (GSourceFunc)_asm_lazy_pause, (gpointer)player);
+                               debug_log ("set lazy pause timer (id=[%d], timeout=[%d ms])", player->lazy_pause_event_id, LAZY_PAUSE_TIMEOUT_MSEC);
+                       }
+                       else
+                       {
+                               //immediate pause
+                               debug_log ("immediate pause");
+                               result = _mmplayer_pause((MMHandleType)player);
+                       }
+                       cb_res = ASM_CB_RES_PAUSE;
+               }
+               break;
+                       
+               case ASM_COMMAND_RESUME:
+               {
+                       debug_log("Got msg from asm to Resume. So, application can resume. code (%d) \n", event_src);
+                       player->sm.by_asm_cb = 0;
+                       //ASM server is single thread daemon. So use g_idle_add() to post resume msg
+                       g_idle_add((GSourceFunc)_asm_postmsg, (gpointer)player);
+                       cb_res = ASM_CB_RES_IGNORE;
+               }
+               break;
+
+               default:
+               break;
+       }
+
+       if (!lazy_pause)
+               player->sm.by_asm_cb = 0;
+
+       debug_fleave();
+
+       return cb_res;
+}
+
+int
+_mmplayer_create_player(MMHandleType handle) // @
+{
+       mm_player_t* player = MM_PLAYER_CAST(handle);
+       gint i;
+
+       debug_fenter();
+
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       MMTA_ACUM_ITEM_BEGIN("[KPI] media player service create->playing", FALSE);
+
+       /* initialize player state */
+       MMPLAYER_CURRENT_STATE(player) = MM_PLAYER_STATE_NONE;
+       MMPLAYER_PREV_STATE(player) = MM_PLAYER_STATE_NONE;
+       MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_NONE;
+       MMPLAYER_TARGET_STATE(player) = MM_PLAYER_STATE_NONE;
+
+       /* check current state */
+       MMPLAYER_CHECK_STATE_RETURN_IF_FAIL ( player, MMPLAYER_COMMAND_CREATE );
+
+       /* construct attributes */
+       player->attrs = _mmplayer_construct_attribute(handle);
+
+       if ( !player->attrs )
+       {
+               debug_critical("Failed to construct attributes\n");
+               goto ERROR;
+       }
+
+       /* initialize gstreamer with configured parameter */
+       if ( ! __mmplayer_gstreamer_init() )
+       {
+               debug_critical("Initializing gstreamer failed\n");
+               goto ERROR;
+       }
+
+       /* initialize factories if not using decodebin */
+       if ( FALSE == PLAYER_INI()->use_decodebin )
+       {
+               if( player->factories == NULL )
+                   __mmplayer_init_factories(player);
+       }
+
+       /* create lock. note that g_tread_init() has already called in gst_init() */
+       player->fsink_lock = g_mutex_new();
+       if ( ! player->fsink_lock )
+       {
+               debug_critical("Cannot create mutex for command lock\n");
+               goto ERROR;
+       }
+
+       /* create repeat mutex */
+       player->repeat_thread_mutex = g_mutex_new();
+       if ( ! player->repeat_thread_mutex )
+       {
+               debug_critical("Cannot create repeat mutex\n");
+               goto ERROR;
+       }
+
+       /* create repeat cond */
+       player->repeat_thread_cond = g_cond_new();
+       if ( ! player->repeat_thread_cond )
+       {
+               debug_critical("Cannot create repeat cond\n");
+               goto ERROR;
+       }
+
+       /* create repeat thread */
+       player->repeat_thread =
+               g_thread_create (__mmplayer_repeat_thread, (gpointer)player, TRUE, NULL);
+       if ( ! player->repeat_thread )
+       {
+               goto ERROR;
+       }
+
+       if ( MM_ERROR_NONE != _mmplayer_initialize_video_capture(player))
+       {
+               debug_error("failed to initialize video capture\n");
+               goto ERROR;
+       }
+
+       /* register to asm */
+       if ( MM_ERROR_NONE != _mmplayer_asm_register(&player->sm, (ASM_sound_cb_t)__mmplayer_asm_callback, (void*)player) )
+       {
+               /* NOTE : we are dealing it as an error since we cannot expect it's behavior */
+               debug_error("failed to register asm server\n");
+               return MM_ERROR_POLICY_INTERNAL;
+       }
+
+       if (MMPLAYER_IS_HTTP_PD(player))
+       {
+               player->pd_downloader = NULL;
+               player->pd_file_save_path = NULL;
+       }
+
+       /* give default value of audio effect setting */
+       player->bypass_audio_effect = TRUE;
+       player->sound.volume = MM_VOLUME_FACTOR_DEFAULT;
+       player->playback_rate = DEFAULT_PLAYBACK_RATE;
+       player->no_more_pad = TRUE;
+
+       player->play_subtitle = FALSE;
+       player->use_textoverlay = FALSE;
+
+       /* set player state to null */
+       MMPLAYER_STATE_CHANGE_TIMEOUT(player) = PLAYER_INI()->localplayback_state_change_timeout;
+       MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_NULL );
+
+       debug_fleave();
+
+       return MM_ERROR_NONE;
+
+ERROR:
+       /* free lock */
+       if ( player->fsink_lock )
+               g_mutex_free( player->fsink_lock );
+       player->fsink_lock = NULL;
+
+       /* free thread */
+       if ( player->repeat_thread_cond &&
+                player->repeat_thread_mutex &&
+                player->repeat_thread )
+       {
+               player->repeat_thread_exit = TRUE;
+               g_cond_signal( player->repeat_thread_cond );
+
+               g_thread_join( player->repeat_thread );
+               player->repeat_thread = NULL;
+
+               g_mutex_free ( player->repeat_thread_mutex );
+               player->repeat_thread_mutex = NULL;
+
+               g_cond_free ( player->repeat_thread_cond );
+               player->repeat_thread_cond = NULL;
+       }
+       /* clear repeat thread mutex/cond if still alive
+        * this can happen if only thread creating has failed
+        */
+       if ( player->repeat_thread_mutex )
+               g_mutex_free ( player->repeat_thread_mutex );
+
+       if ( player->repeat_thread_cond )
+               g_cond_free ( player->repeat_thread_cond );
+
+       /* release attributes */
+       _mmplayer_deconstruct_attribute(handle);
+
+       return MM_ERROR_PLAYER_INTERNAL;
+}
+
+static gboolean
+__mmplayer_gstreamer_init(void) // @
+{
+       static gboolean initialized = FALSE;
+       static const int max_argc = 50;
+       gint* argc = NULL;
+       gchar** argv = NULL;
+       GError *err = NULL;
+       int i = 0;
+
+       debug_fenter();
+
+       if ( initialized )
+       {
+               debug_log("gstreamer already initialized.\n");
+               return TRUE;
+       }
+
+       /* alloc */
+       argc = malloc( sizeof(int) );
+       argv = malloc( sizeof(gchar*) * max_argc );
+
+       if ( !argc || !argv )
+               goto ERROR;
+
+       memset( argv, 0, sizeof(gchar*) * max_argc );
+
+       /* add initial */
+       *argc = 1;
+       argv[0] = g_strdup( "mmplayer" );
+
+       /* add gst_param */
+       for ( i = 0; i < 5; i++ ) /* FIXIT : num of param is now fixed to 5. make it dynamic */
+       {
+               if ( strlen( PLAYER_INI()->gst_param[i] ) > 0 )
+               {
+                       argv[*argc] = g_strdup( PLAYER_INI()->gst_param[i] );
+                       (*argc)++;
+               }
+       }
+
+       /* we would not do fork for scanning plugins */
+       argv[*argc] = g_strdup("--gst-disable-registry-fork");
+       (*argc)++;
+
+       /* check disable registry scan */
+       if ( PLAYER_INI()->skip_rescan )
+       {
+               argv[*argc] = g_strdup("--gst-disable-registry-update");
+               (*argc)++;
+       }
+
+       /* check disable segtrap */
+       if ( PLAYER_INI()->disable_segtrap )
+       {
+               argv[*argc] = g_strdup("--gst-disable-segtrap");
+               (*argc)++;
+       }
+
+       debug_log("initializing gstreamer with following parameter\n");
+       debug_log("argc : %d\n", *argc);
+
+       for ( i = 0; i < *argc; i++ )
+       {
+               debug_log("argv[%d] : %s\n", i, argv[i]);
+       }
+
+
+       /* initializing gstreamer */
+       __ta__("gst_init time",
+
+               if ( ! gst_init_check (argc, &argv, &err))
+               {
+                       debug_error("Could not initialize GStreamer: %s\n", err ? err->message : "unknown error occurred");
+                       if (err)
+                       {
+                               g_error_free (err);
+                       }
+
+                       goto ERROR;
+               }
+       );
+
+       /* release */
+       for ( i = 0; i < *argc; i++ )
+       {
+               MMPLAYER_FREEIF( argv[i] );
+       }
+
+       MMPLAYER_FREEIF( argv );
+       MMPLAYER_FREEIF( argc );
+
+       /* done */
+       initialized = TRUE;
+
+       debug_fleave();
+
+       return TRUE;
+
+ERROR:
+
+       MMPLAYER_FREEIF( argv );
+       MMPLAYER_FREEIF( argc );
+
+       return FALSE;
+}
+
+int
+__mmplayer_destroy_streaming_ext(mm_player_t* player)
+{
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       if (player->pd_downloader)
+               _mmplayer_unrealize_pd_downloader((MMHandleType)player);
+
+       if (MMPLAYER_IS_HTTP_PD(player))
+               _mmplayer_destroy_pd_downloader((MMHandleType)player);
+
+       if (MMPLAYER_IS_STREAMING(player))
+       {
+               if (player->streamer)
+               {
+                       __mm_player_streaming_deinitialize (player->streamer);
+                       __mm_player_streaming_destroy(player->streamer);
+                       player->streamer = NULL;
+               }
+       }
+       return MM_ERROR_NONE;
+}
+
+int
+_mmplayer_destroy(MMHandleType handle) // @
+{
+       mm_player_t* player = MM_PLAYER_CAST(handle);
+
+       debug_fenter();
+
+       /* check player handle */
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       /* destroy can called at anytime */
+       MMPLAYER_CHECK_STATE_RETURN_IF_FAIL ( player, MMPLAYER_COMMAND_DESTROY );
+
+       __mmplayer_destroy_streaming_ext(player);
+
+       /* release repeat thread */
+       if ( player->repeat_thread_cond &&
+                player->repeat_thread_mutex &&
+                player->repeat_thread )
+       {
+               player->repeat_thread_exit = TRUE;
+               g_cond_signal( player->repeat_thread_cond );
+
+               debug_log("waitting for repeat thread exit\n");
+               g_thread_join ( player->repeat_thread );
+               g_mutex_free ( player->repeat_thread_mutex );
+               g_cond_free ( player->repeat_thread_cond );
+               debug_log("repeat thread released\n");
+       }
+
+       if (MM_ERROR_NONE != _mmplayer_release_video_capture(player))
+       {
+               debug_error("failed to release video capture\n");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       /* withdraw asm */
+       if ( MM_ERROR_NONE != _mmplayer_asm_deregister(&player->sm) )
+       {
+               debug_error("failed to deregister asm server\n");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       /* release pipeline */
+       if ( MM_ERROR_NONE != __mmplayer_gst_destroy_pipeline( player ) )
+       {
+               debug_error("failed to destory pipeline\n");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       /* release attributes */
+       _mmplayer_deconstruct_attribute( handle );
+
+       /* release factories */
+       __mmplayer_release_factories( player );
+
+       /* release lock */
+       if ( player->fsink_lock )
+               g_mutex_free( player->fsink_lock );
+
+       if ( player->msg_cb_lock )
+               g_mutex_free( player->msg_cb_lock );
+
+       if (player->lazy_pause_event_id) 
+       {
+               g_source_remove (player->lazy_pause_event_id);
+               player->lazy_pause_event_id = 0;
+       }
+
+       debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+int 
+__mmplayer_realize_streaming_ext(mm_player_t* player)
+{
+       int ret = MM_ERROR_NONE;
+
+       debug_fenter();
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       if (MMPLAYER_IS_HTTP_PD(player))
+       {
+               gboolean bret = FALSE;
+
+               player->pd_downloader = _mmplayer_create_pd_downloader();
+               if ( !player->pd_downloader )
+               {
+                       debug_error ("Unable to create PD Downloader...");
+                       ret = MM_ERROR_PLAYER_NO_FREE_SPACE;
+               }
+
+               bret = _mmplayer_realize_pd_downloader((MMHandleType)player, player->profile.uri, player->pd_file_save_path, player->pipeline->mainbin[MMPLAYER_M_SRC].gst);
+               
+               if (FALSE == bret)
+               {
+                       debug_error ("Unable to create PD Downloader...");
+                       ret = MM_ERROR_PLAYER_NOT_INITIALIZED;
+               }
+       }
+
+       debug_fleave();
+       return ret;
+}
+
+int
+_mmplayer_realize(MMHandleType hplayer) // @
+{
+       mm_player_t* player =  (mm_player_t*)hplayer;
+       char *uri =NULL;
+       void *param = NULL;
+       int application_pid = -1;
+       gboolean update_registry = FALSE;
+       MMHandleType attrs = 0;
+       int ret = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       /* check player handle */
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED )
+
+       /* check current state */
+       MMPLAYER_CHECK_STATE_RETURN_IF_FAIL( player, MMPLAYER_COMMAND_REALIZE );
+
+       attrs = MMPLAYER_GET_ATTRS(player);
+       if ( !attrs )
+       {
+               debug_error("fail to get attributes.\n");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       mm_attrs_get_int_by_name(attrs, "sound_application_pid", &application_pid );
+       player->sm.pid = application_pid;
+
+       mm_attrs_get_string_by_name(attrs, "profile_uri", &uri);
+       mm_attrs_get_data_by_name(attrs, "profile_user_param", &param);
+
+       if (! __mmfplayer_parse_profile((const char*)uri, param, &player->profile) )
+       {
+               debug_error("failed to parse profile\n");
+               return MM_ERROR_PLAYER_INVALID_URI;
+       }
+
+       /* FIXIT : we can use thouse in player->profile directly */
+       if (player->profile.uri_type == MM_PLAYER_URI_TYPE_MEM)
+       {
+               player->mem_buf.buf = (char *)player->profile.mem;
+               player->mem_buf.len = player->profile.mem_size;
+               player->mem_buf.offset = 0;
+       }
+
+       if (player->profile.uri_type == MM_PLAYER_URI_TYPE_URL_MMS)
+       {
+               debug_warning("mms protocol is not supported format.\n");
+               return MM_ERROR_PLAYER_NOT_SUPPORTED_FORMAT;
+       }
+
+       if (MMPLAYER_IS_STREAMING(player))
+               MMPLAYER_STATE_CHANGE_TIMEOUT(player) = PLAYER_INI()->live_state_change_timeout;
+       else
+               MMPLAYER_STATE_CHANGE_TIMEOUT(player) = PLAYER_INI()->localplayback_state_change_timeout;
+
+       player->videodec_linked  = 0;
+       player->videosink_linked = 0;
+       player->audiodec_linked  = 0;
+       player->audiosink_linked = 0;
+       player->textsink_linked = 0;
+
+       /* set the subtitle ON default */
+       player->is_subtitle_off = FALSE;
+
+       /* we need to update content attrs only the content has changed */
+       player->need_update_content_attrs = TRUE;
+       player->need_update_content_dur = FALSE;
+
+       /* registry should be updated for downloadable codec */
+       mm_attrs_get_int_by_name(attrs, "profile_update_registry", &update_registry);
+
+       if ( update_registry )
+       {
+               debug_log("updating registry...\n");
+               gst_update_registry();
+
+               /* then we have to rebuild factories */
+               __mmplayer_release_factories( player );
+               __mmplayer_init_factories(player);
+       }
+
+       /* realize pipeline */
+       ret = __gst_realize( player );
+       if ( ret != MM_ERROR_NONE )
+       {
+               debug_error("fail to realize the player.\n");
+       }
+       else
+       {
+               __mmplayer_realize_streaming_ext(player);
+       }
+
+       debug_fleave();
+
+       return ret;
+}
+
+int
+__mmplayer_unrealize_streaming_ext(mm_player_t *player)
+{
+       debug_fenter();
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       
+       /* destroy can called at anytime */
+       if (player->pd_downloader && MMPLAYER_IS_HTTP_PD(player))
+       {
+               _mmplayer_unrealize_pd_downloader ((MMHandleType)player);
+               player->pd_downloader = NULL;
+       }
+
+       debug_fleave();
+       return MM_ERROR_NONE;
+}
+
+int
+_mmplayer_unrealize(MMHandleType hplayer) // @
+{
+       mm_player_t* player = (mm_player_t*)hplayer;
+       int ret = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED )
+
+       /* check current state */
+       MMPLAYER_CHECK_STATE_RETURN_IF_FAIL( player, MMPLAYER_COMMAND_UNREALIZE );
+
+       __mmplayer_unrealize_streaming_ext(player);
+
+       /* unrealize pipeline */
+       ret = __gst_unrealize( player );
+
+       /* set player state if success */
+       if ( MM_ERROR_NONE == ret )
+       {
+               ret = _mmplayer_asm_set_state(hplayer, ASM_STATE_STOP);
+               if ( ret )
+               {
+                       debug_error("failed to set asm state to STOP\n");
+                       return ret;
+               }
+       }
+
+       debug_fleave();
+
+       return ret;
+}
+
+int
+_mmplayer_set_message_callback(MMHandleType hplayer, MMMessageCallback callback, gpointer user_param) // @
+{
+       mm_player_t* player = (mm_player_t*)hplayer;
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       return __gst_set_message_callback(player, callback, user_param);
+}
+
+int
+_mmplayer_get_state(MMHandleType hplayer, int* state) // @
+{
+       mm_player_t *player = (mm_player_t*)hplayer;
+
+       return_val_if_fail(state, MM_ERROR_INVALID_ARGUMENT);
+
+       *state = MMPLAYER_CURRENT_STATE(player);
+
+       return MM_ERROR_NONE;
+}
+
+
+int
+_mmplayer_set_volume(MMHandleType hplayer, MMPlayerVolumeType volume) // @
+{
+       mm_player_t* player = (mm_player_t*) hplayer;
+       GstElement* vol_element = NULL;
+       int i = 0;
+
+       debug_fenter();
+
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       debug_log("volume [L]=%f:[R]=%f\n", 
+               volume.level[MM_VOLUME_CHANNEL_LEFT], volume.level[MM_VOLUME_CHANNEL_RIGHT]);
+
+       /* invalid factor range or not */
+       for ( i = 0; i < MM_VOLUME_CHANNEL_NUM; i++ )
+       {
+               if (volume.level[i] < MM_VOLUME_FACTOR_MIN || volume.level[i] > MM_VOLUME_FACTOR_MAX) {
+                       debug_error("Invalid factor! (valid factor:0~1.0)\n");
+                       return MM_ERROR_INVALID_ARGUMENT;
+               }
+       }
+
+       /* Save volume to handle. Currently the first array element will be saved. */
+       player->sound.volume = volume.level[0];
+
+       /* check pipeline handle */
+       if ( ! player->pipeline || ! player->pipeline->audiobin )
+       {
+               debug_log("audiobin is not created yet\n");
+               debug_log("but, current stored volume will be set when it's created.\n");
+
+               /* NOTE : stored volume will be used in create_audiobin
+                * returning MM_ERROR_NONE here makes application to able to
+                * set volume at anytime.
+                */
+               return MM_ERROR_NONE;
+       }
+
+       /* setting volume to volume element */
+       vol_element = player->pipeline->audiobin[MMPLAYER_A_VOL].gst;
+
+       if ( vol_element )
+       {
+               debug_log("volume is set [%f]\n", player->sound.volume);
+               g_object_set(vol_element, "volume", player->sound.volume, NULL);
+       }
+
+       debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+
+int
+_mmplayer_get_volume(MMHandleType hplayer, MMPlayerVolumeType* volume)
+{
+       mm_player_t* player = (mm_player_t*) hplayer;
+       int i = 0;
+
+       debug_fenter();
+
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail( volume, MM_ERROR_INVALID_ARGUMENT );
+
+       /* returning stored volume */
+       for (i = 0; i < MM_VOLUME_CHANNEL_NUM; i++)
+               volume->level[i] = player->sound.volume;
+
+       debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+
+
+int
+_mmplayer_set_mute(MMHandleType hplayer, int mute) // @
+{
+       mm_player_t* player = (mm_player_t*) hplayer;
+       GstElement* vol_element = NULL;
+
+       debug_fenter();
+
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       debug_log("mute : %d\n", mute);
+
+       /* mute value shoud 0 or 1 */
+       if ( mute != 0 && mute != 1 )
+       {
+               debug_error("bad mute value\n");
+
+               /* FIXIT : definitly, we need _BAD_PARAM error code */
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+
+
+       /* just hold mute value if pipeline is not ready */
+       if ( !player->pipeline || !player->pipeline->audiobin )
+       {
+               debug_log("pipeline is not ready. holding mute value\n");
+               player->sound.mute = mute;
+               return MM_ERROR_NONE;
+       }
+
+
+       vol_element = player->pipeline->audiobin[MMPLAYER_A_VOL].gst;
+
+       /* NOTE : volume will only created when the bt is enabled */
+       if ( vol_element )
+       {
+               g_object_set(vol_element, "mute", mute, NULL);
+       }
+       else
+       {
+               debug_log("volume elemnet is not created. using volume in audiosink\n");
+       }
+
+       player->sound.mute = mute;
+
+       debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+int
+_mmplayer_get_mute(MMHandleType hplayer, int* pmute) // @
+{
+       mm_player_t* player = (mm_player_t*) hplayer;
+       GstElement* vol_element = NULL;
+
+       debug_fenter();
+
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail ( pmute, MM_ERROR_INVALID_ARGUMENT );
+
+       /* just hold mute value if pipeline is not ready */
+       if ( !player->pipeline || !player->pipeline->audiobin )
+       {
+               debug_log("pipeline is not ready. returning stored value\n");
+               *pmute = player->sound.mute;
+               return MM_ERROR_NONE;
+       }
+
+
+       vol_element = player->pipeline->audiobin[MMPLAYER_A_VOL].gst;
+
+       if ( vol_element )
+       {
+               g_object_get(vol_element, "mute", pmute, NULL);
+               debug_log("mute=%d\n\n", *pmute);
+       }
+       else
+       {
+               *pmute = player->sound.mute;
+       }
+
+       debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+int
+_mmplayer_set_videostream_cb(MMHandleType hplayer, mm_player_video_stream_callback callback, void *user_param) // @
+{
+       mm_player_t* player = (mm_player_t*) hplayer;
+
+       debug_fenter();
+
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail ( callback, MM_ERROR_INVALID_ARGUMENT );
+
+       player->video_stream_cb = callback;
+       player->video_stream_cb_user_param = user_param;
+       player->use_video_stream = TRUE;
+       debug_log("Stream cb Handle value is %p : %p\n", player, player->video_stream_cb);
+
+       debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+int
+_mmplayer_set_audiostream_cb(MMHandleType hplayer, mm_player_audio_stream_callback callback, void *user_param) // @
+{
+       mm_player_t* player = (mm_player_t*) hplayer;
+
+       debug_fenter();
+
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail(callback, MM_ERROR_INVALID_ARGUMENT);
+
+       player->audio_stream_cb = callback;
+       player->audio_stream_cb_user_param = user_param;
+       debug_log("Audio Stream cb Handle value is %p : %p\n", player, player->audio_stream_cb);
+
+       debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+int
+_mmplayer_set_audiobuffer_cb(MMHandleType hplayer, mm_player_audio_stream_callback callback, void *user_param) // @
+{
+       mm_player_t* player = (mm_player_t*) hplayer;
+
+       debug_fenter();
+
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail(callback, MM_ERROR_INVALID_ARGUMENT);
+
+       player->audio_buffer_cb = callback;
+       player->audio_buffer_cb_user_param = user_param;
+       debug_log("Audio Stream cb Handle value is %p : %p\n", player, player->audio_buffer_cb);
+
+       debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+int
+_mmplayer_set_buffer_need_data_cb(MMHandleType hplayer, mm_player_buffer_need_data_callback callback, void *user_param) // @
+{
+       mm_player_t* player = (mm_player_t*) hplayer;
+
+       debug_fenter();
+
+       return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail(callback, MM_ERROR_INVALID_ARGUMENT);
+
+       player->need_data_cb = callback;
+       player->buffer_cb_user_param = user_param;
+
+       debug_log("buffer need dataHandle value is %p : %p\n", player, player->need_data_cb);
+
+       debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+int
+_mmplayer_set_buffer_enough_data_cb(MMHandleType hplayer, mm_player_buffer_enough_data_callback callback, void *user_param) // @
+{
+       mm_player_t* player = (mm_player_t*) hplayer;
+
+       debug_fenter();
+
+       return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail(callback, MM_ERROR_INVALID_ARGUMENT);
+
+       player->enough_data_cb = callback;
+       player->buffer_cb_user_param = user_param;
+
+       debug_log("buffer enough data cb Handle value is %p : %p\n", player, player->enough_data_cb);
+
+       debug_fleave();
+               
+       return MM_ERROR_NONE;
+}
+
+int
+_mmplayer_set_buffer_seek_data_cb(MMHandleType hplayer, mm_player_buffer_seek_data_callback callback, void *user_param) // @
+{
+       mm_player_t* player = (mm_player_t*) hplayer;
+
+       debug_fenter();
+
+       return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail(callback, MM_ERROR_INVALID_ARGUMENT);
+
+       player->seek_data_cb = callback;
+       player->buffer_cb_user_param = user_param;
+
+       debug_log("buffer seek data cb Handle value is %p : %p\n", player, player->seek_data_cb);
+
+       debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+int
+_mmplayer_set_videoframe_render_error_cb(MMHandleType hplayer, mm_player_video_frame_render_error_callback callback, void *user_param) // @
+{
+       mm_player_t* player = (mm_player_t*) hplayer;
+
+       debug_fenter();
+
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail ( callback, MM_ERROR_INVALID_ARGUMENT );
+
+       player->video_frame_render_error_cb = callback;
+       player->video_frame_render_error_cb_user_param = user_param;
+
+       debug_log("Video frame render error cb Handle value is %p : %p\n", player, player->video_frame_render_error_cb);
+
+       debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+int
+__mmplayer_start_streaming_ext(mm_player_t *player)
+{
+       gint ret = MM_ERROR_NONE;
+
+       debug_fenter();
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       if (MMPLAYER_IS_HTTP_PD(player))
+       {
+               if ( !player->pd_downloader )
+               {
+                       ret = __mmplayer_realize_streaming_ext(player);
+
+                       if ( ret != MM_ERROR_NONE)
+                       {
+                               debug_error ("failed to realize streaming ext\n");
+                               return ret;
+                       }
+               }
+
+               if (player->pd_downloader && player->pd_mode == MM_PLAYER_PD_MODE_URI)
+               {
+                       ret = _mmplayer_start_pd_downloader ((MMHandleType)player);
+                       if ( !ret )
+                       {
+                               debug_error ("ERROR while starting PD...\n");
+                               return MM_ERROR_PLAYER_NOT_INITIALIZED;
+                       }
+                       ret = MM_ERROR_NONE;
+               }
+       }
+
+       debug_fleave();
+       return ret;
+}
+
+int
+_mmplayer_start(MMHandleType hplayer) // @
+{
+       mm_player_t* player = (mm_player_t*) hplayer;
+       gint ret = MM_ERROR_NONE;
+       
+       debug_fenter();
+
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       /* check current state */
+       MMPLAYER_CHECK_STATE_RETURN_IF_FAIL( player, MMPLAYER_COMMAND_START );
+
+       ret = _mmplayer_asm_set_state(hplayer, ASM_STATE_PLAYING);
+       if ( ret != MM_ERROR_NONE )
+       {
+               debug_error("failed to set asm state to PLAYING\n");
+               return ret;
+       }
+
+       /* NOTE : we should check and create pipeline again if not created as we destroy
+        * whole pipeline when stopping in streamming playback
+        */
+       if ( ! player->pipeline )
+       {
+               ret = __gst_realize( player ); 
+               if ( MM_ERROR_NONE != ret )
+               {
+                       debug_error("failed to realize before starting. only in streamming\n");
+                       return ret;
+               }
+       }
+
+       ret = __mmplayer_start_streaming_ext(player);
+       if ( ret != MM_ERROR_NONE )
+       {
+               debug_error("failed to start streaming ext \n");
+       }
+       
+       /* start pipeline */
+       ret = __gst_start( player );
+       if ( ret != MM_ERROR_NONE )
+       {
+               debug_error("failed to start player.\n");
+       }
+
+       debug_fleave();
+       
+       return ret;
+}
+
+/* NOTE: post "not supported codec message" to application
+ * when one codec is not found during AUTOPLUGGING in MSL.
+ * So, it's separated with error of __mmplayer_gst_callback().
+ * And, if any codec is not found, don't send message here.
+ * Because GST_ERROR_MESSAGE is posted by other plugin internally.
+ */
+int
+__mmplayer_post_missed_plugin(mm_player_t* player)
+{
+       MMMessageParamType msg_param;
+       memset (&msg_param, 0, sizeof(MMMessageParamType));
+       gboolean post_msg_direct = FALSE;
+
+       debug_fenter();
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       debug_log("not_supported_codec = 0x%02x, can_support_codec = 0x%02x\n",
+                       player->not_supported_codec, player->can_support_codec);
+
+       if( player->not_found_demuxer )
+       {
+               msg_param.code = MM_ERROR_PLAYER_CODEC_NOT_FOUND;
+               msg_param.data = g_strdup_printf("%s", player->unlinked_demuxer_mime);
+
+               MMPLAYER_POST_MSG( player, MM_MESSAGE_ERROR, &msg_param );
+               MMPLAYER_FREEIF(msg_param.data);
+
+               return MM_ERROR_NONE;
+       }
+
+       if (player->not_supported_codec)
+       {
+               if ( player->can_support_codec ) // There is one codec to play
+               {
+                       post_msg_direct = TRUE;
+               }
+               else
+               {
+                       if ( player->pipeline->audiobin ) // Some content has only PCM data in container.
+                               post_msg_direct = TRUE;
+               }
+
+               if ( post_msg_direct )
+               {
+                       MMMessageParamType msg_param;
+                       memset (&msg_param, 0, sizeof(MMMessageParamType));
+
+                       if ( player->not_supported_codec ==  MISSING_PLUGIN_AUDIO )
+                       {
+                               debug_warning("not found AUDIO codec, posting error code to application.\n");
+
+                               msg_param.code = MM_ERROR_PLAYER_AUDIO_CODEC_NOT_FOUND;
+                               msg_param.data = g_strdup_printf("%s", player->unlinked_audio_mime);
+                       }
+                       else if ( player->not_supported_codec ==  MISSING_PLUGIN_VIDEO )
+                       {
+                               debug_warning("not found VIDEO codec, posting error code to application.\n");
+
+                               msg_param.code = MM_ERROR_PLAYER_VIDEO_CODEC_NOT_FOUND;
+                               msg_param.data = g_strdup_printf("%s", player->unlinked_video_mime);
+                       }
+
+                       MMPLAYER_POST_MSG( player, MM_MESSAGE_ERROR, &msg_param );
+
+                       MMPLAYER_FREEIF(msg_param.data);
+
+                       return MM_ERROR_NONE;
+               }
+               else // no any supported codec case 
+               {
+                       debug_warning("not found any codec, posting error code to application.\n");
+                       
+                       if ( player->not_supported_codec ==  MISSING_PLUGIN_AUDIO )
+                       {
+                               msg_param.code = MM_ERROR_PLAYER_AUDIO_CODEC_NOT_FOUND;
+                               msg_param.data = g_strdup_printf("%s", player->unlinked_audio_mime);
+                       }
+                       else
+                       {
+                               msg_param.code = MM_ERROR_PLAYER_CODEC_NOT_FOUND;
+                               msg_param.data = g_strdup_printf("%s, %s", player->unlinked_video_mime, player->unlinked_audio_mime);
+                       }
+
+                       MMPLAYER_POST_MSG( player, MM_MESSAGE_ERROR, &msg_param );
+                       
+                       MMPLAYER_FREEIF(msg_param.data);
+               }
+       }
+       
+       debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+/* NOTE : it should be able to call 'stop' anytime*/
+int
+_mmplayer_stop(MMHandleType hplayer) // @
+{
+       mm_player_t* player = (mm_player_t*)hplayer;
+       int ret = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       /* check current state */
+       MMPLAYER_CHECK_STATE_RETURN_IF_FAIL( player, MMPLAYER_COMMAND_STOP );
+
+       /* NOTE : application should not wait for EOS after calling STOP */
+       __mmplayer_cancel_delayed_eos( player );
+
+       __mmplayer_unrealize_streaming_ext(player);
+
+       /* stop pipeline */
+       ret = __gst_stop( player );
+
+       if ( ret != MM_ERROR_NONE )
+       {
+               debug_error("failed to stop player.\n");
+       }
+
+       debug_fleave();
+
+       return ret;
+}
+
+int
+_mmplayer_pause(MMHandleType hplayer) // @
+{
+       mm_player_t* player = (mm_player_t*)hplayer;
+       GstFormat fmt = GST_FORMAT_TIME;
+       gint64 pos_msec = 0;
+       gboolean async = FALSE;
+       gint ret = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       /* check current state */
+       MMPLAYER_CHECK_STATE_RETURN_IF_FAIL( player, MMPLAYER_COMMAND_PAUSE );
+
+       switch (MMPLAYER_CURRENT_STATE(player))
+       {
+               case MM_PLAYER_STATE_READY:
+               {
+                       /* check prepare async or not.
+                        * In the case of streaming playback, it's recommned to avoid blocking wait.
+                        */
+                       mm_attrs_get_int_by_name(player->attrs, "profile_prepare_async", &async);
+                       debug_log("prepare mode : %s", (async ? "async" : "sync"));
+               }
+               break;
+
+               case MM_PLAYER_STATE_PLAYING:
+               {
+                       /* NOTE : store current point to overcome some bad operation
+                       * ( returning zero when getting current position in paused state) of some
+                       * elements
+                       */
+                       ret = gst_element_query_position(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst,        &fmt, &pos_msec);
+                       if ( ! ret )
+                       debug_warning("getting current position failed in paused\n");
+
+                       player->last_position = pos_msec;
+               }
+               break;
+       }
+
+       /* pause pipeline */
+       ret = __gst_pause( player, async );
+
+       if ( ret != MM_ERROR_NONE )
+       {
+               debug_error("failed to pause player.\n");
+       }
+
+       debug_fleave();
+
+       return ret;
+}
+
+int
+_mmplayer_resume(MMHandleType hplayer)
+{
+       mm_player_t* player = (mm_player_t*)hplayer;
+       int ret = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       ret = _mmplayer_asm_set_state(hplayer, ASM_STATE_PLAYING);
+       if ( ret )
+       {
+               debug_error("failed to set asm state to PLAYING\n");
+               return ret;
+       }
+
+       /* check current state */
+       MMPLAYER_CHECK_STATE_RETURN_IF_FAIL( player, MMPLAYER_COMMAND_RESUME );
+
+       /* resume pipeline */
+       ret = __gst_resume( player, FALSE );
+
+       if ( ret != MM_ERROR_NONE )
+       {
+               debug_error("failed to resume player.\n");
+       }
+
+
+       debug_fleave();
+
+       return ret;
+}
+
+int
+__mmplayer_set_play_count(mm_player_t* player, gint count)
+{
+       MMHandleType attrs = 0;
+
+       debug_fenter();
+
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       attrs =  MMPLAYER_GET_ATTRS(player);
+       if ( !attrs )
+       {
+               debug_error("fail to get attributes.\n");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       mm_attrs_set_int_by_name(attrs, "profile_play_count", count);
+       if ( mmf_attrs_commit ( attrs ) ) /* return -1 if error */
+               debug_error("failed to commit\n");
+
+       debug_fleave();
+
+       return  MM_ERROR_NONE;
+}
+
+int
+_mmplayer_activate_section_repeat(MMHandleType hplayer, unsigned long start, unsigned long end)
+{
+       mm_player_t* player = (mm_player_t*)hplayer;
+       gint64 start_pos = 0;
+       gint64 end_pos = 0;
+       gint infinity = -1;
+
+       debug_fenter();
+
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail ( end <= GST_TIME_AS_MSECONDS(player->duration), MM_ERROR_INVALID_ARGUMENT );
+
+       player->section_repeat = TRUE;
+       player->section_repeat_start = start;
+       player->section_repeat_end = end;
+
+       start_pos = player->section_repeat_start * G_GINT64_CONSTANT(1000000);
+       end_pos = player->section_repeat_end * G_GINT64_CONSTANT(1000000);
+
+       __mmplayer_set_play_count( player, infinity );
+
+       if ( (!__gst_seek( player, player->pipeline->mainbin[MMPLAYER_M_PIPE].gst,
+                                       1.0,
+                                       GST_FORMAT_TIME,
+                                       ( GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE ),
+                                       GST_SEEK_TYPE_SET, start_pos,
+                                       GST_SEEK_TYPE_SET, end_pos)))
+       {
+               debug_error("failed to activate section repeat\n");
+
+               return MM_ERROR_PLAYER_SEEK;
+       }
+
+       debug_log("succeeded to set section repeat from %d to %d\n",
+               player->section_repeat_start, player->section_repeat_end);
+
+       debug_fleave();
+
+       return  MM_ERROR_NONE;
+}
+
+static int 
+__mmplayer_set_pcm_extraction(mm_player_t* player)
+{
+       guint64 start_nsec = 0;
+       guint64 end_nsec = 0;
+       guint64 dur_nsec = 0;
+       guint64 dur_msec = 0;
+       GstFormat fmt = GST_FORMAT_TIME;
+       int required_start = 0;
+       int required_end = 0;
+       int ret = 0;
+
+       debug_fenter();
+
+       return_val_if_fail( player, FALSE );
+
+       mm_attrs_multiple_get(player->attrs,
+               NULL,
+               "pcm_extraction_start_msec", &required_start,
+               "pcm_extraction_end_msec", &required_end,
+               NULL);
+
+       debug_log("pcm extraction required position is from [%d] to [%d] (msec)\n", required_start, required_end);
+
+       if (required_start == 0 && required_end == 0)
+       {
+               debug_log("extracting entire stream");
+               return MM_ERROR_NONE;
+       }
+       else if (required_start < 0 || required_start > required_end || required_end < 0 )
+       {
+               debug_log("invalid range for pcm extraction");
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+
+       /* get duration */
+       ret = gst_element_query_duration(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, &fmt, &dur_nsec);
+       if ( !ret )
+       {
+               debug_error("failed to get duration");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+       dur_msec = GST_TIME_AS_MSECONDS(dur_nsec);
+
+       if (dur_msec < required_end) // FIXME
+       {
+               debug_log("invalid end pos for pcm extraction");
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+
+       start_nsec = required_start * G_GINT64_CONSTANT(1000000);
+       end_nsec = required_end * G_GINT64_CONSTANT(1000000);
+
+       if ( (!__gst_seek( player, player->pipeline->mainbin[MMPLAYER_M_PIPE].gst,
+                                       1.0,
+                                       GST_FORMAT_TIME,
+                                       ( GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE ),
+                                       GST_SEEK_TYPE_SET, start_nsec,
+                                       GST_SEEK_TYPE_SET, end_nsec)))
+       {
+               debug_error("failed to seek for pcm extraction\n");
+
+               return MM_ERROR_PLAYER_SEEK;
+       }
+
+       debug_log("succeeded to set up segment extraction from [%llu] to [%llu] (nsec)\n", start_nsec, end_nsec);
+
+       debug_fleave(); 
+
+       return MM_ERROR_NONE;
+}
+
+int
+_mmplayer_deactivate_section_repeat(MMHandleType hplayer)
+{
+       mm_player_t* player = (mm_player_t*)hplayer;
+       gint64 cur_pos = 0;
+       GstFormat fmt  = GST_FORMAT_TIME;
+       gint onetime = 1;
+
+       debug_fenter();
+
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       player->section_repeat = FALSE;
+
+       __mmplayer_set_play_count( player, onetime );
+
+       gst_element_query_position(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, &fmt, &cur_pos);
+
+       if ( (!__gst_seek( player, player->pipeline->mainbin[MMPLAYER_M_PIPE].gst,
+                                       1.0,
+                                       GST_FORMAT_TIME,
+                                       ( GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE ),
+                                       GST_SEEK_TYPE_SET, cur_pos,
+                                       GST_SEEK_TYPE_SET, player->duration )))
+       {
+               debug_error("failed to deactivate section repeat\n");
+
+               return MM_ERROR_PLAYER_SEEK;
+       }
+
+       debug_fenter();
+
+       return MM_ERROR_NONE;
+}
+
+int
+_mmplayer_set_playspeed(MMHandleType hplayer, gdouble rate)
+{
+       mm_player_t* player = (mm_player_t*)hplayer;
+       signed long long pos_msec = 0;
+       int ret = MM_ERROR_NONE;
+       int mute = FALSE;
+       GstFormat format =GST_FORMAT_TIME;
+       MMPlayerStateType current_state = MM_PLAYER_STATE_NONE;
+       debug_fenter();
+
+       return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail ( !MMPLAYER_IS_STREAMING(player), MM_ERROR_NOT_SUPPORT_API );
+
+       /* The sound of video is not supported under 0.0 and over 2.0. */
+       if(rate >= TRICK_PLAY_MUTE_THRESHOLD_MAX || rate < TRICK_PLAY_MUTE_THRESHOLD_MIN)
+       {
+               if (player->can_support_codec & FOUND_PLUGIN_VIDEO)
+                       mute = TRUE;
+       }
+       _mmplayer_set_mute(hplayer, mute);
+
+       if (player->playback_rate == rate)
+               return MM_ERROR_NONE;
+
+       /* If the position is reached at start potion during fast backward, EOS is posted.
+        * So, This EOS have to be classified with it which is posted at reaching the end of stream.
+        * */
+       player->playback_rate = rate;
+
+       current_state = MMPLAYER_CURRENT_STATE(player);
+
+       if ( current_state != MM_PLAYER_STATE_PAUSED )
+               ret = gst_element_query_position(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, &format, &pos_msec);
+
+       debug_log ("pos_msec = %"GST_TIME_FORMAT" and ret = %d and state = %d", GST_TIME_ARGS (pos_msec), ret, current_state);
+
+       if ( ( current_state == MM_PLAYER_STATE_PAUSED )
+               || ( ! ret ))
+               //|| ( player->last_position != 0 && pos_msec == 0 ) )
+       {
+               debug_warning("returning last point : %lld\n", player->last_position );
+               pos_msec = player->last_position;
+       }
+
+       if ((!gst_element_seek (player->pipeline->mainbin[MMPLAYER_M_PIPE].gst,
+                               rate,
+                               GST_FORMAT_TIME,
+                               ( GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE ),
+                               //( GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE | GST_SEEK_FLAG_KEY_UNIT),
+                               GST_SEEK_TYPE_SET, pos_msec,
+                               //GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE,
+                GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE)))
+       {
+               debug_error("failed to set speed playback\n");
+               return MM_ERROR_PLAYER_SEEK;
+       }
+
+       debug_log("succeeded to set speed playback as %fl\n", rate);
+
+       debug_fleave();
+
+       return MM_ERROR_NONE;;
+}
+
+int
+_mmplayer_set_position(MMHandleType hplayer, int format, int position) // @
+{
+       mm_player_t* player = (mm_player_t*)hplayer;
+       int ret = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       ret = __gst_set_position ( player, format, (unsigned long)position, FALSE );
+
+       debug_fleave(); 
+
+       return ret;
+}
+
+int
+_mmplayer_get_position(MMHandleType hplayer, int format, unsigned long *position) // @
+{
+       mm_player_t* player = (mm_player_t*)hplayer;
+       int ret = MM_ERROR_NONE;
+
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       ret = __gst_get_position ( player, format, position );
+       
+       return ret;
+}
+
+int
+_mmplayer_get_buffer_position(MMHandleType hplayer, int format, unsigned long* start_pos, unsigned long* stop_pos) // @
+{
+       mm_player_t* player = (mm_player_t*)hplayer;
+       int ret = MM_ERROR_NONE;
+
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       ret = __gst_get_buffer_position ( player, format, start_pos, stop_pos );
+
+       return ret;
+}
+
+int
+_mmplayer_adjust_subtitle_postion(MMHandleType hplayer, int format, int position) // @
+{
+       mm_player_t* player = (mm_player_t*)hplayer;
+       int ret = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       ret = __gst_adjust_subtitle_position(player, format, position);
+
+       debug_fleave();
+
+       return ret;
+}
+
+static gboolean
+__mmplayer_is_midi_type( gchar* str_caps)
+{
+       if ( ( g_strrstr(str_caps, "audio/midi") ) ||
+               ( g_strrstr(str_caps, "application/x-gst_ff-mmf") ) ||
+               ( g_strrstr(str_caps, "application/x-smaf") ) ||
+               ( g_strrstr(str_caps, "audio/x-imelody") ) ||
+               ( g_strrstr(str_caps, "audio/mobile-xmf") ) ||
+               ( g_strrstr(str_caps, "audio/xmf") ) ||
+               ( g_strrstr(str_caps, "audio/mxmf") ) )
+       {
+               debug_log("midi\n");
+
+               return TRUE;
+       }
+
+       debug_log("not midi.\n");
+
+       return FALSE;
+}
+
+static gboolean
+__mmplayer_is_amr_type (gchar *str_caps)
+{
+       if ((g_strrstr(str_caps, "AMR")) ||
+               (g_strrstr(str_caps, "amr")))
+       {
+               return TRUE;
+       }
+       return FALSE;
+}
+
+static gboolean
+__mmplayer_is_only_mp3_type (gchar *str_caps)
+{
+       if (g_strrstr(str_caps, "application/x-id3") ||
+               (g_strrstr(str_caps, "audio/mpeg") && g_strrstr(str_caps, "mpegversion=(int)1")))
+       {
+               return TRUE;
+       }
+       return FALSE;
+}
+
+static void
+__mmplayer_typefind_have_type(  GstElement *tf, guint probability,  // @
+GstCaps *caps, gpointer data)
+{
+       mm_player_t* player = (mm_player_t*)data;
+       GstPad* pad = NULL;
+
+       debug_fenter();
+
+       return_if_fail( player && tf && caps );
+
+       /* store type string */
+       MMPLAYER_FREEIF(player->type);
+       player->type = gst_caps_to_string(caps);
+       if (player->type)
+               debug_log("meida type %s found, probability %d%% / %d\n", player->type, probability, gst_caps_get_size(caps));
+
+       /* midi type should be stored because it will be used to set audio gain in avsysaudiosink */
+       if ( __mmplayer_is_midi_type(player->type))
+       {
+               player->profile.play_mode = MM_PLAYER_MODE_MIDI;
+       }
+       else if (__mmplayer_is_amr_type(player->type))
+       {
+               player->bypass_audio_effect = FALSE;
+               if ( (PLAYER_INI()->use_audio_effect_preset || PLAYER_INI()->use_audio_effect_custom) )
+               {
+                       if ( player->audio_effect_info.effect_type == MM_AUDIO_EFFECT_TYPE_PRESET )
+                       {
+                               if (!_mmplayer_audio_effect_preset_apply(player, player->audio_effect_info.preset))
+                               {
+                                       debug_msg("apply audio effect(preset:%d) setting success\n",player->audio_effect_info.preset);
+                               }
+                       }
+                       else if ( player->audio_effect_info.effect_type == MM_AUDIO_EFFECT_TYPE_CUSTOM )
+                       {
+                               if (!_mmplayer_audio_effect_custom_apply(player))
+                               {
+                                       debug_msg("apply audio effect(custom) setting success\n");
+                               }
+                       }
+               }
+       }
+       else if ( g_strrstr(player->type, "application/x-hls"))
+       {
+               /* If it can't know exact type when it parses uri because of redirection case,
+                 * it will be fixed by typefinder here.
+                 */
+               player->profile.uri_type = MM_PLAYER_URI_TYPE_HLS;
+       }
+
+       pad = gst_element_get_static_pad(tf, "src");
+       if ( !pad )
+       {
+               debug_error("fail to get typefind src pad.\n");
+               return;
+       }
+
+
+       /* try to plug */
+       if ( ! __mmplayer_try_to_plug( player, pad, caps ) )
+       {
+               debug_error("failed to autoplug for type : %s\n", player->type);
+
+               if ( ( PLAYER_INI()->async_start ) &&
+               ( player->posted_msg == FALSE ) )
+               {
+                       __mmplayer_post_missed_plugin( player );
+               }
+                       
+               goto DONE;
+       }
+
+       /* finish autopluging if no dynamic pad waiting */
+       if( ( ! player->have_dynamic_pad) && ( ! player->has_many_types) )
+       {
+               if ( ! MMPLAYER_IS_RTSP_STREAMING( player ) )
+               {
+                       __mmplayer_pipeline_complete( NULL, (gpointer)player );
+               }
+       }
+
+DONE:
+       gst_object_unref( GST_OBJECT(pad) );
+
+       debug_fleave(); 
+
+       return;
+}
+
+static gboolean
+__mmplayer_warm_up_video_codec( mm_player_t* player,  GstElementFactory *factory)
+{
+       GstElement *element;
+       GstStateChangeReturn  ret;
+       gboolean usable = TRUE;
+
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail ( factory, MM_ERROR_COMMON_INVALID_ARGUMENT );
+
+       element = gst_element_factory_create (factory, NULL);
+
+       ret = gst_element_set_state (element, GST_STATE_READY);
+
+       if (ret != GST_STATE_CHANGE_SUCCESS)
+       {
+               debug_error ("resource conflict so,  %s unusable\n", GST_PLUGIN_FEATURE_NAME (factory));
+               usable = FALSE;
+       }
+
+       gst_element_set_state (element, GST_STATE_NULL);
+       gst_object_unref (element);
+
+       return usable;
+}
+
+/* it will return first created element */
+static gboolean
+__mmplayer_try_to_plug(mm_player_t* player, GstPad *pad, const GstCaps *caps) // @
+{
+       MMPlayerGstElement* mainbin = NULL;
+       const char* mime = NULL;
+       const GList* item = NULL;
+       const gchar* klass = NULL;
+       GstCaps* res = NULL;
+       gboolean skip = FALSE;
+       GstPad* queue_pad = NULL;
+       GstElement* queue = NULL;
+       GstElement *element = NULL;
+
+       debug_fenter();
+
+       return_val_if_fail( player &&
+                                               player->pipeline &&
+                                               player->pipeline->mainbin,
+                                               FALSE );
+
+
+       mainbin = player->pipeline->mainbin;
+
+       mime = gst_structure_get_name(gst_caps_get_structure(caps, 0));
+
+       /* return if we got raw output */
+       if(g_str_has_prefix(mime, "video/x-raw") || g_str_has_prefix(mime, "audio/x-raw") || g_str_has_prefix(mime, "text/plain") ||g_str_has_prefix(mime, "text/x-pango-markup"))
+       {
+
+               element = (GstElement*)gst_pad_get_parent(pad);
+
+
+/* NOTE : When no decoder has added during autoplugging. like a simple wave playback.
+ * No queue will be added. I think it can caused breaking sound when playing raw audio
+ * frames but there's no different. Decodebin also doesn't add with those wav fils.
+ * Anyway, currentely raw-queue seems not necessary.
+ */
+#if 1
+               /* NOTE : check if previously linked element is demuxer/depayloader/parse means no decoder
+                * has linked. if so, we need to add queue for quality of output. note that
+                * decodebin also has same problem.
+                */
+
+               klass = gst_element_factory_get_klass( gst_element_get_factory(element) );
+
+               /* add queue if needed */
+               if( (g_strrstr(klass, "Demux") ||
+               g_strrstr(klass, "Depayloader") ||
+                       g_strrstr(klass, "Parse")) &&  !g_str_has_prefix(mime, "text"))
+               {
+                       debug_log("adding raw queue\n");
+
+                       queue = gst_element_factory_make("queue", NULL);
+                       if ( ! queue )
+                       {
+                               debug_warning("failed to create queue\n");
+                               goto ERROR;
+                       }
+
+                       /* warmup */
+                       if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state(queue, GST_STATE_READY) )
+                       {
+                               debug_warning("failed to set state READY to queue\n");
+                               goto ERROR;
+                       }
+
+                       /* add to pipeline */
+                       if ( ! gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), queue) )
+                       {
+                               debug_warning("failed to add queue\n");
+                               goto ERROR;
+                       }
+
+                       /* link queue */
+                       queue_pad = gst_element_get_static_pad(queue, "sink");
+
+                       if ( GST_PAD_LINK_OK != gst_pad_link(pad, queue_pad) )
+                       {
+                               debug_warning("failed to link queue\n");
+                               goto ERROR;
+                       }
+                       gst_object_unref ( GST_OBJECT(queue_pad) );
+                       queue_pad = NULL;
+
+                       /* running */
+                       if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state(queue, GST_STATE_PAUSED) )
+                       {
+                               debug_warning("failed to set state READY to queue\n");
+                               goto ERROR;
+                       }
+
+                       /* replace given pad to queue:src */
+                       pad = gst_element_get_static_pad(queue, "src");
+                       if ( ! pad )
+                       {
+                               debug_warning("failed to get pad from queue\n");
+                               goto ERROR;
+                       }
+               }
+#endif
+               /* check if player can do start continually */
+               MMPLAYER_CHECK_CMD_IF_EXIT(player);
+
+               if(__mmplayer_link_sink(player,pad))
+                        __mmplayer_gst_decode_callback(element, pad, FALSE, player);
+
+               gst_object_unref( GST_OBJECT(element));
+               element = NULL;
+
+               return TRUE;
+       }
+
+       item = player->factories;
+       for(; item != NULL ; item = item->next)
+       {
+
+               GstElementFactory *factory = GST_ELEMENT_FACTORY(item->data);
+               const GList *pads;
+               gint idx = 0;
+
+               skip = FALSE;
+
+               /* filtering exclude keyword */
+               for ( idx = 0; PLAYER_INI()->exclude_element_keyword[idx][0] != '\0'; idx++ )
+               {
+                       if ( g_strrstr(GST_PLUGIN_FEATURE_NAME (factory),
+                                       PLAYER_INI()->exclude_element_keyword[idx] ) )
+                       {
+                               debug_warning("skipping [%s] by exculde keyword [%s]\n",
+                                       GST_PLUGIN_FEATURE_NAME (factory),
+                                       PLAYER_INI()->exclude_element_keyword[idx] );
+
+                               skip = TRUE;
+                               break;
+                       }
+               }
+
+               if ( skip ) continue;
+
+
+               /* check factory class for filtering */
+               klass = gst_element_factory_get_klass(GST_ELEMENT_FACTORY(factory));
+
+               /* NOTE : msl don't need to use image plugins.
+                * So, those plugins should be skipped for error handling.
+                */
+               if ( g_strrstr(klass, "Codec/Decoder/Image") )
+               {
+                       debug_log("player doesn't need [%s] so, skipping it\n",
+                               GST_PLUGIN_FEATURE_NAME (factory) );
+
+                       continue;
+               }
+
+
+               /* check pad compatability */
+               for(pads = gst_element_factory_get_static_pad_templates(factory);
+                    pads != NULL; pads=pads->next)
+              {
+                      GstStaticPadTemplate *temp1 = pads->data;
+                       GstCaps* static_caps = NULL;
+
+                       if( temp1->direction != GST_PAD_SINK ||
+                               temp1->presence != GST_PAD_ALWAYS)
+                               continue;
+
+
+                       if ( GST_IS_CAPS( &temp1->static_caps.caps) )
+                       {
+                               /* using existing caps */
+                               static_caps = gst_caps_ref( &temp1->static_caps.caps );
+                       }
+                       else
+                       {
+                               /* create one */
+                               static_caps = gst_caps_from_string ( temp1->static_caps.string );
+                       }
+
+                       res = gst_caps_intersect(caps, static_caps);
+
+                       gst_caps_unref( static_caps );
+                       static_caps = NULL;
+
+                       if( res && !gst_caps_is_empty(res) )
+                       {
+                               GstElement *new_element;
+                               GList *elements = player->parsers;
+                               char *name_template = g_strdup(temp1->name_template);
+                               gchar *name_to_plug = GST_PLUGIN_FEATURE_NAME(factory);
+
+                               gst_caps_unref(res);
+
+                               debug_log("found %s to plug\n", name_to_plug);
+
+                               new_element = gst_element_factory_create(GST_ELEMENT_FACTORY(factory), NULL);
+                               if ( ! new_element )
+                               {
+                                       debug_error("failed to create element [%s]. continue with next.\n",
+                                               GST_PLUGIN_FEATURE_NAME (factory));
+
+                                       MMPLAYER_FREEIF(name_template);
+
+                                       continue;
+                               }
+
+                               /* check and skip it if it was already used. Otherwise, it can be an infinite loop
+                                * because parser can accept its own output as input.
+                                */
+                               if (g_strrstr(klass, "Parser"))
+                               {
+                                       gchar *selected = NULL;
+
+                                       for ( ; elements; elements = g_list_next(elements))
+                                       {
+                                               gchar *element_name = elements->data;
+
+                                               if (g_strrstr(element_name, name_to_plug))
+                                               {
+                                                       debug_log("but, %s already linked, so skipping it\n", name_to_plug);
+                                                       skip = TRUE;
+                                               }
+                                       }
+
+                                       if (skip) continue;
+
+                                       selected = g_strdup(name_to_plug);
+
+                                       player->parsers = g_list_append(player->parsers, selected);
+                               }
+
+                               /* store specific handles for futher control */
+                               if(g_strrstr(klass, "Demux") || g_strrstr(klass, "Parse"))
+                       {
+                                       /* FIXIT : first value will be overwritten if there's more
+                                        * than 1 demuxer/parser
+                                        */
+                                       debug_log("plugged element is demuxer. take it\n");
+                                       mainbin[MMPLAYER_M_DEMUX].id = MMPLAYER_M_DEMUX;
+                                       mainbin[MMPLAYER_M_DEMUX].gst = new_element;
+                               }
+                               else if(g_strrstr(klass, "Decoder") && __mmplayer_link_decoder(player,pad))
+                               {                                                                       
+                                   if(mainbin[MMPLAYER_M_DEC1].gst == NULL)
+                                   {
+                                               debug_log("plugged element is decoder. take it[MMPLAYER_M_DEC1]\n");
+                                               mainbin[MMPLAYER_M_DEC1].id = MMPLAYER_M_DEC1;
+                                               mainbin[MMPLAYER_M_DEC1].gst = new_element;
+                                   }
+                                   else if(mainbin[MMPLAYER_M_DEC2].gst == NULL)
+                                   {
+                                               debug_log("plugged element is decoder. take it[MMPLAYER_M_DEC2]\n");
+                                               mainbin[MMPLAYER_M_DEC2].id = MMPLAYER_M_DEC2;
+                                               mainbin[MMPLAYER_M_DEC2].gst = new_element;
+                                   }
+
+                                       /* NOTE : IF one codec is found, add it to supported_codec and remove from
+                                        * missing plugin. Both of them are used to check what's supported codec
+                                        * before returning result of play start. And, missing plugin should be
+                                        * updated here for multi track files.
+                                        */
+                                       if(g_str_has_prefix(mime, "video"))
+                                       {
+                                               GstPad *src_pad = NULL;
+                                               GstPadTemplate *pad_templ = NULL;
+                                               GstCaps *caps = NULL;
+                                               gchar *caps_type = NULL;
+                                                       
+                                               debug_log("found VIDEO decoder\n");
+                                               player->not_supported_codec &= MISSING_PLUGIN_AUDIO;
+                                               player->can_support_codec |= FOUND_PLUGIN_VIDEO;
+
+                                               src_pad = gst_element_get_static_pad (new_element, "src");
+                                               pad_templ = gst_pad_get_pad_template (src_pad);
+                                               caps = GST_PAD_TEMPLATE_CAPS(pad_templ);
+
+                                               caps_type = gst_caps_to_string(caps);
+
+                                               if ( g_strrstr( caps_type, "ST12") )
+                                                       player->is_nv12_tiled = TRUE;
+
+                                               /* clean */
+                                               MMPLAYER_FREEIF( caps_type );
+                                               gst_object_unref (src_pad);
+                                       }
+                                       else if (g_str_has_prefix(mime, "audio"))
+                                       {
+                                               debug_log("found AUDIO decoder\n");
+                                               player->not_supported_codec &= MISSING_PLUGIN_VIDEO;
+                                               player->can_support_codec |= FOUND_PLUGIN_AUDIO;
+                                       }
+                               }
+                               if ( ! __mmplayer_close_link(player, pad, new_element,
+                                           name_template,gst_element_factory_get_static_pad_templates(factory)) )
+                               {
+                                       if (player->keep_detecting_vcodec)
+                                               continue;
+
+                                       /* Link is failed even though a supportable codec is found. */
+                                       __mmplayer_check_not_supported_codec(player, (gchar *)mime);
+
+                                       MMPLAYER_FREEIF(name_template);
+                                       debug_error("failed to call _close_link\n");
+                                       return FALSE;
+                               }
+
+                               MMPLAYER_FREEIF(name_template);
+                               return TRUE;
+                       }
+
+                       gst_caps_unref(res);
+
+                       break;
+               }
+       }
+
+       /* There is no any found codec. */
+       __mmplayer_check_not_supported_codec(player,(gchar *)mime);
+
+       debug_error("failed to autoplug\n");
+
+       debug_fleave();
+       
+       return FALSE;
+
+
+ERROR:
+
+       /* release */
+       if ( queue )
+               gst_object_unref( queue );
+
+
+       if ( queue_pad )
+               gst_object_unref( queue_pad );
+
+       if ( element )
+               gst_object_unref ( element );
+
+       return FALSE;
+}
+
+
+static
+int __mmplayer_check_not_supported_codec(mm_player_t* player, gchar* mime)
+{
+       debug_fenter();
+
+       return_val_if_fail(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       return_val_if_fail ( mime, MM_ERROR_INVALID_ARGUMENT );
+
+       debug_log("mimetype to check: %s\n", mime );
+
+       /* add missing plugin */
+       /* NOTE : msl should check missing plugin for image mime type.
+        * Some motion jpeg clips can have playable audio track.
+        * So, msl have to play audio after displaying popup written video format not supported.
+        */
+       if ( !( player->pipeline->mainbin[MMPLAYER_M_DEMUX].gst ) )
+       {
+               if ( !( player->can_support_codec | player->videodec_linked | player->audiodec_linked ) )
+               {
+                       debug_log("not found demuxer\n");
+                       player->not_found_demuxer = TRUE;
+                       player->unlinked_demuxer_mime = g_strdup_printf ( "%s", mime );
+
+                       goto DONE;
+               }
+       }
+
+       if( ( g_str_has_prefix(mime, "video") ) ||( g_str_has_prefix(mime, "image") ) )
+       {
+               debug_log("can support codec=%d, vdec_linked=%d, adec_linked=%d\n",
+                       player->can_support_codec, player->videodec_linked, player->audiodec_linked);
+
+               /* check that clip have multi tracks or not */
+               if ( ( player->can_support_codec & FOUND_PLUGIN_VIDEO ) && ( player->videodec_linked ) )
+               {
+                       debug_log("video plugin is already linked\n");
+               }
+               else
+               {
+                       debug_warning("add VIDEO to missing plugin\n");
+                       player->not_supported_codec |= MISSING_PLUGIN_VIDEO;
+               }
+       }
+       else if ( g_str_has_prefix(mime, "audio") )
+       {
+               if ( ( player->can_support_codec & FOUND_PLUGIN_AUDIO ) && ( player->audiodec_linked ) )
+               {
+                       debug_log("audio plugin is already linked\n");
+               }
+               else
+               {
+                       debug_warning("add AUDIO to missing plugin\n");
+                       player->not_supported_codec |= MISSING_PLUGIN_AUDIO;
+               }
+       }
+
+DONE:
+       debug_fleave(); 
+
+       return MM_ERROR_NONE;
+}
+
+
+static void __mmplayer_pipeline_complete(GstElement *decodebin,  gpointer data) // @
+{
+    mm_player_t* player = (mm_player_t*)data;
+
+       debug_fenter();
+
+       return_if_fail( player );
+
+       /* remove fakesink */
+       if ( ! __mmplayer_gst_remove_fakesink( player,
+               &player->pipeline->mainbin[MMPLAYER_M_SRC_FAKESINK]) )
+       {
+               /* NOTE : __mmplayer_pipeline_complete() can be called several time. because
+                * signaling mechanism ( pad-added, no-more-pad, new-decoded-pad ) from various
+                * source element are not same. To overcome this situation, this function will called
+                * several places and several times. Therefore, this is not an error case.
+                */
+               return;
+       }
+       debug_log("pipeline has completely constructed\n");
+
+       player->pipeline_is_constructed = TRUE;
+       
+       if ( ( PLAYER_INI()->async_start ) &&
+               ( player->posted_msg == FALSE ) &&
+               ( player->cmd >= MMPLAYER_COMMAND_START ))
+       {
+               __mmplayer_post_missed_plugin( player );
+       }
+       
+       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-complete" );
+}
+
+static gboolean __mmplayer_configure_audio_callback(mm_player_t* player)
+{
+       debug_fenter();
+
+       return_val_if_fail ( player, FALSE );
+
+
+       if ( MMPLAYER_IS_STREAMING(player) )
+               return FALSE;
+
+       /* This callback can be set to music player only. */
+       if((player->can_support_codec & 0x02) == FOUND_PLUGIN_VIDEO)
+       {
+               debug_warning("audio callback is not supported for video");
+               return FALSE;
+       }
+
+       if (player->audio_stream_cb)
+       {
+               {
+                       GstPad *pad = NULL;
+
+                       pad = gst_element_get_static_pad (player->pipeline->audiobin[MMPLAYER_A_SINK].gst, "sink");
+
+                       if ( !pad )
+                       {
+                               debug_error("failed to get sink pad from audiosink to probe data\n");
+                               return FALSE;
+                       }
+
+                       player->audio_cb_probe_id = gst_pad_add_buffer_probe (pad,
+                               G_CALLBACK (__mmplayer_audio_stream_probe), player);
+
+                       gst_object_unref (pad);
+
+                       pad = NULL;
+              }
+       }
+       else
+       {
+               debug_error("There is no audio callback to configure.\n");
+               return FALSE;
+       }
+
+       debug_fleave(); 
+
+       return TRUE;
+}
+
+static void
+__mmplayer_init_factories(mm_player_t* player) // @
+{
+       debug_fenter();
+
+       return_if_fail ( player );
+
+       player->factories = gst_registry_feature_filter(gst_registry_get_default(),
+                                        (GstPluginFeatureFilter)__mmplayer_feature_filter, FALSE, NULL);
+
+       player->factories = g_list_sort(player->factories, (GCompareFunc)util_factory_rank_compare);
+
+       debug_fleave(); 
+}
+
+static void
+__mmplayer_release_factories(mm_player_t* player) // @
+{
+       debug_fenter();
+
+       return_if_fail ( player );
+
+       if (player->factories)
+       {
+               gst_plugin_feature_list_free (player->factories);
+               player->factories = NULL;
+       }
+
+       debug_fleave();
+}
+
+static void
+__mmplayer_release_misc(mm_player_t* player)
+{
+       int i;
+       debug_fenter();
+
+       return_if_fail ( player );
+
+       player->use_video_stream = FALSE;
+       player->video_stream_cb = NULL;
+       player->video_stream_cb_user_param = NULL;
+
+       player->audio_stream_cb = NULL;
+       player->audio_stream_cb_user_param = NULL;
+
+       player->audio_buffer_cb = NULL;
+       player->audio_buffer_cb_user_param = NULL;
+
+       player->sent_bos = FALSE;
+       player->playback_rate = DEFAULT_PLAYBACK_RATE;
+
+       player->doing_seek = FALSE;
+
+       player->streamer = NULL;
+       player->updated_bitrate_count = 0;
+       player->total_bitrate = 0;
+       player->updated_maximum_bitrate_count = 0;
+       player->total_maximum_bitrate = 0;
+
+       player->not_found_demuxer = 0;
+
+       player->last_position = 0;
+       player->duration = 0;
+       player->http_content_size = 0;
+       player->not_supported_codec = MISSING_PLUGIN_NONE;
+       player->can_support_codec = FOUND_PLUGIN_NONE;
+       player->need_update_content_dur = FALSE;
+       player->pending_seek.is_pending = FALSE;
+       player->pending_seek.format = MM_PLAYER_POS_FORMAT_TIME;
+       player->pending_seek.pos = 0;
+       player->posted_msg = FALSE;
+       player->has_many_types = FALSE;
+
+       for (i = 0; i < MM_PLAYER_STREAM_COUNT_MAX; i++)
+       {
+               player->bitrate[i] = 0;
+               player->maximum_bitrate[i] = 0;
+       }
+
+       /* clean found parsers */
+       if (player->parsers)
+       {
+               g_list_free(player->parsers);
+               player->parsers = NULL;
+       }
+
+       MMPLAYER_FREEIF(player->album_art);
+
+       /* free memory related to audio effect */
+       if(player->audio_effect_info.custom_ext_level_for_plugin)
+       {
+               free(player->audio_effect_info.custom_ext_level_for_plugin);
+       }
+
+       debug_fleave();
+}
+
+static GstElement *__mmplayer_element_create_and_link(mm_player_t *player, GstPad* pad, const char* name)
+{
+       GstElement *element = NULL;
+       GstPad *sinkpad;
+
+       debug_log("creating %s to plug\n", name);
+       
+       element = gst_element_factory_make(name, NULL);
+       if ( ! element )
+       {
+               debug_error("failed to create queue\n");
+               return NULL;
+       }
+
+       if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state(element, GST_STATE_READY) )
+       {
+               debug_error("failed to set state READY to %s\n", name);
+               return NULL;
+       }
+
+       if ( ! gst_bin_add(GST_BIN(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst), element))
+       {
+               debug_error("failed to add %s\n", name);
+               return NULL;
+       }
+
+       sinkpad = gst_element_get_static_pad(element, "sink");
+
+       if ( GST_PAD_LINK_OK != gst_pad_link(pad, sinkpad) )
+       {
+               debug_error("failed to link %s\n", name);
+               gst_object_unref (sinkpad);
+               
+               return NULL;
+       }
+
+       debug_log("linked %s to pipeline successfully\n", name);
+
+       gst_object_unref (sinkpad);
+
+       return element; 
+}
+
+static gboolean
+__mmplayer_close_link(mm_player_t* player, GstPad *srcpad, GstElement *sinkelement,
+const char *padname, const GList *templlist)
+{
+       GstPad *pad = NULL;
+       gboolean has_dynamic_pads = FALSE;
+       gboolean has_many_types = FALSE;        
+       const char *klass = NULL;
+       GstStaticPadTemplate *padtemplate = NULL;
+       GstElementFactory *factory = NULL;
+       GstElement* queue = NULL;
+       GstElement* parser = NULL;      
+       GstPad *pssrcpad = NULL;
+       GstPad *qsrcpad = NULL, *qsinkpad = NULL;
+       MMPlayerGstElement *mainbin = NULL;
+       GstStructure* str = NULL;
+       GstCaps* srccaps = NULL;
+       GstState warmup = GST_STATE_READY;
+       gboolean isvideo_decoder = FALSE;
+       guint q_max_size_time = 0;
+
+       debug_fenter();
+
+       return_val_if_fail ( player && 
+               player->pipeline && 
+               player->pipeline->mainbin, 
+               FALSE );
+
+       mainbin = player->pipeline->mainbin;
+
+       debug_log("plugging pad %s:%s to newly create %s:%s\n",
+                                       GST_ELEMENT_NAME( GST_PAD_PARENT ( srcpad ) ),
+                       GST_PAD_NAME( srcpad ),
+                       GST_ELEMENT_NAME( sinkelement ),
+                       padname);
+
+       factory = gst_element_get_factory(sinkelement);
+       klass = gst_element_factory_get_klass(factory);
+
+       /* check if player can do start continually */
+       MMPLAYER_CHECK_CMD_IF_EXIT(player);
+
+       if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state(sinkelement, warmup) )
+       {
+               if (isvideo_decoder)
+                       player->keep_detecting_vcodec = TRUE;
+
+               debug_error("failed to set %d state to %s\n", warmup, GST_ELEMENT_NAME( sinkelement ));
+               goto ERROR;
+       }
+
+       /* add to pipeline */
+       if ( ! gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), sinkelement) )
+       {
+               debug_error("failed to add %s to mainbin\n", GST_ELEMENT_NAME( sinkelement ));
+               goto ERROR;
+       }
+
+       debug_log("element klass : %s\n", klass);
+
+       /* added to support multi track files */
+       /* only decoder case and any of the video/audio still need to link*/
+       if(g_strrstr(klass, "Decoder") && __mmplayer_link_decoder(player,srcpad))
+       {
+               gchar *name = NULL;
+
+               name = g_strdup(GST_ELEMENT_NAME( GST_PAD_PARENT ( srcpad )));
+               
+               if (g_strrstr(name, "mpegtsdemux"))
+               {
+                       gchar *demux_caps = NULL;
+                       gchar *parser_name = NULL;
+                       GstCaps *dcaps = NULL;
+
+                       dcaps = gst_pad_get_caps(srcpad);
+                       demux_caps = gst_caps_to_string(dcaps);
+                       
+                       if (g_strrstr(demux_caps, "video/x-h264"))
+                       {
+                               parser_name = g_strdup("h264parse");
+                       }
+                       else if (g_strrstr(demux_caps, "video/mpeg"))
+                       {
+                               parser_name = g_strdup("mpeg4videoparse");
+                       }
+                       
+                       gst_caps_unref(dcaps);
+                       MMPLAYER_FREEIF( demux_caps );
+
+                       if (parser_name)
+                       {
+                               parser = __mmplayer_element_create_and_link(player, srcpad, parser_name);
+
+                               MMPLAYER_FREEIF(parser_name);
+                               
+                               if ( ! parser )
+                               {
+                                       debug_error("failed to create parser\n");
+                               }
+                               else
+                               {
+                                       /* update srcpad if parser is created */
+                                       pssrcpad = gst_element_get_static_pad(parser, "src");
+                                       srcpad = pssrcpad;
+                               }
+                       }
+               }
+               MMPLAYER_FREEIF(name);
+
+               queue = __mmplayer_element_create_and_link(player, srcpad, "queue"); // parser - queue or demuxer - queue
+               if ( ! queue )
+               {
+                       debug_error("failed to create queue\n");
+                       goto ERROR;
+               }
+
+               /* update srcpad to link with decoder */
+               qsrcpad = gst_element_get_static_pad(queue, "src");
+               srcpad = qsrcpad;
+
+               q_max_size_time = GST_QUEUE_DEFAULT_TIME;
+
+               /* assigning queue handle for futher manipulation purpose */
+               /* FIXIT : make it some kind of list so that msl can support more then two stream (text, data, etc...) */
+               if(mainbin[MMPLAYER_M_Q1].gst == NULL)
+               {
+                       mainbin[MMPLAYER_M_Q1].id = MMPLAYER_M_Q1;
+                       mainbin[MMPLAYER_M_Q1].gst = queue;
+
+                       g_object_set (G_OBJECT (mainbin[MMPLAYER_M_Q1].gst), "max-size-time", q_max_size_time * GST_SECOND, NULL);
+               }
+               else if(mainbin[MMPLAYER_M_Q2].gst == NULL)
+               {
+                       mainbin[MMPLAYER_M_Q2].id = MMPLAYER_M_Q2;
+                       mainbin[MMPLAYER_M_Q2].gst = queue;
+
+                       g_object_set (G_OBJECT (mainbin[MMPLAYER_M_Q2].gst), "max-size-time", q_max_size_time * GST_SECOND, NULL);
+               }
+               else
+               {
+                       debug_critical("Not supporting more then two elementary stream\n");
+                       g_assert(1);
+               }
+
+               pad = gst_element_get_static_pad(sinkelement, padname);
+
+               if ( ! pad )
+               {
+                       debug_warning("failed to get pad(%s) from %s. retrying with [sink]\n",
+                               padname, GST_ELEMENT_NAME(sinkelement) );
+
+                       pad = gst_element_get_static_pad(sinkelement, "sink");
+                       if ( ! pad )
+                       {
+                               debug_error("failed to get pad(sink) from %s. \n",
+                               GST_ELEMENT_NAME(sinkelement) );
+                               goto ERROR;
+                       }
+               }
+
+               /*  to check the video/audio type set the proper flag*/
+               {
+                       srccaps = gst_pad_get_caps( srcpad );
+                       if ( !srccaps )
+                               goto ERROR;
+
+                       str = gst_caps_get_structure( srccaps, 0 );
+                       if ( ! str )
+                               goto ERROR;
+
+                       name = gst_structure_get_name(str);
+                       if ( ! name )
+                               goto ERROR;
+               }
+
+               /* link queue and decoder. so, it will be queue - decoder. */
+               if ( GST_PAD_LINK_OK != gst_pad_link(srcpad, pad) )
+               {
+                       gst_object_unref(GST_OBJECT(pad));
+                       debug_error("failed to link (%s) to pad(%s)\n", GST_ELEMENT_NAME( sinkelement ), padname );
+
+                       /* reconstitute supportable codec */
+                       if (strstr(name, "video"))
+                       {
+                               player->can_support_codec ^= FOUND_PLUGIN_VIDEO;
+                       }
+                       else if (strstr(name, "audio"))
+                       {
+                               player->can_support_codec ^= FOUND_PLUGIN_AUDIO;
+                       }
+                       goto ERROR;
+               }
+
+               if (strstr(name, "video"))
+               {
+                       player->videodec_linked = 1;
+                       debug_msg("player->videodec_linked set to 1\n");
+
+               }
+               else if (strstr(name, "audio"))
+               {
+                       player->audiodec_linked = 1;
+                       debug_msg("player->auddiodec_linked set to 1\n");
+               }
+
+               gst_object_unref(GST_OBJECT(pad));
+               gst_caps_unref(GST_CAPS(srccaps));
+               srccaps = NULL;
+       }
+
+       if ( !MMPLAYER_IS_HTTP_PD(player) )
+       {
+               if( (g_strrstr(klass, "Demux") && !g_strrstr(klass, "Metadata")) || (g_strrstr(klass, "Parser") ) )
+               {
+                       if (MMPLAYER_IS_HTTP_STREAMING(player))
+                       {
+                               GstFormat fmt  = GST_FORMAT_BYTES;
+                               gint64 dur_bytes = 0L;
+                               gchar *file_buffering_path = NULL;
+                               gboolean use_file_buffer = FALSE;
+
+                               if ( !mainbin[MMPLAYER_M_S_BUFFER].gst)
+                               {
+                                       debug_log("creating http streaming buffering queue\n");
+
+                                       queue = gst_element_factory_make("queue2", "http_streaming_buffer");
+                                       if ( ! queue )
+                                       {
+                                               debug_critical ( "failed to create buffering queue element\n" );
+                                               goto ERROR;
+                                       }
+
+                                       if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state(queue, GST_STATE_READY) )
+                                       {
+                                               debug_error("failed to set state READY to buffering queue\n");
+                                               goto ERROR;
+                                       }
+
+                                       if ( !gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), queue) )
+                                       {
+                                               debug_error("failed to add buffering queue\n");
+                                               goto ERROR;
+                                       }
+
+                                       qsinkpad = gst_element_get_static_pad(queue, "sink");
+                                       qsrcpad = gst_element_get_static_pad(queue, "src");
+
+                                       if ( GST_PAD_LINK_OK != gst_pad_link(srcpad, qsinkpad) )
+                                       {
+                                               debug_error("failed to link buffering queue\n");
+                                               goto ERROR;
+                                       }
+                                       srcpad = qsrcpad;
+
+
+                                       mainbin[MMPLAYER_M_S_BUFFER].id = MMPLAYER_M_S_BUFFER;
+                                       mainbin[MMPLAYER_M_S_BUFFER].gst = queue;
+
+                                       if ( !MMPLAYER_IS_HTTP_LIVE_STREAMING(player))
+                                        {
+                                               if ( !gst_element_query_duration(player->pipeline->mainbin[MMPLAYER_M_SRC].gst, &fmt, &dur_bytes))
+                                                       debug_error("fail to get duration.\n");
+
+                                               if (dur_bytes>0)
+                                               {
+                                                       use_file_buffer = MMPLAYER_USE_FILE_FOR_BUFFERING(player);
+                                                       file_buffering_path = g_strdup(PLAYER_INI()->http_file_buffer_path);
+                                               }
+                                       }
+
+                                       __mm_player_streaming_set_buffer(player->streamer,
+                                               queue,
+                                               TRUE,
+                                               PLAYER_INI()->http_max_size_bytes,
+                                               1.0,
+                                               PLAYER_INI()->http_buffering_limit,
+                                               PLAYER_INI()->http_buffering_time,
+                                               use_file_buffer,
+                                               file_buffering_path,
+                                               dur_bytes);
+
+                                       MMPLAYER_FREEIF(file_buffering_path);
+                               }
+                       }
+               }
+       }
+       /* if it is not decoder or */
+       /* in decoder case any of the video/audio still need to link*/
+       if(!g_strrstr(klass, "Decoder"))
+       {
+
+               pad = gst_element_get_static_pad(sinkelement, padname);
+               if ( ! pad )
+               {
+                       debug_warning("failed to get pad(%s) from %s. retrying with [sink]\n",
+                                       padname, GST_ELEMENT_NAME(sinkelement) );
+
+                       pad = gst_element_get_static_pad(sinkelement, "sink");
+
+                       if ( ! pad )
+                       {
+                               debug_error("failed to get pad(sink) from %s. \n",
+                                       GST_ELEMENT_NAME(sinkelement) );
+                               goto ERROR;
+                       }
+               }
+
+               if ( GST_PAD_LINK_OK != gst_pad_link(srcpad, pad) )
+               {
+                       gst_object_unref(GST_OBJECT(pad));
+                       debug_error("failed to link (%s) to pad(%s)\n", GST_ELEMENT_NAME( sinkelement ), padname );
+                       goto ERROR;
+               }
+
+               gst_object_unref(GST_OBJECT(pad));
+       }
+
+       for(;templlist != NULL; templlist = templlist->next)
+       {
+               padtemplate = templlist->data;
+
+               debug_log ("director = [%d], presence = [%d]\n", padtemplate->direction, padtemplate->presence);
+
+               if(     padtemplate->direction != GST_PAD_SRC ||
+                       padtemplate->presence == GST_PAD_REQUEST        )
+                       continue;
+
+               switch(padtemplate->presence)
+               {
+                       case GST_PAD_ALWAYS:
+                       {
+                               GstPad *srcpad = gst_element_get_static_pad(sinkelement, "src");
+                               GstCaps *caps = gst_pad_get_caps(srcpad);
+
+                               /* Check whether caps has many types */
+                               if ( gst_caps_get_size (caps) > 1 && g_strrstr(klass, "Parser")) {
+                                       debug_log ("has_many_types for this caps [%s]\n", gst_caps_to_string(caps));
+                                       has_many_types = TRUE;
+                                       break;
+                               }
+
+                               if ( ! __mmplayer_try_to_plug(player, srcpad, caps) )
+                               {
+                                       gst_object_unref(GST_OBJECT(srcpad));
+                                       gst_caps_unref(GST_CAPS(caps));
+
+                                       debug_error("failed to plug something after %s\n", GST_ELEMENT_NAME( sinkelement ));
+                                       goto ERROR;
+                               }
+
+                               gst_caps_unref(GST_CAPS(caps));
+                               gst_object_unref(GST_OBJECT(srcpad));
+
+                       }
+                       break;
+
+
+                       case GST_PAD_SOMETIMES:
+                               has_dynamic_pads = TRUE;
+                       break;
+
+                       default:
+                               break;
+               }
+       }
+
+       /* check if player can do start continually */
+       MMPLAYER_CHECK_CMD_IF_EXIT(player);
+
+       if( has_dynamic_pads )
+       {
+               player->have_dynamic_pad = TRUE;
+               MMPLAYER_SIGNAL_CONNECT ( player, sinkelement, "pad-added",
+                       G_CALLBACK(__mmplayer_add_new_pad), player);
+
+               /* for streaming, more then one typefind will used for each elementary stream
+                * so this doesn't mean the whole pipeline completion
+                */
+               if ( ! MMPLAYER_IS_RTSP_STREAMING( player ) )
+               {
+                       MMPLAYER_SIGNAL_CONNECT( player, sinkelement, "no-more-pads",
+                               G_CALLBACK(__mmplayer_pipeline_complete), player);
+               }
+       }
+
+       if (has_many_types)
+       {
+               GstPad *pad = NULL;
+
+               player->has_many_types = has_many_types;
+               
+               pad = gst_element_get_static_pad(sinkelement, "src");
+               MMPLAYER_SIGNAL_CONNECT (player, pad, "notify::caps", G_CALLBACK(__mmplayer_add_new_caps), player);
+               gst_object_unref (GST_OBJECT(pad));
+       }
+
+
+       /* check if player can do start continually */
+       MMPLAYER_CHECK_CMD_IF_EXIT(player);
+
+       if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state(sinkelement, GST_STATE_PAUSED) )
+       {
+               debug_error("failed to set state PAUSED to %s\n", GST_ELEMENT_NAME( sinkelement ));
+               goto ERROR;
+       }
+
+       if ( queue )
+       {
+               if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state (queue, GST_STATE_PAUSED) )
+               {
+                       debug_error("failed to set state PAUSED to queue\n");
+                       goto ERROR;
+               }
+
+               queue = NULL;
+
+               gst_object_unref (GST_OBJECT(qsrcpad));
+               qsrcpad = NULL;
+       }
+
+       if ( parser )
+       {
+               if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state (parser, GST_STATE_PAUSED) )
+               {
+                       debug_error("failed to set state PAUSED to queue\n");
+                       goto ERROR;
+               }
+
+               parser = NULL;
+
+               gst_object_unref (GST_OBJECT(pssrcpad));
+               pssrcpad = NULL;
+       }
+
+       debug_fleave();
+
+       return TRUE;
+
+ERROR:
+
+       if ( queue )
+       {
+               gst_object_unref(GST_OBJECT(qsrcpad));
+
+               /* NOTE : Trying to dispose element queue0, but it is in READY instead of the NULL state.
+                * You need to explicitly set elements to the NULL state before
+                * dropping the final reference, to allow them to clean up.
+                */
+               gst_element_set_state(queue, GST_STATE_NULL);
+               /* And, it still has a parent "player".
+                * You need to let the parent manage the object instead of unreffing the object directly.
+                */
+
+               gst_bin_remove (GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), queue);
+               //gst_object_unref( queue );
+       }
+
+       if ( srccaps )
+               gst_caps_unref(GST_CAPS(srccaps));
+
+    return FALSE;
+}
+
+static gboolean __mmplayer_feature_filter(GstPluginFeature *feature, gpointer data) // @
+{
+       const gchar *klass;
+       //const gchar *name;
+
+       /* we only care about element factories */
+       if (!GST_IS_ELEMENT_FACTORY(feature))
+               return FALSE;
+
+       /* only parsers, demuxers and decoders */
+       klass = gst_element_factory_get_klass(GST_ELEMENT_FACTORY(feature));
+       //name = gst_element_factory_get_longname(GST_ELEMENT_FACTORY(feature));
+
+       if( g_strrstr(klass, "Demux") == NULL &&
+               g_strrstr(klass, "Codec/Decoder") == NULL &&
+               g_strrstr(klass, "Depayloader") == NULL &&
+               g_strrstr(klass, "Parse") == NULL)
+       {
+               return FALSE;
+       }
+    return TRUE;
+}
+
+
+static void    __mmplayer_add_new_caps(GstPad* pad, GParamSpec* unused, gpointer data)
+{
+       mm_player_t* player = (mm_player_t*) data;
+       GstCaps *caps = NULL;
+       GstStructure *str = NULL;
+       const char *name;
+
+       debug_fenter();
+
+       return_if_fail ( pad )
+       return_if_fail ( unused )
+       return_if_fail ( data )
+
+       caps = gst_pad_get_caps(pad);
+       if ( !caps )
+               return;
+       
+       str = gst_caps_get_structure(caps, 0);
+       if ( !str )
+               return;
+
+       name = gst_structure_get_name(str);
+       if ( !name )
+               return;
+       debug_log("name=%s\n", name);
+
+       if ( ! __mmplayer_try_to_plug(player, pad, caps) )
+       {
+               debug_error("failed to autoplug for type (%s)\n", name);
+               gst_caps_unref(caps);
+               return;
+       }
+
+       gst_caps_unref(caps);
+
+       __mmplayer_pipeline_complete( NULL, (gpointer)player );
+
+       debug_fleave(); 
+
+       return;
+}
+
+static void __mmplayer_set_unlinked_mime_type(mm_player_t* player, GstCaps *caps)
+{
+       GstStructure *str;
+       gint version = 0;
+       const char *stream_type;
+       gchar *version_field = NULL;
+
+       debug_fenter();
+
+       return_if_fail ( player );
+       return_if_fail ( caps );
+       
+       str = gst_caps_get_structure(caps, 0);
+       if ( !str )
+               return;
+       
+       stream_type = gst_structure_get_name(str);
+       if ( !stream_type )
+               return;
+
+
+       /* set unlinked mime type for downloadable codec */
+       if (g_str_has_prefix(stream_type, "video/"))
+       {       
+               if (g_str_has_prefix(stream_type, "video/mpeg")) 
+               {
+                       gst_structure_get_int (str, MM_PLAYER_MPEG_VNAME, &version);
+                       version_field = MM_PLAYER_MPEG_VNAME;
+               }
+               else if (g_str_has_prefix(stream_type, "video/x-wmv"))
+               {
+                       gst_structure_get_int (str, MM_PLAYER_WMV_VNAME, &version);
+                       version_field = MM_PLAYER_WMV_VNAME;
+                       
+               }
+               else if (g_str_has_prefix(stream_type, "video/x-divx"))
+               {
+                       gst_structure_get_int (str, MM_PLAYER_DIVX_VNAME, &version);
+                       version_field = MM_PLAYER_DIVX_VNAME;
+               }
+
+               if (version)
+               {
+                       player->unlinked_video_mime = g_strdup_printf("%s, %s=%d", stream_type, version_field, version);
+               }
+               else
+               {
+                       player->unlinked_video_mime = g_strdup_printf("%s", stream_type);
+               }
+       }
+       else if (g_str_has_prefix(stream_type, "audio/"))
+       {
+               if (g_str_has_prefix(stream_type, "audio/mpeg")) // mp3 or aac
+               {
+                       gst_structure_get_int (str, MM_PLAYER_MPEG_VNAME, &version);
+                       version_field = MM_PLAYER_MPEG_VNAME;
+               }
+               else if (g_str_has_prefix(stream_type, "audio/x-wma")) 
+               {
+                       gst_structure_get_int (str, MM_PLAYER_WMA_VNAME, &version);
+                       version_field = MM_PLAYER_WMA_VNAME;
+               }
+
+               if (version)
+               {
+                       player->unlinked_audio_mime = g_strdup_printf("%s, %s=%d", stream_type, version_field, version);
+               }
+               else
+               {
+                       player->unlinked_audio_mime = g_strdup_printf("%s", stream_type);
+               }
+       }
+
+       debug_fleave();
+}
+
+static void __mmplayer_add_new_pad(GstElement *element, GstPad *pad, gpointer data)
+{
+       mm_player_t* player = (mm_player_t*) data;
+       GstCaps *caps = NULL;
+       GstStructure *str = NULL;
+       const char *name;
+
+       debug_fenter();
+       return_if_fail ( player );
+       return_if_fail ( pad );
+
+       GST_OBJECT_LOCK (pad);
+       if ((caps = GST_PAD_CAPS(pad)))
+               gst_caps_ref(caps);
+       GST_OBJECT_UNLOCK (pad);
+
+       if ( NULL == caps )
+       {
+               caps = gst_pad_get_caps(pad);
+               if ( !caps ) return;
+       }
+
+       //MMPLAYER_LOG_GST_CAPS_TYPE(caps);
+       
+       str = gst_caps_get_structure(caps, 0);
+       if ( !str )
+               return;
+
+       name = gst_structure_get_name(str);
+       if ( !name )
+               return;
+
+       player->num_dynamic_pad++;
+       debug_log("stream count inc : %d\n", player->num_dynamic_pad);
+
+       /* Note : If the stream is the subtitle, we try not to play it. Just close the demuxer subtitle pad.
+         *     If want to play it, remove this code.
+         */
+       if (g_strrstr(name, "application"))
+       {
+               if (g_strrstr(name, "x-id3") || g_strrstr(name, "x-apetag"))
+               {
+                       /* If id3/ape tag comes, keep going */
+                       debug_log("application mime exception : id3/ape tag");
+               }
+               else
+               {
+                       /* Otherwise, we assume that this stream is subtile. */
+                       debug_log(" application mime type pad is closed.");
+                       return;
+               }
+       }
+       else if (g_strrstr(name, "audio"))
+       {
+               gint samplerate = 0, channels = 0;
+
+               /* set stream information */
+               /* if possible, set it here because the caps is not distrubed by resampler. */
+               gst_structure_get_int (str, "rate", &samplerate);
+               mm_attrs_set_int_by_name(player->attrs, "content_audio_samplerate", samplerate);
+
+               gst_structure_get_int (str, "channels", &channels);
+               mm_attrs_set_int_by_name(player->attrs, "content_audio_channels", channels);
+
+               debug_log("audio samplerate : %d        channels : %d", samplerate, channels);
+
+               /* validate all */
+               if (  mmf_attrs_commit ( player->attrs ) )
+               {
+                       debug_error("failed to update attributes");
+                       return;
+               }
+       }
+       else if (g_strrstr(name, "video"))
+       {
+               gint stype;
+               mm_attrs_get_int_by_name (player->attrs, "display_surface_type", &stype);
+
+               /* don't make video because of not required */
+               if (stype == MM_DISPLAY_SURFACE_NULL)
+               {
+                       debug_log("no video because it's not required");
+                       return;
+               }
+
+               player->v_stream_caps = gst_caps_copy(caps); //if needed, video caps is required when videobin is created
+       }
+
+       if ( ! __mmplayer_try_to_plug(player, pad, caps) )
+       {
+               debug_error("failed to autoplug for type (%s)", name);
+
+               __mmplayer_set_unlinked_mime_type(player, caps);
+       }
+
+       gst_caps_unref(caps);
+
+       debug_fleave();
+       return;
+}
+
+/* test API for tuning audio gain. this API should be
+ * deprecated before the day of final release
+ */
+int
+_mmplayer_set_volume_tune(MMHandleType hplayer, MMPlayerVolumeType volume)
+{
+       mm_player_t* player = (mm_player_t*) hplayer;
+       gint error = MM_ERROR_NONE;
+       gint vol_max = 0;
+       gboolean isMidi = FALSE;
+       gint i = 0;
+
+       debug_fenter();
+
+       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail( player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED )
+
+       debug_log("clip type=%d(1-midi, 0-others), volume [L]=%d:[R]=%d\n",
+               player->profile.play_mode, volume.level[0], volume.level[1]);
+
+       isMidi = ( player->profile.play_mode == MM_PLAYER_MODE_MIDI ) ? TRUE : FALSE;
+
+       if ( isMidi )
+               vol_max = 1000;
+       else
+               vol_max = 100;
+
+       /* is it proper volume level? */
+       for (i = 0; i < MM_VOLUME_CHANNEL_NUM; ++i)
+       {
+               if (volume.level[i] < 0 || volume.level[i] > vol_max) {
+                       debug_log("Invalid Volume level!!!! \n");
+                       return MM_ERROR_INVALID_ARGUMENT;
+               }
+       }
+
+       if ( isMidi )
+       {
+               if ( player->pipeline->mainbin )
+               {
+                       GstElement *midi_element = player->pipeline->mainbin[MMPLAYER_M_DEMUX].gst;
+
+                       if ( midi_element && ( strstr(GST_ELEMENT_NAME(midi_element), "midiparse")) )
+                       {
+                               debug_log("setting volume (%d) level to midi plugin\n", volume.level[0]);
+
+                               g_object_set(midi_element, "volume", volume.level[0], NULL);
+                       }
+               }
+       }
+       else
+       {
+               if ( player->pipeline->audiobin )
+               {
+                       GstElement *sink_element = player->pipeline->audiobin[MMPLAYER_A_SINK].gst;
+
+                       /* Set to Avsysaudiosink element */
+                       if ( sink_element )
+                       {
+                               gint vol_value = 0;
+                               gboolean mute = FALSE;
+                               vol_value = volume.level[0];
+
+                               g_object_set(G_OBJECT(sink_element), "tuningvolume", vol_value, NULL);
+
+                               mute = (vol_value == 0)? TRUE:FALSE;
+
+                               g_object_set(G_OBJECT(sink_element), "mute", mute, NULL);
+                       }
+
+               }
+       }
+
+       debug_fleave();
+
+       return error;
+}
+
+gboolean
+__mmplayer_dump_pipeline_state( mm_player_t* player )
+{
+       GstIterator*iter = NULL;
+       gboolean done = FALSE;
+
+       GstElement *item = NULL;
+       GstElementFactory *factory = NULL;
+
+       GstState state = GST_STATE_VOID_PENDING;
+       GstState pending = GST_STATE_VOID_PENDING;
+       GstClockTime time = 200*GST_MSECOND;
+
+       debug_fenter();
+
+       return_val_if_fail ( player &&
+               player->pipeline &&
+               player->pipeline->mainbin,
+               FALSE );
+
+
+       iter = gst_bin_iterate_recurse(GST_BIN(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst) );
+
+       if ( iter != NULL )
+       {
+               while (!done) {
+                        switch ( gst_iterator_next (iter, (gpointer)&item) )
+                        {
+                          case GST_ITERATOR_OK:
+                               gst_element_get_state(GST_ELEMENT (item),&state, &pending,time);
+
+                               factory = gst_element_get_factory (item) ;
+                                debug_error("%s:%s : From:%s To:%s   refcount : %d\n", GST_OBJECT_NAME(factory) , GST_ELEMENT_NAME(item) ,
+                                       gst_element_state_get_name(state), gst_element_state_get_name(pending) , GST_OBJECT_REFCOUNT_VALUE(item));
+
+
+                                gst_object_unref (item);
+                                break;
+                          case GST_ITERATOR_RESYNC:
+                                gst_iterator_resync (iter);
+                                break;
+                          case GST_ITERATOR_ERROR:
+                                done = TRUE;
+                                break;
+                          case GST_ITERATOR_DONE:
+                                done = TRUE;
+                                break;
+                        }
+               }
+       }
+
+       item = GST_ELEMENT(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst);
+
+       gst_element_get_state(GST_ELEMENT (item),&state, &pending,time);
+
+       factory = gst_element_get_factory (item) ;
+
+       debug_error("%s:%s : From:%s To:%s  refcount : %d\n",
+               GST_OBJECT_NAME(factory),
+               GST_ELEMENT_NAME(item),
+               gst_element_state_get_name(state),
+               gst_element_state_get_name(pending),
+               GST_OBJECT_REFCOUNT_VALUE(item) );
+
+       if ( iter )
+               gst_iterator_free (iter);
+
+       debug_fleave();
+
+       return FALSE;
+}
+
+
+gboolean
+__mmplayer_check_subtitle( mm_player_t* player )
+{
+       MMHandleType attrs = 0;
+       char *subtitle_uri = NULL;
+
+       debug_fenter();
+
+       return_val_if_fail( player, FALSE );
+
+       /* get subtitle attribute */
+       attrs = MMPLAYER_GET_ATTRS(player);
+       if ( !attrs )
+               return FALSE;
+
+       mm_attrs_get_string_by_name(attrs, "subtitle_uri", &subtitle_uri);
+       if ( !subtitle_uri || !strlen(subtitle_uri))
+               return FALSE;
+
+       debug_log ("subtite uri is %s[%d]\n", subtitle_uri, strlen(subtitle_uri));
+
+       debug_fleave();
+
+       return TRUE;
+}
+
+static gboolean
+__mmplayer_can_extract_pcm( mm_player_t* player )
+{
+       MMHandleType attrs = 0;
+       gboolean is_drm = FALSE;
+       gboolean sound_extraction = FALSE;
+
+       debug_fenter();
+
+       return_val_if_fail ( player, FALSE );
+
+       attrs = MMPLAYER_GET_ATTRS(player);
+       if ( !attrs )
+       {
+               debug_error("fail to get attributes.");
+               return FALSE;
+       }
+       
+       /* check file is drm or not */
+       g_object_get(G_OBJECT(player->pipeline->mainbin[MMPLAYER_M_SRC].gst), "is-drm", &is_drm, NULL);
+
+       /* get sound_extraction property */
+       mm_attrs_get_int_by_name(attrs, "pcm_extraction", &sound_extraction);
+
+       if ( ! sound_extraction || is_drm )
+       {
+               debug_log("pcm extraction param.. is drm = %d, extraction mode = %d", is_drm, sound_extraction);
+               return FALSE;
+       }
+
+       debug_fleave();
+
+       return TRUE;
+}
+
+static gboolean
+__mmplayer_handle_gst_error ( mm_player_t* player, GstMessage * message, GError* error )
+{
+       MMMessageParamType msg_param;
+       gchar *msg_src_element;
+
+       debug_fenter();
+
+       return_val_if_fail( player, FALSE );
+       return_val_if_fail( error, FALSE );
+
+       /* NOTE : do somthing necessary inside of __gst_handle_XXX_error. not here */
+
+       memset (&msg_param, 0, sizeof(MMMessageParamType));
+
+       if ( error->domain == GST_CORE_ERROR )
+       {
+               msg_param.code = __gst_handle_core_error( player, error->code );
+       }
+       else if ( error->domain == GST_LIBRARY_ERROR )
+       {
+               msg_param.code = __gst_handle_library_error( player, error->code );
+       }
+       else if ( error->domain == GST_RESOURCE_ERROR )
+       {
+               msg_param.code = __gst_handle_resource_error( player, error->code );
+       }
+       else if ( error->domain == GST_STREAM_ERROR )
+       {
+               msg_param.code = __gst_handle_stream_error( player, error, message );
+       }
+       else
+       {
+               debug_warning("This error domain is not defined.\n");
+
+               /* we treat system error as an internal error */
+               msg_param.code = MM_ERROR_PLAYER_INVALID_STREAM;
+       }
+
+       if ( message->src )
+       {
+               msg_src_element = GST_ELEMENT_NAME( GST_ELEMENT_CAST( message->src ) );
+
+               msg_param.data = (void *) error->message;
+
+               debug_error("-Msg src : [%s]    Domain : [%s]   Error : [%s]  Code : [%d] is tranlated to error code : [0x%x]\n",
+                       msg_src_element, g_quark_to_string (error->domain), error->message, error->code, msg_param.code);
+       }
+
+       /* post error to application */
+       if ( ! player->posted_msg )
+       {
+               if (msg_param.code == MM_MESSAGE_DRM_NOT_AUTHORIZED )
+               {
+                       MMPLAYER_POST_MSG( player, MM_MESSAGE_DRM_NOT_AUTHORIZED, NULL );
+               }
+               else
+               {
+                       MMPLAYER_POST_MSG( player, MM_MESSAGE_ERROR, &msg_param );
+               }
+
+               /* don't post more if one was sent already */
+               player->posted_msg = TRUE;
+       }
+       else
+       {
+               debug_log("skip error post because it's sent already.\n");
+       }
+
+       debug_fleave();
+
+       return TRUE;
+}
+
+static gboolean
+__mmplayer_handle_streaming_error  ( mm_player_t* player, GstMessage * message )
+{
+       debug_log("\n");
+       MMMessageParamType msg_param;
+       gchar *msg_src_element = NULL;
+       GstStructure *s = NULL;
+       guint error_id = 0;
+       gchar *error_string = NULL;
+
+       debug_fenter();
+
+       return_val_if_fail ( player, FALSE );
+       return_val_if_fail ( message, FALSE );
+
+       s = malloc( sizeof(GstStructure) );
+       memcpy ( s, gst_message_get_structure ( message ), sizeof(GstStructure));
+
+       if ( !gst_structure_get_uint (s, "error_id", &error_id) )
+               error_id = MMPLAYER_STREAMING_ERROR_NONE;
+
+       switch ( error_id )
+       {
+               case MMPLAYER_STREAMING_ERROR_UNSUPPORTED_AUDIO:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_UNSUPPORTED_AUDIO;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_UNSUPPORTED_VIDEO:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_UNSUPPORTED_VIDEO;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_CONNECTION_FAIL:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_CONNECTION_FAIL;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_DNS_FAIL:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_DNS_FAIL;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_SERVER_DISCONNECTED:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_SERVER_DISCONNECTED;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_BAD_SERVER:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_BAD_SERVER;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_INVALID_PROTOCOL:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_INVALID_PROTOCOL;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_INVALID_URL:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_INVALID_URL;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_UNEXPECTED_MSG:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_UNEXPECTED_MSG;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_OUT_OF_MEMORIES:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_OUT_OF_MEMORIES;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_RTSP_TIMEOUT:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_RTSP_TIMEOUT;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_BAD_REQUEST:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_BAD_REQUEST;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_NOT_AUTHORIZED:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_NOT_AUTHORIZED;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_PAYMENT_REQUIRED:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_PAYMENT_REQUIRED;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_FORBIDDEN:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_FORBIDDEN;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_CONTENT_NOT_FOUND:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_CONTENT_NOT_FOUND;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_METHOD_NOT_ALLOWED:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_METHOD_NOT_ALLOWED;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_NOT_ACCEPTABLE:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_NOT_ACCEPTABLE;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_PROXY_AUTHENTICATION_REQUIRED:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_PROXY_AUTHENTICATION_REQUIRED;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_SERVER_TIMEOUT:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_SERVER_TIMEOUT;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_GONE:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_GONE;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_LENGTH_REQUIRED:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_LENGTH_REQUIRED;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_PRECONDITION_FAILED:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_PRECONDITION_FAILED;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_REQUEST_ENTITY_TOO_LARGE:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_REQUEST_ENTITY_TOO_LARGE;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_REQUEST_URI_TOO_LARGE:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_REQUEST_URI_TOO_LARGE;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_UNSUPPORTED_MEDIA_TYPE:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_UNSUPPORTED_MEDIA_TYPE;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_PARAMETER_NOT_UNDERSTOOD:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_PARAMETER_NOT_UNDERSTOOD;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_CONFERENCE_NOT_FOUND:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_CONFERENCE_NOT_FOUND;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_NOT_ENOUGH_BANDWIDTH:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_NOT_ENOUGH_BANDWIDTH;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_NO_SESSION_ID:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_NO_SESSION_ID;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_METHOD_NOT_VALID_IN_THIS_STATE:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_METHOD_NOT_VALID_IN_THIS_STATE;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_HEADER_FIELD_NOT_VALID_FOR_SOURCE:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_HEADER_FIELD_NOT_VALID_FOR_SOURCE;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_INVALID_RANGE:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_INVALID_RANGE;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_PARAMETER_IS_READONLY:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_PARAMETER_IS_READONLY;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_AGGREGATE_OP_NOT_ALLOWED:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_AGGREGATE_OP_NOT_ALLOWED;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_ONLY_AGGREGATE_OP_ALLOWED:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_ONLY_AGGREGATE_OP_ALLOWED;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_BAD_TRANSPORT:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_BAD_TRANSPORT;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_DESTINATION_UNREACHABLE:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_DESTINATION_UNREACHABLE;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_INTERNAL_SERVER_ERROR:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_INTERNAL_SERVER_ERROR;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_NOT_IMPLEMENTED:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_NOT_IMPLEMENTED;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_BAD_GATEWAY:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_BAD_GATEWAY;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_SERVICE_UNAVAILABLE:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_SERVICE_UNAVAILABLE;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_GATEWAY_TIME_OUT:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_GATEWAY_TIME_OUT;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_RTSP_VERSION_NOT_SUPPORTED:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_RTSP_VERSION_NOT_SUPPORTED;
+                       break;
+               case MMPLAYER_STREAMING_ERROR_OPTION_NOT_SUPPORTED:
+                       msg_param.code = MM_ERROR_PLAYER_STREAMING_OPTION_NOT_SUPPORTED;
+                       break;
+               default:
+                       return MM_ERROR_PLAYER_STREAMING_FAIL;
+       }
+
+       error_string = g_strdup(gst_structure_get_string (s, "error_string"));
+       if ( error_string )
+               msg_param.data = (void *) error_string;
+
+       if ( message->src )
+       {
+               msg_src_element = GST_ELEMENT_NAME( GST_ELEMENT_CAST( message->src ) );
+
+               debug_error("-Msg src : [%s] Code : [%x] Error : [%s]  \n",
+                       msg_src_element, msg_param.code, (char*)msg_param.data );
+       }
+
+       /* post error to application */
+       if ( ! player->posted_msg )
+       {
+               MMPLAYER_POST_MSG( player, MM_MESSAGE_ERROR, &msg_param );
+
+               /* don't post more if one was sent already */
+               player->posted_msg = TRUE;
+       }
+       else
+       {
+               debug_log("skip error post because it's sent already.\n");
+       }
+
+       debug_fleave();
+
+       return TRUE;
+
+}
+
+static gint
+__gst_handle_core_error( mm_player_t* player, int code )
+{
+       gint trans_err = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       switch ( code )
+       {
+               case GST_CORE_ERROR_STATE_CHANGE:
+               case GST_CORE_ERROR_MISSING_PLUGIN:
+               case GST_CORE_ERROR_SEEK:
+               case GST_CORE_ERROR_NOT_IMPLEMENTED:
+               case GST_CORE_ERROR_FAILED:
+               case GST_CORE_ERROR_TOO_LAZY:
+               case GST_CORE_ERROR_PAD:
+               case GST_CORE_ERROR_THREAD:
+               case GST_CORE_ERROR_NEGOTIATION:
+               case GST_CORE_ERROR_EVENT:
+               case GST_CORE_ERROR_CAPS:
+               case GST_CORE_ERROR_TAG:
+               case GST_CORE_ERROR_CLOCK:
+               case GST_CORE_ERROR_DISABLED:
+               default:
+                       trans_err = MM_ERROR_PLAYER_INVALID_STREAM;
+               break;
+       }
+
+       debug_fleave();
+
+       return trans_err;
+}
+
+static gint
+__gst_handle_library_error( mm_player_t* player, int code )
+{
+       gint trans_err = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       switch ( code )
+       {
+               case GST_LIBRARY_ERROR_FAILED:
+               case GST_LIBRARY_ERROR_TOO_LAZY:
+               case GST_LIBRARY_ERROR_INIT:
+               case GST_LIBRARY_ERROR_SHUTDOWN:
+               case GST_LIBRARY_ERROR_SETTINGS:
+               case GST_LIBRARY_ERROR_ENCODE:
+               default:
+                       trans_err =  MM_ERROR_PLAYER_INVALID_STREAM;
+               break;
+       }
+       
+       debug_fleave();
+
+       return trans_err;
+}
+
+
+static gint
+__gst_handle_resource_error( mm_player_t* player, int code )
+{
+       gint trans_err = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       switch ( code )
+       {
+               case GST_RESOURCE_ERROR_NO_SPACE_LEFT:
+                       trans_err = MM_ERROR_PLAYER_NO_FREE_SPACE;
+                       break;
+               case GST_RESOURCE_ERROR_NOT_FOUND:
+               case GST_RESOURCE_ERROR_OPEN_READ:
+                       if ( MMPLAYER_IS_HTTP_STREAMING(player) || MMPLAYER_IS_HTTP_LIVE_STREAMING ( player ) )
+                       {
+                               trans_err = MM_ERROR_PLAYER_STREAMING_CONNECTION_FAIL;
+                               break;
+                       }
+               case GST_RESOURCE_ERROR_READ:
+                       if ( MMPLAYER_IS_HTTP_STREAMING(player) ||  MMPLAYER_IS_HTTP_LIVE_STREAMING ( player ))
+                       {
+                               trans_err = MM_ERROR_PLAYER_STREAMING_FAIL;
+                               break;
+                       }
+               case GST_RESOURCE_ERROR_SEEK:
+               case GST_RESOURCE_ERROR_FAILED:
+               case GST_RESOURCE_ERROR_TOO_LAZY:
+               case GST_RESOURCE_ERROR_BUSY:
+               case GST_RESOURCE_ERROR_OPEN_WRITE:
+               case GST_RESOURCE_ERROR_OPEN_READ_WRITE:
+               case GST_RESOURCE_ERROR_CLOSE:
+               case GST_RESOURCE_ERROR_WRITE:
+               case GST_RESOURCE_ERROR_SYNC:
+               case GST_RESOURCE_ERROR_SETTINGS:
+               default:
+                       trans_err = MM_ERROR_PLAYER_FILE_NOT_FOUND;
+               break;
+       }
+
+       debug_fleave();
+
+       return trans_err;
+}
+
+
+static gint
+__gst_handle_stream_error( mm_player_t* player, GError* error, GstMessage * message )
+{
+       gint trans_err = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail( error, MM_ERROR_INVALID_ARGUMENT );
+       return_val_if_fail ( message, MM_ERROR_INVALID_ARGUMENT );
+
+       switch ( error->code )
+       {
+               case GST_STREAM_ERROR_FAILED:
+               case GST_STREAM_ERROR_TYPE_NOT_FOUND:
+               case GST_STREAM_ERROR_DECODE:
+               case GST_STREAM_ERROR_WRONG_TYPE:
+               case GST_STREAM_ERROR_DECRYPT:
+               case GST_STREAM_ERROR_DECRYPT_NOKEY:
+                        trans_err = __gst_transform_gsterror( player, message, error );
+               break;
+
+               case GST_STREAM_ERROR_CODEC_NOT_FOUND:
+               case GST_STREAM_ERROR_NOT_IMPLEMENTED:
+               case GST_STREAM_ERROR_TOO_LAZY:
+               case GST_STREAM_ERROR_ENCODE:
+               case GST_STREAM_ERROR_DEMUX:
+               case GST_STREAM_ERROR_MUX:
+               case GST_STREAM_ERROR_FORMAT:
+               default:
+                       trans_err = MM_ERROR_PLAYER_INVALID_STREAM;
+               break;
+       }
+
+       debug_fleave();
+
+       return trans_err;
+}
+
+
+/* NOTE : decide gstreamer state whether there is some playable track or not. */
+static gint
+__gst_transform_gsterror( mm_player_t* player, GstMessage * message, GError* error )
+{
+       gchar *src_element_name = NULL;
+       GstElement *src_element = NULL;
+       GstElementFactory *factory = NULL;
+       const gchar* klass = NULL;
+       
+       debug_fenter();
+
+       /* FIXIT */
+       return_val_if_fail ( message, MM_ERROR_INVALID_ARGUMENT );
+       return_val_if_fail ( message->src, MM_ERROR_INVALID_ARGUMENT );
+       return_val_if_fail ( error, MM_ERROR_INVALID_ARGUMENT );
+
+       src_element = GST_ELEMENT_CAST(message->src);
+       if ( !src_element )
+               goto INTERNAL_ERROR;
+       
+       src_element_name = GST_ELEMENT_NAME(src_element);
+       if ( !src_element_name )
+               goto INTERNAL_ERROR;
+
+       factory = gst_element_get_factory(src_element);
+       if ( !factory )
+               goto INTERNAL_ERROR;
+       
+       klass = gst_element_factory_get_klass(factory);
+       if ( !klass )
+               goto INTERNAL_ERROR;
+
+       debug_log("error code=%d, msg=%s, src element=%s, class=%s\n", 
+                       error->code, error->message, src_element_name, klass);
+
+
+       switch ( error->code )
+       {
+               case GST_STREAM_ERROR_DECODE:
+               {
+                       /* NOTE : Delay is needed because gst callback is sometime sent
+                        * before completing autoplugging.
+                        * Timer is more better than usleep.
+                        * But, transformed msg value should be stored in player handle
+                        * for function to call by timer.
+                        */
+                       if ( PLAYER_INI()->async_start )
+                               usleep(500000);
+
+                       /* Demuxer can't parse one track because it's corrupted.
+                        * So, the decoder for it is not linked.
+                        * But, it has one playable track.
+                        */
+                       if ( g_strrstr(klass, "Demux") )
+                       {
+                               if ( player->can_support_codec == FOUND_PLUGIN_VIDEO )
+                               {
+                                       return MM_ERROR_PLAYER_AUDIO_CODEC_NOT_FOUND;
+                               }
+                               else if ( player->can_support_codec == FOUND_PLUGIN_AUDIO )
+                               {
+                                       return MM_ERROR_PLAYER_VIDEO_CODEC_NOT_FOUND;
+                               }
+                               else
+                               {
+                                       if ( player->pipeline->audiobin ) // PCM
+                                       {
+                                               return MM_ERROR_PLAYER_VIDEO_CODEC_NOT_FOUND;
+                                       }
+                                       else
+                                       {
+                                               goto CODEC_NOT_FOUND;
+                                       }
+                               }
+                       }
+                       return MM_ERROR_PLAYER_INVALID_STREAM;
+               }
+               break;
+
+               case GST_STREAM_ERROR_WRONG_TYPE:
+               {
+                       return MM_ERROR_PLAYER_NOT_SUPPORTED_FORMAT;
+               }
+               break;
+
+               case GST_STREAM_ERROR_FAILED:
+               {
+                       /* Decoder Custom Message */
+                       if ( strstr(error->message, "ongoing") )
+                       {
+                               if ( strcasestr(klass, "audio") )
+                               {
+                                       if ( ( player->can_support_codec & FOUND_PLUGIN_VIDEO ) )
+                                       {
+                                               debug_log("Video can keep playing.\n");
+                                               return MM_ERROR_PLAYER_AUDIO_CODEC_NOT_FOUND;
+                                       }
+                                       else
+                                       {
+                                               goto CODEC_NOT_FOUND;
+                                       }
+
+                               }
+                               else if ( strcasestr(klass, "video") )
+                               {
+                                       if ( ( player->can_support_codec & FOUND_PLUGIN_AUDIO ) )
+                                       {
+                                               debug_log("Audio can keep playing.\n");
+                                               return MM_ERROR_PLAYER_VIDEO_CODEC_NOT_FOUND;
+                                       }
+                                       else
+                                       {
+                                               goto CODEC_NOT_FOUND;
+                                       }
+                               }
+                       }
+                       return MM_ERROR_PLAYER_INVALID_STREAM;
+               }
+               break;
+
+               case GST_STREAM_ERROR_TYPE_NOT_FOUND:
+               {                               
+                       goto CODEC_NOT_FOUND;
+               }
+               break;
+
+               case GST_STREAM_ERROR_DECRYPT:
+               case GST_STREAM_ERROR_DECRYPT_NOKEY:
+               {
+                       debug_error("decryption error, [%s] failed, reason : [%s]\n", src_element_name, error->message);
+                       return MM_MESSAGE_DRM_NOT_AUTHORIZED;
+               }
+               break;
+
+               default:
+               break;
+       }
+
+       debug_fleave();
+
+       return MM_ERROR_PLAYER_INVALID_STREAM;
+
+INTERNAL_ERROR:
+       return MM_ERROR_PLAYER_INTERNAL;
+
+CODEC_NOT_FOUND:
+       debug_log("not found any available codec. Player should be destroyed.\n");
+       return MM_ERROR_PLAYER_CODEC_NOT_FOUND;
+}
+
+static void
+__mmplayer_post_delayed_eos( mm_player_t* player, int delay_in_ms )
+{
+       debug_fenter();
+
+       return_if_fail( player );
+
+       /* cancel if existing */
+       __mmplayer_cancel_delayed_eos( player );
+
+
+       /* post now if delay is zero */
+       if ( delay_in_ms == 0 || player->is_sound_extraction)
+       {
+               debug_log("eos delay is zero. posting EOS now\n");
+               MMPLAYER_POST_MSG( player, MM_MESSAGE_END_OF_STREAM, NULL );
+
+               if ( player->is_sound_extraction )
+                       __mmplayer_cancel_delayed_eos(player);
+
+               return;
+       }
+
+       /* init new timeout */
+       /* NOTE : consider give high priority to this timer */
+
+       debug_log("posting EOS message after [%d] msec\n", delay_in_ms);
+       player->eos_timer = g_timeout_add( delay_in_ms,
+               __mmplayer_eos_timer_cb, player );
+
+
+       /* check timer is valid. if not, send EOS now */
+       if ( player->eos_timer == 0 )
+       {
+               debug_warning("creating timer for delayed EOS has failed. sending EOS now\n");
+               MMPLAYER_POST_MSG( player, MM_MESSAGE_END_OF_STREAM, NULL );
+       }
+
+       debug_fleave();
+}
+
+static void
+__mmplayer_cancel_delayed_eos( mm_player_t* player )
+{
+       debug_fenter();
+
+       return_if_fail( player );
+
+       if ( player->eos_timer )
+       {
+               g_source_remove( player->eos_timer );
+       }
+
+       player->eos_timer = 0;
+
+       debug_fleave();
+
+       return;
+}
+
+static gboolean
+__mmplayer_eos_timer_cb(gpointer u_data)
+{
+       mm_player_t* player = NULL;
+       player = (mm_player_t*) u_data;
+
+       debug_fenter();
+
+       return_val_if_fail( player, FALSE );
+
+       /* posting eos */
+       MMPLAYER_POST_MSG( player, MM_MESSAGE_END_OF_STREAM, NULL );
+
+       /* cleare timer id */
+       player->eos_timer = 0;
+
+       debug_fleave();
+
+       /* we are returning FALSE as we need only one posting */
+       return FALSE;
+}
+
+static void __mmplayer_set_antishock( mm_player_t* player, gboolean disable_by_force)
+{
+       gint antishock = FALSE;
+       MMHandleType attrs = 0;
+
+       debug_fenter();
+
+       return_if_fail ( player && player->pipeline );
+
+       /* It should be passed for video only clip */
+       if ( ! player->pipeline->audiobin )
+               return;
+
+       if ( ( g_strrstr(PLAYER_INI()->name_of_audiosink, "avsysaudiosink")) )
+       {
+               attrs = MMPLAYER_GET_ATTRS(player);
+               if ( ! attrs )
+               {
+                       debug_error("fail to get attributes.\n");
+                       return;
+               }
+
+               mm_attrs_get_int_by_name(attrs, "sound_fadeup", &antishock);
+
+               debug_log("setting antishock as (%d)\n", antishock);
+
+               if ( disable_by_force )
+               {
+                       debug_log("but, antishock is disabled by force when is seeked\n");
+
+                       antishock = FALSE;
+               }
+
+               g_object_set(G_OBJECT(player->pipeline->audiobin[MMPLAYER_A_SINK].gst), "fadeup", antishock, NULL);
+       }
+
+       debug_fleave();
+
+       return;
+}
+
+
+static gboolean
+__mmplayer_link_decoder( mm_player_t* player, GstPad *srcpad)
+{
+       const gchar* name = NULL;
+       GstStructure* str = NULL;
+       GstCaps* srccaps = NULL;
+
+       debug_fenter();
+
+       return_val_if_fail( player, FALSE );
+       return_val_if_fail ( srcpad, FALSE );
+
+       /* to check any of the decoder (video/audio) need to be linked  to parser*/
+       srccaps = gst_pad_get_caps( srcpad );
+       if ( !srccaps )
+               goto ERROR;
+
+       str = gst_caps_get_structure( srccaps, 0 );
+       if ( ! str )
+               goto ERROR;
+
+       name = gst_structure_get_name(str);
+       if ( ! name )
+               goto ERROR;
+
+       if (strstr(name, "video"))
+       {
+               if(player->videodec_linked)
+               {
+                   debug_msg("Video decoder already linked\n");
+                       return FALSE;
+               }
+       }
+       if (strstr(name, "audio"))
+       {
+               if(player->audiodec_linked)
+               {
+                   debug_msg("Audio decoder already linked\n");
+                       return FALSE;
+               }
+       }
+
+       gst_caps_unref( srccaps );
+
+       debug_fleave();
+
+       return TRUE;
+
+ERROR:
+       if ( srccaps )
+               gst_caps_unref( srccaps );
+
+       return FALSE;
+}
+
+static gboolean
+__mmplayer_link_sink( mm_player_t* player , GstPad *srcpad)
+{
+       const gchar* name = NULL;
+       GstStructure* str = NULL;
+       GstCaps* srccaps = NULL;
+
+       debug_fenter();
+
+       return_val_if_fail ( player, FALSE );
+       return_val_if_fail ( srcpad, FALSE );
+
+       /* to check any of the decoder (video/audio) need to be linked  to parser*/
+       srccaps = gst_pad_get_caps( srcpad );
+       if ( !srccaps )
+               goto ERROR;
+
+       str = gst_caps_get_structure( srccaps, 0 );
+       if ( ! str )
+               goto ERROR;
+
+       name = gst_structure_get_name(str);
+       if ( ! name )
+               goto ERROR;
+
+       if (strstr(name, "video"))
+       {
+               if(player->videosink_linked)
+               {
+                       debug_msg("Video Sink already linked\n");
+                       return FALSE;
+               }
+       }
+       if (strstr(name, "audio"))
+       {
+               if(player->audiosink_linked)
+               {
+                       debug_msg("Audio Sink already linked\n");
+                       return FALSE;
+               }
+       }
+       if (strstr(name, "text"))
+       {
+               if(player->textsink_linked)
+               {
+                       debug_msg("Text Sink already linked\n");
+                       return FALSE;
+               }
+       }
+
+       gst_caps_unref( srccaps );
+
+       debug_fleave();
+
+       return TRUE;
+       //return (!player->videosink_linked || !player->audiosink_linked);
+
+ERROR:
+       if ( srccaps )
+               gst_caps_unref( srccaps );
+
+       return FALSE;
+}
+
+
+/* sending event to one of sinkelements */
+static gboolean
+__gst_send_event_to_sink( mm_player_t* player, GstEvent* event )
+{
+       GstEvent * event2 = NULL;
+       GList *sinks = NULL;
+       gboolean res = FALSE;
+
+       debug_fenter();
+       
+       return_val_if_fail( player, FALSE );
+       return_val_if_fail ( event, FALSE );
+
+       if ( player->play_subtitle && !player->use_textoverlay)
+               event2 = gst_event_copy((const GstEvent *)event);
+
+       sinks = player->sink_elements;
+       while (sinks)
+       {
+               GstElement *sink = GST_ELEMENT_CAST (sinks->data);
+
+               if (GST_IS_ELEMENT(sink))
+               {
+                       /* keep ref to the event */
+                       gst_event_ref (event);
+
+                       if ( (res = gst_element_send_event (sink, event)) )
+                       {
+                               debug_log("sending event[%s] to sink element [%s] success!\n",
+                                       GST_EVENT_TYPE_NAME(event), GST_ELEMENT_NAME(sink) );
+                               break;
+                       }
+
+                       debug_log("sending event[%s] to sink element [%s] failed. try with next one.\n",
+                               GST_EVENT_TYPE_NAME(event), GST_ELEMENT_NAME(sink) );
+               }
+
+               sinks = g_list_next (sinks);
+       }
+
+       /* Note : Textbin is not linked to the video or audio bin.
+        *              It needs to send the event to the text sink seperatelly.
+        */
+        if ( player->play_subtitle && !player->use_textoverlay)
+        {
+               GstElement *text_sink = GST_ELEMENT_CAST (player->pipeline->textbin[MMPLAYER_T_SINK].gst);
+
+               if (GST_IS_ELEMENT(text_sink))
+               {
+                       /* keep ref to the event */
+                       gst_event_ref (event2);
+
+                       if ( (res != gst_element_send_event (text_sink, event2)) )
+                       {
+                               debug_error("sending event[%s] to subtitle sink element [%s] failed!\n",
+                                       GST_EVENT_TYPE_NAME(event2), GST_ELEMENT_NAME(text_sink) );
+                       }
+                       else
+                       {
+                               debug_log("sending event[%s] to subtitle sink element [%s] success!\n",
+                                       GST_EVENT_TYPE_NAME(event2), GST_ELEMENT_NAME(text_sink) );
+                       }
+
+                       gst_event_unref (event2);
+               }
+        }
+
+       gst_event_unref (event);
+
+       debug_fleave();
+
+       return res;
+}
+
+static void
+__mmplayer_add_sink( mm_player_t* player, GstElement* sink )
+{
+       debug_fenter();
+
+       return_if_fail ( player );
+       return_if_fail ( sink );
+
+       player->sink_elements =
+               g_list_append(player->sink_elements, sink);
+
+       debug_fleave();
+}
+
+static void
+__mmplayer_del_sink( mm_player_t* player, GstElement* sink )
+{
+       debug_fenter();
+
+       return_if_fail ( player );
+       return_if_fail ( sink );
+
+       player->sink_elements =
+                       g_list_remove(player->sink_elements, sink);
+
+       debug_fleave();
+}
+
+static gboolean
+__gst_seek(mm_player_t* player, GstElement * element, gdouble rate,
+                       GstFormat format, GstSeekFlags flags, GstSeekType cur_type,
+                       gint64 cur, GstSeekType stop_type, gint64 stop )
+{
+       GstEvent* event = NULL;
+       gboolean result = FALSE;
+
+       debug_fenter();
+       
+       return_val_if_fail( player, FALSE );
+
+       event = gst_event_new_seek (rate, format, flags, cur_type,
+               cur, stop_type, stop);
+
+       result = __gst_send_event_to_sink( player, event );
+
+       debug_fleave();
+
+       return result;
+}
+
+/* NOTE : be careful with calling this api. please refer to below glib comment
+ * glib comment : Note that there is a bug in GObject that makes this function much
+ * less useful than it might seem otherwise. Once gobject is disposed, the callback
+ * will no longer be called, but, the signal handler is not currently disconnected.
+ * If the instance is itself being freed at the same time than this doesn't matter,
+ * since the signal will automatically be removed, but if instance persists,
+ * then the signal handler will leak. You should not remove the signal yourself
+ * because in a future versions of GObject, the handler will automatically be
+ * disconnected.
+ *
+ * It's possible to work around this problem in a way that will continue to work
+ * with future versions of GObject by checking that the signal handler is still
+ * connected before disconnected it:
+ *
+ *  if (g_signal_handler_is_connected (instance, id))
+ *    g_signal_handler_disconnect (instance, id);
+ */
+static void
+__mmplayer_release_signal_connection(mm_player_t* player)
+{
+       GList* sig_list = player->signals;
+       MMPlayerSignalItem* item = NULL;
+
+       debug_fenter();
+       
+       return_if_fail( player );
+
+       for ( ; sig_list; sig_list = sig_list->next )
+       {
+               item = sig_list->data;
+
+               if ( item && item->obj && GST_IS_ELEMENT(item->obj) )
+               {
+                       debug_log("checking signal connection : [%lud] from [%s]\n", item->sig, GST_OBJECT_NAME( item->obj ));
+
+                       if ( g_signal_handler_is_connected ( item->obj, item->sig ) )
+                       {
+                               debug_log("signal disconnecting : [%lud] from [%s]\n", item->sig, GST_OBJECT_NAME( item->obj ));
+                               g_signal_handler_disconnect ( item->obj, item->sig );
+                       }
+               }
+
+               MMPLAYER_FREEIF( item );
+
+       }
+       g_list_free ( player->signals );
+       player->signals = NULL;
+
+       debug_fleave();
+
+       return;
+}
+
+
+/* Note : if silent is true, then subtitle would not be displayed. :*/
+int _mmplayer_set_subtitle_silent (MMHandleType hplayer, int silent)
+{
+       mm_player_t* player = (mm_player_t*) hplayer;
+
+       debug_fenter();
+
+       /* check player handle */
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       player->is_subtitle_off = silent;
+
+       debug_log("subtitle is %s.\n", player->is_subtitle_off ? "ON" : "OFF");
+
+       debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+
+int _mmplayer_get_subtitle_silent (MMHandleType hplayer, int* silent)
+{
+       mm_player_t* player = (mm_player_t*) hplayer;
+
+       debug_fenter();
+
+       /* check player handle */
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       *silent = player->is_subtitle_off;
+
+       debug_log("subtitle is %s.\n", silent ? "ON" : "OFF");
+
+       debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+int _mmplayer_get_track_count(MMHandleType hplayer,  MMPlayerTrackType track_type, int *count)
+{
+       mm_player_t* player = (mm_player_t*) hplayer;
+       MMHandleType attrs = 0;
+       int ret = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       /* check player handle */
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       return_val_if_fail(count, MM_ERROR_COMMON_INVALID_ARGUMENT);
+       return_val_if_fail((MMPLAYER_CURRENT_STATE(player) != MM_PLAYER_STATE_PAUSED)
+                ||(MMPLAYER_CURRENT_STATE(player) != MM_PLAYER_STATE_PLAYING),
+               MM_ERROR_PLAYER_INVALID_STATE);
+
+       attrs = MMPLAYER_GET_ATTRS(player);
+       if ( !attrs )
+       {
+               debug_error("cannot get content attribute");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       switch (track_type)
+       {
+               case MM_PLAYER_TRACK_TYPE_AUDIO:
+                       ret = mm_attrs_get_int_by_name(attrs, "content_audio_track_num", count);
+                       break;
+               case MM_PLAYER_TRACK_TYPE_VIDEO:
+                       ret = mm_attrs_get_int_by_name(attrs, "content_video_track_num", count);
+                       break;
+               case MM_PLAYER_TRACK_TYPE_TEXT:
+                       ret = mm_attrs_get_int_by_name(attrs, "content_text_track_num", count);
+                       break;
+               default:
+                       ret = MM_ERROR_COMMON_INVALID_ARGUMENT;
+                       break;
+       }
+
+       debug_log ("%d track num is %d\n", track_type, *count);
+
+       debug_fleave();
+
+       return ret;
+}
+
+
+
+const gchar * 
+__get_state_name ( int state )
+{
+       switch ( state )
+       {
+               case MM_PLAYER_STATE_NULL:
+                       return "NULL";
+               case MM_PLAYER_STATE_READY:
+                       return "READY";
+               case MM_PLAYER_STATE_PAUSED:
+                       return "PAUSED";
+               case MM_PLAYER_STATE_PLAYING:
+                       return "PLAYING";
+               case MM_PLAYER_STATE_NONE:
+                       return "NONE";
+               default:
+                       return "INVAID";
+       }
+}
+gboolean
+__is_rtsp_streaming ( mm_player_t* player )
+{
+       return_val_if_fail ( player, FALSE );
+
+       return ( player->profile.uri_type == MM_PLAYER_URI_TYPE_URL_RTSP ) ? TRUE : FALSE;
+}
+
+static gboolean
+__is_http_streaming ( mm_player_t* player )
+{
+       return_val_if_fail ( player, FALSE );
+
+       return ( player->profile.uri_type == MM_PLAYER_URI_TYPE_URL_HTTP ) ? TRUE : FALSE;
+}
+
+static gboolean
+__is_streaming ( mm_player_t* player )
+{
+       return_val_if_fail ( player, FALSE );
+
+       return ( __is_rtsp_streaming ( player ) || __is_http_streaming ( player ) || __is_http_live_streaming ( player )) ? TRUE : FALSE;
+}
+
+gboolean
+__is_live_streaming ( mm_player_t* player )
+{
+       return_val_if_fail ( player, FALSE );
+
+       return ( __is_rtsp_streaming ( player ) && player->streaming_type == STREAMING_SERVICE_LIVE ) ? TRUE : FALSE;
+}
+
+static gboolean
+__is_http_live_streaming( mm_player_t* player )
+{
+       return_val_if_fail( player, FALSE );
+
+       return ( player->profile.uri_type == MM_PLAYER_URI_TYPE_HLS ) ? TRUE : FALSE;
+}
+
+static gboolean
+__is_http_progressive_down(mm_player_t* player)
+{
+       return_val_if_fail( player, FALSE );
+
+       return ((player->pd_mode) ? TRUE:FALSE);
+}
diff --git a/src/mm_player_streaming.c b/src/mm_player_streaming.c
new file mode 100644 (file)
index 0000000..3f76b87
--- /dev/null
@@ -0,0 +1,433 @@
+/*
+ * libmm-player
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YeJin Cho <cho.yejin@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>
+ *
+ * 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 <sys/vfs.h>
+#include "mm_player_utils.h"
+
+#include "mm_player_streaming.h"
+
+static void streaming_set_buffer_size(mm_player_streaming_t* streamer, guint buffer_size);
+static void streaming_set_buffer_percent(mm_player_streaming_t* streamer, gdouble low_percent, gdouble high_percent);
+static void streaming_set_buffer_type (mm_player_streaming_t* streamer, gboolean use_file, gchar * file_path, guint64 content_size);
+static void streaming_set_buffering_time(mm_player_streaming_t* streamer, gdouble buffering_time);
+
+
+mm_player_streaming_t *
+__mm_player_streaming_create ()
+{
+       mm_player_streaming_t *streamer = NULL;
+
+       debug_fenter();
+
+       streamer = (mm_player_streaming_t *) malloc (sizeof (mm_player_streaming_t));
+       if (!streamer)
+       {
+               debug_error ("fail to create streaming player handle..\n");
+               return NULL;
+       }
+
+       debug_fleave();
+
+       return streamer;
+}
+
+void __mm_player_streaming_initialize (mm_player_streaming_t* streamer)
+{
+       debug_fenter();
+
+       streamer->buffer = NULL;
+       streamer->buffer_size = DEFAULT_BUFFER_SIZE;
+       streamer->buffer_low_percent = DEFAULT_BUFFER_LOW_PERCENT;
+       streamer->buffer_high_percent = DEFAULT_BUFFER_HIGH_PERCENT;
+       streamer->buffer_avg_bitrate = 0;
+       streamer->buffer_max_bitrate = 0;
+       streamer->need_update = FALSE;
+
+       streamer->is_buffering = FALSE;
+       streamer->buffering_percent = -1;
+       streamer->buffering_time = DEFAULT_BUFFERING_TIME;
+
+       debug_fleave();
+
+       return;
+}
+
+void __mm_player_streaming_deinitialize (mm_player_streaming_t* streamer)
+{
+       debug_fenter();
+
+       return_if_fail(streamer);
+
+       streamer->buffer_size = DEFAULT_BUFFER_SIZE;
+       streamer->buffer_low_percent = DEFAULT_BUFFER_LOW_PERCENT;
+       streamer->buffer_high_percent = DEFAULT_BUFFER_HIGH_PERCENT;
+       streamer->buffer_avg_bitrate = 0;
+       streamer->buffer_max_bitrate = 0;
+       streamer->need_update = FALSE;
+
+       streamer->is_buffering = FALSE;
+       streamer->buffering_percent = -1;
+       streamer->buffering_time = DEFAULT_BUFFERING_TIME;
+
+       debug_fleave();
+
+       return;
+}
+
+void __mm_player_streaming_destroy (mm_player_streaming_t* streamer)
+{
+       debug_fenter();
+
+       if(streamer)
+       {
+               g_free (streamer);
+               streamer = NULL;
+       }
+
+       debug_fleave();
+
+       return;
+}
+
+void __mm_player_streaming_set_buffer(mm_player_streaming_t* streamer, GstElement * buffer,
+       gboolean use_buffering, guint buffer_size, gdouble low_percent, gdouble high_percent, gdouble buffering_time,
+       gboolean use_file, gchar * file_path, guint64 content_size)
+{
+       debug_fenter();
+
+       return_if_fail(streamer);
+
+       if (buffer)
+       {
+               streamer->buffer = buffer;
+
+               debug_log("buffer element is %s.", GST_ELEMENT_NAME(buffer));
+
+               g_object_set ( G_OBJECT (streamer->buffer), "use-buffering", use_buffering, NULL );
+       }
+
+       streaming_set_buffer_size(streamer, buffer_size);
+       streaming_set_buffer_percent(streamer, low_percent, high_percent);
+       streaming_set_buffer_type (streamer, use_file, file_path, content_size);
+       streaming_set_buffering_time(streamer, buffering_time);
+
+       debug_fleave();
+
+       return;
+}
+
+void __mm_player_streaming_set_content_bitrate(mm_player_streaming_t* streamer, guint max_bitrate, guint avg_bitrate)
+{
+       debug_fenter();
+
+       return_if_fail(streamer);
+
+       /* Note : Update buffering criterion bytes
+         *      1. maximum bitrate is considered first.
+         *      2. average bitrage * 3 is next.
+         *      3. if there are no updated bitrate, use default buffering limit.
+         */
+        if (max_bitrate > 0 && streamer->buffer_max_bitrate != max_bitrate)
+        {
+              debug_log("set maximum bitrate(%dbps).\n", max_bitrate);
+              streamer->buffer_max_bitrate = max_bitrate;
+
+               streamer->need_update = TRUE;
+        }
+
+        if (avg_bitrate > 0 && streamer->buffer_avg_bitrate != avg_bitrate)
+       {
+              debug_log("set averate bitrate(%dbps).\n", avg_bitrate);
+              streamer->buffer_avg_bitrate = avg_bitrate;
+
+               streamer->need_update = TRUE;
+       }
+
+       debug_fleave();
+
+       return;
+}
+
+static void
+streaming_set_buffer_size(mm_player_streaming_t* streamer, guint buffer_size)
+{
+       debug_fenter();
+
+       return_if_fail(streamer);
+       return_if_fail(buffer_size>0);
+
+       debug_log("set buffer size to %d.", buffer_size);
+
+       streamer->buffer_size = buffer_size;
+
+       if (streamer->buffer)
+               g_object_set (G_OBJECT(streamer->buffer), "max-size-bytes", buffer_size, NULL);
+
+       debug_fleave();
+
+       return;
+}
+
+static void
+streaming_set_buffer_percent(mm_player_streaming_t* streamer, gdouble low_percent, gdouble high_percent)
+{
+       gdouble buffer_low_percent = DEFAULT_BUFFER_LOW_PERCENT;
+       gdouble buffer_high_percent = DEFAULT_BUFFER_HIGH_PERCENT;
+
+       debug_fenter();
+
+       return_if_fail(streamer);
+
+       if (low_percent <= MIN_BUFFER_PERCENT || low_percent >= MAX_BUFFER_PERCENT)
+       {
+               debug_warning("buffer low percent is out of range. use defaut value.");
+               buffer_low_percent = DEFAULT_BUFFER_LOW_PERCENT;
+       }
+       else
+       {
+               buffer_low_percent = low_percent;
+       }
+
+       if (high_percent  <=  MIN_BUFFER_PERCENT || high_percent  >=  MAX_BUFFER_PERCENT)
+       {
+               debug_warning("buffer high percent is out of range. use defaut value.");
+               buffer_high_percent = DEFAULT_BUFFER_HIGH_PERCENT;
+       }
+       else
+       {
+               buffer_high_percent = high_percent;
+       }
+
+       if (buffer_high_percent <= buffer_low_percent)
+               buffer_high_percent =  buffer_low_percent + 1.0;
+
+       debug_log("set buffer percent to %2.3f ~ %2.3f.",  streamer->buffer_low_percent, streamer->buffer_high_percent);
+
+       if (streamer->buffer)
+       {
+               if ( streamer->buffer_low_percent != buffer_low_percent )
+                       g_object_set (G_OBJECT(streamer->buffer), "low-percent", streamer->buffer_low_percent, NULL);
+
+               if ( streamer->buffer_high_percent != buffer_high_percent )
+                       g_object_set (G_OBJECT(streamer->buffer), "high-percent", streamer->buffer_high_percent, NULL);
+       }
+
+       streamer->buffer_low_percent = buffer_low_percent;
+       streamer->buffer_high_percent = buffer_high_percent;
+
+       debug_fleave();
+
+       return;
+}
+
+static void
+streaming_set_buffering_time(mm_player_streaming_t* streamer, gdouble buffering_time)
+{
+       gdouble buffer_buffering_time = DEFAULT_BUFFERING_TIME;
+
+       debug_fenter();
+
+       return_if_fail(streamer);
+
+       if (buffering_time < MIN_BUFFERING_TIME)
+               buffer_buffering_time = MIN_BUFFERING_TIME;
+       else if (buffering_time > MAX_BUFFERING_TIME)
+               buffer_buffering_time = MAX_BUFFERING_TIME;
+       else
+               buffer_buffering_time = buffering_time;
+
+       if (streamer->buffering_time != buffer_buffering_time)
+       {
+               debug_log("set buffer buffering time from %2.1f to %2.1f.", streamer->buffering_time, buffer_buffering_time);
+
+               streamer->buffering_time = buffer_buffering_time;
+       }
+
+       debug_fleave();
+
+       return;
+}
+
+static void
+streaming_set_buffer_type (mm_player_streaming_t* streamer, gboolean use_file, gchar * file_path, guint64 content_size)
+{
+       guint64 storage_available_size = 0L; //bytes
+       guint64 file_buffer_size = 0L;  //bytes
+       gchar file_buffer_name[MAX_FILE_BUFFER_NAME_LEN] = {0};
+       struct statfs buf = {0};
+
+       debug_fenter();
+
+       return_if_fail(streamer && streamer->buffer);
+
+       if (!use_file)
+       {
+               debug_log("use memory for buffering. streaming is played on push-based. \n"
+                               "buffering position would not be updated.\n"
+                               "buffered data would be flushed after played.\n"
+                               "seeking and getting duration could be failed due to file format.");
+               return;
+       }
+
+       debug_log("use file for buffering. streaming is played on pull-based. \n");
+
+       if (!file_path || strlen(file_path) <= 0)
+               file_path = g_strdup(DEFAULT_FILE_BUFFER_PATH);
+
+       g_snprintf(file_buffer_name, MM_MAX_URL_LEN, "%s/XXXXXX", file_path);
+       debug_log("the buffering file name is %s.\n", file_buffer_name);
+
+       if (statfs((const char *)file_path, &buf) < 0)
+       {
+               debug_warning ("fail to get availabe storage capacity. just use file buffer.\n");
+               file_buffer_size = 0L;
+       }
+       else
+       {
+               storage_available_size = (guint64)buf.f_bavail * (guint64)buf.f_bsize; //bytes
+
+               debug_log ("the number of available blocks : %"G_GUINT64_FORMAT", the block size is %"G_GUINT64_FORMAT".\n",
+                       (guint64)buf.f_bavail, (guint64)buf.f_bsize);
+               debug_log ("calculated availabe storage size is %"G_GUINT64_FORMAT" Bytes.\n", storage_available_size);
+
+               if (content_size <= 0 || content_size >= storage_available_size)
+                       file_buffer_size = storage_available_size;
+               else
+                       file_buffer_size = 0L;
+       }
+
+       if (file_buffer_size>0)
+               debug_log("use file ring buffer for buffering.");
+
+       g_object_set (G_OBJECT(streamer->buffer), "temp-template", file_buffer_name, NULL);
+       g_object_set (G_OBJECT(streamer->buffer), "file-buffer-max-size", file_buffer_size, NULL);
+
+       debug_fleave();
+
+       return;
+}
+
+#define GET_BYTE_FROM_BIT(bit) (bit/8)
+void __mm_player_streaming_buffering(mm_player_streaming_t* streamer, GstMessage *buffering_msg)
+{
+       GstBufferingMode mode = GST_BUFFERING_STREAM;
+       gint byte_in_rate = 0;
+       gint byte_out_rate = 0;
+       gint64 buffering_left = -1;
+       gdouble buffering_time = DEFAULT_BUFFERING_TIME;
+       gdouble low_percent = 0.0;
+       gdouble high_percent = 0.0;
+       guint high_percent_byte = 0;
+       gint buffer_percent = 0;
+       guint buffer_criteria = 0;
+
+       return_if_fail ( streamer );
+       return_if_fail ( buffering_msg );
+       return_if_fail ( GST_IS_MESSAGE ( buffering_msg ) );
+       return_if_fail ( GST_MESSAGE_TYPE ( buffering_msg ) == GST_MESSAGE_BUFFERING );
+
+       /* update when buffering has started. */
+       if ( !streamer->is_buffering )
+       {
+               debug_log ( "buffering has started.\n" );
+
+               streamer->is_buffering = TRUE;
+               streamer->buffering_percent = -1;
+               streamer->need_update = TRUE;
+       }
+
+       /* update buffer percent */
+       gst_message_parse_buffering ( buffering_msg, &buffer_percent );
+
+       if ( streamer->buffering_percent < buffer_percent )
+       {
+               debug_log ( "buffering %d%%....\n", buffer_percent );
+               streamer->buffering_percent = buffer_percent;
+       }
+
+       if ( streamer->buffering_percent == MAX_BUFFER_PERCENT )
+       {
+               debug_log ( "buffering had done.\n" );
+               streamer->is_buffering = FALSE;
+       }
+
+       if (!streamer->need_update)
+       {
+               debug_log ( "don't need to update buffering stats during buffering.\n" );
+               return;
+       }
+
+        /* Note : Parse the buffering message to get the in/out throughput.
+         *     avg_in is the network throughput and avg_out is the consumed throughtput by the linkded element.
+         */
+       gst_message_parse_buffering_stats ( buffering_msg, &mode, &byte_in_rate, &byte_out_rate, &buffering_left );
+
+       if (streamer->buffer_max_bitrate > 0)
+       {
+               buffer_criteria = GET_BYTE_FROM_BIT(streamer->buffer_max_bitrate);
+               byte_out_rate = GET_BYTE_FROM_BIT(streamer->buffer_max_bitrate /3);
+       }
+       else if (streamer->buffer_avg_bitrate > 0)
+       {
+               buffer_criteria = GET_BYTE_FROM_BIT(streamer->buffer_avg_bitrate * 3);
+               byte_out_rate = GET_BYTE_FROM_BIT(streamer->buffer_avg_bitrate);
+       }
+
+       debug_log ( "in rate is %d, out rate is %d (bytes/sec).\n", byte_in_rate, byte_out_rate );
+
+       if ( byte_in_rate > 0  &&  byte_out_rate > 0)
+               buffering_time =  byte_out_rate / byte_in_rate;
+       else if (byte_in_rate <= 0 && byte_out_rate > 0)
+               buffering_time = MAX_BUFFERING_TIME;
+       else
+               buffering_time = DEFAULT_BUFFERING_TIME;
+
+       streaming_set_buffering_time(streamer, buffering_time);
+
+       /* calculate buffer low/high percent */
+       low_percent = DEFAULT_BUFFER_LOW_PERCENT;
+
+       if ( buffer_criteria > 0 )
+       {
+               high_percent_byte = buffer_criteria * streamer->buffering_time;
+               high_percent = ( (gdouble)high_percent_byte * 100.0 )  / (gdouble)streamer->buffer_size;
+       }
+       else
+       {
+               high_percent_byte = streamer->buffer_high_percent * streamer->buffer_size / 100;
+               high_percent= streamer->buffer_high_percent;
+       }
+
+       if ( streamer->buffer_size < high_percent_byte )
+       {
+               debug_log ( "buffer size[%d bytes] is smaller than high threshold[%d bytes]. update it. \n",
+                       streamer->buffer_size, high_percent_byte );
+
+               streaming_set_buffer_size(streamer, high_percent_byte * 1.1);
+       }
+
+       streaming_set_buffer_percent(streamer, low_percent, high_percent);
+
+       streamer->need_update = FALSE;
+
+       return;
+}
+
diff --git a/src/mm_player_utils.c b/src/mm_player_utils.c
new file mode 100644 (file)
index 0000000..261d7d4
--- /dev/null
@@ -0,0 +1,447 @@
+/*
+ * libmm-player
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YeJin Cho <cho.yejin@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>
+ *
+ * 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 <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unicode/ucsdet.h>
+
+#include <mm_debug.h>
+#include "mm_player_utils.h"
+
+bool util_exist_file_path(const char *file_path)
+{
+       debug_log("\n");
+
+       if (!file_path || !strlen(file_path))
+               return FALSE;
+
+       int res = access(file_path, R_OK);
+       if (res)
+               return FALSE;
+
+       return TRUE;
+}
+
+bool util_write_file_backup(const char *backup_path, char *data_ptr, int data_size)
+{
+       debug_log("\n");
+
+       FILE *fp = NULL;
+       int wsize = 0;
+
+       fp = fopen(backup_path, "wb");
+       if (!fp)
+               return FALSE;
+
+       wsize = fwrite(data_ptr, sizeof(char), data_size, fp);
+
+       fclose(fp);
+
+       if (wsize != data_size) {
+               if (!access(backup_path, R_OK))
+                       remove(backup_path);
+
+               debug_error("No space to write!\n");
+
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+bool util_remove_file_backup(const char *backup_path)
+{
+       debug_log("\n");
+
+       if (!backup_path || !strlen(backup_path))
+               return FALSE;
+
+       int res = access(backup_path, R_OK);
+       if (!res)
+       {
+               if (remove(backup_path) == -1)
+                       return FALSE;
+       }
+
+       return TRUE;
+}
+
+#define DETECTION_PREFIX_SIZE  20
+//bool util_is_midi_type_by_mem(void *mem, int size)
+int util_is_midi_type_by_mem(void *mem, int size)
+{
+       debug_log("\n");
+       
+       const char *p = (const char *)mem;
+
+       if (size < DETECTION_PREFIX_SIZE)
+               return MM_AUDIO_CODEC_INVALID;
+
+       /* mmf file detection */
+       if (p[0] == 'M' && p[1] == 'M' && p[2] == 'M' && p[3] == 'D') {
+               debug_log("MM_AUDIO_CODEC_MMF\n");
+               return MM_AUDIO_CODEC_MMF;
+       }
+
+       /* midi file detection */
+       if (p[0] == 'M' && p[1] == 'T' && p[2] == 'h' && p[3] == 'd') {
+               debug_log ("MM_AUDIO_CODEC_MIDI, %d\n", MM_AUDIO_CODEC_MIDI);
+               return MM_AUDIO_CODEC_MIDI;
+       }
+       /* mxmf file detection */
+       if (p[0] == 'X' && p[1] == 'M' && p[2] == 'F' && p[3] == '_') {
+               debug_log ("MM_AUDIO_CODEC_MXMF\n");
+               return MM_AUDIO_CODEC_MXMF;
+       }
+
+       /* wave file detection */
+       if (p[0] == 'R' && p[1] == 'I' && p[2] == 'F' && p[3] == 'F' &&
+               p[8] == 'W' && p[9] == 'A' && p[10] == 'V' && p[11] == 'E' &&
+               p[12] == 'f' && p[13] == 'm' && p[14] == 't') {
+               debug_log ("MM_AUDIO_CODEC_WAVE\n");
+               return MM_AUDIO_CODEC_WAVE;
+       }
+       /* i-melody file detection */
+       if (memcmp(p, "BEGIN:IMELODY", 13) == 0)
+       {
+               debug_log ("MM_AUDIO_CODEC_IMELODY\n");
+               return MM_AUDIO_CODEC_IMELODY;
+       }
+
+       return MM_AUDIO_CODEC_INVALID;
+}
+
+//bool util_is_midi_type_by_file(const char *file_path)
+int util_is_midi_type_by_file(const char *file_path)
+{
+       debug_log("\n");
+       
+       struct stat file_attrib;
+       FILE *fp = NULL;
+       char prefix[DETECTION_PREFIX_SIZE] = {0,};
+       int size;
+
+       if (!file_path)
+               return FALSE;
+
+       fp = fopen(file_path, "r");
+
+       if (!fp)
+       return FALSE;
+
+       memset(&file_attrib, 0, sizeof(file_attrib));
+
+       if (stat(file_path, &file_attrib) != 0)
+       {
+               fclose(fp);
+               return FALSE;
+       }
+
+       size = (int) file_attrib.st_size;
+
+       if (size < DETECTION_PREFIX_SIZE)
+       {
+               fclose(fp);
+               return FALSE;
+       }
+       
+       size = fread(prefix, sizeof(char), DETECTION_PREFIX_SIZE, fp);
+
+       fclose(fp);
+
+       return util_is_midi_type_by_mem(prefix, size);
+}
+
+/* messages are treated as warnings bcz those code should not be checked in. 
+ * and no error handling will supported for same manner. 
+ */
+gboolean 
+__util_gst_pad_probe(GstPad *pad, GstBuffer *buffer, gpointer u_data)
+{
+       gint flag = (gint) u_data;
+       GstElement* parent = NULL;
+       gboolean ret = TRUE;
+       
+       /* show name as default */
+       parent = (GstElement*)gst_object_get_parent(GST_OBJECT(pad));
+       debug_warning("PAD PROBE : %s:%s\n", GST_ELEMENT_NAME(parent), GST_PAD_NAME(pad));
+       
+       /* show time stamp */
+       if ( flag & MM_PROBE_TIMESTAMP )
+       {
+               debug_warning("ts : %u:%02u:%02u.%09u\n",  GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)));
+       }
+
+       /* show buffer size */
+       if ( flag & MM_PROBE_BUFFERSIZE )
+       {
+               debug_warning("buffer size : %ud\n", GST_BUFFER_SIZE(buffer));
+       }
+
+       /* show buffer duration */
+       if ( flag & MM_PROBE_BUFFER_DURATION )
+       {
+               debug_warning("dur : %lld\n", GST_BUFFER_DURATION(buffer));
+       }
+
+       /* show buffer caps */
+       if ( flag & MM_PROBE_CAPS )
+       {
+               debug_warning("caps : %s\n", gst_caps_to_string(GST_BUFFER_CAPS(buffer)));
+       }
+
+       /* drop buffer if flag is on */
+       if ( flag & MM_PROBE_DROP_BUFFER )
+       {
+               debug_warning("dropping\n");
+               ret = FALSE;
+       }
+               
+       /* show clock time */
+       if ( flag & MM_PROBE_CLOCK_TIME )
+       {
+               GstClock* clock = NULL;
+               GstClockTime now = GST_CLOCK_TIME_NONE;
+
+               clock = GST_ELEMENT_CLOCK ( parent );
+
+               if ( clock )
+               {
+                       now = gst_clock_get_time( clock );
+                       debug_warning("clock time : %" GST_TIME_FORMAT "\n", GST_TIME_ARGS( now ));
+               }
+       }
+
+       if ( parent )
+               gst_object_unref(parent);
+
+       return ret;
+}
+
+char** 
+util_get_cookie_list ( const char *cookies )
+{
+       char **cookie_list = NULL;
+       char *temp = NULL;
+       gint i = 0;
+
+       if ( !cookies || !strlen(cookies) )
+               return NULL;
+
+       debug_log("cookies : %d[bytes] - %s \n", strlen(cookies), cookies);
+
+       temp = g_strdup(cookies);
+
+       /* trimming. it works inplace */
+       g_strstrip(temp);
+
+       /* split */
+       cookie_list = g_strsplit(temp, ";", 100);
+
+       for ( i = 0; i < g_strv_length(cookie_list); i++ )
+       {
+               if ( cookie_list[i] && strlen(cookie_list[i]) )
+               {
+                       g_strstrip(cookie_list[i]);
+                       debug_log("cookie_list[%d] : %d[bytes] - %s \n", i, strlen(cookie_list[i]), cookie_list[i]);
+               }
+               else
+               {
+                       cookie_list[i][0]='\0';
+               }
+       }
+
+       if (temp)
+               g_free (temp);
+       temp=NULL;
+
+       return cookie_list;
+}
+
+bool util_check_valid_url ( const char *proxy )
+{
+       struct in_addr proxy_addr;
+       bool ret = TRUE;
+       
+       return_val_if_fail ( proxy, FALSE );
+       return_val_if_fail ( strlen(proxy), FALSE );
+
+       if ( inet_aton(proxy, &proxy_addr) != 0 )
+       {
+               debug_warning("invalid proxy is set. \n");
+               ret = FALSE;
+       }
+          
+       return ret;
+}
+
+/* check the given path is indicating sdp file */
+bool 
+util_is_sdp_file ( const char *path )
+{
+       gboolean ret = FALSE;
+       gchar* uri = NULL;
+       
+       debug_fenter();
+       
+       return_val_if_fail ( path, FALSE );
+
+       uri = g_ascii_strdown ( path, -1 );
+
+       if ( uri == -1)
+       {
+               return FALSE;
+       }
+
+       /* trimming */
+       g_strstrip( uri );
+
+       /* strlen(".sdp") == 4 */
+       if ( strlen( uri ) <= 4 )
+       {
+               debug_warning ( "path is too short.\n" );
+               return ret;
+       }
+
+       /* first, check extension name */
+       ret = g_str_has_suffix ( uri, "sdp" );
+
+       /* second, if no suffix is there, check it's contents */
+       if ( ! ret )
+       {
+               /* FIXIT : do it soon */
+               debug_warning("determining whether it's sdp or not with it's content is not implemented yet. ;)\n");
+       }
+
+       g_free( uri);
+       uri = NULL;
+
+       return ret;
+}
+
+int64_t 
+util_get_time ( void )
+{
+       struct timeval tv;
+       gettimeofday(&tv,NULL);
+       return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
+}
+
+int 
+util_get_rank_increase ( const char *factory_class )
+{
+       gint rank_pri_inc = 20;
+       gint rank_sec_inc = 10;
+       gint ret = 0;
+
+       if ( g_strrstr(factory_class,"Dsp") ) 
+               ret = rank_pri_inc;
+       else if ( g_strrstr(factory_class,"HW") ) 
+               ret = rank_pri_inc;
+       else if ( g_strrstr(factory_class,"Arm") )
+               ret = rank_sec_inc;
+
+       return ret;
+}
+
+int 
+util_factory_rank_compare(GstPluginFeature *f1, GstPluginFeature *f2) // @
+{
+       const gchar *klass;
+       int f1_rank_inc=0, f2_rank_inc=0;
+
+       klass = gst_element_factory_get_klass(GST_ELEMENT_FACTORY(f1));
+       f1_rank_inc = util_get_rank_increase ( klass );
+
+       klass = gst_element_factory_get_klass(GST_ELEMENT_FACTORY(f2));
+       f2_rank_inc = util_get_rank_increase ( klass );
+
+       return (gst_plugin_feature_get_rank(f2)+f2_rank_inc) - (gst_plugin_feature_get_rank(f1)+f1_rank_inc );
+}
+
+char*
+util_get_charset(const char *file_path)
+{
+       UCharsetDetector* ucsd;
+       const UCharsetMatch* ucm;
+       UErrorCode status = U_ZERO_ERROR;
+
+       const char* charset = NULL;
+       char *buf = NULL;
+       FILE* fin;
+
+       fin = fopen(file_path, "r");
+       if (!fin)
+       {
+               debug_error("fail to open file %s\n", file_path);
+               return NULL;
+       }
+
+       ucsd = ucsdet_open( &status );
+       if( U_FAILURE(status) ) {
+               debug_error("fail to ucsdet_open\n");
+               return NULL;
+       }
+
+       ucsdet_enableInputFilter( ucsd, TRUE );
+
+       buf = g_malloc(1024*1024);
+       if (!buf)
+       {
+               debug_error("fail to alloc\n");
+               goto done;
+       }
+
+       fread( buf, 1, 1024*1024, fin );
+       fclose(fin);
+
+       ucsdet_setText( ucsd, buf, strlen(buf), &status );
+       if( U_FAILURE(status) ) {
+               debug_error("fail to ucsdet_setText\n");
+               goto done;
+       }
+
+       ucm = ucsdet_detect( ucsd, &status );
+       if( U_FAILURE(status) ) {
+               debug_error("fail to ucsdet_detect\n");
+               goto done;
+       }
+
+       charset = ucsdet_getName( ucm, &status );
+       if( U_FAILURE(status) ) {
+               debug_error("fail to ucsdet_getName\n");
+               goto done;
+       }
+
+done:
+       ucsdet_close( ucsd );
+
+       if (buf)
+               g_free(buf);
+
+       return charset;
+}
+