tizen 2.3.1 release tizen_2.3.1 submit/tizen_2.3.1/20150915.081515 tizen_2.3.1_release
authorjk7744.park <jk7744.park@samsung.com>
Tue, 8 Sep 2015 13:30:39 +0000 (22:30 +0900)
committerjk7744.park <jk7744.park@samsung.com>
Tue, 8 Sep 2015 13:30:39 +0000 (22:30 +0900)
42 files changed:
AUTHORS [changed mode: 0755->0644]
COPYING [deleted file]
LICENSE.APLv2 [moved from LICENSE with 98% similarity, mode: 0644]
Makefile.am [changed mode: 0755->0644]
NOTICE [new file with mode: 0644]
configure.ac
depcomp [deleted file]
install-sh [deleted file]
libmm-player.manifest [new file with mode: 0755]
license [deleted file]
missing [deleted file]
packaging/libmm-player.spec [changed mode: 0644->0755]
src/Makefile.am [changed mode: 0755->0644]
src/include/mm_player.h
src/include/mm_player_ahs.h [deleted file]
src/include/mm_player_ahs_hls.h [deleted file]
src/include/mm_player_asm.h
src/include/mm_player_attrs.h
src/include/mm_player_audioeffect.h [new file with mode: 0755]
src/include/mm_player_capture.h
src/include/mm_player_ini.h
src/include/mm_player_internal.h
src/include/mm_player_m3u8.h [deleted file]
src/include/mm_player_pd.h
src/include/mm_player_priv.h
src/include/mm_player_sndeffect.h [deleted file]
src/include/mm_player_streaming.h
src/include/mm_player_utils.h
src/mm_player.c
src/mm_player_ahs.c [deleted file]
src/mm_player_ahs_hls.c [deleted file]
src/mm_player_asm.c
src/mm_player_attrs.c
src/mm_player_audioeffect.c [new file with mode: 0755]
src/mm_player_capture.c
src/mm_player_ini.c
src/mm_player_m3u8.c [deleted file]
src/mm_player_pd.c
src/mm_player_priv.c
src/mm_player_sndeffect.c [deleted file]
src/mm_player_streaming.c
src/mm_player_utils.c

diff --git a/AUTHORS b/AUTHORS
old mode 100755 (executable)
new mode 100644 (file)
diff --git a/COPYING b/COPYING
deleted file mode 100644 (file)
index 8add30a..0000000
--- a/COPYING
+++ /dev/null
@@ -1,504 +0,0 @@
-                 GNU LESSER GENERAL PUBLIC LICENSE
-                      Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
-     51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the Lesser GPL.  It also counts
- as the successor of the GNU Library Public License, version 2, hence
- the version number 2.1.]
-
-                           Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
-  This license, the Lesser General Public License, applies to some
-specially designated software packages--typically libraries--of the
-Free Software Foundation and other authors who decide to use it.  You
-can use it too, but we suggest you first think carefully about whether
-this license or the ordinary General Public License is the better
-strategy to use in any particular case, based on the explanations below.
-
-  When we speak of free software, we are referring to freedom of use,
-not price.  Our General Public Licenses are designed to make sure that
-you have the freedom to distribute copies of free software (and charge
-for this service if you wish); that you receive source code or can get
-it if you want it; that you can change the software and use pieces of
-it in new free programs; and that you are informed that you can do
-these things.
-
-  To protect your rights, we need to make restrictions that forbid
-distributors to deny you these rights or to ask you to surrender these
-rights.  These restrictions translate to certain responsibilities for
-you if you distribute copies of the library or if you modify it.
-
-  For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you.  You must make sure that they, too, receive or can get the source
-code.  If you link other code with the library, you must provide
-complete object files to the recipients, so that they can relink them
-with the library after making changes to the library and recompiling
-it.  And you must show them these terms so they know their rights.
-
-  We protect your rights with a two-step method: (1) we copyright the
-library, and (2) we offer you this license, which gives you legal
-permission to copy, distribute and/or modify the library.
-
-  To protect each distributor, we want to make it very clear that
-there is no warranty for the free library.  Also, if the library is
-modified by someone else and passed on, the recipients should know
-that what they have is not the original version, so that the original
-author's reputation will not be affected by problems that might be
-introduced by others.
-\f
-  Finally, software patents pose a constant threat to the existence of
-any free program.  We wish to make sure that a company cannot
-effectively restrict the users of a free program by obtaining a
-restrictive license from a patent holder.  Therefore, we insist that
-any patent license obtained for a version of the library must be
-consistent with the full freedom of use specified in this license.
-
-  Most GNU software, including some libraries, is covered by the
-ordinary GNU General Public License.  This license, the GNU Lesser
-General Public License, applies to certain designated libraries, and
-is quite different from the ordinary General Public License.  We use
-this license for certain libraries in order to permit linking those
-libraries into non-free programs.
-
-  When a program is linked with a library, whether statically or using
-a shared library, the combination of the two is legally speaking a
-combined work, a derivative of the original library.  The ordinary
-General Public License therefore permits such linking only if the
-entire combination fits its criteria of freedom.  The Lesser General
-Public License permits more lax criteria for linking other code with
-the library.
-
-  We call this license the "Lesser" General Public License because it
-does Less to protect the user's freedom than the ordinary General
-Public License.  It also provides other free software developers Less
-of an advantage over competing non-free programs.  These disadvantages
-are the reason we use the ordinary General Public License for many
-libraries.  However, the Lesser license provides advantages in certain
-special circumstances.
-
-  For example, on rare occasions, there may be a special need to
-encourage the widest possible use of a certain library, so that it becomes
-a de-facto standard.  To achieve this, non-free programs must be
-allowed to use the library.  A more frequent case is that a free
-library does the same job as widely used non-free libraries.  In this
-case, there is little to gain by limiting the free library to free
-software only, so we use the Lesser General Public License.
-
-  In other cases, permission to use a particular library in non-free
-programs enables a greater number of people to use a large body of
-free software.  For example, permission to use the GNU C Library in
-non-free programs enables many more people to use the whole GNU
-operating system, as well as its variant, the GNU/Linux operating
-system.
-
-  Although the Lesser General Public License is Less protective of the
-users' freedom, it does ensure that the user of a program that is
-linked with the Library has the freedom and the wherewithal to run
-that program using a modified version of the Library.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.  Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library".  The
-former contains code derived from the library, whereas the latter must
-be combined with the library in order to run.
-\f
-                 GNU LESSER GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License Agreement applies to any software library or other
-program which contains a notice placed by the copyright holder or
-other authorized party saying it may be distributed under the terms of
-this Lesser General Public License (also called "this License").
-Each licensee is addressed as "you".
-
-  A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
-  The "Library", below, refers to any such software library or work
-which has been distributed under these terms.  A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language.  (Hereinafter, translation is
-included without limitation in the term "modification".)
-
-  "Source code" for a work means the preferred form of the work for
-making modifications to it.  For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
-  Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it).  Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-  
-  1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
-  You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-\f
-  2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) The modified work must itself be a software library.
-
-    b) You must cause the files modified to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    c) You must cause the whole of the work to be licensed at no
-    charge to all third parties under the terms of this License.
-
-    d) If a facility in the modified Library refers to a function or a
-    table of data to be supplied by an application program that uses
-    the facility, other than as an argument passed when the facility
-    is invoked, then you must make a good faith effort to ensure that,
-    in the event an application does not supply such function or
-    table, the facility still operates, and performs whatever part of
-    its purpose remains meaningful.
-
-    (For example, a function in a library to compute square roots has
-    a purpose that is entirely well-defined independent of the
-    application.  Therefore, Subsection 2d requires that any
-    application-supplied function or table used by this function must
-    be optional: if the application does not supply it, the square
-    root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library.  To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License.  (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.)  Do not make any other change in
-these notices.
-\f
-  Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
-  This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
-  4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
-  If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library".  Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
-  However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library".  The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
-  When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library.  The
-threshold for this to be true is not precisely defined by law.
-
-  If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work.  (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
-  Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-\f
-  6. As an exception to the Sections above, you may also combine or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
-  You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License.  You must supply a copy of this License.  If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License.  Also, you must do one
-of these things:
-
-    a) Accompany the work with the complete corresponding
-    machine-readable source code for the Library including whatever
-    changes were used in the work (which must be distributed under
-    Sections 1 and 2 above); and, if the work is an executable linked
-    with the Library, with the complete machine-readable "work that
-    uses the Library", as object code and/or source code, so that the
-    user can modify the Library and then relink to produce a modified
-    executable containing the modified Library.  (It is understood
-    that the user who changes the contents of definitions files in the
-    Library will not necessarily be able to recompile the application
-    to use the modified definitions.)
-
-    b) Use a suitable shared library mechanism for linking with the
-    Library.  A suitable mechanism is one that (1) uses at run time a
-    copy of the library already present on the user's computer system,
-    rather than copying library functions into the executable, and (2)
-    will operate properly with a modified version of the library, if
-    the user installs one, as long as the modified version is
-    interface-compatible with the version that the work was made with.
-
-    c) Accompany the work with a written offer, valid for at
-    least three years, to give the same user the materials
-    specified in Subsection 6a, above, for a charge no more
-    than the cost of performing this distribution.
-
-    d) If distribution of the work is made by offering access to copy
-    from a designated place, offer equivalent access to copy the above
-    specified materials from the same place.
-
-    e) Verify that the user has already received a copy of these
-    materials or that you have already sent this user a copy.
-
-  For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it.  However, as a special exception,
-the materials to be distributed need not include anything that is
-normally distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
-  It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system.  Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-\f
-  7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
-    a) Accompany the combined library with a copy of the same work
-    based on the Library, uncombined with any other library
-    facilities.  This must be distributed under the terms of the
-    Sections above.
-
-    b) Give prominent notice with the combined library of the fact
-    that part of it is a work based on the Library, and explaining
-    where to find the accompanying uncombined form of the same work.
-
-  8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License.  Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License.  However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
-  9. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Library or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
-  10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties with
-this License.
-\f
-  11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded.  In such case, this License incorporates the limitation as if
-written in the body of this License.
-
-  13. The Free Software Foundation may publish revised and/or new
-versions of the Lesser General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation.  If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-\f
-  14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission.  For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this.  Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
-                           NO WARRANTY
-
-  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
-                    END OF TERMS AND CONDITIONS
-\f
-           How to Apply These Terms to Your New Libraries
-
-  If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change.  You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
-  To apply these terms, attach the following notices to the library.  It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the library's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the
-  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
-  <signature of Ty Coon>, 1 April 1990
-  Ty Coon, President of Vice
-
-That's all there is to it!
-
-
old mode 100755 (executable)
new mode 100644 (file)
similarity index 98%
rename from LICENSE
rename to LICENSE.APLv2
index 9c13a9b..bbe9d02
--- a/LICENSE
@@ -202,3 +202,5 @@ Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
    See the License for the specific language governing permissions and\r
    limitations under the License.\r
 \r
+\r
+\r
old mode 100755 (executable)
new mode 100644 (file)
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.
index 99fd7a3..3ca9b43 100755 (executable)
@@ -39,10 +39,6 @@ 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)
@@ -71,10 +67,19 @@ PKG_CHECK_MODULES(GST_APP, gstreamer-app-0.10 >= 0.10)
 AC_SUBST(GST_APP_CFLAGS)
 AC_SUBST(GST_APP_LIBS)
 
+PKG_CHECK_MODULES(APPFWK, appcore-efl)
+AC_SUBST(APPFWK_CFLAGS)
+AC_SUBST(APPFWK_LIBS)
+
+PKG_CHECK_MODULES(ELEMENTARY, elementary)
+AC_SUBST(ELEMENTARY_CFLAGS)
+AC_SUBST(ELEMENTARY_LIBS)
+
 PKG_CHECK_MODULES(MMSESSION, mm-session)
 AC_SUBST(MMSESSION_CFLAGS)
 AC_SUBST(MMSESSION_LIBS)
 
+# for testsuite
 PKG_CHECK_MODULES(MMUTIL, mmutil-imgp)
 AC_SUBST(MMUTIL_CFLAGS)
 AC_SUBST(MMUTIL_LIBS)
@@ -83,18 +88,34 @@ PKG_CHECK_MODULES(AUDIOSESSIONMGR, audio-session-mgr)
 AC_SUBST(AUDIOSESSIONMGR_CFLAGS)
 AC_SUBST(AUDIOSESSIONMGR_LIBS)
 
+PKG_CHECK_MODULES(ECORE_X, ecore-x)
+AC_SUBST(ECORE_X_CFLAGS)
+AC_SUBST(ECORE_X_LIBS)
+
+PKG_CHECK_MODULES(EVAS, evas)
+AC_SUBST(EVAS_CFLAGS)
+AC_SUBST(EVAS_LIBS)
+
+PKG_CHECK_MODULES(ECORE, ecore)
+AC_SUBST(ECORE_CFLAGS)
+AC_SUBST(ECORE_LIBS)
+
 PKG_CHECK_MODULES(INIPARSER, iniparser)
 AC_SUBST(INIPARSER_CFLAGS)
 AC_SUBST(INIPARSER_LIBS)
 
-PKG_CHECK_MODULES(CRYPTO, libcrypto)
-AC_SUBST(CRYPTO_CFLAGS)
-AC_SUBST(CRYPTO_LIBS)
-
 PKG_CHECK_MODULES(VCONF, vconf)
 AC_SUBST(VCONF_CFLAGS)
 AC_SUBST(VCONF_LIBS)
 
+PKG_CHECK_MODULES(ICU, icu-i18n)
+AC_SUBST(ICU_CFLAGS)
+AC_SUBST(ICU_LIBS)
+
+PKG_CHECK_MODULES(UTILX, utilX)
+AC_SUBST(UTILX_CFLAGS)
+AC_SUBST(UTILX_LIBS)
+
 AC_CONFIG_FILES([Makefile
                 src/Makefile
                 mm-player.pc
diff --git a/depcomp b/depcomp
deleted file mode 100755 (executable)
index e5f9736..0000000
--- a/depcomp
+++ /dev/null
@@ -1,589 +0,0 @@
-#! /bin/sh
-# depcomp - compile a program generating dependencies as side-effects
-
-scriptversion=2007-03-29.01
-
-# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007 Free Software
-# Foundation, Inc.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.
-
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
-
-case $1 in
-  '')
-     echo "$0: No command.  Try \`$0 --help' for more information." 1>&2
-     exit 1;
-     ;;
-  -h | --h*)
-    cat <<\EOF
-Usage: depcomp [--help] [--version] PROGRAM [ARGS]
-
-Run PROGRAMS ARGS to compile a file, generating dependencies
-as side-effects.
-
-Environment variables:
-  depmode     Dependency tracking mode.
-  source      Source file read by `PROGRAMS ARGS'.
-  object      Object file output by `PROGRAMS ARGS'.
-  DEPDIR      directory where to store dependencies.
-  depfile     Dependency file to output.
-  tmpdepfile  Temporary file to use when outputing dependencies.
-  libtool     Whether libtool is used (yes/no).
-
-Report bugs to <bug-automake@gnu.org>.
-EOF
-    exit $?
-    ;;
-  -v | --v*)
-    echo "depcomp $scriptversion"
-    exit $?
-    ;;
-esac
-
-if test -z "$depmode" || test -z "$source" || test -z "$object"; then
-  echo "depcomp: Variables source, object and depmode must be set" 1>&2
-  exit 1
-fi
-
-# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
-depfile=${depfile-`echo "$object" |
-  sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
-tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
-
-rm -f "$tmpdepfile"
-
-# Some modes work just like other modes, but use different flags.  We
-# parameterize here, but still list the modes in the big case below,
-# to make depend.m4 easier to write.  Note that we *cannot* use a case
-# here, because this file can only contain one case statement.
-if test "$depmode" = hp; then
-  # HP compiler uses -M and no extra arg.
-  gccflag=-M
-  depmode=gcc
-fi
-
-if test "$depmode" = dashXmstdout; then
-   # This is just like dashmstdout with a different argument.
-   dashmflag=-xM
-   depmode=dashmstdout
-fi
-
-case "$depmode" in
-gcc3)
-## gcc 3 implements dependency tracking that does exactly what
-## we want.  Yay!  Note: for some reason libtool 1.4 doesn't like
-## it if -MD -MP comes after the -MF stuff.  Hmm.
-## Unfortunately, FreeBSD c89 acceptance of flags depends upon
-## the command line argument order; so add the flags where they
-## appear in depend2.am.  Note that the slowdown incurred here
-## affects only configure: in makefiles, %FASTDEP% shortcuts this.
-  for arg
-  do
-    case $arg in
-    -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
-    *)  set fnord "$@" "$arg" ;;
-    esac
-    shift # fnord
-    shift # $arg
-  done
-  "$@"
-  stat=$?
-  if test $stat -eq 0; then :
-  else
-    rm -f "$tmpdepfile"
-    exit $stat
-  fi
-  mv "$tmpdepfile" "$depfile"
-  ;;
-
-gcc)
-## There are various ways to get dependency output from gcc.  Here's
-## why we pick this rather obscure method:
-## - Don't want to use -MD because we'd like the dependencies to end
-##   up in a subdir.  Having to rename by hand is ugly.
-##   (We might end up doing this anyway to support other compilers.)
-## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
-##   -MM, not -M (despite what the docs say).
-## - Using -M directly means running the compiler twice (even worse
-##   than renaming).
-  if test -z "$gccflag"; then
-    gccflag=-MD,
-  fi
-  "$@" -Wp,"$gccflag$tmpdepfile"
-  stat=$?
-  if test $stat -eq 0; then :
-  else
-    rm -f "$tmpdepfile"
-    exit $stat
-  fi
-  rm -f "$depfile"
-  echo "$object : \\" > "$depfile"
-  alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
-## The second -e expression handles DOS-style file names with drive letters.
-  sed -e 's/^[^:]*: / /' \
-      -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
-## This next piece of magic avoids the `deleted header file' problem.
-## The problem is that when a header file which appears in a .P file
-## is deleted, the dependency causes make to die (because there is
-## typically no way to rebuild the header).  We avoid this by adding
-## dummy dependencies for each header file.  Too bad gcc doesn't do
-## this for us directly.
-  tr ' ' '
-' < "$tmpdepfile" |
-## Some versions of gcc put a space before the `:'.  On the theory
-## that the space means something, we add a space to the output as
-## well.
-## Some versions of the HPUX 10.20 sed can't process this invocation
-## correctly.  Breaking it into two sed invocations is a workaround.
-    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
-  rm -f "$tmpdepfile"
-  ;;
-
-hp)
-  # This case exists only to let depend.m4 do its work.  It works by
-  # looking at the text of this script.  This case will never be run,
-  # since it is checked for above.
-  exit 1
-  ;;
-
-sgi)
-  if test "$libtool" = yes; then
-    "$@" "-Wp,-MDupdate,$tmpdepfile"
-  else
-    "$@" -MDupdate "$tmpdepfile"
-  fi
-  stat=$?
-  if test $stat -eq 0; then :
-  else
-    rm -f "$tmpdepfile"
-    exit $stat
-  fi
-  rm -f "$depfile"
-
-  if test -f "$tmpdepfile"; then  # yes, the sourcefile depend on other files
-    echo "$object : \\" > "$depfile"
-
-    # Clip off the initial element (the dependent).  Don't try to be
-    # clever and replace this with sed code, as IRIX sed won't handle
-    # lines with more than a fixed number of characters (4096 in
-    # IRIX 6.2 sed, 8192 in IRIX 6.5).  We also remove comment lines;
-    # the IRIX cc adds comments like `#:fec' to the end of the
-    # dependency line.
-    tr ' ' '
-' < "$tmpdepfile" \
-    | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
-    tr '
-' ' ' >> $depfile
-    echo >> $depfile
-
-    # The second pass generates a dummy entry for each header file.
-    tr ' ' '
-' < "$tmpdepfile" \
-   | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
-   >> $depfile
-  else
-    # The sourcefile does not contain any dependencies, so just
-    # store a dummy comment line, to avoid errors with the Makefile
-    # "include basename.Plo" scheme.
-    echo "#dummy" > "$depfile"
-  fi
-  rm -f "$tmpdepfile"
-  ;;
-
-aix)
-  # The C for AIX Compiler uses -M and outputs the dependencies
-  # in a .u file.  In older versions, this file always lives in the
-  # current directory.  Also, the AIX compiler puts `$object:' at the
-  # start of each line; $object doesn't have directory information.
-  # Version 6 uses the directory in both cases.
-  dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
-  test "x$dir" = "x$object" && dir=
-  base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
-  if test "$libtool" = yes; then
-    tmpdepfile1=$dir$base.u
-    tmpdepfile2=$base.u
-    tmpdepfile3=$dir.libs/$base.u
-    "$@" -Wc,-M
-  else
-    tmpdepfile1=$dir$base.u
-    tmpdepfile2=$dir$base.u
-    tmpdepfile3=$dir$base.u
-    "$@" -M
-  fi
-  stat=$?
-
-  if test $stat -eq 0; then :
-  else
-    rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
-    exit $stat
-  fi
-
-  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
-  do
-    test -f "$tmpdepfile" && break
-  done
-  if test -f "$tmpdepfile"; then
-    # Each line is of the form `foo.o: dependent.h'.
-    # Do two passes, one to just change these to
-    # `$object: dependent.h' and one to simply `dependent.h:'.
-    sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
-    # That's a tab and a space in the [].
-    sed -e 's,^.*\.[a-z]*:[     ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
-  else
-    # The sourcefile does not contain any dependencies, so just
-    # store a dummy comment line, to avoid errors with the Makefile
-    # "include basename.Plo" scheme.
-    echo "#dummy" > "$depfile"
-  fi
-  rm -f "$tmpdepfile"
-  ;;
-
-icc)
-  # Intel's C compiler understands `-MD -MF file'.  However on
-  #    icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
-  # ICC 7.0 will fill foo.d with something like
-  #    foo.o: sub/foo.c
-  #    foo.o: sub/foo.h
-  # which is wrong.  We want:
-  #    sub/foo.o: sub/foo.c
-  #    sub/foo.o: sub/foo.h
-  #    sub/foo.c:
-  #    sub/foo.h:
-  # ICC 7.1 will output
-  #    foo.o: sub/foo.c sub/foo.h
-  # and will wrap long lines using \ :
-  #    foo.o: sub/foo.c ... \
-  #     sub/foo.h ... \
-  #     ...
-
-  "$@" -MD -MF "$tmpdepfile"
-  stat=$?
-  if test $stat -eq 0; then :
-  else
-    rm -f "$tmpdepfile"
-    exit $stat
-  fi
-  rm -f "$depfile"
-  # Each line is of the form `foo.o: dependent.h',
-  # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
-  # Do two passes, one to just change these to
-  # `$object: dependent.h' and one to simply `dependent.h:'.
-  sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
-  # Some versions of the HPUX 10.20 sed can't process this invocation
-  # correctly.  Breaking it into two sed invocations is a workaround.
-  sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
-    sed -e 's/$/ :/' >> "$depfile"
-  rm -f "$tmpdepfile"
-  ;;
-
-hp2)
-  # The "hp" stanza above does not work with aCC (C++) and HP's ia64
-  # compilers, which have integrated preprocessors.  The correct option
-  # to use with these is +Maked; it writes dependencies to a file named
-  # 'foo.d', which lands next to the object file, wherever that
-  # happens to be.
-  # Much of this is similar to the tru64 case; see comments there.
-  dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
-  test "x$dir" = "x$object" && dir=
-  base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
-  if test "$libtool" = yes; then
-    tmpdepfile1=$dir$base.d
-    tmpdepfile2=$dir.libs/$base.d
-    "$@" -Wc,+Maked
-  else
-    tmpdepfile1=$dir$base.d
-    tmpdepfile2=$dir$base.d
-    "$@" +Maked
-  fi
-  stat=$?
-  if test $stat -eq 0; then :
-  else
-     rm -f "$tmpdepfile1" "$tmpdepfile2"
-     exit $stat
-  fi
-
-  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
-  do
-    test -f "$tmpdepfile" && break
-  done
-  if test -f "$tmpdepfile"; then
-    sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
-    # Add `dependent.h:' lines.
-    sed -ne '2,${; s/^ *//; s/ \\*$//; s/$/:/; p;}' "$tmpdepfile" >> "$depfile"
-  else
-    echo "#dummy" > "$depfile"
-  fi
-  rm -f "$tmpdepfile" "$tmpdepfile2"
-  ;;
-
-tru64)
-   # The Tru64 compiler uses -MD to generate dependencies as a side
-   # effect.  `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
-   # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
-   # dependencies in `foo.d' instead, so we check for that too.
-   # Subdirectories are respected.
-   dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
-   test "x$dir" = "x$object" && dir=
-   base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
-
-   if test "$libtool" = yes; then
-      # With Tru64 cc, shared objects can also be used to make a
-      # static library.  This mechanism is used in libtool 1.4 series to
-      # handle both shared and static libraries in a single compilation.
-      # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
-      #
-      # With libtool 1.5 this exception was removed, and libtool now
-      # generates 2 separate objects for the 2 libraries.  These two
-      # compilations output dependencies in $dir.libs/$base.o.d and
-      # in $dir$base.o.d.  We have to check for both files, because
-      # one of the two compilations can be disabled.  We should prefer
-      # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
-      # automatically cleaned when .libs/ is deleted, while ignoring
-      # the former would cause a distcleancheck panic.
-      tmpdepfile1=$dir.libs/$base.lo.d   # libtool 1.4
-      tmpdepfile2=$dir$base.o.d          # libtool 1.5
-      tmpdepfile3=$dir.libs/$base.o.d    # libtool 1.5
-      tmpdepfile4=$dir.libs/$base.d      # Compaq CCC V6.2-504
-      "$@" -Wc,-MD
-   else
-      tmpdepfile1=$dir$base.o.d
-      tmpdepfile2=$dir$base.d
-      tmpdepfile3=$dir$base.d
-      tmpdepfile4=$dir$base.d
-      "$@" -MD
-   fi
-
-   stat=$?
-   if test $stat -eq 0; then :
-   else
-      rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
-      exit $stat
-   fi
-
-   for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
-   do
-     test -f "$tmpdepfile" && break
-   done
-   if test -f "$tmpdepfile"; then
-      sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
-      # That's a tab and a space in the [].
-      sed -e 's,^.*\.[a-z]*:[   ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
-   else
-      echo "#dummy" > "$depfile"
-   fi
-   rm -f "$tmpdepfile"
-   ;;
-
-#nosideeffect)
-  # This comment above is used by automake to tell side-effect
-  # dependency tracking mechanisms from slower ones.
-
-dashmstdout)
-  # Important note: in order to support this mode, a compiler *must*
-  # always write the preprocessed file to stdout, regardless of -o.
-  "$@" || exit $?
-
-  # Remove the call to Libtool.
-  if test "$libtool" = yes; then
-    while test $1 != '--mode=compile'; do
-      shift
-    done
-    shift
-  fi
-
-  # Remove `-o $object'.
-  IFS=" "
-  for arg
-  do
-    case $arg in
-    -o)
-      shift
-      ;;
-    $object)
-      shift
-      ;;
-    *)
-      set fnord "$@" "$arg"
-      shift # fnord
-      shift # $arg
-      ;;
-    esac
-  done
-
-  test -z "$dashmflag" && dashmflag=-M
-  # Require at least two characters before searching for `:'
-  # in the target name.  This is to cope with DOS-style filenames:
-  # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
-  "$@" $dashmflag |
-    sed 's:^[  ]*[^: ][^:][^:]*\:[    ]*:'"$object"'\: :' > "$tmpdepfile"
-  rm -f "$depfile"
-  cat < "$tmpdepfile" > "$depfile"
-  tr ' ' '
-' < "$tmpdepfile" | \
-## Some versions of the HPUX 10.20 sed can't process this invocation
-## correctly.  Breaking it into two sed invocations is a workaround.
-    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
-  rm -f "$tmpdepfile"
-  ;;
-
-dashXmstdout)
-  # This case only exists to satisfy depend.m4.  It is never actually
-  # run, as this mode is specially recognized in the preamble.
-  exit 1
-  ;;
-
-makedepend)
-  "$@" || exit $?
-  # Remove any Libtool call
-  if test "$libtool" = yes; then
-    while test $1 != '--mode=compile'; do
-      shift
-    done
-    shift
-  fi
-  # X makedepend
-  shift
-  cleared=no
-  for arg in "$@"; do
-    case $cleared in
-    no)
-      set ""; shift
-      cleared=yes ;;
-    esac
-    case "$arg" in
-    -D*|-I*)
-      set fnord "$@" "$arg"; shift ;;
-    # Strip any option that makedepend may not understand.  Remove
-    # the object too, otherwise makedepend will parse it as a source file.
-    -*|$object)
-      ;;
-    *)
-      set fnord "$@" "$arg"; shift ;;
-    esac
-  done
-  obj_suffix="`echo $object | sed 's/^.*\././'`"
-  touch "$tmpdepfile"
-  ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
-  rm -f "$depfile"
-  cat < "$tmpdepfile" > "$depfile"
-  sed '1,2d' "$tmpdepfile" | tr ' ' '
-' | \
-## Some versions of the HPUX 10.20 sed can't process this invocation
-## correctly.  Breaking it into two sed invocations is a workaround.
-    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
-  rm -f "$tmpdepfile" "$tmpdepfile".bak
-  ;;
-
-cpp)
-  # Important note: in order to support this mode, a compiler *must*
-  # always write the preprocessed file to stdout.
-  "$@" || exit $?
-
-  # Remove the call to Libtool.
-  if test "$libtool" = yes; then
-    while test $1 != '--mode=compile'; do
-      shift
-    done
-    shift
-  fi
-
-  # Remove `-o $object'.
-  IFS=" "
-  for arg
-  do
-    case $arg in
-    -o)
-      shift
-      ;;
-    $object)
-      shift
-      ;;
-    *)
-      set fnord "$@" "$arg"
-      shift # fnord
-      shift # $arg
-      ;;
-    esac
-  done
-
-  "$@" -E |
-    sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
-       -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
-    sed '$ s: \\$::' > "$tmpdepfile"
-  rm -f "$depfile"
-  echo "$object : \\" > "$depfile"
-  cat < "$tmpdepfile" >> "$depfile"
-  sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
-  rm -f "$tmpdepfile"
-  ;;
-
-msvisualcpp)
-  # Important note: in order to support this mode, a compiler *must*
-  # always write the preprocessed file to stdout, regardless of -o,
-  # because we must use -o when running libtool.
-  "$@" || exit $?
-  IFS=" "
-  for arg
-  do
-    case "$arg" in
-    "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
-       set fnord "$@"
-       shift
-       shift
-       ;;
-    *)
-       set fnord "$@" "$arg"
-       shift
-       shift
-       ;;
-    esac
-  done
-  "$@" -E |
-  sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
-  rm -f "$depfile"
-  echo "$object : \\" > "$depfile"
-  . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::   \1 \\:p' >> "$depfile"
-  echo "       " >> "$depfile"
-  . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
-  rm -f "$tmpdepfile"
-  ;;
-
-none)
-  exec "$@"
-  ;;
-
-*)
-  echo "Unknown depmode $depmode" 1>&2
-  exit 1
-  ;;
-esac
-
-exit 0
-
-# Local Variables:
-# mode: shell-script
-# sh-indentation: 2
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "scriptversion="
-# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-end: "$"
-# End:
diff --git a/install-sh b/install-sh
deleted file mode 100755 (executable)
index a5897de..0000000
+++ /dev/null
@@ -1,519 +0,0 @@
-#!/bin/sh
-# install - install a program, script, or datafile
-
-scriptversion=2006-12-25.00
-
-# This originates from X11R5 (mit/util/scripts/install.sh), which was
-# later released in X11R6 (xc/config/util/install.sh) with the
-# following copyright and license.
-#
-# Copyright (C) 1994 X Consortium
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to
-# deal in the Software without restriction, including without limitation the
-# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-# sell copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
-# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-#
-# Except as contained in this notice, the name of the X Consortium shall not
-# be used in advertising or otherwise to promote the sale, use or other deal-
-# ings in this Software without prior written authorization from the X Consor-
-# tium.
-#
-#
-# FSF changes to this file are in the public domain.
-#
-# Calling this script install-sh is preferred over install.sh, to prevent
-# `make' implicit rules from creating a file called install from it
-# when there is no Makefile.
-#
-# This script is compatible with the BSD install script, but was written
-# from scratch.
-
-nl='
-'
-IFS=" ""       $nl"
-
-# set DOITPROG to echo to test this script
-
-# Don't use :- since 4.3BSD and earlier shells don't like it.
-doit=${DOITPROG-}
-if test -z "$doit"; then
-  doit_exec=exec
-else
-  doit_exec=$doit
-fi
-
-# Put in absolute file names if you don't have them in your path;
-# or use environment vars.
-
-chgrpprog=${CHGRPPROG-chgrp}
-chmodprog=${CHMODPROG-chmod}
-chownprog=${CHOWNPROG-chown}
-cmpprog=${CMPPROG-cmp}
-cpprog=${CPPROG-cp}
-mkdirprog=${MKDIRPROG-mkdir}
-mvprog=${MVPROG-mv}
-rmprog=${RMPROG-rm}
-stripprog=${STRIPPROG-strip}
-
-posix_glob='?'
-initialize_posix_glob='
-  test "$posix_glob" != "?" || {
-    if (set -f) 2>/dev/null; then
-      posix_glob=
-    else
-      posix_glob=:
-    fi
-  }
-'
-
-posix_mkdir=
-
-# Desired mode of installed file.
-mode=0755
-
-chgrpcmd=
-chmodcmd=$chmodprog
-chowncmd=
-mvcmd=$mvprog
-rmcmd="$rmprog -f"
-stripcmd=
-
-src=
-dst=
-dir_arg=
-dst_arg=
-
-copy_on_change=false
-no_target_directory=
-
-usage="\
-Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
-   or: $0 [OPTION]... SRCFILES... DIRECTORY
-   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
-   or: $0 [OPTION]... -d DIRECTORIES...
-
-In the 1st form, copy SRCFILE to DSTFILE.
-In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
-In the 4th, create DIRECTORIES.
-
-Options:
-     --help     display this help and exit.
-     --version  display version info and exit.
-
-  -c            (ignored)
-  -C            install only if different (preserve the last data modification time)
-  -d            create directories instead of installing files.
-  -g GROUP      $chgrpprog installed files to GROUP.
-  -m MODE       $chmodprog installed files to MODE.
-  -o USER       $chownprog installed files to USER.
-  -s            $stripprog installed files.
-  -t DIRECTORY  install into DIRECTORY.
-  -T            report an error if DSTFILE is a directory.
-
-Environment variables override the default commands:
-  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
-  RMPROG STRIPPROG
-"
-
-while test $# -ne 0; do
-  case $1 in
-    -c) ;;
-
-    -C) copy_on_change=true;;
-
-    -d) dir_arg=true;;
-
-    -g) chgrpcmd="$chgrpprog $2"
-       shift;;
-
-    --help) echo "$usage"; exit $?;;
-
-    -m) mode=$2
-       case $mode in
-         *' '* | *'    '* | *'
-'*       | *'*'* | *'?'* | *'['*)
-           echo "$0: invalid mode: $mode" >&2
-           exit 1;;
-       esac
-       shift;;
-
-    -o) chowncmd="$chownprog $2"
-       shift;;
-
-    -s) stripcmd=$stripprog;;
-
-    -t) dst_arg=$2
-       shift;;
-
-    -T) no_target_directory=true;;
-
-    --version) echo "$0 $scriptversion"; exit $?;;
-
-    --)        shift
-       break;;
-
-    -*)        echo "$0: invalid option: $1" >&2
-       exit 1;;
-
-    *)  break;;
-  esac
-  shift
-done
-
-if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
-  # When -d is used, all remaining arguments are directories to create.
-  # When -t is used, the destination is already specified.
-  # Otherwise, the last argument is the destination.  Remove it from $@.
-  for arg
-  do
-    if test -n "$dst_arg"; then
-      # $@ is not empty: it contains at least $arg.
-      set fnord "$@" "$dst_arg"
-      shift # fnord
-    fi
-    shift # arg
-    dst_arg=$arg
-  done
-fi
-
-if test $# -eq 0; then
-  if test -z "$dir_arg"; then
-    echo "$0: no input file specified." >&2
-    exit 1
-  fi
-  # It's OK to call `install-sh -d' without argument.
-  # This can happen when creating conditional directories.
-  exit 0
-fi
-
-if test -z "$dir_arg"; then
-  trap '(exit $?); exit' 1 2 13 15
-
-  # Set umask so as not to create temps with too-generous modes.
-  # However, 'strip' requires both read and write access to temps.
-  case $mode in
-    # Optimize common cases.
-    *644) cp_umask=133;;
-    *755) cp_umask=22;;
-
-    *[0-7])
-      if test -z "$stripcmd"; then
-       u_plus_rw=
-      else
-       u_plus_rw='% 200'
-      fi
-      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
-    *)
-      if test -z "$stripcmd"; then
-       u_plus_rw=
-      else
-       u_plus_rw=,u+rw
-      fi
-      cp_umask=$mode$u_plus_rw;;
-  esac
-fi
-
-for src
-do
-  # Protect names starting with `-'.
-  case $src in
-    -*) src=./$src;;
-  esac
-
-  if test -n "$dir_arg"; then
-    dst=$src
-    dstdir=$dst
-    test -d "$dstdir"
-    dstdir_status=$?
-  else
-
-    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
-    # might cause directories to be created, which would be especially bad
-    # if $src (and thus $dsttmp) contains '*'.
-    if test ! -f "$src" && test ! -d "$src"; then
-      echo "$0: $src does not exist." >&2
-      exit 1
-    fi
-
-    if test -z "$dst_arg"; then
-      echo "$0: no destination specified." >&2
-      exit 1
-    fi
-
-    dst=$dst_arg
-    # Protect names starting with `-'.
-    case $dst in
-      -*) dst=./$dst;;
-    esac
-
-    # If destination is a directory, append the input filename; won't work
-    # if double slashes aren't ignored.
-    if test -d "$dst"; then
-      if test -n "$no_target_directory"; then
-       echo "$0: $dst_arg: Is a directory" >&2
-       exit 1
-      fi
-      dstdir=$dst
-      dst=$dstdir/`basename "$src"`
-      dstdir_status=0
-    else
-      # Prefer dirname, but fall back on a substitute if dirname fails.
-      dstdir=`
-       (dirname "$dst") 2>/dev/null ||
-       expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-            X"$dst" : 'X\(//\)[^/]' \| \
-            X"$dst" : 'X\(//\)$' \| \
-            X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
-       echo X"$dst" |
-           sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
-                  s//\1/
-                  q
-                }
-                /^X\(\/\/\)[^/].*/{
-                  s//\1/
-                  q
-                }
-                /^X\(\/\/\)$/{
-                  s//\1/
-                  q
-                }
-                /^X\(\/\).*/{
-                  s//\1/
-                  q
-                }
-                s/.*/./; q'
-      `
-
-      test -d "$dstdir"
-      dstdir_status=$?
-    fi
-  fi
-
-  obsolete_mkdir_used=false
-
-  if test $dstdir_status != 0; then
-    case $posix_mkdir in
-      '')
-       # Create intermediate dirs using mode 755 as modified by the umask.
-       # This is like FreeBSD 'install' as of 1997-10-28.
-       umask=`umask`
-       case $stripcmd.$umask in
-         # Optimize common cases.
-         *[2367][2367]) mkdir_umask=$umask;;
-         .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
-
-         *[0-7])
-           mkdir_umask=`expr $umask + 22 \
-             - $umask % 100 % 40 + $umask % 20 \
-             - $umask % 10 % 4 + $umask % 2
-           `;;
-         *) mkdir_umask=$umask,go-w;;
-       esac
-
-       # With -d, create the new directory with the user-specified mode.
-       # Otherwise, rely on $mkdir_umask.
-       if test -n "$dir_arg"; then
-         mkdir_mode=-m$mode
-       else
-         mkdir_mode=
-       fi
-
-       posix_mkdir=false
-       case $umask in
-         *[123567][0-7][0-7])
-           # POSIX mkdir -p sets u+wx bits regardless of umask, which
-           # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
-           ;;
-         *)
-           tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
-           trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
-
-           if (umask $mkdir_umask &&
-               exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
-           then
-             if test -z "$dir_arg" || {
-                  # Check for POSIX incompatibilities with -m.
-                  # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
-                  # other-writeable bit of parent directory when it shouldn't.
-                  # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
-                  ls_ld_tmpdir=`ls -ld "$tmpdir"`
-                  case $ls_ld_tmpdir in
-                    d????-?r-*) different_mode=700;;
-                    d????-?--*) different_mode=755;;
-                    *) false;;
-                  esac &&
-                  $mkdirprog -m$different_mode -p -- "$tmpdir" && {
-                    ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
-                    test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
-                  }
-                }
-             then posix_mkdir=:
-             fi
-             rmdir "$tmpdir/d" "$tmpdir"
-           else
-             # Remove any dirs left behind by ancient mkdir implementations.
-             rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
-           fi
-           trap '' 0;;
-       esac;;
-    esac
-
-    if
-      $posix_mkdir && (
-       umask $mkdir_umask &&
-       $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
-      )
-    then :
-    else
-
-      # The umask is ridiculous, or mkdir does not conform to POSIX,
-      # or it failed possibly due to a race condition.  Create the
-      # directory the slow way, step by step, checking for races as we go.
-
-      case $dstdir in
-       /*) prefix='/';;
-       -*) prefix='./';;
-       *)  prefix='';;
-      esac
-
-      eval "$initialize_posix_glob"
-
-      oIFS=$IFS
-      IFS=/
-      $posix_glob set -f
-      set fnord $dstdir
-      shift
-      $posix_glob set +f
-      IFS=$oIFS
-
-      prefixes=
-
-      for d
-      do
-       test -z "$d" && continue
-
-       prefix=$prefix$d
-       if test -d "$prefix"; then
-         prefixes=
-       else
-         if $posix_mkdir; then
-           (umask=$mkdir_umask &&
-            $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
-           # Don't fail if two instances are running concurrently.
-           test -d "$prefix" || exit 1
-         else
-           case $prefix in
-             *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
-             *) qprefix=$prefix;;
-           esac
-           prefixes="$prefixes '$qprefix'"
-         fi
-       fi
-       prefix=$prefix/
-      done
-
-      if test -n "$prefixes"; then
-       # Don't fail if two instances are running concurrently.
-       (umask $mkdir_umask &&
-        eval "\$doit_exec \$mkdirprog $prefixes") ||
-         test -d "$dstdir" || exit 1
-       obsolete_mkdir_used=true
-      fi
-    fi
-  fi
-
-  if test -n "$dir_arg"; then
-    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
-    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
-    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
-      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
-  else
-
-    # Make a couple of temp file names in the proper directory.
-    dsttmp=$dstdir/_inst.$$_
-    rmtmp=$dstdir/_rm.$$_
-
-    # Trap to clean up those temp files at exit.
-    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
-
-    # Copy the file name to the temp name.
-    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
-
-    # and set any options; do chmod last to preserve setuid bits.
-    #
-    # If any of these fail, we abort the whole thing.  If we want to
-    # ignore errors from any of these, just make sure not to ignore
-    # errors from the above "$doit $cpprog $src $dsttmp" command.
-    #
-    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
-    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
-    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
-    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
-
-    # If -C, don't bother to copy if it wouldn't change the file.
-    if $copy_on_change &&
-       old=`LC_ALL=C ls -dlL "$dst"    2>/dev/null` &&
-       new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
-
-       eval "$initialize_posix_glob" &&
-       $posix_glob set -f &&
-       set X $old && old=:$2:$4:$5:$6 &&
-       set X $new && new=:$2:$4:$5:$6 &&
-       $posix_glob set +f &&
-
-       test "$old" = "$new" &&
-       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
-    then
-      rm -f "$dsttmp"
-    else
-      # Rename the file to the real destination.
-      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
-
-      # The rename failed, perhaps because mv can't rename something else
-      # to itself, or perhaps because mv is so ancient that it does not
-      # support -f.
-      {
-       # Now remove or move aside any old file at destination location.
-       # We try this two ways since rm can't unlink itself on some
-       # systems and the destination file might be busy for other
-       # reasons.  In this case, the final cleanup might fail but the new
-       # file should still install successfully.
-       {
-         test ! -f "$dst" ||
-         $doit $rmcmd -f "$dst" 2>/dev/null ||
-         { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
-           { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
-         } ||
-         { echo "$0: cannot unlink or rename $dst" >&2
-           (exit 1); exit 1
-         }
-       } &&
-
-       # Now rename the file to the real destination.
-       $doit $mvcmd "$dsttmp" "$dst"
-      }
-    fi || exit 1
-
-    trap '' 0
-  fi
-done
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "scriptversion="
-# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-end: "$"
-# End:
diff --git a/libmm-player.manifest b/libmm-player.manifest
new file mode 100755 (executable)
index 0000000..e0e2a61
--- /dev/null
@@ -0,0 +1,8 @@
+<manifest>
+       <request>
+               <domain name="_" />
+       </request>
+       <assign>
+               <filesystem path="/usr/bin/mm_player_testsuite" label="_" exec_label="none" />
+       </assign>
+</manifest>
diff --git a/license b/license
deleted file mode 100644 (file)
index 52a3218..0000000
--- a/license
+++ /dev/null
@@ -1,13 +0,0 @@
-libmm-player:
-
-Most files in libmm-player are under the Apache License Version 2.0.
-Read the file LICENSE for details.
-
-Some parts of libmm-player are licensed under the GNU Lesser General Public License version 2.1
-See the file COPYING for details.
-
-Specifically, the LGPL parts of libmm-player are
- - src/mm_player_m3u8.c
- - src/include/mm_player_m3u8.h
-
-
diff --git a/missing b/missing
deleted file mode 100755 (executable)
index 1c8ff70..0000000
--- a/missing
+++ /dev/null
@@ -1,367 +0,0 @@
-#! /bin/sh
-# Common stub for a few missing GNU programs while installing.
-
-scriptversion=2006-05-10.23
-
-# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006
-#   Free Software Foundation, Inc.
-# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.
-
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-if test $# -eq 0; then
-  echo 1>&2 "Try \`$0 --help' for more information"
-  exit 1
-fi
-
-run=:
-sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
-sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
-
-# In the cases where this matters, `missing' is being run in the
-# srcdir already.
-if test -f configure.ac; then
-  configure_ac=configure.ac
-else
-  configure_ac=configure.in
-fi
-
-msg="missing on your system"
-
-case $1 in
---run)
-  # Try to run requested program, and just exit if it succeeds.
-  run=
-  shift
-  "$@" && exit 0
-  # Exit code 63 means version mismatch.  This often happens
-  # when the user try to use an ancient version of a tool on
-  # a file that requires a minimum version.  In this case we
-  # we should proceed has if the program had been absent, or
-  # if --run hadn't been passed.
-  if test $? = 63; then
-    run=:
-    msg="probably too old"
-  fi
-  ;;
-
-  -h|--h|--he|--hel|--help)
-    echo "\
-$0 [OPTION]... PROGRAM [ARGUMENT]...
-
-Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
-error status if there is no known handling for PROGRAM.
-
-Options:
-  -h, --help      display this help and exit
-  -v, --version   output version information and exit
-  --run           try to run the given command, and emulate it if it fails
-
-Supported PROGRAM values:
-  aclocal      touch file \`aclocal.m4'
-  autoconf     touch file \`configure'
-  autoheader   touch file \`config.h.in'
-  autom4te     touch the output file, or create a stub one
-  automake     touch all \`Makefile.in' files
-  bison        create \`y.tab.[ch]', if possible, from existing .[ch]
-  flex         create \`lex.yy.c', if possible, from existing .c
-  help2man     touch the output file
-  lex          create \`lex.yy.c', if possible, from existing .c
-  makeinfo     touch the output file
-  tar          try tar, gnutar, gtar, then tar without non-portable flags
-  yacc         create \`y.tab.[ch]', if possible, from existing .[ch]
-
-Send bug reports to <bug-automake@gnu.org>."
-    exit $?
-    ;;
-
-  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
-    echo "missing $scriptversion (GNU Automake)"
-    exit $?
-    ;;
-
-  -*)
-    echo 1>&2 "$0: Unknown \`$1' option"
-    echo 1>&2 "Try \`$0 --help' for more information"
-    exit 1
-    ;;
-
-esac
-
-# Now exit if we have it, but it failed.  Also exit now if we
-# don't have it and --version was passed (most likely to detect
-# the program).
-case $1 in
-  lex|yacc)
-    # Not GNU programs, they don't have --version.
-    ;;
-
-  tar)
-    if test -n "$run"; then
-       echo 1>&2 "ERROR: \`tar' requires --run"
-       exit 1
-    elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
-       exit 1
-    fi
-    ;;
-
-  *)
-    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
-       # We have it, but it failed.
-       exit 1
-    elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
-       # Could not run --version or --help.  This is probably someone
-       # running `$TOOL --version' or `$TOOL --help' to check whether
-       # $TOOL exists and not knowing $TOOL uses missing.
-       exit 1
-    fi
-    ;;
-esac
-
-# If it does not exist, or fails to run (possibly an outdated version),
-# try to emulate it.
-case $1 in
-  aclocal*)
-    echo 1>&2 "\
-WARNING: \`$1' is $msg.  You should only need it if
-         you modified \`acinclude.m4' or \`${configure_ac}'.  You might want
-         to install the \`Automake' and \`Perl' packages.  Grab them from
-         any GNU archive site."
-    touch aclocal.m4
-    ;;
-
-  autoconf)
-    echo 1>&2 "\
-WARNING: \`$1' is $msg.  You should only need it if
-         you modified \`${configure_ac}'.  You might want to install the
-         \`Autoconf' and \`GNU m4' packages.  Grab them from any GNU
-         archive site."
-    touch configure
-    ;;
-
-  autoheader)
-    echo 1>&2 "\
-WARNING: \`$1' is $msg.  You should only need it if
-         you modified \`acconfig.h' or \`${configure_ac}'.  You might want
-         to install the \`Autoconf' and \`GNU m4' packages.  Grab them
-         from any GNU archive site."
-    files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
-    test -z "$files" && files="config.h"
-    touch_files=
-    for f in $files; do
-      case $f in
-      *:*) touch_files="$touch_files "`echo "$f" |
-                                      sed -e 's/^[^:]*://' -e 's/:.*//'`;;
-      *) touch_files="$touch_files $f.in";;
-      esac
-    done
-    touch $touch_files
-    ;;
-
-  automake*)
-    echo 1>&2 "\
-WARNING: \`$1' is $msg.  You should only need it if
-         you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
-         You might want to install the \`Automake' and \`Perl' packages.
-         Grab them from any GNU archive site."
-    find . -type f -name Makefile.am -print |
-          sed 's/\.am$/.in/' |
-          while read f; do touch "$f"; done
-    ;;
-
-  autom4te)
-    echo 1>&2 "\
-WARNING: \`$1' is needed, but is $msg.
-         You might have modified some files without having the
-         proper tools for further handling them.
-         You can get \`$1' as part of \`Autoconf' from any GNU
-         archive site."
-
-    file=`echo "$*" | sed -n "$sed_output"`
-    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
-    if test -f "$file"; then
-       touch $file
-    else
-       test -z "$file" || exec >$file
-       echo "#! /bin/sh"
-       echo "# Created by GNU Automake missing as a replacement of"
-       echo "#  $ $@"
-       echo "exit 0"
-       chmod +x $file
-       exit 1
-    fi
-    ;;
-
-  bison|yacc)
-    echo 1>&2 "\
-WARNING: \`$1' $msg.  You should only need it if
-         you modified a \`.y' file.  You may need the \`Bison' package
-         in order for those modifications to take effect.  You can get
-         \`Bison' from any GNU archive site."
-    rm -f y.tab.c y.tab.h
-    if test $# -ne 1; then
-        eval LASTARG="\${$#}"
-       case $LASTARG in
-       *.y)
-           SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
-           if test -f "$SRCFILE"; then
-                cp "$SRCFILE" y.tab.c
-           fi
-           SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
-           if test -f "$SRCFILE"; then
-                cp "$SRCFILE" y.tab.h
-           fi
-         ;;
-       esac
-    fi
-    if test ! -f y.tab.h; then
-       echo >y.tab.h
-    fi
-    if test ! -f y.tab.c; then
-       echo 'main() { return 0; }' >y.tab.c
-    fi
-    ;;
-
-  lex|flex)
-    echo 1>&2 "\
-WARNING: \`$1' is $msg.  You should only need it if
-         you modified a \`.l' file.  You may need the \`Flex' package
-         in order for those modifications to take effect.  You can get
-         \`Flex' from any GNU archive site."
-    rm -f lex.yy.c
-    if test $# -ne 1; then
-        eval LASTARG="\${$#}"
-       case $LASTARG in
-       *.l)
-           SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
-           if test -f "$SRCFILE"; then
-                cp "$SRCFILE" lex.yy.c
-           fi
-         ;;
-       esac
-    fi
-    if test ! -f lex.yy.c; then
-       echo 'main() { return 0; }' >lex.yy.c
-    fi
-    ;;
-
-  help2man)
-    echo 1>&2 "\
-WARNING: \`$1' is $msg.  You should only need it if
-        you modified a dependency of a manual page.  You may need the
-        \`Help2man' package in order for those modifications to take
-        effect.  You can get \`Help2man' from any GNU archive site."
-
-    file=`echo "$*" | sed -n "$sed_output"`
-    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
-    if test -f "$file"; then
-       touch $file
-    else
-       test -z "$file" || exec >$file
-       echo ".ab help2man is required to generate this page"
-       exit 1
-    fi
-    ;;
-
-  makeinfo)
-    echo 1>&2 "\
-WARNING: \`$1' is $msg.  You should only need it if
-         you modified a \`.texi' or \`.texinfo' file, or any other file
-         indirectly affecting the aspect of the manual.  The spurious
-         call might also be the consequence of using a buggy \`make' (AIX,
-         DU, IRIX).  You might want to install the \`Texinfo' package or
-         the \`GNU make' package.  Grab either from any GNU archive site."
-    # The file to touch is that specified with -o ...
-    file=`echo "$*" | sed -n "$sed_output"`
-    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
-    if test -z "$file"; then
-      # ... or it is the one specified with @setfilename ...
-      infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
-      file=`sed -n '
-       /^@setfilename/{
-         s/.* \([^ ]*\) *$/\1/
-         p
-         q
-       }' $infile`
-      # ... or it is derived from the source name (dir/f.texi becomes f.info)
-      test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
-    fi
-    # If the file does not exist, the user really needs makeinfo;
-    # let's fail without touching anything.
-    test -f $file || exit 1
-    touch $file
-    ;;
-
-  tar)
-    shift
-
-    # We have already tried tar in the generic part.
-    # Look for gnutar/gtar before invocation to avoid ugly error
-    # messages.
-    if (gnutar --version > /dev/null 2>&1); then
-       gnutar "$@" && exit 0
-    fi
-    if (gtar --version > /dev/null 2>&1); then
-       gtar "$@" && exit 0
-    fi
-    firstarg="$1"
-    if shift; then
-       case $firstarg in
-       *o*)
-           firstarg=`echo "$firstarg" | sed s/o//`
-           tar "$firstarg" "$@" && exit 0
-           ;;
-       esac
-       case $firstarg in
-       *h*)
-           firstarg=`echo "$firstarg" | sed s/h//`
-           tar "$firstarg" "$@" && exit 0
-           ;;
-       esac
-    fi
-
-    echo 1>&2 "\
-WARNING: I can't seem to be able to run \`tar' with the given arguments.
-         You may want to install GNU tar or Free paxutils, or check the
-         command line arguments."
-    exit 1
-    ;;
-
-  *)
-    echo 1>&2 "\
-WARNING: \`$1' is needed, and is $msg.
-         You might have modified some files without having the
-         proper tools for further handling them.  Check the \`README' file,
-         it often tells you about the needed prerequisites for installing
-         this package.  You may also peek at any GNU archive site, in case
-         some other package would contain this missing \`$1' program."
-    exit 1
-    ;;
-esac
-
-exit 0
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "scriptversion="
-# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-end: "$"
-# End:
old mode 100644 (file)
new mode 100755 (executable)
index cb0aee2..114fcb1
@@ -1,27 +1,29 @@
-
 Name:       libmm-player
 Summary:    Multimedia Framework Player Library
-Version:    0.2.1
+Version:    0.5.58
 Release:    1
 Group:      System/Libraries
-License:    TBD
+License:    Apache-2.0
 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(appcore-efl)
+BuildRequires:  pkgconfig(elementary)
 BuildRequires:  pkgconfig(mm-session)
 BuildRequires:  pkgconfig(mmutil-imgp)
 BuildRequires:  pkgconfig(audio-session-mgr)
+BuildRequires:  pkgconfig(ecore-x)
+BuildRequires:  pkgconfig(evas)
 BuildRequires:  pkgconfig(iniparser)
-BuildRequires:  pkgconfig(libcrypto)
 BuildRequires:  pkgconfig(vconf)
-
+BuildRequires:  pkgconfig(icu-i18n)
+BuildRequires:  pkgconfig(utilX)
 
 BuildRoot:  %{_tmppath}/%{name}-%{version}-build
 
@@ -41,16 +43,19 @@ Requires:   %{name} = %{version}-%{release}
 
 ./autogen.sh
 
-CFLAGS+=" -DEXPORT_API=\"__attribute__((visibility(\\\"default\\\")))\" "; export CFLAGS
+CFLAGS+="  -Wall -Werror -D_MM_PLAYER_ALP_PARSER -D_FILE_OFFSET_BITS=64 -DMMFW_DEBUG_MODE -DGST_EXT_TIME_ANALYSIS -DUSE_AUDIO_EFFECT -DEXPORT_API=\"__attribute__((visibility(\\\"default\\\")))\" "; export CFLAGS
 LDFLAGS+="-Wl,--rpath=%{_prefix}/lib -Wl,--hash-style=both -Wl,--as-needed"; export LDFLAGS
 
+# always enable sdk build. This option should go away
 CFLAGS=$CFLAGS LDFLAGS=$LDFLAGS ./configure --prefix=%{_prefix} --disable-static
 
 # Call make instruction with smp support
-make -j1 
+make %{?jobs:-j%jobs}
 
 %install
 rm -rf %{buildroot}
+mkdir -p %{buildroot}/%{_datadir}/license
+cp -rf %{_builddir}/%{name}-%{version}/LICENSE.APLv2 %{buildroot}/%{_datadir}/license/%{name}
 %make_install
 
 %clean
@@ -64,9 +69,10 @@ rm -rf %{buildroot}
 
 
 %files
+%manifest libmm-player.manifest
 %defattr(-,root,root,-)
 %{_libdir}/*.so.*
-
+%{_datadir}/license/%{name}
 
 %files devel
 %defattr(-,root,root,-)
old mode 100755 (executable)
new mode 100644 (file)
index 6c85b78..640bbd5
@@ -1,25 +1,10 @@
-lib_LTLIBRARIES = libmmfplayer_m3u8.la
-
-
-libmmfplayer_m3u8_la_SOURCES = mm_player_m3u8.c
-
-libmmfplayer_m3u8_la_CFLAGS =  -I$(srcdir)/include \
-                          $(MMCOMMON_CFLAGS) \
-                          $(GLIB_CFLAGS)
-
-noinst_HEADERS = include/mm_player_m3u8.h
-
-libmmfplayer_m3u8_la_LIBADD = $(GLIB_LIBS) \
-                         $(MMCOMMON_LIBS)
-
-
-lib_LTLIBRARIES += libmmfplayer.la
+lib_LTLIBRARIES = libmmfplayer.la
 
 includelibmmfplayerdir = $(includedir)/mmf
 
 includelibmmfplayer_HEADERS = include/mm_player.h \
                              include/mm_player_internal.h \
-                             include/mm_player_sndeffect.h
+                             include/mm_player_audioeffect.h
 
 libmmfplayer_la_SOURCES = mm_player.c \
                          mm_player_priv.c \
@@ -27,52 +12,45 @@ libmmfplayer_la_SOURCES = mm_player.c \
                          mm_player_utils.c \
                          mm_player_asm.c \
                          mm_player_attrs.c \
-                         mm_player_ahs_hls.c \
-                         mm_player_ahs.c \
                          mm_player_capture.c \
                          mm_player_pd.c \
                          mm_player_streaming.c \
-                         mm_player_sndeffect.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) \
-                         $(CRYPTO_CFLAGS)
-
-noinst_HEADERS += include/mm_player_utils.h \
+                       $(MMCOMMON_CFLAGS) \
+                       $(MMUTIL_CFLAGS) \
+                       $(GST_CFLAGS) \
+                       $(GST_INTERFACE_CFLAGS) \
+                       $(GST_APP_CFLAGS) \
+                       $(MMSESSION_CFLAGS) \
+                       $(MMSOUND_CFLAGS) \
+                       $(AUDIOSESSIONMGR_CFLAGS) \
+                       $(VCONF_CFLAGS) \
+                       $(ICU_CFLAGS) \
+                       $(UTILX_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_ahs.h \
-                include/mm_player_ahs_hls.h \
                 include/mm_player_capture.h \
                 include/mm_player_pd.h \
                 include/mm_player_streaming.h
 
-libmmfplayer_la_DEPENDENCIES = $(top_builddir)/src/libmmfplayer_m3u8.la
-
 libmmfplayer_la_LIBADD = $(GST_LIBS) \
-                        $(MMCOMMON_LIBS) \
-                        $(MMTA_LIBS) \
-                        $(MMUTIL_LIBS) \
-                        $(GST_INTERFACE_LIBS) \
-                        $(GST_APP_LIBS) \
-                        $(INIPARSER_LIBS) \
-                        $(CRYPTO_LIBS) \
-                        $(MMSESSION_LIBS) \
-                        $(MMSOUND_LIBS) \
-                        $(AUDIOSESSIONMGR_LIBS) \
-                        $(VCONF_LIBS) \
-                        $(top_builddir)/src/libmmfplayer_m3u8.la
+               $(MMCOMMON_LIBS) \
+               $(MMUTIL_LIBS) \
+                       $(GST_INTERFACE_LIBS) \
+                       $(GST_APP_LIBS) \
+                       $(INIPARSER_LIBS) \
+                       $(MMSESSION_LIBS) \
+                       $(MMSOUND_LIBS) \
+                       $(AUDIOSESSIONMGR_LIBS) \
+                       $(VCONF_LIBS) \
+            $(ICU_LIBS) \
+                       $(UTILX_LIBS)
 
 libmmfplayer_la_CFLAGS += $(MMLOG_CFLAGS) -DMMF_LOG_OWNER=0x008 -DMMF_DEBUG_PREFIX=\"MMF-PLAYER\" -D_INTERNAL_SESSION_MANAGER_
 libmmfplayer_la_LIBADD += $(MMLOG_LIBS)
index 7d3ce63..3201feb 100755 (executable)
        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, 
+       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 
+       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.
 
@@ -69,7 +69,7 @@
 
        @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 
+       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.
 
        <td>range</td>
        </tr>
        <tr>
-       <td>"display_overlay"</td>
-       <td>data</td>
-       <td>N/A</td>
+       <td>"streaming_timeout"</td>
+       <td>int</td>
+       <td>range</td>
        </tr>
        <tr>
-       <td>"display_overlay_ext"</td>
+       <td>"display_overlay"</td>
        <td>data</td>
        <td>N/A</td>
        </tr>
 
        @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. 
+       Please use mm_fileinfo for local playback.
 
        @par
        <div><table>
 /**
  * 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. 
+ * 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_WIDTH:
  *
- * get the video width (int), It's guaranteed after calling mm_player_start() or 
- * receiving MM_MESSAGE_BEGIN_OF_STREAM. 
+ * 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. 
+ * 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_PLAYBACK_COUNT
  *
- * can set playback count (int), Default value is 1 and -1 is for infinity playing until releasing it. 
+ * 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"
  */
 #define MM_PLAYER_STREAMING_PROXY_PORT         "streaming_proxy_port"
 /**
+ * MM_PLAYER_STREAMING_TIMEOUT
+ *
+ * set the streaming timeout (int)
+ */
+#define MM_PLAYER_STREAMING_TIMEOUT                    "streaming_timeout"
+/**
  * MM_PLAYER_VIDEO_CODEC
  *
  * codec the video data is stored in (string)
  */
 #define MM_PLAYER_PD_MODE                                              "pd_mode"
 
+#define BUFFER_MAX_PLANE_NUM (4)
+
+typedef struct {
+       MMPixelFormatType format;                       /**< image format */
+       int width;                                              /**< width of video buffer */
+       int height;                                             /**< height of video buffer */
+       unsigned int timestamp;                         /**< timestamp of stream buffer (msec)*/
+       unsigned int length_total;                      /**< total length of stream buffer (in byte)*/
+       void *data;
+       void *bo[BUFFER_MAX_PLANE_NUM];  /**< TBM buffer object */
+       void *internal_buffer;                          /**< Internal buffer pointer */
+       int stride[BUFFER_MAX_PLANE_NUM];               /**< stride of plane */
+       int elevation[BUFFER_MAX_PLANE_NUM];    /**< elevation of plane */
+}MMPlayerVideoStreamDataType;
+
 /**
  * Enumerations of player state.
  */
@@ -718,12 +739,45 @@ typedef enum {
  * Enumeration of track types
  */
 typedef enum {
-       MM_PLAYER_TRACK_TYPE_AUDIO,
+       MM_PLAYER_TRACK_TYPE_AUDIO = 0,
        MM_PLAYER_TRACK_TYPE_VIDEO,
-       MM_PLAYER_TRACK_TYPE_TEXT
+       MM_PLAYER_TRACK_TYPE_TEXT,
+       MM_PLAYER_TRACK_TYPE_MAX
 }MMPlayerTrackType;
 
 /**
+ * Enumeration of runtime buffering mode
+ */
+typedef enum {
+       MM_PLAYER_BUFFERING_MODE_ADAPTIVE = 0,  /**< default, If buffering is occurred, player will consider the bandwidth to adjust buffer setting. */
+       MM_PLAYER_BUFFERING_MODE_FIXED,                 /**< player will set buffer size with this fixed size value. */
+       MM_PLAYER_BUFFERING_MODE_SLINK,                 /**< If buffering is occurred, player will adjust buffer setting and no more buffering will be occurred again. */
+       MM_PLAYER_BUFFERING_MODE_MAX = MM_PLAYER_BUFFERING_MODE_SLINK,
+}MMPlayerBufferingMode;
+
+/**
+ * Enumeration of audio channel for video share
+ */
+typedef enum
+{
+       MM_PLAYER_AUDIO_CH_MONO_LEFT = 0,
+       MM_PLAYER_AUDIO_CH_MONO_RIGHT,
+       MM_PLAYER_AUDIO_CH_STEREO,
+} MMPlayerAudioChannel;
+
+/**
+ * Edge Properties of the text.
+ */
+typedef enum {
+       MM_PLAYER_EDGE_NO,
+       MM_PLAYER_EDGE_RAISED,
+       MM_PLAYER_EDGE_DEPRESSED,
+       MM_PLAYER_EDGE_UNIFORM,
+       MM_PLAYER_EDGE_DROPSHADOW
+} MMPlayerSubtitleEdge;
+
+
+/**
  * Attribute validity structure
  */
 typedef struct {
@@ -793,6 +847,18 @@ typedef struct {
 typedef bool   (*mm_player_audio_stream_callback) (void *stream, int stream_size, void *user_param);
 
 
+/**
+ * selected subtitle track number callback function type.
+ *
+ * @param      track_num       [in]    Track number of subtitle
+ * @param      user_param      [in]    User defined parameter
+ *
+ *
+ * @return     This callback function have to return MM_ERROR_NONE.
+ */
+typedef bool           (*mm_player_track_selected_subtitle_language_callback)(int track_num, void *user_param);
+
+
 /*===========================================================================================
 |                                                                                           |
 |  GLOBAL FUNCTION PROTOTYPES                                        |
@@ -810,28 +876,28 @@ typedef bool      (*mm_player_audio_stream_callback) (void *stream, int stream_size,
  * @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 
+ * @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.  
+ *                     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) 
+if (mm_player_create(&g_player) != MM_ERROR_NONE)
 {
-       printf("failed to create player\n");
+       debug_error("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) 
+                                               NULL) != MM_ERROR_NONE)
 {
-       printf("failed to set %s attribute\n", g_err_attr_name);
+       debug_error("failed to set %s attribute\n", g_err_attr_name);
        free(g_err_attr_name);
 }
 
@@ -842,25 +908,25 @@ 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. 
+ * 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. 
+ *                     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) 
+if (mm_player_destroy(g_player) != MM_ERROR_NONE)
 {
-       printf("failed to destroy player\n");
+       debug_error("failed to destroy player\n");
 }
- * @endcode 
+ * @endcode
  */
 int mm_player_destroy(MMHandleType player);
 
@@ -873,14 +939,14 @@ int mm_player_destroy(MMHandleType 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. 
+ * @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) 
+if (mm_player_realize(g_player) != MM_ERROR_NONE)
 {
-       printf("failed to realize player\n");
+       debug_error("failed to realize player\n");
 }
  * @endcode
  */
@@ -889,30 +955,30 @@ 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. 
+ * 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.  
+ *                     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) 
+if (mm_player_unrealize(g_player) != MM_ERROR_NONE)
 {
-       printf("failed to unrealize player\n");
+       debug_error("failed to unrealize player\n");
 }
- * @endcode 
+ * @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. 
+ * 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
@@ -923,25 +989,25 @@ int mm_player_unrealize(MMHandleType player);
  * @remark     None
  * @par Example
  * @code
-if (mm_player_get_state(g_player, &state) != MM_ERROR_NONE) 
+if (mm_player_get_state(g_player, &state) != MM_ERROR_NONE)
 {
-       printf("failed to get state\n");
-} 
- * @endcode 
+       debug_error("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. 
+ * 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. 
+ * @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;
@@ -952,9 +1018,9 @@ for (i = 0; i < MM_VOLUME_CHANNEL_NUM; i++)
 
 if (mm_player_set_volume(g_player, &volume) != MM_ERROR_NONE)
 {
-    printf("failed to set volume\n");
+    debug_error("failed to set volume\n");
 }
- * @endcode 
+ * @endcode
  */
 int mm_player_set_volume(MMHandleType player, MMPlayerVolumeType *volume);
 
@@ -965,7 +1031,7 @@ int mm_player_set_volume(MMHandleType player, MMPlayerVolumeType *volume);
  * @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
@@ -975,12 +1041,12 @@ int i;
 
 if (mm_player_get_volume(g_player, &volume) != MM_ERROR_NONE)
 {
-        printf("failed to get volume\n");
+        debug_warning("failed to get volume\n");
 }
 
 for (i = 0; i < MM_VOLUME_CHANNEL_NUM; i++)
-       printf("channel[%d] = %d \n", i, volume.level[i]);
- * @endcode 
+       debug_log("channel[%d] = %d \n", i, volume.level[i]);
+ * @endcode
  */
 int mm_player_get_volume(MMHandleType player, MMPlayerVolumeType *volume);
 
@@ -995,23 +1061,23 @@ int mm_player_get_volume(MMHandleType player, MMPlayerVolumeType *volume);
  * @remark
  *
  * @pre                Player state may be MM_PLAYER_STATE_READY.
- * @post               Player state will be MM_PLAYER_STATE_PLAYING. 
- * @see                mm_player_stop 
+ * @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) 
+ * @par Example
+ * @code
+if (mm_player_start(g_player) != MM_ERROR_NONE)
 {
-       printf("failed to start player\n");
+       debug_error("failed to start player\n");
 }
- * @endcode 
+ * @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.  
+ * So, it can be used to close current playback.
  *
  * @param      player          [in]    Handle of player
  *
@@ -1019,15 +1085,15 @@ int mm_player_start(MMHandleType player);
  *
  * @pre                Player state may be MM_PLAYER_STATE_PLAYING.
  * @post               Player state will be MM_PLAYER_STATE_READY.
- * @see                mm_player_start 
+ * @see                mm_player_start
  * @remark     None
- * @par Example 
+ * @par Example
  * @code
-if (mm_player_stop(g_player) != MM_ERROR_NONE) 
+if (mm_player_stop(g_player) != MM_ERROR_NONE)
 {
-       printf("failed to stop player\n");
+       debug_error("failed to stop player\n");
 }
- * @endcode 
+ * @endcode
  */
 int mm_player_stop(MMHandleType player);
 
@@ -1036,19 +1102,19 @@ int mm_player_stop(MMHandleType player);
  *
  * @param      player          [in]    Handle of player.
  *
- * @return     This function returns zero on success, or negative value with error code. 
+ * @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 
+ * @see                mm_player_resume
  * @remark     None
- * @par Example 
+ * @par Example
  * @code
-if (mm_player_pause(g_player) != MM_ERROR_NONE) 
+if (mm_player_pause(g_player) != MM_ERROR_NONE)
 {
-       printf("failed to pause player\n");
+       debug_error("failed to pause player\n");
 }
- * @endcode 
+ * @endcode
  */
 int mm_player_pause(MMHandleType player);
 
@@ -1061,38 +1127,38 @@ int mm_player_pause(MMHandleType player);
  *
  * @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 
+ * @see                mm_player_pause
+ * @remark     None
+ * @par Example
  * @code
-if (mm_player_resume(g_player) != MM_ERROR_NONE) 
+if (mm_player_resume(g_player) != MM_ERROR_NONE)
 {
-       printf("failed to resume player\n");
+       debug_error("failed to resume player\n");
 }
- * @endcode 
+ * @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 
+ * @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 
+       debug_error("failed to set position\n");
+}
+ * @endcode
  */
 int mm_player_set_position(MMHandleType player, MMPlayerPosFormatType format, int pos);
 
@@ -1105,8 +1171,8 @@ int mm_player_set_position(MMHandleType player, MMPlayerPosFormatType format, in
  *
  * @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 
+ * @remark     the unit of time-based format is millisecond and other case is percent.
+ * @par Example
  * @code
 int position = 0;
 int duration = 0;
@@ -1115,8 +1181,8 @@ 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 
+debug_log("pos: [%d/%d] msec\n", position, duration);
+ * @endcode
  */
 int mm_player_get_position(MMHandleType player, MMPlayerPosFormatType format, int *pos);
 
@@ -1130,15 +1196,15 @@ int mm_player_get_position(MMHandleType player, MMPlayerPosFormatType format, in
  *
  * @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 
+ * @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 
+debug_log("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);
 
@@ -1154,7 +1220,7 @@ int mm_player_get_buffer_position(MMHandleType player, MMPlayerPosFormatType for
  * @return     This function returns zero on success, or negative value with error code.
  * @see                mm_player_deactivate_section_repeat
  * @remark     None
- * @par Example 
+ * @par Example
  * @code
 int position;
 int endtime = 4000; //msec
@@ -1162,7 +1228,7 @@ 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 
+ * @endcode
  */
 int mm_player_activate_section_repeat(MMHandleType player, int start_pos, int end_pos);
 
@@ -1173,20 +1239,20 @@ int mm_player_activate_section_repeat(MMHandleType player, int start_pos, int en
  *
  * @return     This function returns zero on success, or negative value with error code.
  * @see                mm_player_activate_section_repeat
- * @remark     None 
- * @par Example 
+ * @remark     None
+ * @par Example
  * @code
 if ( mm_player_deactivate_section_repeat(g_player) != MM_ERROR_NONE)
 {
-       printf("failed to deactivate section repeat\n");
-} 
- * @endcode 
+       debug_warning("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. 
+ * So, player can notify warning, error and normal cases to application.
  *
  * @param      player          [in]    Handle of player.
  * @param      callback        [in]    Message callback function.
@@ -1194,29 +1260,29 @@ int mm_player_deactivate_section_repeat(MMHandleType player);
  *
  * @return     This function returns zero on success, or negative value with error code.
  * @see                MMMessageCallback
- * @remark     None 
- * @par Example 
+ * @remark     None
+ * @par Example
  * @code
-int msg_callback(int message, MMMessageParamType *param, void *user_param) 
+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;
        }
@@ -1224,7 +1290,7 @@ int msg_callback(int message, MMMessageParamType *param, void *user_param)
 }
 
 mm_player_set_message_callback(g_player, msg_callback, (void*)g_player);
- * @endcode 
+ * @endcode
  */
 int mm_player_set_message_callback(MMHandleType player, MMMessageCallback callback, void *user_param);
 
@@ -1242,16 +1308,16 @@ int mm_player_set_message_callback(MMHandleType player, MMMessageCallback callba
  * @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 
+ * @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");
+       debug_log("audio stream callback\n");
        return TRUE;
 }
 mm_player_set_audio_stream_callback(g_player, audio_callback, NULL);
- * @endcode 
+ * @endcode
  */
  int mm_player_set_audio_stream_callback(MMHandleType player, mm_player_audio_stream_callback callback, void *user_param);
 
@@ -1264,13 +1330,13 @@ mm_player_set_audio_stream_callback(g_player, audio_callback, NULL);
  * @return     This function returns zero on success, or negative value with error code
  * @see                mm_player_get_mute
  * @remark     None
- * @par Example 
+ * @par Example
  * @code
 if (mm_player_set_mute(g_player, TRUE) != MM_ERROR_NONE)
 {
-       printf("failed to set mute\n");
-} 
- * @endcode 
+       debug_warning("failed to set mute\n");
+}
+ * @endcode
  */
 int mm_player_set_mute(MMHandleType player, int mute);
 
@@ -1283,17 +1349,17 @@ int mm_player_set_mute(MMHandleType player, int mute);
  * @return     This function returns zero on success, or negative value with error code
  * @see                mm_player_set_mute
  * @remark     None
- * @par Example 
+ * @par Example
  * @code
 int mute;
+
 if (mm_player_get_mute(g_player, &mute) != MM_ERROR_NONE)
 {
-       printf("failed to get mute\n");
+       debug_warning("failed to get mute\n");
 }
 
-printf("mute status:%d\n", mute);
- * @endcode 
+debug_log("mute status:%d\n", mute);
+ * @endcode
  */
 int mm_player_get_mute(MMHandleType player, int *mute);
 
@@ -1315,7 +1381,7 @@ 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");
+       debug_warning("failed to adjust subtitle postion.\n");
 }
  * @endcode
  */
@@ -1323,59 +1389,6 @@ if (mm_player_adjust_subtitle_position(g_player, MM_PLAYER_POS_FORMAT_TIME, pos)
 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
  *
@@ -1389,22 +1402,22 @@ int mm_player_get_subtitle_silent(MMHandleType player, int *silent);
  *
  * @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 
+ *                     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, 
+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);
+       debug_warning("failed to set %s attribute\n", g_err_attr_name);
        free(g_err_attr_name);
 }
 
- * @endcode 
+ * @endcode
  */
 int mm_player_set_attribute(MMHandleType player,  char **err_attr_name, const char *first_attribute_name, ...)G_GNUC_NULL_TERMINATED;
 
@@ -1421,17 +1434,17 @@ int mm_player_set_attribute(MMHandleType player,  char **err_attr_name, const ch
  *                     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 
+ *                     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);
+       debug_warning("failed to set %s attribute\n", g_err_attr_name);
        free(g_err_attr_name);
 }
- * @endcode 
+ * @endcode
  */
 int mm_player_get_attribute(MMHandleType player,  char **err_attr_name, const char *first_attribute_name, ...)G_GNUC_NULL_TERMINATED;
 
@@ -1447,23 +1460,23 @@ int mm_player_get_attribute(MMHandleType player,  char **err_attr_name, const ch
  *
  * @see                mm_player_set_attribute, mm_player_get_attribute
  * @remark     None
- * @par Example 
+ * @par Example
  * @code
 if (mm_player_get_attribute_info (g_player, "display_method", &method_info) != MM_ERROR_NONE)
 {
-       printf("failed to get info\n");
+       debug_warning("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..
+debug_log("type:%d \n", method_info.type); //int, double..
+debug_log("flag:%d \n", method_info.flag); //readable, writable..
+debug_log("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);
+       debug_log("range min:%d\n", method_info.int_range.min);
+       debug_log("range max:%d\n", method_info.int_range.max);
 }
- * @endcode 
+ * @endcode
  */
 int mm_player_get_attribute_info(MMHandleType player,  const char *attribute_name, MMPlayerAttrsInfo *info);
 
@@ -1485,7 +1498,7 @@ 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);
+       debug_log("current download pos = %llu, total size = %llu\n", current_pos, total_size);
 }
  * @endcode
  */
@@ -1508,10 +1521,10 @@ int msg_callback(int message, MMMessageParamType *param, void *user_param)
        switch (message)
        {
                case MM_MESSAGE_PD_DOWNLOADER_START:
-                       printf("Progressive download is started...\n");
+                       debug_log("Progressive download is started...\n");
                        break;
                case MM_MESSAGE_PD_DOWNLOADER_END:
-                       printf("Progressive download is ended...\n");
+                       debug_log("Progressive download is ended...\n");
                        break;
                default:
                        break;
@@ -1525,30 +1538,99 @@ mm_player_set_pd_message_callback(g_player, msg_callback, NULL);
 int mm_player_set_pd_message_callback(MMHandleType player, MMMessageCallback callback, void *user_param);
 
 /**
- * This function is to get the track count
+ * This function is to set the start position of zoom
  *
- * @param      player          [in]    handle of player.
- * @param      track_type      [in]    type of the track type
- * @param      info                    [out]   the count of the track
+ * @param       player          [in]    handle of player
+ * @param       level           [in]    level of zoom
+ * @param       x              [in]    start x position
+ * @param       y              [in]    start y position
  *
- * @return     This function returns zero on success, or negative value with error
- *                     code.
+ * @return      This function returns zero on success, or negative value with error
+ *                      code.
  *
  * @see
- * @remark     None
- * @par Example
- * @code
-gint audio_count = 0;
+ * @remark      None
+ */
+int mm_player_set_display_zoom(MMHandleType player, float level, int x, int y);
 
-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");
-}
+/**
+ * This function is to get the start position of zoom
+ *
+ * @param       player           [in]    handle of player
+ * @param       type            [out]    current level of zoom
+ * @param       x              [out]    start x position
+ * @param       y              [out]    start y position
+ *
+ * @return      This function returns zero on success, or negative value with error
+ *                      code.
+ *
+ * @see
+ * @remark      None
+ */
+int mm_player_get_display_zoom(MMHandleType player, float *level, int *x, int *y);
 
-printf("audio track count : %d \n", audio_count);
- * @endcode
+/**
+ * This function is to set the subtitle path
+ *
+ * @param       player  [in]    handle of player
+ * @param       path    [in]    subtitle path
+ *
+ * @return      This function returns zero on success, or negative value with error code.
+ *
+ * @see
+ * @remark      None
+ */
+int mm_player_set_external_subtitle_path(MMHandleType player, const char* path);
+
+/**
+ * This function is to set audio channel
+ *
+ * @param       player         [in]    handle of player
+ * @param       ch                     [in]    audio channel
+ * @return      This function returns zero on success, or negative value with error code.
+ *
+ * @see
+ * @remark      None
  */
-int mm_player_get_track_count(MMHandleType player,  MMPlayerTrackType track_type, int *count);
+int mm_player_gst_set_audio_channel(MMHandleType player, MMPlayerAudioChannel ch);
+
+/**
+ * This function is to set uri.
+ *
+ * @param       player         [in]    handle of player
+ * @param       uri            [in]    uri
+ * @return      This function returns zero on success, or negative value with error code.
+ *
+ * @see
+ * @remark      None
+ */
+int mm_player_set_uri(MMHandleType player, const char *uri);
+
+/**
+ * This function is to set next uri.
+ *
+ * @param       player         [in]    handle of player
+ * @param       uri            [in]    uri
+ * @return      This function returns zero on success, or negative value with error code.
+ *
+ * @see
+ * @remark      None
+ */
+int mm_player_set_next_uri(MMHandleType player, const char *uri);
+
+/**
+ * This function is to get next uri.
+ *
+ * @param       player         [in]    handle of player
+ * @param       uri            [out]   uri
+ * @return      This function returns zero on success, or negative value with error code.
+ *
+ * @see
+ * @remark      None
+ */
+int mm_player_get_next_uri(MMHandleType player, char **uri);
+
+int mm_player_enable_media_packet_video_stream(MMHandleType player, bool enable);
 
 
 /**
diff --git a/src/include/mm_player_ahs.h b/src/include/mm_player_ahs.h
deleted file mode 100755 (executable)
index 7caafe7..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * 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>,
- * naveen cherukuri <naveen.ch@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_AHS_H__
-#define        __MM_PLAYER_AHS_H__
-
-#include <glib.h>
-#include "mm_player_ahs_hls.h"
-#include <gst/gst.h>
-#include <gst/app/gstappsrc.h>
-#include <gst/app/gstappsink.h>
-#include <string.h>
-#include "mm_debug.h"
-
-#define HLS_POSIX_PATH_MAX                             256
-#define HLS_MANIFEST_DEFAULT_PATH              "/opt/media/"
-#define HLS_MANIFEST_DEFAULT_FILE_NAME HLS_MANIFEST_DEFAULT_PATH"XXXXXX"
-
-typedef struct
-{
-       void *ahs_client;
-       GstElement *appsrc; /* appsrc to push data */
-
-       int uri_type;
-       gboolean need_bw_switch;
-       
-       /* manifest file (mf) uris */
-       gchar *main_mf_uri;
-       
-       /* user agent */
-       gchar *user_agent;
-
-       gchar *cur_mf_uri;
-       gchar *cur_media_uri;
-       gchar *cur_key_uri;
-       gchar cur_key_data[16];
-       char cur_iv[16];
-       
-       char ahs_manifest_dmp_location[HLS_POSIX_PATH_MAX];  /* manifest file dumped location */
-       char ahs_key_dmp_location [HLS_POSIX_PATH_MAX];
-       
-       int ahs_state;
-       GMutex* state_lock;
-
-       /* manifest/playlist download */
-       GThread *manifest_thread;
-       gboolean manifest_thread_exit;
-       GstElement *manifest_download_pipeline;
-       GstElement *manifest_download_src;
-       GstElement *manifest_download_sink;
-       GCond* manifest_start_cond;
-       GCond* manifest_update_cond;
-       GCond* manifest_eos_cond;
-       GCond* manifest_exit_cond;
-       GMutex* manifest_mutex;
-
-       /* media download */
-       GThread *media_thread;
-       GMutex *media_mutex;
-       gboolean media_thread_exit;
-       GstElement *media_download_pipeline;
-       GstElement *media_download_src;
-       GstElement *media_download_sink;
-       GCond *media_eos_cond;
-       GCond *media_start_cond;
-
-       /* key download */
-       GstElement *key_download_pipeline;
-       GstElement *key_download_src;
-       GstElement *key_download_sink;
-       GCond *key_eos_cond;
-
-       guint64 seg_start_time;     /* segment start time in usec*/
-       guint64 seg_end_time;     /* segment end time usec*/
-       guint download_rate;
-       guint64 seg_size;
-       gint cache_frag_count;
-
-       gboolean hls_is_wait_for_reload;
-
-       GCond* tmp_cond;
-
-       gboolean is_initialized;
-}mm_player_ahs_t;
-
-
-
-mm_player_ahs_t * __mm_player_ahs_create ();
-gboolean __mm_player_ahs_initialize (mm_player_ahs_t *ahs_player, int uri_type, char *uri, GstElement *appsrc);
-gboolean __mm_player_ahs_start (mm_player_ahs_t *ahs_player);
-gboolean  __mm_player_ahs_deinitialize (mm_player_ahs_t *ahs_player);
-gboolean __mm_player_ahs_stop (mm_player_ahs_t *ahs_player);
-gboolean __mm_player_ahs_destroy (mm_player_ahs_t *ahs_player);
-gboolean
-ahs_store_media_presentation (mm_player_ahs_t *ahs_player, unsigned char *buffer, unsigned int buffer_len);
-gboolean ahs_check_allow_cache (mm_player_ahs_t *ahs_player);
-#endif
-
diff --git a/src/include/mm_player_ahs_hls.h b/src/include/mm_player_ahs_hls.h
deleted file mode 100755 (executable)
index 8bea5d5..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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>,
- * naveen cherukuri <naveen.ch@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_AHS_HLS_H__
-#define        __MM_PLAYER_AHS_HLS_H__
-
-#include "mm_player_m3u8.h"
-#include <glib.h>
-#include <gst/gst.h>
-#include "mm_debug.h"
-#include <string.h>
-#include <openssl/evp.h>
-#include <openssl/aes.h>
-
-typedef struct
-{
-       gchar *uri;
-       EVP_CIPHER_CTX decrypt;
-       GstM3U8Client *client;
-       GstBuffer *remained; /* remained data in aes decryption */
-       gboolean discontinuity; /* discontinuity flag */
-       GList *list_to_switch;
-       FILE *allow_cache_fd;
-}mm_player_hls_t;
-#define DEFAULT_FRAGMENTS_CACHE 2
-
-
-void * __mm_player_hls_create ();
-gboolean __mm_player_hls_destroy (void *hls_handle);
-gboolean __mm_player_hls_initialize (void *hls_handle, gchar *uri);
-gboolean hls_decryption_initialize (void *hls_handle, gchar *key_data, unsigned char *iv);
-gboolean hls_decrypt_media_fragment (void *hls_handle,GstBuffer *InBuf, GstBuffer **OutBuf);
-gboolean hls_get_next_media_fragment (void *hls_handle, gchar **media_uri, gchar **key_uri, char **iv);
-gboolean hls_switch_playlist (void *hls_handle, guint download_rate, gboolean *need_bw_switch);
-gboolean hls_playlist_update_interval (void *hls_handle, GTimeVal *next_update);
-gboolean hls_has_variant_playlist (void *hls_handle);
-gchar  *hls_get_current_playlist (mm_player_hls_t *hls_player);
-gboolean hls_set_current_playlist (mm_player_hls_t *hls_player);
-gboolean hls_parse_playlist_update_client (void *hls_handle, char* playlist);
-gboolean hls_client_is_live (void *hls_handle);
-gboolean hls_determining_next_file_load (void *hls_handle, gboolean *is_ready);
-gboolean hls_is_buffer_discontinuous (void *hls_handle);
-gboolean hls_downloaded_variant_playlist (void *hls_handle, gchar *cur_mf_uri);
-gboolean hls_clear_discontinuous (void *hls_handle);
-gboolean hls_check_allow_cache (void *hls_handle);
-gboolean hls_store_media_presentation (void *hls_handle, unsigned char *buffer, unsigned int buffer_len);
-#endif
-
index dc5f8b2..fd239d7 100755 (executable)
  * 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>
@@ -38,16 +37,23 @@ extern "C" {
 typedef struct {
        int handle;
        int pid;
-       int by_asm_cb;
+       bool by_asm_cb;
+       int antishock;
        int event_src;
+       int skip_session;
+       bool keep_last_pos;
+       int user_route_policy;
        ASM_sound_states_t state;
        ASM_sound_events_t event;
+       ASM_resource_t resource;
+       bool exit_cb;
+       bool cb_pending;
 } 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);
+gint _mmplayer_asm_unregister(MMPlayerASM* sm);
+gint _mmplayer_asm_set_state(MMHandleType player, ASM_sound_states_t state, gboolean enable_safety_vol);
+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);
 
 #ifdef __cplusplus
 }
index 12d124f..bbbe8f6 100755 (executable)
@@ -64,7 +64,7 @@ int _mmplayer_get_attribute(MMHandleType handle,  char **err_atr_name, const cha
  * @see
  *
  */
-int _mmplayer_get_attribute_info(MMHandleType handle,  const char *attribute_name, MMPlayerAttrsInfo *info);
+int _mmplayer_get_attributes_info(MMHandleType handle,  const char *attribute_name, MMPlayerAttrsInfo *info);
 /**
  * This function allocates structure of attributes and sets initial values.
  *
diff --git a/src/include/mm_player_audioeffect.h b/src/include/mm_player_audioeffect.h
new file mode 100755 (executable)
index 0000000..4ac1f4e
--- /dev/null
@@ -0,0 +1,324 @@
+/*
+ * 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
+
+#define MM_AUDIO_EFFECT_SQUARE_VALUE_MAX       4
+#define MM_AUDIO_EFFECT_SQUARE_VALUE_MIN       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_TUBE,         /**<  Preset type Tube */
+       MM_AUDIO_EFFECT_PRESET_VIRT71,       /**<  Preset type Virtual 7.1 */
+       MM_AUDIO_EFFECT_PRESET_STUDIO,       /**<  Preset type Studio */
+       MM_AUDIO_EFFECT_PRESET_CLUB,         /**<  Preset type Club */
+       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,
+       MM_AUDIO_EFFECT_TYPE_SQUARE,
+} MMAudioEffectType;
+
+
+/**
+ * Enumerations of Output Mode
+ */
+typedef enum {
+       MM_AUDIO_EFFECT_OUTPUT_SPK,    /**< Speaker out */
+       MM_AUDIO_EFFECT_OUTPUT_EAR,    /**< Earjack out */
+       MM_AUDIO_EFFECT_OUTPUT_OTHERS, /**< MIRRORING out */
+       MM_AUDIO_EFFECT_OUTPUT_BT,
+       MM_AUDIO_EFFECT_OUTPUT_DOCK,
+       MM_AUDIO_EFFECT_OUTPUT_MULTIMEDIA_DOCK,
+       MM_AUDIO_EFFECT_OUTPUT_USB_AUDIO,
+       MM_AUDIO_EFFECT_OUTPUT_HDMI,
+       MM_AUDIO_EFFECT_OUTPUT_NUM
+} 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*/
+       int square_row;    /**< for square type, square row configure*/
+       int square_col;    /**< for square type, square col configure*/
+} 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 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 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 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__ */
index 81eb123..44dcbb4 100755 (executable)
@@ -1,74 +1,75 @@
-/*\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>,\r
- * Seungbae Shin <seungbae.shin@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
+/*
+ * 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_CAPTURE_H__
+#define __MM_PLAYER_CAPTURE_H__
+
+/*=======================================================================================
+| INCLUDE FILES                                                                                |
+========================================================================================*/
+#include <mm_types.h>
+#include "mm_player_priv.h"
+
+#ifdef __cplusplus
+       extern "C" {
+#endif
+
+/*=======================================================================================
+| GLOBAL FUNCTION PROTOTYPES                                                           |
+========================================================================================*/
+/**
+ * This function is to initialize video capture
+ *
+ * @param[in]  handle          Handle of player.
+ * @return     This function returns zero on success, or negative value with errors.
+ * @remarks
+ * @see
+ *
+ */
+int _mmplayer_initialize_video_capture(mm_player_t* player);
+/**
+ * This function is to release video capture
+ *
+ * @param[in]  handle          Handle of player.
+ * @return     This function returns zero on success, or negative value with errors.
+ * @remarks
+ * @see
+ *
+ */
+int _mmplayer_release_video_capture(mm_player_t* player);
+/**
+ * This function is to get video snapshot during playback.
+ *
+ * @param[in]  handle          Handle of player.
+ * @return     This function returns zero on success, or negative value with errors.
+ * @remarks
+ * @see
+ *
+ */
+int _mmplayer_do_video_capture(MMHandleType hplayer);
+
+#ifdef __cplusplus
+       }
+#endif
+
+#endif
+
index 6fb472f..7d61a2e 100755 (executable)
@@ -25,7 +25,7 @@
 
 #include <glib.h>
 #include <mm_types.h>
-#include "mm_player_sndeffect.h"
+#include "mm_player_audioeffect.h"
 
 #ifdef __cplusplus
        extern "C" {
 
 
 #define MM_PLAYER_INI_DEFAULT_PATH     "/usr/etc/mmfw_player.ini"
-
-#define PLAYER_INI() mm_player_ini_get_structure()
+#define MM_PLAYER_INI_DEFAULT_AUDIOEFFECT_PATH "/usr/etc/mmfw_player_audio_effect.ini"
 
 #define PLAYER_INI_MAX_STRLEN  100
 #define PLAYER_INI_MAX_PARAM_STRLEN    256
 
+#define PLAYER_INI_MAX_ELEMENT 10
+
 /* 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.
  * before that time, we should be careful with size limitation
  * of each string item.
  */
+enum keyword_type
+{
+       KEYWORD_EXCLUDE,        // for element exclude keyworld
+       KEYWORD_DUMP            // for dump element keyworld
+};
 
 /* @ mark means the item has tested */
 typedef struct __mm_player_ini
 {
        /* general */
-       gboolean use_decodebin; // @
-       gint video_surface;
        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_audio_resampler[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; // @
+       gboolean skip_rescan;
+       gboolean generate_dot;
+       gboolean provide_clock_for_music;
+       gboolean provide_clock_for_movie;
+       gint live_state_change_timeout;
+       gint localplayback_state_change_timeout;
        gint delay_before_repeat;
-       gint eos_delay; // @
+       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];
+
+       gchar gst_param[5][PLAYER_INI_MAX_PARAM_STRLEN];
+       gchar exclude_element_keyword[PLAYER_INI_MAX_ELEMENT][PLAYER_INI_MAX_STRLEN];
        gboolean async_start;
        gboolean disable_segtrap;
 
-       /* audio filter */
-       gboolean use_audio_filter_preset;
-       gboolean audio_filter_preset_list[MM_AUDIO_FILTER_PRESET_NUM];
-       gboolean audio_filter_preset_earphone_only_list[MM_AUDIO_FILTER_PRESET_NUM];
+       /* audio effect */
+       gchar name_of_audio_effect[PLAYER_INI_MAX_STRLEN];
+       gchar name_of_audio_effect_sec[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];
 
-       gboolean use_audio_filter_custom;
-       gboolean audio_filter_custom_list[MM_AUDIO_FILTER_CUSTOM_NUM];
-       gboolean audio_filter_custom_earphone_only_list[MM_AUDIO_FILTER_CUSTOM_NUM];
-       gint audio_filter_custom_eq_num;
-       gint audio_filter_custom_ext_num;
-       gint audio_filter_custom_min_level_list[MM_AUDIO_FILTER_CUSTOM_NUM];
-       gint audio_filter_custom_max_level_list[MM_AUDIO_FILTER_CUSTOM_NUM];
+       gboolean use_audio_effect_square;
+       gint audio_effect_square_max_row;
+       gint audio_effect_square_max_col;
 
        /* http streaming */
-       gchar name_of_httpsrc[PLAYER_INI_MAX_STRLEN]; // @
+       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;
+       gint http_timeout;
 
        /* rtsp streaming */
-       gchar name_of_rtspsrc[PLAYER_INI_MAX_STRLEN]; // @
+       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 */
 
        /* hw accelation */
-       gboolean use_video_hw_accel; // @
-       
+       gboolean use_video_hw_accel;
+
        /* priority */
        gboolean use_priority_setting;
        gint demux_priority;
        gint audiosink_priority;
        gint videosink_priority;
        gint ringbuffer_priority;
+
+       /* subtitle */
+       gint mirroring_width;
+       gint mirroring_height;
+       guint font_color;
+       guint font_background_color;
+       gboolean external_subtitle;
+
+       /* dump buffer for debug */
+       gchar dump_element_keyword[PLAYER_INI_MAX_ELEMENT][PLAYER_INI_MAX_STRLEN];
+       gchar dump_element_path[PLAYER_INI_MAX_STRLEN];
+       gboolean set_dump_element_flag;
 } mm_player_ini_t;
 
 /* default values if each values are not specified in inifile */
 /* general */
-#define DEFAULT_USE_DECODEBIN                          FALSE
-#define DEFAULT_USE_AUDIO_FILTER_PRESET                        FALSE
-#define DEFAULT_AUDIO_FILTER_PRESET_LIST               ""
-#define DEFAULT_AUDIO_FILTER_PRESET_LIST_EARPHONE_ONLY ""
-#define DEFAULT_USE_AUDIO_FILTER_CUSTOM                        FALSE
-#define DEFAULT_AUDIO_FILTER_CUSTOM_LIST               ""
-#define DEFAULT_AUDIO_FILTER_CUSTOM_LIST_EARPHONE_ONLY ""
-#define DEFAULT_AUDIO_FILTER_CUSTOM_EQ_NUM             0
-#define DEFAULT_AUDIO_FILTER_CUSTOM_EQ_MIN             0
-#define DEFAULT_AUDIO_FILTER_CUSTOM_EQ_MAX             0
-#define DEFAULT_AUDIO_FILTER_CUSTOM_EXT_NUM            0
+#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_AUDIO_EFFECT_SQUARE                        FALSE
+#define DEFAULT_AUDIO_EFFECT_SQUARE_ROW_MAX            0
+#define DEFAULT_AUDIO_EFFECT_SQUARE_COL_MAX            0
 #define DEFAULT_USE_SINK_HANDLER                       TRUE
 #define DEFAULT_SKIP_RESCAN                            TRUE
 #define DEFAULT_GENERATE_DOT                           FALSE
-#define DEFAULT_PROVIDE_CLOCK                          TRUE
+#define DEFAULT_PROVIDE_CLOCK_FOR_MUSIC                TRUE
+#define DEFAULT_PROVIDE_CLOCK_FOR_MOVIE                FALSE
 #define DEFAULT_DELAY_BEFORE_REPEAT                    50 /* msec */
 #define DEFAULT_EOS_DELAY                              150 /* msec */
 #define DEFAULT_DRMSRC                                 "drmsrc"
-#define DEFAULT_VIDEO_SURFACE                          MM_DISPLAY_SURFACE_X
 #define DEFAULT_VIDEOSINK_X                            "xvimagesink"
 #define DEFAULT_VIDEOSINK_EVAS                         "evasimagesink"
 #define DEFAULT_VIDEOSINK_FAKE                         "fakesink"
+#define DEFAULT_AUDIORESAMPLER                 "audioresample"
 #define DEFAULT_AUDIOSINK                              "avsysaudiosink"
 #define DEFAULT_GST_PARAM                              ""
 #define DEFAULT_EXCLUDE_KEYWORD                                ""
@@ -147,11 +180,11 @@ typedef struct __mm_player_ini
 #define DEFAULT_LOCALPLAYBACK_STATE_CHANGE_TIMEOUT     10 /* sec */
 /* http streaming */
 #define DEFAULT_HTTPSRC                                "souphttpsrc"
-#define DEFAULT_HTTP_FILE_BUFFER_PATH          ""
+#define DEFAULT_HTTP_FILE_BUFFER_PATH          "/opt/usr/media"
 #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 */
+#define DEFAULT_HTTP_MAX_SIZE_BYTES            1048576         /* bytes : 1 MBytes  */
+#define DEFAULT_HTTP_BUFFERING_TIME            1.2                     /* sec */
+#define DEFAULT_HTTP_TIMEOUT                   -1                      /* infinite retry */
 /* rtsp streaming */
 #define DEFAULT_RTSPSRC                                "secrtspsrc"
 #define DEFAULT_RTSP_BUFFERING                 5000    /* msec */
@@ -166,6 +199,16 @@ typedef struct __mm_player_ini
 #define DEFAULT_PRIORITY_VIDEO_SINK    97
 #define DEFAULT_PRIORITY_AUDIO_SINK    98
 #define DEFAULT_PRIORITY_RINGBUFFER    99
+/* subtitle */
+#define DEFAULT_MIRRORING_WIDTH                        1920
+#define DEFAULT_MIRRORING_HEIGHT                       1080
+#define DEFAULT_FONT_COLOR             "0xffffffff"
+#define DEFAULT_FONT_BACKGROUND_COLOR          "0x0"
+#define DEFAULT_EXTERNAL_SUBTITLE              FALSE
+
+/* dump buffer for debug */
+#define DEFAULT_DUMP_ELEMENT_KEYWORD                           ""
+#define DEFAULT_DUMP_ELEMENT_PATH                              "/opt/usr/media/"
 
 /* NOTE : following content should be same with above default values */
 /* FIXIT : need smarter way to generate default ini file. */
@@ -174,9 +217,6 @@ typedef struct __mm_player_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\
@@ -214,7 +254,8 @@ gstparam5 = \n\
 generate dot = no \n\
 \n\
 ; parameter for clock provide in audiosink \n\
-provide clock = yes \n\
+provide clock for music = yes \n\
+provide clock for movie = no \n\
 \n\
 ; allowed timeout for changing pipeline state \n\
 live state change timeout = 30 ; sec \n\
@@ -229,15 +270,15 @@ eos delay = 150 ; msec \n\
 httppsrc element = souphttpsrc \n\
 \n\
 ; if set, use file or not use memory for buffering\n\
-http file buffer path = /opt/media\n\
+http file buffer path = /opt/usr/media\n\
 \n\
 http buffering limit = 99 ; percent\n\
 \n\
 http max size bytes = 1048576 ; bytes\n\
 \n\
-http buffering time = 3.0 \n\
+http buffering time = 1.2 \n\
 \n\
-http timeout = 30 ; sec \n\
+http timeout = -1 ; infinite retry \n\
 \n\
 \n\
 [rtsp streaming] \n\
@@ -257,11 +298,6 @@ rtsp error concealment = yes \n\
 use video hw accel = yes \n\
 \n\
 \n\
-[features] \n\
-\n\
-audio filter = no \n\
-\n\
-\n\
 [priority] \n\
 \n\
 use priority setting = no \n\
@@ -274,14 +310,24 @@ audiosink = 97\n\
 \n\
 ringbuffer = 98 \n\
 \n\
+\n\
+[subtitle] \n\
+\n\
+mirroring width = 1920 \n\
+\n\
+mirroring height = 1080 \n\
+\n\
+font color = 0xffffffff \n\
+\n\
+font background color = 0x00000000 \n\
+\n\
 "
 
 int
-mm_player_ini_load(void);
-
-mm_player_ini_t*
-mm_player_ini_get_structure(void);
+mm_player_ini_load(mm_player_ini_t* ini);
 
+int
+mm_player_audio_effect_ini_load(mm_player_ini_t* ini);
 
 #ifdef __cplusplus
        }
index 9dd378b..a830a4e 100755 (executable)
 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 */
+    MM_PLAYER_COLORSPACE_NV12_TILED,           /**< Customized color format */
+    MM_PLAYER_COLORSPACE_NV12,
 }MMPlayerVideoColorspace;
 
 typedef struct
 {
        unsigned char *data;                                    /* capture image buffer */
        int size;                                                               /* capture image size */
-       MMPlayerVideoColorspace fmt;                    /* color space type */  
-} MMPlayerVideoCapture;
+       MMPlayerVideoColorspace fmt;                    /* color space type */
+       unsigned int width;                                             /* width of captured image */
+       unsigned int height;                                    /* height of captured image */
+       unsigned int orientation;                               /* content orientation */
+}MMPlayerVideoCapture;
 
 /**
  * Buffer need data callback function type.
@@ -148,11 +152,11 @@ typedef bool      (*mm_player_buffer_seek_data_callback) (unsigned long long offset,
  * @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                                                   
+ * @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);
+typedef bool   (*mm_player_video_stream_callback) (void *stream, void *user_param);
 
 /**
  * Audio stream callback function type.
@@ -167,6 +171,17 @@ typedef bool       (*mm_player_video_stream_callback) (void *stream, int stream_size,
 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.
@@ -174,9 +189,9 @@ typedef bool        (*mm_player_video_capture_callback) (void *stream, int stream_size,
  *
  * @return     This function returns zero on success, or negative value with error
  *                     code
- * @remark     The current supported range is from -64x to 64x. 
+ * @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.  
+ *             And, the sound is muted under normal speed and more than double speed.
  * @see
  * @since
  */
@@ -198,30 +213,15 @@ int mm_player_set_play_speed(MMHandleType player, float rate);
 int mm_player_set_video_stream_callback(MMHandleType player, mm_player_video_stream_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. 
+ * 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. 
+ * @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
  */
@@ -287,6 +287,20 @@ int mm_player_set_buffer_seek_data_callback(MMHandleType player, mm_player_buffe
  */
 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
+ * @see
+ * @since
+ */
+int mm_player_change_videosink(MMHandleType player, MMDisplaySurfaceType display_surface_type, void *display_overlay);
 
 /**
        @}
diff --git a/src/include/mm_player_m3u8.h b/src/include/mm_player_m3u8.h
deleted file mode 100755 (executable)
index d5597f5..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-/* GStreamer
- * Copyright (C) 2010 Marc-Andre Lureau <marcandre.lureau@gmail.com>
- * Copyright (C) 2010 Andoni Morales Alastruey <ylatuya@gmail.com>
- *
- * m3u8.h:
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/* This source code is taken from m3u8.c, which is licensed by GNU Library General Public License.
- * AES-128 bit decryption features are changed from m3u8.c.
- * - gst_m3u8_update and gst_m3u8_media_file_new are modified.
- * - gst_m3u8_getIV_from_mediasequence is added.
- * For convenience,
- * - gst_m3u8_client_get_next_fragment is modified.
- * - gst_m3u8_client_check_next_fragment is added.
- * File name is changed to mm_player_m3u8.c
- */
-
-
-#ifndef __MM_PLAYER_M3U8_H__
-#define __MM_PLAYER_M3U8_H__
-
-#include <glib.h>
-
-G_BEGIN_DECLS typedef struct _GstM3U8 GstM3U8;
-typedef struct _GstM3U8MediaFile GstM3U8MediaFile;
-typedef struct _GstM3U8Client GstM3U8Client;
-
-#define GST_M3U8_MEDIA_FILE(f) ((GstM3U8MediaFile*)f)
-
-struct _GstM3U8
-{
-  gchar *uri;
-
-  gboolean endlist;             /* if ENDLIST has been reached */
-  gint version;                 /* last EXT-X-VERSION */
-  gint targetduration;          /* last EXT-X-TARGETDURATION */
-  gchar *allowcache;            /* last EXT-X-ALLOWCACHE */
-
-  gint bandwidth;
-  gint program_id;
-  gchar *codecs;
-  gint width;
-  gint height;
-  GList *files;
-
-  /*< private > */
-  gchar *last_data;
-  GList *lists;                 /* list of GstM3U8 from the main playlist */
-  GstM3U8 *parent;              /* main playlist (if any) */
-  guint mediasequence;          /* EXT-X-MEDIA-SEQUENCE & increased with new media file */
-};
-
-struct _GstM3U8MediaFile
-{
-  gchar *title;
-  gint duration;
-  gchar *uri;
-  guint sequence;               /* the sequence nb of this file */
-
-  gchar *key_url;
-  unsigned char key[16];
-  unsigned char iv[16];
-  
-};
-
-struct _GstM3U8Client
-{
-  GstM3U8 *main;                /* main playlist */
-  GstM3U8 *current;
-  guint update_failed_count;
-  gint sequence;                /* the next sequence for this client */
-};
-
-
-GstM3U8Client *gst_m3u8_client_new (const gchar * uri);
-void gst_m3u8_client_free (GstM3U8Client * client);
-gboolean gst_m3u8_client_update (GstM3U8Client * client, gchar * data);
-void gst_m3u8_client_set_current (GstM3U8Client * client, GstM3U8 * m3u8);
-const GstM3U8MediaFile *gst_m3u8_client_get_next_fragment (GstM3U8Client * client,  gboolean * discontinuity);
-#define gst_m3u8_client_get_uri(Client) ((Client)->main->uri)
-#define gst_m3u8_client_has_variant_playlist(Client) ((Client)->main->lists)
-#define gst_m3u8_client_is_live(Client) (!(Client)->current->endlist)
-#define gst_m3u8_client_allow_cache(Client) ((Client)->current->allowcache)
-
-const gboolean gst_m3u8_client_check_next_fragment (GstM3U8Client * client);
-
-G_END_DECLS
-#endif /* __MM_PLAYER_M3U8_H__ */
index 81268e1..163f65c 100755 (executable)
 
 typedef struct
 {
-       gchar *uri_to_download;         // path for download and playback
-       gchar *uri_to_save;                     // path for saving to local 
+       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 *pushsrc;                    // src element of playback pipeline
-       GstElement *download_pipe;
-       GstElement *download_src;
-       GstElement *download_queue;
-       GstElement *download_sink;
+       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;
 
 /**
@@ -51,22 +51,22 @@ typedef struct
  *
  * @return     This function returns allocated handle.
  * @remarks
- * @see                _mmplayer_pd_destroy()
+ * @see                _mmplayer_destroy_pd_downloader()
  *
  */
-mm_player_pd_t * _mmplayer_pd_create ();
+mm_player_pd_t * _mmplayer_create_pd_downloader ();
 /**
- * This function release handle of progressive download.
+ * 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_pd_create()
+ * @see                _mmplayer_create_pd_downloader()
  *
  */
-gboolean _mmplayer_pd_destroy (MMHandleType handle);
+gboolean _mmplayer_destroy_pd_downloader  (MMHandleType handle);
 /**
- * This function initialize progressive download.
+ * This function realize progressive download.
  *
  * @param[in]  handle  Handle of player.
  * @param[in]  src_uri path to download.
@@ -74,40 +74,30 @@ gboolean _mmplayer_pd_destroy (MMHandleType handle);
  * @param[in]  pushsrc source element of playback pipeline
  * @return     This function returns true on success, or false on failure.
  * @remarks
- * @see                _mmplayer_pd_deinitialize()
+ * @see
  *
  */
-gboolean _mmplayer_pd_initialize (MMHandleType handle, gchar *src_uri, gchar *dst_uri, GstElement *pushsrc);
+gboolean _mmplayer_realize_pd_downloader (MMHandleType handle, gchar *src_uri, gchar *dst_uri, GstElement *pushsrc);
 /**
- * This function deinitialize progressive download.
+ * 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_pd_initialize()
+ * @see                _mmplayer_realize_pd_downloader()
  *
  */
-gboolean _mmplayer_pd_deinitialize (MMHandleType handle);
+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                _mmplayer_pd_stop()
- *
- */
-gboolean _mmplayer_pd_start (MMHandleType handle);
-/**
- * This function stop progressive download.
- *
- * @param[in]  handle  Handle of player.
- * @return     This function returns true on success, or false on failure.
- * @remarks
- * @see                _mmplayer_pd_start()
+ * @see
  *
  */
-gboolean _mmplayer_pd_stop (MMHandleType handle);
+gboolean _mmplayer_start_pd_downloader (MMHandleType handle);
 /**
  * This function get pd current status.
  *
@@ -119,7 +109,7 @@ gboolean _mmplayer_pd_stop (MMHandleType handle);
  * @see
  *
  */
-gboolean _mmplayer_pd_get_status(MMHandleType handle, guint64 *current_pos, guint64 *total_size);
+gboolean _mmplayer_get_pd_downloader_status(MMHandleType handle, guint64 *current_pos, guint64 *total_size);
 /**
  * This function set message callback of PD downloader.
  *
@@ -131,7 +121,7 @@ gboolean _mmplayer_pd_get_status(MMHandleType handle, guint64 *current_pos, guin
  * @see
  *
  */
-gint _mm_player_set_pd_message_callback(MMHandleType player, MMMessageCallback callback, gpointer user_param);
+gint _mm_player_set_pd_downloader_message_cb(MMHandleType player, MMMessageCallback callback, gpointer user_param);
 
 #ifdef __cplusplus
        }
index 3a29bfc..cf57da4 100755 (executable)
 ========================================================================================== */
 #include <glib.h>
 #include <gst/gst.h>
-#include <mm_types.h>
 #include <mm_attrs.h>
-#include <mm_ta.h>
 #include <mm_debug.h>
+#include <math.h>
 
 #include "mm_player.h"
 #include "mm_player_internal.h"
-#include "mm_player_sndeffect.h"
+#include "mm_player_audioeffect.h"
 #include "mm_message.h"
-#include "mm_player_utils.h"
+#include "mm_player_ini.h"
 #include "mm_player_asm.h"
-#include "mm_player_ahs.h"
 #include "mm_player_pd.h"
 #include "mm_player_streaming.h"
 
@@ -89,6 +87,16 @@ enum tag_info
        TAG_TRACK_NUMBER = 0x0200
 };
 
+enum content_attr_flag
+{
+       ATTR_MISSING_ONLY = 0x0001,
+       ATTR_DURATION = 0x0002,
+       ATTR_AUDIO  = 0x0004,
+       ATTR_VIDEO = 0x0008,
+       ATTR_BITRATE = 0x0010,
+       ATTR_ALL = 0x0020,
+};
+
 /* async mode makes trouble. alsasink sometimes fails to pause. */
 enum alassink_sync
 {
@@ -113,13 +121,17 @@ enum MMPlayerMode {
 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_WFD,  /**< Player URI type WFD */
        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_HLS,                 /**< Player URI type http live streaming */
+       MM_PLAYER_URI_TYPE_SS,                  /**< Player URI type Smooth streaming */
+       MM_PLAYER_URI_TYPE_DASH,                        /**< Player URI type Mpeg Dash */
+       MM_PLAYER_URI_TYPE_NO_PERMISSION,/**< Player URI type No Permission  */
        MM_PLAYER_URI_TYPE_TEMP,                        /**< Player URI type Temp */
 };
 
@@ -138,13 +150,35 @@ typedef enum _FoundCodec
        FOUND_PLUGIN_VIDEO                      = 0x02
 }FoundCodec;
 
+typedef enum
+{
+       MMPLAYER_DISPLAY_STATUS_NULL = 0,
+       MMPLAYER_DISPLAY_STATUS_HDMI_ACTIVE,
+       MMPLAYER_DISPLAY_STATUS_UNKNOWN_ACTIVE,
+}MMPlayerDisplayStatus;
+
+/**
+ * Enumeration of signal type
+ */
+typedef enum {
+       MM_PLAYER_SIGNAL_TYPE_AUTOPLUG = 0,
+       MM_PLAYER_SIGNAL_TYPE_VIDEOBIN,
+       MM_PLAYER_SIGNAL_TYPE_AUDIOBIN,
+       MM_PLAYER_SIGNAL_TYPE_TEXTBIN,
+       MM_PLAYER_SIGNAL_TYPE_OTHERS,
+       MM_PLAYER_SIGNAL_TYPE_ALL,
+       MM_PLAYER_SIGNAL_TYPE_MAX = MM_PLAYER_SIGNAL_TYPE_ALL,
+}MMPlayerSignalType;
+
 /* 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_TYPEFIND,
        MMPLAYER_M_AUTOPLUG,
 
        /* NOTE : we need two fakesink to autoplug without decodebin.
@@ -156,16 +190,29 @@ enum MainElementID
        MMPLAYER_M_SRC_2ND_FAKESINK,
 
        /* streaming plugin */
-       MMPLAYER_M_S_BUFFER, 
-       MMPLAYER_M_S_ADEC, 
-       MMPLAYER_M_S_VDEC, 
-       
+       MMPLAYER_M_MUXED_S_BUFFER,
+       MMPLAYER_M_DEMUXED_S_BUFFER,
+       MMPLAYER_M_ID3DEMUX,
+
        /* 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_DEMUX_EX,
+       MMPLAYER_M_V_INPUT_SELECTOR,    // video input_select   // not yet
+       MMPLAYER_M_A_INPUT_SELECTOR,    // audio input_select
+       MMPLAYER_M_T_INPUT_SELECTOR,    // text input_select
+       MMPLAYER_M_T_SUBMUX_EXTERNAL,
+       MMPLAYER_M_T_SUBMUX_INTERNAL,
+       MMPLAYER_M_A_TEE,
+       MMPLAYER_M_A_Q1,
+       MMPLAYER_M_A_Q2,
+       MMPLAYER_M_A_CONV,
+       MMPLAYER_M_A_FILTER,
+       MMPLAYER_M_A_DEINTERLEAVE,
+       MMPLAYER_M_A_SELECTOR,
        MMPLAYER_M_NUM
 };
 
@@ -177,6 +224,8 @@ enum AudioElementID
        MMPLAYER_A_CONV,
        MMPLAYER_A_VOL,
        MMPLAYER_A_FILTER,
+       MMPLAYER_A_FILTER_SEC,
+       MMPLAYER_A_VSP,
        MMPLAYER_A_CAPS_DEFAULT,
        MMPLAYER_A_SINK,
        MMPLAYER_A_RESAMPLER,
@@ -191,9 +240,7 @@ enum VideoElementID
        MMPLAYER_V_CONV,
        MMPLAYER_V_SCALE,
        MMPLAYER_V_CAPS,
-       MMPLAYER_V_TEE,
        MMPLAYER_V_SINK,
-       MMPLAYER_V_SINK_EXT,
        MMPLAYER_V_NUM
 };
 
@@ -201,28 +248,21 @@ enum VideoElementID
 enum TextElementID
 {
        MMPLAYER_T_BIN = 0, /* NOTE : MMPLAYER_V_BIN should be zero */
-       MMPLAYER_T_QUEUE,
+       MMPLAYER_T_TEXT_FAKE_QUEUE,
+       MMPLAYER_T_TEXT_QUEUE,
+       MMPLAYER_T_VIDEO_QUEUE,
+       MMPLAYER_T_VIDEO_CONVERTER,
        MMPLAYER_T_OVERLAY,
-       MMPLAYER_T_SINK,
+       MMPLAYER_T_FAKE_SINK,
+       MMPLAYER_T_VIDEO_SINK,
+       MMPLAYER_T_TEE,
+       MMPLAYER_T_RENDER,
+       MMPLAYER_T_CAPSFILTER,
+       MMPLAYER_T_TEXT_FAKE_IDENTITY,
+       MMPLAYER_T_TEXT_IDENTITY,
        MMPLAYER_T_NUM
 };
 
-/* subtitle pipeline's element id */
-enum SubtitleElementID
-{
-       MMPLAYER_SUB_PIPE = 0, /* NOTE : MMPLAYER_SUB_PIPE should be zero */
-       MMPLAYER_SUB_SRC,
-       MMPLAYER_SUB_QUEUE,
-       MMPLAYER_SUB_SUBPARSE,
-       MMPLAYER_SUB_TEXTRENDER,
-       MMPLAYER_SUB_FLIP,
-       MMPLAYER_SUB_CONV1,
-       MMPLAYER_SUB_CONV2,
-       MMPLAYER_SUB_SCALE,
-       MMPLAYER_SUB_SINK,
-       MMPLAYER_SUB_NUM
-};
-
 /* midi main pipeline's element id */
 enum MidiElementID
 {
@@ -236,9 +276,9 @@ enum PlayerCommandState
        MMPLAYER_COMMAND_NONE,
        MMPLAYER_COMMAND_CREATE,
        MMPLAYER_COMMAND_DESTROY,
-       MMPLAYER_COMMAND_REALIZE,
        MMPLAYER_COMMAND_UNREALIZE,
        MMPLAYER_COMMAND_START,
+       MMPLAYER_COMMAND_REALIZE,
        MMPLAYER_COMMAND_STOP,
        MMPLAYER_COMMAND_PAUSE,
        MMPLAYER_COMMAND_RESUME,
@@ -299,7 +339,6 @@ enum StreamingSrcError
        MMPLAYER_STREAMING_ERROR_OPTION_NOT_SUPPORTED,
 };
 
-
 /*---------------------------------------------------------------------------
 |    GLOBAL DATA TYPE DEFINITIONS:                                                                                     |
 ---------------------------------------------------------------------------*/
@@ -314,7 +353,6 @@ typedef struct
 {
        GstTagList                      *tag_list;
        MMPlayerGstElement      *mainbin;
-       MMPlayerGstElement      *subtitlebin;
        MMPlayerGstElement      *audiobin;
        MMPlayerGstElement      *videobin;
        MMPlayerGstElement      *textbin;
@@ -322,7 +360,6 @@ typedef struct
 
 typedef struct
 {
-       char    device[MAX_SOUND_DEVICE_LEN];
        float volume;
        int mute;
        int bluetooth;  /* enable/disable */
@@ -355,6 +392,25 @@ typedef struct {
        gulong sig;
 } MMPlayerSignalItem;
 
+typedef struct {
+       bool rich_audio;
+       bool safety_volume;
+       bool pcm_extraction;
+       bool video_zc; // video zero-copy
+       bool subtitle_off;
+       bool media_packet_video_stream;
+}MMPlayerSetMode;
+
+typedef struct {
+       GMainContext *global_default;
+       GMainContext *thread_default;
+}MMPlayerGMainContext;
+
+typedef struct {
+       gint uri_idx;
+       GList *uri_list;
+}MMPlayerUriList;
+
 /* image buffer definition ***************************************************
 
     +------------------------------------------+ ---
@@ -379,40 +435,73 @@ typedef struct {
 typedef struct
 {
        /* width of each image plane */
-       int     w[MM_PLAYER_IMGB_MPLANE_MAX];
+       int w[MM_PLAYER_IMGB_MPLANE_MAX];
        /* height of each image plane */
-       int     h[MM_PLAYER_IMGB_MPLANE_MAX];
+       int h[MM_PLAYER_IMGB_MPLANE_MAX];
        /* stride of each image plane */
-       int     s[MM_PLAYER_IMGB_MPLANE_MAX];
+       int s[MM_PLAYER_IMGB_MPLANE_MAX];
        /* elevation of each image plane */
-       int     e[MM_PLAYER_IMGB_MPLANE_MAX];
+       int e[MM_PLAYER_IMGB_MPLANE_MAX];
        /* user space address of each image plane */
-       void    *a[MM_PLAYER_IMGB_MPLANE_MAX];
+       void *a[MM_PLAYER_IMGB_MPLANE_MAX];
        /* physical address of each image plane, if needs */
-       void    *p[MM_PLAYER_IMGB_MPLANE_MAX];
+       void *p[MM_PLAYER_IMGB_MPLANE_MAX];
        /* color space type of image */
-       int     cs;
+       int cs;
        /* left postion, if needs */
-       int     x;
+       int x;
        /* top position, if needs */
-       int     y;
+       int y;
        /* to align memory */
-       int     __dummy2;
+       int __dummy2;
        /* arbitrary data */
-       int     data[16];
+       int data[16];
+       /* dmabuf or ion fd */
+       int fd[MM_PLAYER_IMGB_MPLANE_MAX];
+       /* flag for buffer share */
+       int buf_share_method;
+       /* Y plane size */
+       int y_size;
+       /* UV plane size */
+       int uv_size;
+       /* Tizen buffer object of each image plane */
+       void *bo[MM_PLAYER_IMGB_MPLANE_MAX];
+       /* JPEG data */
+       void *jpeg_data;
+       /* JPEG size */
+       int jpeg_size;
+       /* tzmem buffer */
+       int tz_enable;
 } MMPlayerMPlaneImage;
 
 typedef struct {
+       gint active_pad_index;
+       gint total_track_num;
+       GPtrArray *channels;
+} mm_player_selector_t;
+
+/* Things needed to be done after output device has changed */
+typedef struct {
+       gboolean need_async;
+       gboolean need_seek;
+       gboolean need_pause_and_resume;
+       guint cb_score;
+       guint required_cb_score;
+       guint id;
+} mm_player_post_proc_t;
+
+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;     
+       guint state_change_timeout;
 
        gboolean section_repeat;
        gint section_repeat_start;
        gint section_repeat_end;
+       guint play_count;
 
        gchar *album_art;
 
@@ -420,9 +509,7 @@ typedef struct {
 
        /* command lock */
        GMutex* cmd_lock;
-
-       /* handle of adaptive http streaming */
-       mm_player_ahs_t *ahs_player;
+       GMutex* playback_lock;
 
        /* repeat thread lock */
        GCond* repeat_thread_cond;
@@ -430,15 +517,21 @@ typedef struct {
        GThread* repeat_thread;
        gboolean repeat_thread_exit;
 
+       /* next play thread */
+       GThread* next_play_thread;
+       gboolean next_play_thread_exit;
+       GCond* next_play_thread_cond;
+       GMutex* next_play_thread_mutex;
+
        /* capture thread */
        GThread* capture_thread;
        gboolean capture_thread_exit;
        GCond* capture_thread_cond;
        GMutex* capture_thread_mutex;
        MMPlayerVideoCapture capture;
-       MMPlayerVideoColorspace video_cs;       
+       MMPlayerVideoColorspace video_cs;
        MMPlayerMPlaneImage captured;
-       
+
        /* fakesink handling lock */
        GMutex* fsink_lock;
 
@@ -452,7 +545,7 @@ typedef struct {
 
        /* progressive download */
        mm_player_pd_t *pd_downloader;
-       gchar *pd_file_location;
+       gchar *pd_file_save_path;
        MMPlayerPDMode pd_mode;
 
        /* streaming player */
@@ -460,16 +553,18 @@ typedef struct {
 
        /* gstreamer pipeline */
        MMPlayerGstPipelineInfo *pipeline;
-       gboolean pipeline_is_constructed;
-       
-       /* Buffering support cbs*/
+
+       /* pad */
+       GstPad *ghost_pad_for_videobin;
+
+       /* 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;
 
-       /* for video stream callback */
+       /* video stream callback */
        mm_player_video_stream_callback video_stream_cb;
        void* video_stream_cb_user_param;
        int use_video_stream;
@@ -478,16 +573,12 @@ typedef struct {
        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 display */
-       GstPad* tee_src_pad[2];
-       gboolean use_multi_surface;
+       /* 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;
@@ -498,11 +589,12 @@ typedef struct {
        /* video stream caps parsed by demuxer */
        GstCaps* v_stream_caps;
 
-       /* audio filter infomation */
-       MMAudioFilterInfo audio_filter_info;
-       gboolean bypass_sound_effect;
+       /* audio effect infomation */
+       MMAudioEffectInfo audio_effect_info;
+       gboolean bypass_audio_effect;
 
        gulong audio_cb_probe_id;
+       gulong video_cb_probe_id;
 
        /* for appsrc */
        tBuffer mem_buf;
@@ -517,6 +609,7 @@ typedef struct {
        GList* factories;
        gboolean have_dynamic_pad;
        GList* parsers; // list of linked parser name
+       GList* audio_decoders; // list of linked audio name
        gboolean no_more_pad;
        gint num_dynamic_pad;
        gboolean has_many_types;
@@ -543,6 +636,9 @@ typedef struct {
        /* last error */
        gchar last_error_msg[1024]; /* FIXIT : should it be dynamic ? */
 
+       gboolean needed_v_parser;
+       gboolean smooth_streaming;
+
        gint videodec_linked;
        gint audiodec_linked;
        gint videosink_linked;
@@ -568,38 +664,31 @@ typedef struct {
        gboolean doing_seek;
 
        /* prevent to post msg over and over */
-       gboolean posted_msg;
+       gboolean msg_posted;
 
        /* list of sink elements */
        GList* sink_elements;
 
        /* signal notifiers */
-       GList* signals;
+       GList* signals[MM_PLAYER_SIGNAL_TYPE_MAX];
        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;
+       MMPlayerGMainContext context;
+       MMPlayerUriList uri_info;
 
        gboolean is_sound_extraction;
 
-       gdouble playback_rate;
-       /* player state resumed by fast rewind */
+       gfloat playback_rate;
+
+       /* player state resumed by fast rewind */
        gboolean resumed_by_rewind;
 
        gboolean is_nv12_tiled;
+       gboolean is_drm_file;
 
        MMPlayerASM     sm;
 
        gboolean is_subtitle_off;
+       gboolean is_external_subtitle_present;
 
        /* contents bitrate for buffering management */
        guint bitrate[MM_PLAYER_STREAM_COUNT_MAX];
@@ -614,16 +703,95 @@ typedef struct {
 
        /* timeout source for lazy pause */
        guint lazy_pause_event_id;
+       guint resume_event_id;
+       guint resumable_cancel_id;
 
        gboolean keep_detecting_vcodec;
 
        gboolean play_subtitle;
+       gboolean use_textoverlay;
+       MMPlayerDisplayStatus display_stat;
+       gboolean is_subtitle_force_drop;        // set TRUE after bus_cb get EOS
 
        /* PD downloader message callback and param */
        MMMessageCallback pd_msg_cb;
        void* pd_msg_cb_param;
+
+       /* adjust subtitle position store */
+       gint64 adjust_subtitle_pos;
+       GList *subtitle_language_list;
+
+       /* To store the current multiwindow status */
+       gboolean last_multiwin_status;
+
+       /* To store the current running audio pad index of demuxer */
+       gint demux_pad_index;
+
+       mm_player_selector_t selector[MM_PLAYER_TRACK_TYPE_MAX];
+       mm_player_selector_t audio_mode;
+       gboolean use_deinterleave;
+       guint max_audio_channels;
+
+       guint internal_text_idx;
+       guint external_text_idx;
+
+       MMPlayerSetMode set_mode;
+
+       /* decodbin usage */
+       gboolean use_decodebin;
+
+       /* initialize values */
+       mm_player_ini_t ini;
+
+       /* check to use h/w codec */
+       GstCaps* state_tune_caps;
+       gboolean ignore_asyncdone;
+
+       /* video share sync */
+       gint64 video_share_api_delta;
+       gint64 video_share_clock_delta;
+
+       /* subtitle option */
+       gchar *font_desc;
+       guint font_color;
+       guint font_bg_color;
+       gboolean subtitle_ignore_markup;
+
+       /* just for native app (video hub) */
+       gboolean video_hub_download_mode;
+       gboolean sync_handler;
+
+       /* seamless next playing */
+       gboolean src_changed;
+       gboolean pp_rebuilding;
+
+       /* store dump pad list */
+       GList* dump_list;
+
+
+       /* audio/video deivce change handling */
+       mm_player_post_proc_t post_proc;
+
+       /* whether a video has closed caption or not */
+       gboolean has_closed_caption;
+
+       GstElement *video_fakesink;
 } mm_player_t;
 
+typedef struct
+{
+       gchar *language_code;
+       gchar *language_key;
+       gboolean active;
+}MMPlayerLangStruct;
+
+typedef struct
+{
+       GstPad *dump_pad;
+       gulong probe_handle_id;
+       FILE *dump_element_file;
+} mm_player_dump_t;
+
 /*===========================================================================================
 |                                                                                                                                                                                      |
 |  GLOBAL FUNCTION PROTOTYPES                                                                                                                          |
@@ -649,27 +817,63 @@ 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_adjust_video_postion(MMHandleType hplayer,int offset);
 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_playspeed(MMHandleType hplayer, float rate);
+int _mmplayer_set_playspeed_ex(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_set_external_subtitle_path(MMHandleType hplayer, const char* filepath);
+int _mmplayer_set_external_subtitle_font(MMHandleType hplayer, char *font_desc);
+int _mmplayer_set_external_subtitle_font_color(MMHandleType hplayer, unsigned int font_color, unsigned int font_bg_color);
+int _mmplayer_external_subtitle_ignore_markup_tags(MMHandleType hplayer, bool ignore_markup);
+int _mmplayer_external_subtitle_set_alignment_in_line(MMHandleType hplayer, unsigned int alignment);
+int _mmplayer_external_subtitle_set_alignment_horizontal(MMHandleType hplayer, unsigned int alignment);
+int _mmplayer_external_subtitle_apply_alignment_right_away(MMHandleType hplayer);
+int _mmplayer_set_external_subtitle_edge(MMHandleType hplayer, MMPlayerSubtitleEdge edge_mode);
 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);
+int _mmplayer_keep_external_video_fullscreen(MMHandleType hplayer);
+
 /* 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);
-
+int _mmplayer_change_videosink(MMHandleType handle, MMDisplaySurfaceType surface_type, void *display_overlay);
+int _mmplayer_audio_effect_custom_apply(mm_player_t *player);
+
+gboolean __mmplayer_post_message(mm_player_t* player, enum MMMessageType msgtype, MMMessageParamType* param);
+gboolean __mmplayer_is_streaming(mm_player_t* player);
+
+
+int _mmplayer_gst_set_audio_channel(MMHandleType hplayer, MMPlayerAudioChannel ch_idx);
+int _mmplayer_change_track_language (MMHandleType hplayer, MMPlayerTrackType type, int index);
+int _mmplayer_sync_subtitle_pipeline(mm_player_t* player);
+int _mmplayer_set_prepare_buffering_time(MMHandleType hplayer, int second);
+int _mmplayer_set_runtime_buffering_mode(MMHandleType hplayer, MMPlayerBufferingMode mode, int second);
+int _mmplayer_set_display_zoom(MMHandleType hplayer, float level, int x, int y);
+int _mmplayer_get_display_zoom(MMHandleType hplayer, float *level, int *x, int *y);
+int _mmplayer_set_video_hub_download_mode(MMHandleType hplayer, bool mode);
+int _mmplayer_use_system_clock (MMHandleType hplayer);
+int _mmplayer_set_video_share_master_clock(MMHandleType hplayer, long long clock, long long clock_delta, long long video_time, long long media_clock, long long audio_time);
+int _mmplayer_get_video_share_master_clock(MMHandleType hplayer, long long *video_time, long long *media_clock, long long *audio_time);
+int _mmplayer_get_video_rotate_angle(MMHandleType hplayer, int *angle);
+int _mmplayer_enable_sync_handler(MMHandleType hplayer, bool enable);
+int _mmplayer_set_uri(MMHandleType hplayer, const char* uri);
+int _mmplayer_set_next_uri(MMHandleType hplayer, const char* uri, bool is_first_path);
+int _mmplayer_get_next_uri(MMHandleType hplayer, char** uri);
+int _mmplayer_has_closed_caption(MMHandleType hplayer, bool* exist);
+int _mmplayer_enable_media_packet_video_stream(MMHandleType hplayer, bool enable);
 #ifdef __cplusplus
        }
 #endif
diff --git a/src/include/mm_player_sndeffect.h b/src/include/mm_player_sndeffect.h
deleted file mode 100755 (executable)
index b09ecda..0000000
+++ /dev/null
@@ -1,315 +0,0 @@
-/*
- * 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_SNDEFFECT_H__
-#define __MM_PLAYER_SNDEFFECT_H__
-
-#include <mm_types.h>
-
-#ifdef __cplusplus
-       extern "C" {
-#endif
-
-#define MM_AUDIO_FILTER_EQ_BAND_MAX            8
-#define MM_AUDIO_FILTER_CUSTOM_LEVEL_INIT      0
-
-/**
-       @addtogroup PLAYER_INTERNAL
-
-*/
-
-/**
- * Enumerations of Preset Filter Type
- */
-typedef enum {
-       MM_AUDIO_FILTER_PRESET_AUTO = 0,        /**<  Filter Preset type Auto */
-       MM_AUDIO_FILTER_PRESET_NORMAL,          /**<  Filter Preset type Normal */
-       MM_AUDIO_FILTER_PRESET_POP,             /**<  Filter Preset type Pop */
-       MM_AUDIO_FILTER_PRESET_ROCK,            /**<  Filter Preset type Rock */
-       MM_AUDIO_FILTER_PRESET_DANCE,           /**<  Filter Preset type Dance */
-       MM_AUDIO_FILTER_PRESET_JAZZ,            /**<  Filter Preset type Jazz */
-       MM_AUDIO_FILTER_PRESET_CLASSIC,         /**<  Filter Preset type Classic */
-       MM_AUDIO_FILTER_PRESET_VOCAL,           /**<  Filter Preset type Vocal */
-       MM_AUDIO_FILTER_PRESET_BASS_BOOST,      /**<  Filter Preset type Bass Boost */
-       MM_AUDIO_FILTER_PRESET_TREBLE_BOOST,    /**<  Filter Preset type Treble Boost */
-       MM_AUDIO_FILTER_PRESET_MTHEATER,        /**<  Filter Preset type MTheater */
-       MM_AUDIO_FILTER_PRESET_EXT,             /**<  Filter Preset type Externalization */
-       MM_AUDIO_FILTER_PRESET_CAFE,            /**<  Filter Preset type Cafe */
-       MM_AUDIO_FILTER_PRESET_CONCERT_HALL,    /**<  Filter Preset type Concert Hall */
-       MM_AUDIO_FILTER_PRESET_VOICE,           /**<  Filter Preset type Voice */
-       MM_AUDIO_FILTER_PRESET_MOVIE,           /**<  Filter Preset type Movie */
-       MM_AUDIO_FILTER_PRESET_VIRT51,          /**<  Filter Preset type Virtual 5.1 */
-       MM_AUDIO_FILTER_PRESET_NUM,             /**<  Number of Filter Preset type */
-} MMAudioFilterPresetType;
-
-/**
- * Enumerations of Custom Filter Type
- */
-typedef enum {
-       MM_AUDIO_FILTER_CUSTOM_EQ = 0,          /**<  Filter Custom type Equalizer */
-       MM_AUDIO_FILTER_CUSTOM_3D,              /**<  Filter Custom type 3D */
-       MM_AUDIO_FILTER_CUSTOM_BASS,            /**<  Filter Custom type Bass */
-       MM_AUDIO_FILTER_CUSTOM_ROOM_SIZE,       /**<  Filter Custom type Room Size */
-       MM_AUDIO_FILTER_CUSTOM_REVERB_LEVEL,    /**<  Filter Custom type Reverb Level */
-       MM_AUDIO_FILTER_CUSTOM_CLARITY,         /**<  Filter Custom type Clarity */
-       MM_AUDIO_FILTER_CUSTOM_NUM,             /**<  Number of Filter Custom type */
-} MMAudioFilterCustomType;
-
-/**
- * Enumerations of Filter Type
- */
-typedef enum {
-       MM_AUDIO_FILTER_TYPE_NONE,
-       MM_AUDIO_FILTER_TYPE_PRESET,
-       MM_AUDIO_FILTER_TYPE_CUSTOM,
-} MMAudioFilterType;
-
-
-/**
- * Enumerations of Output Mode
- */
-typedef enum {
-       MM_AUDIO_FILTER_OUTPUT_SPK,             /**< Speaker out */
-       MM_AUDIO_FILTER_OUTPUT_EAR                      /**< Earjack out */
-} MMAudioFilterOutputMode;
-
-
-/**
- * Structure of FilterInfo
- */
-typedef struct {
-       MMAudioFilterType filter_type;          /**< Filter type, (NONE,PRESET,CUSTOM)*/
-       MMAudioFilterPresetType preset;         /**< for preset type*/
-       int *custom_ext_level_for_plugin;       /**< for custom type, level value list of extension filters*/
-       int custom_eq_level[MM_AUDIO_FILTER_EQ_BAND_MAX];       /**< for custom type, EQ info*/
-       int custom_ext_level[MM_AUDIO_FILTER_CUSTOM_NUM-1];     /**< for custom type, extension filter info*/
-} MMAudioFilterInfo;
-
-
-/**
- * @brief Called to get each supported sound filter.
- *
- * @param      filter_type     [in]    Type of filter (preset filter or custom filter).
- * @param      filter          [in]    Supported sound filter.
- * @param      user_data       [in]    Pointer of user data.
- *
- * @return     True to continue with the next iteration of the loop, False to break outsp of the loop.
- * @see                mm_player_get_foreach_present_supported_filter_type()
- */
-typedef bool (*mmplayer_supported_sound_filter_cb) (int filter_type, int type, void *user_data);
-
-/**
- * This function is to get supported filter type.
- *
- * @param      hplayer         [in]    Handle of player.
- * @param      filter_type     [in]    Type of filter.
- * @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_filter_type(MMHandleType player, MMAudioFilterType filter_type, mmplayer_supported_sound_filter_cb foreach_cb, void *user_data);
-
-/**
- * This function is to bypass sound 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_sound_filter_bypass (MMHandleType hplayer);
-
-/**
- * This function is to apply preset filter.
- *
- * @param      hplayer         [in]    Handle of player.
- * @param      type            [in]    Preset type filter.
- *
- * @return     This function returns zero on success, or negative value with error code.
- *
- * @remark
- * @see                MMAudioFilterPresetType
- * @since
- */
-int mm_player_sound_filter_preset_apply(MMHandleType hplayer, MMAudioFilterPresetType type);
-
-/**
- * This function is to apply custom filter(Equalizer and Extension filters).
- *
- * @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_sound_filter_custom_apply(MMHandleType hplayer);
-
-/**
- * This function is to clear Equalizer custom filter.
- *
- * @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_sound_filter_custom_clear_eq_all(MMHandleType hplayer);
-
-/**
- * This function is to clear Extension custom filters.
- *
- * @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_sound_filter_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_sound_filter_custom_get_eq_bands_number(MMHandleType hplayer, int *bands);
-
-/**
- * This function is to get the level of the custom filter.
- *
- * @param      hplayer         [in]    Handle of player.
- * @param      type            [in]    Custom type filter.
- * @param      eq_index        [in]    Equalizer band index. This parameter is available only when the type is MM_AUDIO_FILTER_CUSTOM_EQ.
- * @param      level           [out]   The level of the custom filter.
- *
- * @return     This function returns zero on success, or negative value with error code.
- *
- * @remark
- * @see                MMAudioFilterCustomType
- * @since
- */
-int mm_player_sound_filter_custom_get_level(MMHandleType hplayer, MMAudioFilterCustomType type, int eq_index, int *level);
-
-/**
- * This function is to get range of the level of the custom filter.
- *
- * @param      hplayer         [in]    Handle of player.
- * @param      type            [in]    Custom type filter.
- * @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                MMAudioFilterCustomType
- * @since
- */
-int mm_player_sound_filter_custom_get_level_range(MMHandleType hplayer, MMAudioFilterCustomType type, int *min, int *max);
-
-/**
- * This function is to set the level of the custom filter.
- *
- * @param      hplayer         [in]    Handle of player.
- * @param      type            [in]    Custom type filter.
- * @param      eq_index        [in]    Equalizer band index. This parameter is available only when the type is MM_AUDIO_FILTER_CUSTOM_EQ.
- * @param      level           [in]    The level of the custom filter.
- *
- * @return     This function returns zero on success, or negative value with error code.
- *
- * @remark
- * @see                MMAudioFilterCustomType
- * @since
- */
-int mm_player_sound_filter_custom_set_level(MMHandleType hplayer, MMAudioFilterCustomType filter_custom_type, int eq_index, int level);
-
-/**
- * This function is to set the bands level of equalizer custom filter using input list.
- *
- * @param      hplayer         [in]    Handle of player.
- * @param      level_list      [in]    list of bands level of equalizer custom filter 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_sound_filter_custom_set_level_eq_from_list(MMHandleType hplayer, int *level_list, int size);
-
-/**
- * This function is to decide if the preset type filter is supported or not
- *
- * @param      hplayer         [in]    Handle of player.
- * @param      filter          [in]    Preset type filter.
- *
- * @return     This function returns zero on success, or negative value with error code.
- *
- * @remark
- * @see
- * @since
- */
-int mm_player_is_supported_preset_filter_type(MMHandleType hplayer, MMAudioFilterPresetType filter);
-
-/**
- * This function is to decide if the custom type filter is supported or not
- *
- * @param      hplayer         [in]    Handle of player.
- * @param      filter          [in]    Custom type filter.
- *
- * @return     This function returns zero on success, or negative value with error code.
- *
- * @remark
- * @see
- * @since
- */
-int mm_player_is_supported_custom_filter_type(MMHandleType hplayer, MMAudioFilterCustomType filter);
-
-/**
-       @}
- */
-
-#ifdef __cplusplus
-       }
-#endif
-
-#endif /* __MM_PLAYER_SNDEFFECT_H__ */
index 7889d84..a2bf57d 100755 (executable)
 #include <glib.h>
 #include <gst/gst.h>
 #include <string.h>
+#include <math.h>
 #include "mm_debug.h"
+#include "mm_player.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 MIN_BUFFERING_TIME 3.0
 #define MAX_BUFFERING_TIME 10.0
 
-#define DEFAULT_BUFFER_SIZE 4194304     // 4 MBytes
-#define DEFAULT_BUFFER_LOW_PERCENT 1.0         // 1%
+#define MAX_DECODEBIN_BUFFER_BYTES     (32 * 1024 * 1024)      // byte
+#define MAX_DECODEBIN_BUFFER_TIME      15      // sec
+
+#define DEFAULT_BUFFER_SIZE_BYTES 4194304      // 4 MBytes
+#define DEFAULT_PLAYING_TIME 10                                // 10 sec
+
+#define DEFAULT_BUFFERING_TIME 3.0             // 3sec
+#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
 
+#define GET_BYTE_FROM_BIT(bit) (bit/8)
+#define GET_BIT_FROM_BYTE(byte) (byte*8)
+#define CALC_PERCENT(a,b) ((gdouble)(a) * 100 / (gdouble)(b))
+#define GET_PERCENT(a, b, c, d) \
+do \
+{ \
+       if (((a) > 0) && ((b) > 0))             \
+       {       \
+               d = CALC_PERCENT(a, b); \
+       }       \
+       else    \
+       {       \
+               debug_warning ("set default per info\n");       \
+               d = c;  \
+       } \
+} while ( 0 );
+
+
+#define PLAYER_BUFFER_CAST(handle)     ((streaming_buffer_t *)(handle))
+#define PLAYER_STREAM_CAST(sr)                 ((mm_player_streaming_t *)(sr))
+
+#define GET_CURRENT_BUFFERING_BYTE(handle)     (PLAYER_BUFFER_CAST(handle)->buffering_bytes)
+#define GET_CURRENT_BUFFERING_TIME(handle)     (PLAYER_BUFFER_CAST(handle)->buffering_time)
+
+#define IS_MUXED_BUFFERING_MODE(sr)            (PLAYER_STREAM_CAST(sr)->streaming_buffer_type == BUFFER_TYPE_MUXED)?(TRUE):(FALSE)
+#define IS_DEMUXED_BUFFERING_MODE(sr)  (PLAYER_STREAM_CAST(sr)->streaming_buffer_type == BUFFER_TYPE_DEMUXED)?(TRUE):(FALSE)
+
+#define GET_NEW_BUFFERING_BYTE(size)   ((size) < MAX_DECODEBIN_BUFFER_BYTES)?(size):(MAX_DECODEBIN_BUFFER_BYTES)
+
+
+typedef enum {
+       BUFFER_TYPE_DEFAULT,
+       BUFFER_TYPE_MUXED = BUFFER_TYPE_DEFAULT,        /* queue2 */
+       BUFFER_TYPE_DEMUXED,            /* multi Q in decodebin */
+       BUFFER_TYPE_MAX,
+} BufferType;
+
 typedef struct
 {
-       GstElement *buffer; /* buffering element of playback pipeline */
+       MMPlayerBufferingMode mode;
+       gboolean is_pre_buffering;
+       gint initial_second;
+       gint runtime_second;
 
-       gboolean is_buffering;
-       gint buffering_percent;
+}streaming_requirement_t;
+
+typedef struct
+{
+       GstElement* buffer;             /* buffering element of playback pipeline */
 
-       gboolean need_update;
-       guint buffer_size;
+       guint buffering_bytes;
+       gdouble buffering_time;         // mq : max buffering time value till now
        gdouble buffer_high_percent;
        gdouble buffer_low_percent;
-       gdouble buffering_time;
-       guint buffer_max_bitrate;
-       guint buffer_avg_bitrate;
+
+       gboolean is_live;
+}streaming_buffer_t;
+
+typedef struct
+{
+       gboolean buffering_monitor;
+       gint64  prev_pos;
+       gdouble buffering_time; // DEFAULT_BUFFERING_TIME
+}streaming_default_t;
+
+typedef struct
+{
+       BufferType      streaming_buffer_type;
+       streaming_buffer_t buffer_handle[BUFFER_TYPE_MAX];      /* front buffer : queue2 */
+
+       streaming_requirement_t buffering_req;
+       streaming_default_t default_val;
+
+       gboolean        is_buffering;
+       gboolean        is_buffering_done;      /* get info from bus sync callback */
+
+       gint            buffering_percent;
+
+       guint           buffer_max_bitrate;
+       guint           buffer_avg_bitrate;
+       gboolean        need_update;
+       gboolean        need_sync;
+
 }mm_player_streaming_t;
 
 
-mm_player_streaming_t *__mm_player_streaming_create ();
+mm_player_streaming_t *__mm_player_streaming_create (void);
 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_queue2(         mm_player_streaming_t* streamer,
+                                                                               GstElement* buffer,
+                                                                               gboolean use_buffering,
+                                                                               guint buffering_bytes,
+                                                                               gdouble buffering_time,
+                                                                               gdouble low_percent,
+                                                                               gdouble high_percent,
+                                                                               gboolean use_file,
+                                                                               gchar* file_path,
+                                                                               guint64 content_size);
+void __mm_player_streaming_set_multiqueue(     mm_player_streaming_t* streamer,
+                                                                               GstElement* buffer,
+                                                                               gboolean use_buffering,
+                                                                               guint buffering_bytes,
+                                                                               gdouble buffering_time,
+                                                                               gdouble low_percent,
+                                                                               gdouble high_percent);
+void __mm_player_streaming_sync_property(mm_player_streaming_t* streamer, GstElement* decodebin);
+void __mm_player_streaming_buffering( mm_player_streaming_t* streamer,
+                                                                         GstMessage *buffering_msg,
+                                                                         guint64 content_size,
+                                                                         gint64 position,
+                                                                         gint64 duration);
 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
index 81214bd..e22d500 100755 (executable)
@@ -20,8 +20,8 @@
  *
  */
 
-#ifndef __MMF_PLAYER_UTILS_H__
-#define __MMF_PLAYER_UTILS_H__
+#ifndef __MM_PLAYER_UTILS_H__
+#define __MM_PLAYER_UTILS_H__
 
 #include <glib.h>
 #include <gst/gst.h>
@@ -54,20 +54,55 @@ do \
                g_mutex_lock(cmd_lock); \
        else \
        { \
-               debug_log("don't get command lock"); \
+               debug_log("no command lock"); \
                return MM_ERROR_PLAYER_NOT_INITIALIZED; \
        } \
-} while (0);
+} 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      
+#define MMPLAYER_PLAYBACK_LOCK(x_player) \
+do \
+{ \
+       GMutex* playback_lock = ((mm_player_t *)x_player)->playback_lock; \
+       if (playback_lock) \
+       {       \
+               debug_log("lock playback_lock"); \
+               g_mutex_lock(playback_lock); \
+       }       \
+       else \
+       { \
+               debug_log("no playback lock"); \
+       } \
+} while (0)
+
+#define MMPLAYER_PLAYBACK_UNLOCK(x_player) \
+do \
+{ \
+       GMutex* playback_lock = ((mm_player_t *)x_player)->playback_lock; \
+       if (playback_lock) \
+       {       \
+               g_mutex_unlock( ((mm_player_t*)x_player)->playback_lock );      \
+               debug_log("unlock playback_lock"); \
+       }       \
+       else \
+       { \
+               debug_warning("can't unlock> no playback lock"); \
+       } \
+} while (0)
+
+#if 0
+#define MMPLAYER_FENTER();                                     debug_fenter();
+#define MMPLAYER_FLEAVE();                                     debug_fleave();
+#else
+#define MMPLAYER_FENTER();
+#define MMPLAYER_FLEAVE();
+#endif
+
+#define MAX_SOUND_DEVICE_LEN   18
 
 /* element linking */
 #ifdef GST_EXT_PAD_LINK_UNCHECKED
@@ -80,6 +115,7 @@ do \
 #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
@@ -92,7 +128,7 @@ do \
        caps_type = gst_caps_to_string(x_caps); \
        debug_log ("caps: %s\n", caps_type ); \
        MMPLAYER_FREEIF (caps_type) \
-} while (0);
+} while (0)
 
 /* message posting */
 #define MMPLAYER_POST_MSG( x_player, x_msgtype, x_msg_param ) \
@@ -101,10 +137,9 @@ __mmplayer_post_message(x_player, x_msgtype, x_msg_param);
 
 /* setting player state */
 #define MMPLAYER_SET_STATE( x_player, x_state ) \
-debug_log("setting player state to %d\n", x_state); \
+debug_log("update 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) ) \
@@ -116,11 +151,13 @@ switch ( __mmplayer_check_state(x_player, x_command) ) \
        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 */ 
+/* 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) ) \
@@ -142,27 +179,6 @@ if ( x_player->cmd == MMPLAYER_COMMAND_UNREALIZE || x_player->cmd == MMPLAYER_CO
        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);
@@ -176,8 +192,8 @@ gboolean __util_gst_pad_probe(GstPad *pad, GstBuffer *buffer, gpointer u_data);
 #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. 
+/* 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"); \
@@ -191,15 +207,14 @@ if ( ! gst_pad_add_buffer_probe(x_pad, \
 
 /* generating dot */
 #define MMPLAYER_GENERATE_DOT_IF_ENABLED( x_player, x_name ) \
-if ( PLAYER_INI()->generate_dot ) \
+if ( x_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 ) \
+#define MMPLAYER_SIGNAL_CONNECT( x_player, x_object, x_type, x_signal, x_callback, x_arg ) \
 do \
 { \
        MMPlayerSignalItem* item = NULL; \
@@ -213,62 +228,98 @@ do \
                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); \
+               if ((x_type >= MM_PLAYER_SIGNAL_TYPE_AUTOPLUG) && (x_type < MM_PLAYER_SIGNAL_TYPE_MAX)) \
+                       x_player->signals[x_type] = g_list_append(x_player->signals[x_type], item); \
+               else \
+                       debug_error("wrong signal type [%d]\n", x_type ); \
        } \
 } while ( 0 );
 
+/* release element resource */
+#define MMPLAYER_RELEASE_ELEMENT( x_player, x_bin, x_id ) \
+do \
+{ \
+       if (x_bin[x_id].gst) \
+       { \
+               gst_element_set_state(x_bin[x_id].gst, GST_STATE_NULL); \
+               gst_bin_remove(GST_BIN(x_player->pipeline->mainbin[MMPLAYER_M_PIPE].gst), x_bin[x_id].gst); \
+               x_bin[x_id].gst = NULL; \
+               debug_log("release done [element %d]", x_id); \
+       } \
+} 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_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", \
+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"); 
-
+       MMPLAYER_STATE_GET_NAME(MMPLAYER_TARGET_STATE(x_player)));
 
-#define        MMPLAYER_STATE_CHANGE_TIMEOUT(x_player )         ((mm_player_t*)x_player)->state_change_timeout 
+#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_WFD_STREAMING(x_player)    __is_wfd_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)
+#define MMPLAYER_IS_DASH_STREAMING(x_player)   __is_dash_streaming(x_player)
+#define MMPLAYER_IS_SMOOTH_STREAMING(x_player)   __is_smooth_streaming(x_player)
+
+#define MMPLAYER_URL_HAS_DASH_SUFFIX(x_player) __has_suffix(x_player, "mpd")
+#define MMPLAYER_URL_HAS_HLS_SUFFIX(x_player) __has_suffix(x_player, "m3u8")
 
 /* 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") )
 
+#define MMPLAYER_VIDEO_SINK_CHECK(x_player) \
+do \
+{ \
+       return_val_if_fail ( x_player && \
+               x_player->pipeline && \
+               x_player->pipeline->videobin && \
+               x_player->pipeline->videobin[MMPLAYER_V_SINK].gst, \
+               MM_ERROR_PLAYER_NOT_INITIALIZED ); \
+} while(0)
+
+enum
+{
+       MMPLAYER_DISPLAY_NULL = 0,
+       MMPLAYER_DISPLAY_HDMI_ACTIVE,
+       MMPLAYER_DISPLAY_MIRRORING_ACTIVE,
+};
+
 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);
+int 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 );
+const char* util_get_charset(const char *file_path);
+
+int util_get_is_connected_external_display(void);
+gboolean util_is_miracast_connected(void);
+int util_get_pixtype(unsigned int fourcc);
 
 #ifdef __cplusplus
        }
 #endif
 
-#endif /* __MMF_PLAYER_UTILS_H__ */
+#endif /* __MM_PLAYER_UTILS_H__ */
 
index 33f848f..0f80abd 100755 (executable)
@@ -39,27 +39,16 @@ 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 MM_ERROR_PLAYER_INTERNAL;
+               g_thread_init (NULL);
 
        /* alloc player structure */
        new_player = g_malloc(sizeof(mm_player_t));
        if ( ! new_player )
        {
-               debug_critical("Cannot allocate memory for player\n");
+               debug_error("Cannot allocate memory for player\n");
                goto ERROR;
        }
        memset(new_player, 0, sizeof(mm_player_t));
@@ -69,7 +58,16 @@ int mm_player_create(MMHandleType *player)
 
        if ( ! new_player->cmd_lock )
        {
-               debug_critical("failed to create player lock\n");
+               debug_error("failed to create player lock\n");
+               goto ERROR;
+       }
+
+       /* create player lock */
+       new_player->playback_lock = g_mutex_new();
+
+       if ( ! new_player->playback_lock )
+       {
+               debug_error("failed to create playback_lock\n");
                goto ERROR;
        }
 
@@ -78,15 +76,34 @@ int mm_player_create(MMHandleType *player)
 
        if ( ! new_player->msg_cb_lock )
        {
-               debug_critical("failed to create msg cb lock\n");
+               debug_error("failed to create msg cb lock\n");
+               goto ERROR;
+       }
+
+       /* load ini files */
+       result = mm_player_ini_load(&new_player->ini);
+       if(result != MM_ERROR_NONE)
+       {
+               debug_error("can't load ini");
+               goto ERROR;
+       }
+
+       result = mm_player_audio_effect_ini_load(&new_player->ini);
+       if(result != MM_ERROR_NONE)
+       {
+               debug_error("can't load audio ini");
                goto ERROR;
        }
-       __ta__("[KPI] create media player service",
+
+
+       /* create player */
        result = _mmplayer_create_player((MMHandleType)new_player);
-       )
 
        if(result != MM_ERROR_NONE)
+       {
+               debug_error("failed to create player");
                goto ERROR;
+       }
 
        *player = (MMHandleType)new_player;
 
@@ -102,7 +119,14 @@ ERROR:
                        new_player->cmd_lock = NULL;
                }
 
+               if (new_player->playback_lock)
+               {
+                       g_mutex_free(new_player->playback_lock);
+                       new_player->playback_lock = NULL;
+               }
+
                _mmplayer_destroy( (MMHandleType)new_player );
+
                MMPLAYER_FREEIF( new_player );
        }
 
@@ -114,81 +138,59 @@ 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;
-       }
+       g_mutex_free(((mm_player_t*)player)->cmd_lock);
+       g_mutex_free(((mm_player_t*)player)->playback_lock);
+
+       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 );
@@ -204,11 +206,9 @@ int mm_player_set_pd_message_callback(MMHandleType player, MMMessageCallback cal
 {
        int result = MM_ERROR_NONE;
 
-       debug_log("\n");
-
        return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-       result = _mm_player_set_pd_message_callback(player, callback, user_param);
+       result = _mm_player_set_pd_downloader_message_cb(player, callback, user_param);
 
        return result;
 }
@@ -217,8 +217,6 @@ int mm_player_set_audio_stream_callback(MMHandleType player, mm_player_audio_str
 {
        int result = MM_ERROR_NONE;
 
-       debug_log("\n");
-
        return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
        MMPLAYER_CMD_LOCK( player );
@@ -230,35 +228,15 @@ int mm_player_set_audio_stream_callback(MMHandleType player, mm_player_audio_str
        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);
+       result = _mmplayer_set_videostream_cb(player, callback, user_param);
 
        MMPLAYER_CMD_UNLOCK( player );
 
@@ -269,8 +247,6 @@ 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 );
@@ -286,31 +262,26 @@ int mm_player_set_buffer_need_data_callback(MMHandleType player, mm_player_buffe
 {
        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);
+       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);
+       result = _mmplayer_set_buffer_enough_data_cb(player, callback, user_param);
 
        MMPLAYER_CMD_UNLOCK( player );
 
@@ -322,26 +293,21 @@ int mm_player_set_buffer_seek_data_callback(MMHandleType player, mm_player_buffe
 {
        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);
+       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);
 
@@ -354,13 +320,10 @@ int mm_player_set_volume(MMHandleType player, MMPlayerVolumeType *volume)
        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);
 
@@ -373,13 +336,10 @@ int mm_player_get_volume(MMHandleType player, MMPlayerVolumeType *volume)
        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 );
@@ -391,13 +351,10 @@ int mm_player_set_mute(MMHandleType player, int mute)
        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);
 
@@ -410,39 +367,44 @@ int mm_player_get_mute(MMHandleType player, int *mute)
        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 : It does not support some use cases, eg using colorspace converter */
+int mm_player_change_videosink(MMHandleType player, MMDisplaySurfaceType display_surface_type, void *display_overlay)
+{
+       int result = MM_ERROR_NONE;
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
        MMPLAYER_CMD_LOCK( player );
 
-       result = _mmplayer_get_state(player, (int*)state); /* FIXIT : why int* ? */
+       result = _mmplayer_change_videosink(player, display_surface_type, display_overlay);
 
        MMPLAYER_CMD_UNLOCK( player );
 
        return result;
 }
 
-
 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 );
@@ -450,18 +412,14 @@ int mm_player_push_buffer(MMHandleType player, unsigned char *buf, int size)
        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 );
@@ -469,67 +427,51 @@ int mm_player_start(MMHandleType 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;
@@ -545,7 +487,6 @@ int mm_player_activate_section_repeat(MMHandleType player, int start_pos, int en
        return result;
 }
 
-
 int mm_player_deactivate_section_repeat(MMHandleType player)
 {
        int result = MM_ERROR_NONE;
@@ -561,6 +502,18 @@ int mm_player_deactivate_section_repeat(MMHandleType player)
        return result;
 }
 
+int mm_player_gst_set_audio_channel(MMHandleType player, MMPlayerAudioChannel ch)
+{
+       int result = MM_ERROR_NONE;
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       MMPLAYER_CMD_LOCK( player );
+
+       result = _mmplayer_gst_set_audio_channel(player, ch);
+
+       MMPLAYER_CMD_UNLOCK( player );
+       return result;
+}
 
 int mm_player_set_play_speed(MMHandleType player, float rate)
 {
@@ -577,13 +530,10 @@ int mm_player_set_play_speed(MMHandleType player, float rate)
        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)
@@ -601,13 +551,10 @@ int mm_player_set_position(MMHandleType player, MMPlayerPosFormatType format, in
        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);
 
@@ -630,8 +577,6 @@ int mm_player_get_buffer_position(MMHandleType player, MMPlayerPosFormatType for
 {
        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);
 
@@ -644,73 +589,46 @@ int mm_player_get_buffer_position(MMHandleType player, MMPlayerPosFormatType for
        return result;
 }
 
-int mm_player_adjust_subtitle_position(MMHandleType player, MMPlayerPosFormatType format, int pos)
+int mm_player_set_external_subtitle_path(MMHandleType player, const char* path)
 {
        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);
+       result = _mmplayer_set_external_subtitle_path(player, path);
 
        MMPLAYER_CMD_UNLOCK( player );
-
        return result;
 }
 
-
-int mm_player_set_subtitle_silent(MMHandleType player, int silent)
+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);
 
-       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);
+       if (format >= MM_PLAYER_POS_FORMAT_NUM)
+       {
+               debug_error("wrong format(%d) \n", format);
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
 
        MMPLAYER_CMD_LOCK( player );
 
-       result = _mmplayer_get_subtitle_silent(player, silent);
+       result = _mmplayer_adjust_subtitle_postion(player, format, pos);
 
        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);
 
@@ -721,14 +639,11 @@ int mm_player_set_attribute(MMHandleType player,  char **err_attr_name, const ch
        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);
 
@@ -739,11 +654,10 @@ int mm_player_get_attribute(MMHandleType player,  char **err_attr_name, const ch
        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);
@@ -758,28 +672,106 @@ int mm_player_get_pd_status(MMHandleType player, guint64 *current_pos, guint64 *
 {
        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_pd_get_status(player, current_pos, total_size);
+       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 mm_player_set_display_zoom(MMHandleType player, float level, int x, int y)
 {
        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_display_zoom(player, level, x, y);
+
+       MMPLAYER_CMD_UNLOCK( player );
+
+       return result;
+}
+
+int mm_player_get_display_zoom(MMHandleType player, float *level, int *x, int *y)
+{
+       int result = MM_ERROR_NONE;
 
        return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-       return_val_if_fail(count, MM_ERROR_COMMON_INVALID_ARGUMENT);
+       return_val_if_fail(level, MM_ERROR_COMMON_INVALID_ARGUMENT);
+
+       MMPLAYER_CMD_LOCK( player );
+
+       result = _mmplayer_get_display_zoom(player, level, x, y);
 
-       result = _mmplayer_get_track_count(player, track_type, count);
+       MMPLAYER_CMD_UNLOCK( player );
+
+       return result;
+}
+
+int mm_player_set_uri(MMHandleType player, const char *uri)
+{
+       int result = MM_ERROR_NONE;
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       MMPLAYER_CMD_LOCK( player );
+
+       result = _mmplayer_set_uri(player, uri);
+
+       MMPLAYER_CMD_UNLOCK( player );
+
+       return result;
+
+}
+
+int mm_player_set_next_uri(MMHandleType player, const char *uri)
+{
+       int result = MM_ERROR_NONE;
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       MMPLAYER_CMD_LOCK( player );
+
+       result = _mmplayer_set_next_uri(player, uri, FALSE);
+
+       MMPLAYER_CMD_UNLOCK( player );
 
        return result;
 
 }
+
+int mm_player_get_next_uri(MMHandleType player, char **uri)
+{
+       int result = MM_ERROR_NONE;
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       MMPLAYER_CMD_LOCK( player );
+
+       result = _mmplayer_get_next_uri(player, uri);
+
+       MMPLAYER_CMD_UNLOCK( player );
+
+       return result;
+
+}
+
+int mm_player_enable_media_packet_video_stream(MMHandleType player, bool enable)
+{
+       int result = MM_ERROR_NONE;
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       return_val_if_fail(enable, MM_ERROR_INVALID_ARGUMENT);
+
+       MMPLAYER_CMD_LOCK( player );
+
+       result = _mmplayer_enable_media_packet_video_stream(player, enable);
+
+       MMPLAYER_CMD_UNLOCK( player );
+
+       return result;
+}
diff --git a/src/mm_player_ahs.c b/src/mm_player_ahs.c
deleted file mode 100755 (executable)
index 12f4d90..0000000
+++ /dev/null
@@ -1,1736 +0,0 @@
-/*
- * 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>,
- * naveen cherukuri <naveen.ch@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 <vconf.h>
-#include "mm_player_ahs.h"
-#include "mm_player_priv.h"
-#include "mm_player_utils.h"
-
-char *state_string[] = { "STATE_STOP", "STATE_PREPARE_MANIFEST", "STATE_MEDIA_STREAMING" };
-
-enum
-{
-       AHS_STATE_STOP = 0,
-       AHS_STATE_PREPARE_MANIFEST,
-       AHS_STATE_MEDIA_STREAMING,
-} AHS_STATE;
-
-enum
-{
-       STATE_STOP = 0,
-       STATE_PREPARE_PLAYLIST,
-       STATE_MEDIA_STREAMING
-} HLS_STATE;
-
-static gpointer manifest_update_thread(gpointer data);
-static gpointer media_download_thread (gpointer data);
-static gboolean ahs_client_is_live (mm_player_ahs_t *ahs_player);
-static gboolean ahs_manifest_get_update_interval (mm_player_ahs_t *ahs_player, GTimeVal *next_update);
-static gboolean ahs_create_manifest_download_pipeline (mm_player_ahs_t *ahs_player);
-static gboolean ahs_create_key_download_pipeline (mm_player_ahs_t *ahs_player);
-static gboolean ahs_create_media_download_pipeline (mm_player_ahs_t *ahs_player);
-static gboolean ahs_parse_manifest_update_client (mm_player_ahs_t *ahs_player);
-static gboolean ahs_manifest_download_callback(GstBus *bus, GstMessage *msg, gpointer data);
-static gboolean ahs_key_download_callback(GstBus *bus, GstMessage *msg, gpointer data);
-static gboolean ahs_media_download_callback(GstBus *bus, GstMessage *msg, gpointer data);
-static gboolean ahs_determining_next_file_load (mm_player_ahs_t *ahs_player, gboolean *is_ready);
-static gboolean ahs_set_current_manifest (mm_player_ahs_t *ahs_player);
-static gchar* ahs_get_current_manifest (mm_player_ahs_t *ahs_player);
-static gboolean ahs_switch_playlist (mm_player_ahs_t *ahs_player, guint download_rate);
-static gboolean ahs_get_next_media_uri (mm_player_ahs_t *ahs_player, gchar **media_uri, gchar **key_uri, char **iv);
-static gboolean ahs_decrypt_media (mm_player_ahs_t *ahs_player,GstBuffer *InBuf, GstBuffer **OutBuf);
-static gboolean ahs_destory_manifest_download_pipeline(mm_player_ahs_t *ahs_player);
-static gboolean ahs_destory_media_download_pipeline(mm_player_ahs_t *ahs_player);
-static gboolean ahs_destory_key_download_pipeline(mm_player_ahs_t *ahs_player);
-static gboolean ahs_is_buffer_discontinuous (mm_player_ahs_t *ahs_player);
-static gboolean ahs_clear_discontinuous (mm_player_ahs_t *ahs_player);
-
-static void
-on_new_buffer_from_appsink (GstElement * appsink, void* data)
-{
-       mm_player_ahs_t *ahs_player = (mm_player_ahs_t*) data;
-       GstBuffer *InBuf = NULL;
-       GstFlowReturn fret = GST_FLOW_OK;
-
-       InBuf = gst_app_sink_pull_buffer ((GstAppSink *)appsink);
-       
-       if (InBuf && ahs_player->appsrc) 
-       {
-               ahs_player->seg_size = ahs_player->seg_size + GST_BUFFER_SIZE (InBuf);
-               
-              //g_print ("******** Pushing buffer size = %d and total_seg_size = %"G_GUINT64_FORMAT"\n", GST_BUFFER_SIZE (InBuf), ahs_player->seg_size);
-
-               if (ahs_player->cur_key_uri)
-               {
-                       GstBuffer *OutBuf = NULL;
-                       
-                       ahs_decrypt_media (ahs_player, InBuf, &OutBuf);
-
-                       gst_buffer_unref (InBuf);
-
-                       /* FIXME : Reset Buffer property */
-                       GST_BUFFER_TIMESTAMP (OutBuf) = GST_CLOCK_TIME_NONE;
-                       GST_BUFFER_DURATION (OutBuf) = GST_CLOCK_TIME_NONE;
-                       GST_BUFFER_FLAGS(OutBuf) = 0;
-                       
-                       if (ahs_is_buffer_discontinuous(ahs_player)) 
-                       {
-                               g_print ("\n\n\n\nMarking fragment as discontinuous...\n\n\n\n\n");
-                               GST_BUFFER_FLAG_SET (OutBuf, GST_BUFFER_FLAG_DISCONT);
-                            ahs_clear_discontinuous (ahs_player);
-                       }
-
-                       fret = gst_app_src_push_buffer ((GstAppSrc *)ahs_player->appsrc, OutBuf);
-                       if (fret != GST_FLOW_OK)
-                       {
-                               g_print ("\n\nError in pushing buffer to appsrc: reason - %s\n\n", gst_flow_get_name(fret));
-                               __mm_player_ahs_stop (ahs_player);
-                       }
-
-               }
-               else
-               {
-                       /* FIXME : Reset Buffer property */
-                       GST_BUFFER_TIMESTAMP (InBuf) = GST_CLOCK_TIME_NONE;
-                       GST_BUFFER_DURATION (InBuf) = GST_CLOCK_TIME_NONE;
-                       GST_BUFFER_FLAGS(InBuf) = 0;
-                       
-                       if (ahs_is_buffer_discontinuous(ahs_player)) 
-                       {
-                               g_print ("\n\n\n\n \t\t(((((((((((((((((((((((   Marking fragment as discontinuous... ))))))))))))))))))))))))\n\n\n\n\n");
-                               GST_BUFFER_FLAG_SET (InBuf, GST_BUFFER_FLAG_DISCONT);
-                               ahs_clear_discontinuous (ahs_player);
-                       }
-
-                       fret = gst_app_src_push_buffer ((GstAppSrc *)ahs_player->appsrc, InBuf);
-                       if (fret != GST_FLOW_OK)
-                       {
-                               g_print ("\n\nError in pushing buffer to appsrc: reason - %s\n\n", gst_flow_get_name(fret));
-                               __mm_player_ahs_stop (ahs_player);
-                       }
-               }
-       }
-       else 
-       {
-               debug_warning ("Pulled buffer is not valid!!!\n");
-       }
-}
-
-static gpointer 
-manifest_update_thread(gpointer data)
-{
-       mm_player_ahs_t *ahs_player = (mm_player_ahs_t*) data;
-       gboolean bret = FALSE;
-       GTimeVal next_update = {0, };
-       GTimeVal tmp_update = {0, };
-       guint64 start = 0;
-       guint64 stop = 0;
-       
-       debug_log ("Waiting for trigger to start downloading manifest...\n");
-       g_mutex_lock (ahs_player->manifest_mutex);
-       g_cond_wait (ahs_player->manifest_update_cond, ahs_player->manifest_mutex);
-       g_mutex_unlock (ahs_player->manifest_mutex);
-
-       while (1)
-       {
-               g_mutex_lock (ahs_player->manifest_mutex);
-               if (ahs_player->manifest_thread_exit == TRUE)
-               {
-                       g_mutex_unlock (ahs_player->manifest_mutex);
-                       goto exit;
-               }
-               g_mutex_unlock (ahs_player->manifest_mutex);
-
-               next_update.tv_sec = 0;
-               next_update.tv_usec = 0;
-               
-               g_get_current_time (&next_update);
-
-               start =  (next_update.tv_sec * 1000000)+ next_update.tv_usec;
-               
-               /* download manifest file */
-               bret = ahs_create_manifest_download_pipeline (ahs_player);
-               if (FALSE == bret)
-               {
-                       goto exit;
-               }
-               
-               /* waiting for playlist to be downloaded */             
-               g_mutex_lock (ahs_player->manifest_mutex);
-               if (ahs_player->manifest_thread_exit == TRUE)
-               {
-                       g_mutex_unlock (ahs_player->manifest_mutex);
-                       goto exit;
-               }
-               debug_log ("waiting for manifest file to be downloaded...waiting on manifest eos cond\n");
-               g_cond_wait (ahs_player->manifest_eos_cond, ahs_player->manifest_mutex);
-               g_mutex_unlock (ahs_player->manifest_mutex);
-               
-               if (ahs_client_is_live (ahs_player))
-               {
-                       ahs_manifest_get_update_interval (ahs_player, &next_update);
-
-                       stop = (next_update.tv_sec * 1000000)+ next_update.tv_usec;
-               
-                       g_mutex_lock (ahs_player->manifest_mutex);
-                       if (ahs_player->manifest_thread_exit == TRUE)
-                       {
-                               g_mutex_unlock (ahs_player->manifest_mutex);
-                               goto exit;
-                       }
-                       debug_log ("Next update scheduled at %s\n", g_time_val_to_iso8601 (&next_update));
-                       bret = g_cond_timed_wait (ahs_player->manifest_update_cond, ahs_player->manifest_mutex, &next_update);
-
-                       g_mutex_unlock (ahs_player->manifest_mutex);
-#if 1
-                       tmp_update.tv_sec = 0;
-                       tmp_update.tv_usec = 0;
-                       
-                       g_get_current_time (&tmp_update);
-
-                       if (bret == TRUE)
-                       {
-                               debug_log ("\n\n@@@@@@@@@ Sombody signalled manifest waiting... going to update current manifest file and diff = %d\n\n\n",
-                                       ((next_update.tv_sec * 1000000)+ next_update.tv_usec) - ((tmp_update.tv_sec * 1000000)+ tmp_update.tv_usec));
-                       }
-                       else
-                       {
-                               debug_log ("\n\n\n~~~~~~~~~~~Timeout happened, need to update current manifest file and diff = %d\n\n\n",
-                                       ((next_update.tv_sec * 1000000)+ next_update.tv_usec) - ((tmp_update.tv_sec * 1000000)+ tmp_update.tv_usec));
-                       }
-#endif
-               }
-               else
-               {
-                       g_mutex_lock (ahs_player->manifest_mutex);
-                       if (ahs_player->manifest_thread_exit == TRUE)
-                       {
-                               g_mutex_unlock (ahs_player->manifest_mutex);
-                               goto exit;
-                       }
-                       g_print ("NOT-LIVE : Waiting for trigger to start downloading manifest...\n");
-                       g_cond_wait (ahs_player->manifest_update_cond, ahs_player->manifest_mutex);
-                       g_mutex_unlock (ahs_player->manifest_mutex);
-
-               }
-       }
-
-exit:
-       debug_log ("Exiting from manifest thread...\n");
-       ahs_player->manifest_thread_exit = TRUE;
-       g_thread_exit (ahs_player->manifest_thread);
-       
-       return NULL;
-
-}
-
-static gpointer
-media_download_thread (gpointer data)
-{
-       mm_player_ahs_t *ahs_player = (mm_player_ahs_t*) data;
-       gboolean bret = FALSE;
-       gchar *media_uri = NULL;
-       gchar *key_uri = NULL;
-       GTimeVal time = {0, };
-       GstFlowReturn fret = GST_FLOW_OK;
-       char *iv = (char *) malloc (16);
-       if (iv == NULL)
-       {
-               g_print ("ERRORR");
-               return NULL;
-       }
-
-       g_mutex_lock (ahs_player->media_mutex);
-       g_cond_wait(ahs_player->media_start_cond, ahs_player->media_mutex);
-       g_mutex_unlock (ahs_player->media_mutex);
-
-       debug_log ("Received received manifest file...Moving to media download\n");
-       
-       while (1)
-       {
-               g_mutex_lock (ahs_player->media_mutex);
-               if (ahs_player->media_thread_exit)
-               {
-                       g_mutex_unlock (ahs_player->media_mutex);
-                       goto exit;
-               }
-               g_mutex_unlock (ahs_player->media_mutex);
-
-               if (ahs_player->need_bw_switch)
-               {
-                       debug_log ("Need to Switch BW, start updating new switched URI...\n");
-                       g_cond_signal (ahs_player->manifest_update_cond);
-                       g_mutex_lock (ahs_player->manifest_mutex);
-                       if (ahs_player->media_thread_exit)
-                       {
-                               g_mutex_unlock (ahs_player->manifest_mutex);
-                               goto exit;
-                       }
-                       debug_log ("waiting for manifest eos in media download thread...\n");
-                       g_cond_wait (ahs_player->manifest_eos_cond, ahs_player->manifest_mutex);        
-                       g_mutex_unlock (ahs_player->manifest_mutex);
-       
-               }
-       
-               media_uri = NULL;
-               key_uri = NULL;
-               
-               /* Get next media file to download */
-               bret = ahs_get_next_media_uri (ahs_player, &media_uri, &key_uri, &iv);
-               if (FALSE == bret)
-               {
-                       ahs_player->media_thread_exit = TRUE;
-                       fret = gst_app_src_end_of_stream ((GstAppSrc *)ahs_player->appsrc);
-                       if (GST_FLOW_OK != fret)
-                       {
-                               g_print ("Error in pushing EOS to appsrc : reason - %s", gst_flow_get_name (fret));
-                       }
-                       goto exit;
-               }
-
-               if (NULL == media_uri)
-               {
-                       if (ahs_client_is_live (ahs_player))
-                       {
-                               g_cond_signal (ahs_player->manifest_update_cond);
-                               g_mutex_lock (ahs_player->manifest_mutex);
-                               if (ahs_player->media_thread_exit)
-                               {
-                                       g_mutex_unlock (ahs_player->manifest_mutex);
-                                       goto exit;
-                               }
-                               debug_log ("waiting for manifest eos in media download thread...\n");   
-                               g_cond_wait (ahs_player->manifest_eos_cond, ahs_player->manifest_mutex);
-                               g_mutex_unlock (ahs_player->manifest_mutex);
-                               continue;
-                       }
-                       else
-                       {
-                               ahs_player->media_thread_exit = TRUE;
-                               g_print ("media download thread exiting....");
-                               fret = gst_app_src_end_of_stream ((GstAppSrc *)ahs_player->appsrc);
-                               if (GST_FLOW_OK != fret)
-                               {
-                                       g_print ("Error in pushing EOS to appsrc : reason - %s", gst_flow_get_name (fret));
-                               }
-                               goto exit;
-                       }
-               }
-               
-               if (key_uri)
-               {       
-                       if (ahs_player->cur_key_uri)
-                       {
-                               g_free (ahs_player->cur_key_uri);
-                               ahs_player->cur_key_uri = NULL;
-                       }
-                       
-                       ahs_player->cur_key_uri = g_strdup (key_uri);
-                       g_free (key_uri);
-                       key_uri = NULL;
-                       
-                       memcpy (ahs_player->cur_iv, iv, 16);
-
-                       g_mutex_lock (ahs_player->media_mutex);
-                       ahs_create_key_download_pipeline (ahs_player);
-                       g_cond_wait (ahs_player->key_eos_cond, ahs_player->media_mutex);
-                       g_mutex_unlock (ahs_player->media_mutex);
-
-                       g_print ("Downloaded key url.. and key data is = %s\n", ahs_player->cur_key_data);
-               }
-
-               ahs_player->cur_media_uri = g_strdup (media_uri);
-               g_free (media_uri);
-               media_uri = NULL;
-
-               /* note down segment start time */
-               g_get_current_time (&time);
-               ahs_player->seg_start_time = (time.tv_sec * 1000000)+ time.tv_usec;
-               debug_log ("start time in usec = %"G_GUINT64_FORMAT"\n", ahs_player->seg_start_time);
-
-               bret = ahs_create_media_download_pipeline (ahs_player);
-               if (FALSE == bret)
-               {
-                       goto exit;
-               }
-
-               /* waiting for media file to be downloaded */
-               g_mutex_lock (ahs_player->media_mutex);
-               if (ahs_player->media_thread_exit)
-               {
-                       g_mutex_unlock (ahs_player->media_mutex);
-                       goto exit;
-               }
-               debug_log ("waiting on media EOS....\n");
-               g_cond_wait (ahs_player->media_eos_cond, ahs_player->media_mutex);
-               g_mutex_unlock (ahs_player->media_mutex);
-       
-               debug_log ("Done with waiting on media EOS....\n");
-               
-       }
-
-
-exit:
-       debug_log ("Exiting from media thread...\n");
-       ahs_player->media_thread_exit = TRUE;
-       g_thread_exit (ahs_player->media_thread);
-       return NULL;
-}
-
-static gboolean
-ahs_create_manifest_download_pipeline (mm_player_ahs_t *ahs_player)
-{
-       gboolean bret = FALSE;
-       GstStateChangeReturn    sret = GST_STATE_CHANGE_SUCCESS;
-       gchar* manifest_dump_file_name = NULL;
-       gint fd = -1;
-
-       debug_log ("<<<\n");
-
-       /* If pipeline exists, then cleanup first */
-       if (ahs_player->manifest_download_pipeline)
-               ahs_destory_manifest_download_pipeline(ahs_player);
-
-       /* Create element */
-       ahs_player->manifest_download_pipeline = gst_pipeline_new ("AHS manifest Pipeline");
-       if (NULL == ahs_player->manifest_download_pipeline)
-       {
-               debug_error ("Can't create manifest download pipeline...");
-               return FALSE;
-       }
-       ahs_player->manifest_download_src = gst_element_factory_make ("souphttpsrc", "AHS manifest download source");
-       if (NULL == ahs_player->manifest_download_src)
-       {
-               debug_error ("Can't create manifest download src...");
-               return FALSE;
-       }
-
-       if (ahs_player->user_agent)
-       {
-               g_object_set (ahs_player->manifest_download_src, "user-agent", ahs_player->user_agent, NULL );
-       }
-
-       ahs_player->manifest_download_sink = gst_element_factory_make ("filesink", "AHS manifest download sink");
-       if (NULL == ahs_player->manifest_download_sink)
-       {
-               debug_error ("Can't create manifest download sink...");
-               return FALSE;
-       }
-       
-       /* Add to bin and link */
-       gst_bin_add_many (GST_BIN (ahs_player->manifest_download_pipeline), 
-                                       ahs_player->manifest_download_src, ahs_player->manifest_download_sink,
-                                       NULL);
-       
-       bret = gst_element_link (ahs_player->manifest_download_src, ahs_player->manifest_download_sink);
-       if (FALSE == bret)
-       {
-               debug_error ("Can't link elements src and sink...");
-               return FALSE;
-       }
-       
-       /* Set Bus */
-       GstBus* bus = gst_pipeline_get_bus (GST_PIPELINE (ahs_player->manifest_download_pipeline));
-       gst_bus_add_watch (bus, ahs_manifest_download_callback, ahs_player);
-       gst_object_unref (bus);
-
-       /* Set URI */
-       g_object_set (G_OBJECT (ahs_player->manifest_download_src), "location", ahs_player->cur_mf_uri, NULL);
-
-       if (ahs_player->ahs_manifest_dmp_location)
-               g_unlink(ahs_player->ahs_manifest_dmp_location);
-
-       /* set path to dump manifest file */
-       manifest_dump_file_name = g_strdup(HLS_MANIFEST_DEFAULT_FILE_NAME);
-
-       fd = g_mkstemp(manifest_dump_file_name);
-       if (fd == -1)
-       {
-               debug_error("failed to open temporary file\n");
-               MMPLAYER_FREEIF(manifest_dump_file_name);
-               return FALSE;
-       }
-       
-       sprintf (ahs_player->ahs_manifest_dmp_location, "%s.m3u8", manifest_dump_file_name);
-
-       if (g_file_test (manifest_dump_file_name, G_FILE_TEST_EXISTS))
-       {
-               close(fd);
-               g_unlink(manifest_dump_file_name);
-       }
-
-       MMPLAYER_FREEIF(manifest_dump_file_name);
-
-       /* ENAMETOOLONG or not  */
-       if (strlen(ahs_player->ahs_manifest_dmp_location) > HLS_POSIX_PATH_MAX)
-       {
-               debug_error("file name too long\n");
-               return FALSE;
-       }
-       
-       g_object_set (G_OBJECT (ahs_player->manifest_download_sink), "location", ahs_player->ahs_manifest_dmp_location, NULL);
-
-       debug_log ("src location = %s, save location = %s\n", ahs_player->cur_mf_uri, ahs_player->ahs_manifest_dmp_location);
-
-       g_print ("Going to download manifest-uri -> %s\n", ahs_player->cur_mf_uri);
-
-       /* Start to download */
-       sret = gst_element_set_state (ahs_player->manifest_download_pipeline, GST_STATE_PLAYING);
-
-       debug_log ("sret = %d\n", sret);
-
-       debug_log (">>>\n");
-
-       return TRUE;
-
-}
-
-static gboolean
-ahs_destory_manifest_download_pipeline(mm_player_ahs_t *ahs_player)
-{
-       debug_log ("<<<\n");
-
-       gst_element_set_state (ahs_player->manifest_download_pipeline, GST_STATE_NULL);
-       gst_element_get_state (ahs_player->manifest_download_pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
-
-       gst_object_unref(ahs_player->manifest_download_pipeline);
-       ahs_player->manifest_download_pipeline = NULL;
-
-       debug_log (">>>\n");
-
-       return TRUE;
-}
-
-static gboolean
-ahs_create_media_download_pipeline (mm_player_ahs_t *ahs_player)
-{
-       gboolean bret = FALSE;
-       GstBus* bus = NULL;
-       
-       debug_log ("<<<\n");
-
-       /* If pipeline exists, then cleanup first */
-       if (ahs_player->media_download_pipeline) 
-               ahs_destory_media_download_pipeline(ahs_player);
-
-       /* Create element */
-       ahs_player->media_download_pipeline = gst_pipeline_new ("AHS media Pipeline");
-       if (NULL == ahs_player->media_download_pipeline)
-       {
-               debug_error ("Can't create media download pipeline...");
-               return FALSE;
-       }
-       ahs_player->media_download_src = gst_element_factory_make ("souphttpsrc", "AHS media download source");
-       if (NULL == ahs_player->media_download_src)
-       {
-               debug_error ("Can't create media download src...");
-               return FALSE;
-       }
-
-       if (ahs_player->user_agent)
-       {
-               g_object_set (ahs_player->media_download_src, "user-agent", ahs_player->user_agent, NULL );
-       }
-
-       ahs_player->media_download_sink = gst_element_factory_make ("appsink", "AHS media download sink");
-       if (NULL == ahs_player->media_download_sink)
-       {
-               debug_error ("Can't create media download sink...");
-               return FALSE;
-       }
-       
-       /* Add to bin and link */
-       gst_bin_add_many (GST_BIN (ahs_player->media_download_pipeline), 
-                                       ahs_player->media_download_src, ahs_player->media_download_sink,
-                                       NULL);
-       
-       bret = gst_element_link (ahs_player->media_download_src, ahs_player->media_download_sink);
-       if (FALSE == bret)
-       {
-               debug_error ("Can't link elements src and sink...");
-               return FALSE;
-       }
-       
-       /* Set Bus */
-       bus = gst_pipeline_get_bus (GST_PIPELINE (ahs_player->media_download_pipeline));
-       gst_bus_add_watch (bus, ahs_media_download_callback, ahs_player);
-       gst_object_unref (bus);
-
-       /* Set URI on src element */
-       g_object_set (G_OBJECT (ahs_player->media_download_src), "location", ahs_player->cur_media_uri, NULL);
-
-       g_print ("Going to download media-uri -> %s\n", ahs_player->cur_media_uri);
-
-       /* setting properties on sink element */
-       g_object_set (G_OBJECT (ahs_player->media_download_sink), "emit-signals", TRUE, "sync", FALSE, NULL);
-       g_signal_connect (ahs_player->media_download_sink, "new-buffer",  G_CALLBACK (on_new_buffer_from_appsink), ahs_player);
-
-       /* Start to download */
-       gst_element_set_state (ahs_player->media_download_pipeline, GST_STATE_PLAYING);
-
-       debug_log (">>>\n");
-
-       return TRUE;
-
-}
-
-static gboolean 
-ahs_destory_media_download_pipeline(mm_player_ahs_t *ahs_player)
-{
-       debug_log ("<<<\n");
-
-       gst_element_set_state (ahs_player->media_download_pipeline, GST_STATE_NULL);
-       gst_element_get_state (ahs_player->media_download_pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
-
-       gst_object_unref(ahs_player->media_download_pipeline);
-       ahs_player->media_download_pipeline = NULL;
-
-       debug_log (">>>\n");
-
-       return TRUE;
-}
-
-static gboolean
-ahs_create_key_download_pipeline (mm_player_ahs_t *ahs_player)
-{
-       gboolean bret = FALSE;
-       GstBus* bus = NULL;
-       
-       debug_log ("<<<\n");
-
-       /* If pipeline exists, then cleanup first */
-       if (ahs_player->key_download_pipeline) 
-               ahs_destory_key_download_pipeline(ahs_player);
-
-       /* Create element */
-       ahs_player->key_download_pipeline = gst_pipeline_new ("AHS key Pipeline");
-       if (NULL == ahs_player->key_download_pipeline)
-       {
-               debug_error ("Can't create key download pipeline...");
-               return FALSE;
-       }
-       ahs_player->key_download_src = gst_element_factory_make ("souphttpsrc", "AHS key download source");
-       if (NULL == ahs_player->key_download_src)
-       {
-               debug_error ("Can't create key download src...");
-               return FALSE;
-       }
-
-       if (ahs_player->user_agent)
-       {
-               g_object_set (ahs_player->key_download_src, "user-agent", ahs_player->user_agent, NULL );
-       }
-
-       ahs_player->key_download_sink = gst_element_factory_make ("filesink", "AHS key download sink");
-       if (NULL == ahs_player->key_download_sink)
-       {
-               debug_error ("Can't create key download sink...");
-               return FALSE;
-       }
-       
-       /* Add to bin and link */
-       gst_bin_add_many (GST_BIN (ahs_player->key_download_pipeline), 
-                                       ahs_player->key_download_src, ahs_player->key_download_sink,
-                                       NULL);
-       
-       bret = gst_element_link (ahs_player->key_download_src, ahs_player->key_download_sink);
-       if (FALSE == bret)
-       {
-               debug_error ("Can't link elements src and sink...");
-               return FALSE;
-       }
-       
-       /* Set Bus */
-       bus = gst_pipeline_get_bus (GST_PIPELINE (ahs_player->key_download_pipeline));
-       gst_bus_add_watch (bus, ahs_key_download_callback, ahs_player);
-       gst_object_unref (bus);
-       
-       /* Set URI */
-       g_object_set (G_OBJECT (ahs_player->key_download_src), "location", ahs_player->cur_key_uri, NULL);
-       sprintf (ahs_player->ahs_key_dmp_location, "/opt/apps/com.samsung.video-player/data%s", strrchr(ahs_player->cur_key_uri, '/'));
-       debug_log ("src location = %s, save location = %s\n", ahs_player->cur_key_uri, ahs_player->ahs_key_dmp_location);
-       
-       g_print ("Going to download key-uri -> %s\n", ahs_player->cur_key_uri);
-
-       g_object_set (G_OBJECT (ahs_player->key_download_sink), "location", ahs_player->ahs_key_dmp_location, NULL);
-
-       /* Start to download */
-       gst_element_set_state (ahs_player->key_download_pipeline, GST_STATE_PLAYING);
-
-       debug_log (">>>\n");
-
-       return TRUE;
-
-}
-
-static gboolean
-ahs_destory_key_download_pipeline(mm_player_ahs_t *ahs_player)
-{
-       debug_log ("<<<\n");
-
-       gst_element_set_state (ahs_player->key_download_pipeline, GST_STATE_NULL);
-       gst_element_get_state (ahs_player->key_download_pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
-
-       gst_object_unref(ahs_player->key_download_pipeline);
-       ahs_player->key_download_pipeline = NULL;
-
-       debug_log (">>>\n");
-
-       return TRUE;
-}
-static gboolean
-ahs_client_is_live (mm_player_ahs_t *ahs_player)
-{
-       if (MM_PLAYER_URI_TYPE_HLS == ahs_player->uri_type)
-       {
-               return (hls_client_is_live(ahs_player->ahs_client));
-       }
-       return TRUE;
-}
-
-static gboolean
-ahs_manifest_get_update_interval (mm_player_ahs_t *ahs_player, GTimeVal *next_update)
-{
-       if (MM_PLAYER_URI_TYPE_HLS == ahs_player->uri_type)
-       {
-               return hls_playlist_update_interval(ahs_player->ahs_client, next_update);
-       }
-       return TRUE;
-}
-
-static gboolean
-ahs_parse_manifest_update_client (mm_player_ahs_t *ahs_player)
-{
-       if (MM_PLAYER_URI_TYPE_HLS == ahs_player->uri_type)
-       {
-               return hls_parse_playlist_update_client(ahs_player->ahs_client, ahs_player->ahs_manifest_dmp_location);
-       }
-       else
-       {
-               return FALSE;
-       }
-}
-
-static gboolean
-ahs_manifest_download_callback(GstBus *bus, GstMessage *msg, gpointer data)
-{
-       mm_player_ahs_t *ahs_player = (mm_player_ahs_t*) data;
-       gboolean bret = TRUE;
-       
-       debug_log ("<<<\n");
-
-       if ( !ahs_player ) 
-       {
-               debug_error("AHS player handle is invalid\n");
-               return FALSE;
-       }
-
-       switch ( GST_MESSAGE_TYPE( msg ) )
-       {
-               case GST_MESSAGE_EOS:
-                       {
-                               debug_log("MANIFEST EOS received, state=[%d]\n", ahs_player->ahs_state);
-                               
-                               if (ahs_player->manifest_download_pipeline)
-                                       ahs_destory_manifest_download_pipeline(ahs_player);
-
-                               /* Parse and Update client*/
-                               ahs_parse_manifest_update_client (ahs_player);
-
-                               debug_log ("Current STATE = [%s]\n", state_string[ahs_player->ahs_state]);
-
-                               debug_log ("Received EOS on manifest download...broadcast manifest eos\n");
-                               g_cond_broadcast (ahs_player->manifest_eos_cond);
-
-                               /* state transition : MAIN PLAYLIST -> SUB PLAYLIST (optional) -> MEDIA FILE STREAMING */
-                               g_mutex_lock (ahs_player->state_lock);
-                               if (ahs_player->ahs_state == AHS_STATE_PREPARE_MANIFEST) 
-                               {
-                                       if (MM_PLAYER_URI_TYPE_HLS == ahs_player->uri_type)
-                                       {
-                                               ////////////////////////////////
-                                               //// http live streaming 
-                                               ///////////////////////////////
-
-                                               if (hls_downloaded_variant_playlist (ahs_player->ahs_client, ahs_player->cur_mf_uri))
-                                               {
-                                                       debug_log ("Downloaded Variant playlist file\n");
-                                                       /* if set current playlist based on bandwidth */
-                                                       ahs_set_current_manifest (ahs_player);
-
-                                                       if (ahs_player->cur_mf_uri)
-                                                       {
-                                                               g_free (ahs_player->cur_mf_uri);
-                                                               ahs_player->cur_mf_uri = NULL;
-                                                       }
-
-                                                       ahs_player->cur_mf_uri = g_strdup(ahs_get_current_manifest(ahs_player));
-                                                       
-                                                       debug_log ("Signal to wakeup manifest thread...\n");
-                                                       g_cond_signal (ahs_player->manifest_update_cond);
-                                               }
-                                               else
-                                               {
-                                                       ahs_player->ahs_state = AHS_STATE_MEDIA_STREAMING;
-                                               }
-                                       }
-                               }
-
-                               /* If state is for media streaming */
-                               debug_log ("Current STATE = [%s]\n", state_string[ahs_player->ahs_state]);
-                                       
-                               if (AHS_STATE_MEDIA_STREAMING == ahs_player->ahs_state) 
-                               {
-                                       debug_log ("Signal start of media download....\n");
-                                       g_cond_signal (ahs_player->media_start_cond);
-                               }
-                               g_mutex_unlock (ahs_player->state_lock);
-                       }
-                       
-                       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 ((GstAppSrc *)ahs_player->appsrc), error, debug);
-                               
-                               ret = gst_element_post_message ((GstAppSrc *)ahs_player->appsrc, new_msg);
-                               __mm_player_ahs_stop (ahs_player);
-                               //__mm_player_ahs_deinitialize(ahs_player);
-                               //__mm_player_ahs_destroy(&ahs_player);
-                               
-                               g_print ("\n\n\nError posting msg = %d\n\n\n\n", ret);
-                               //g_free( debug);
-                               //debug = NULL;
-                               //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);
-                               g_free( debug);
-                               debug = NULL;
-                               g_error_free( error);
-                       }
-                       break;
-
-               default:
-                       //debug_warning("unhandled message\n");
-                       break;
-       }
-
-       debug_log (">>>\n");
-
-       return bret;
-}
-
-static gboolean
-ahs_key_download_callback(GstBus *bus, GstMessage *msg, gpointer data)
-{
-       mm_player_ahs_t *ahs_player = (mm_player_ahs_t*) data;
-       gboolean bret = TRUE;
-       
-       debug_log ("<<<\n");
-
-       if ( !ahs_player ) 
-       {
-               debug_error("AHS player handle is invalid\n");
-               return FALSE;
-       }
-
-       switch ( GST_MESSAGE_TYPE( msg ) )
-       {
-               case GST_MESSAGE_EOS:
-                       {
-                               FILE *keyfd = NULL;
-                               guint bytes_read = 0;
-                               int i =0;
-                               
-                               debug_log("KEY EOS received, state=[%d]\n", ahs_player->ahs_state);
-                               if (ahs_player->key_download_pipeline) 
-                                       ahs_destory_key_download_pipeline(ahs_player);
-
-                               debug_log ("Current STATE = [%s]\n", state_string[ahs_player->ahs_state]);
-
-                               if (MM_PLAYER_URI_TYPE_HLS == ahs_player->uri_type)
-                               {
-                                       keyfd = fopen (ahs_player->ahs_key_dmp_location, "r");
-                                       if (keyfd == NULL)
-                                       {
-                                               g_print ("failed to open key file...\n\n\n");
-                                               return FALSE;
-                                       }
-                                       
-                                       /* read key file */
-                                       bytes_read = fread (ahs_player->cur_key_data, sizeof (unsigned char), 16, keyfd);
-                                       if (sizeof(ahs_player->cur_key_data) != bytes_read)
-                                       {
-                                           printf ("key file is not proper...bytes_read from key file = %d\n", bytes_read);
-                                           return FALSE;
-                                       }       
-
-                                       bret = hls_decryption_initialize (ahs_player->ahs_client, &ahs_player->cur_key_data, ahs_player->cur_iv);
-                                       if (FALSE == bret)
-                                       {
-                                               g_print ("Failed to initialize encryption....\n\n");
-                                       }
-                               }
-                               g_cond_signal (ahs_player->key_eos_cond);
-                               debug_log ("signalling key download EOS\n");
-                       }
-                       
-                       break;
-
-               case GST_MESSAGE_ERROR:
-                       {
-                               GError *error = NULL;
-                               gchar* debug = NULL;
-                               /* get error code */
-                               //gst_message_parse_error( msg, &error, &debug );
-                               debug_error ("GST_MESSAGE_ERROR = %s\n", debug);
-                               
-                               gst_element_post_message ((GstAppSrc *)ahs_player->appsrc, msg);
-                               //g_free( debug);
-                               debug = NULL;
-                               //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);
-                               g_free( debug);
-                               debug = NULL;
-                               g_error_free( error);
-                       }
-                       break;
-
-               default:
-                       //debug_warning("unhandled message\n");
-                       break;
-       }
-       return bret;
-}
-
-
-static gboolean
-ahs_media_download_callback(GstBus *bus, GstMessage *msg, gpointer data)
-{
-       mm_player_ahs_t *ahs_player = (mm_player_ahs_t*) data;
-       gboolean bret = TRUE;
-       
-       debug_log ("<<<\n");
-
-       if ( !ahs_player ) 
-       {
-               debug_error("AHS player handle is invalid\n");
-               return FALSE;
-       }
-
-       switch ( GST_MESSAGE_TYPE( msg ) )
-       {
-               case GST_MESSAGE_EOS:
-                       {
-                               glong diff = 0;
-                               GTimeVal time = {0, };
-                               
-                               debug_log("MEDIA EOS received, state=[%d]\n", ahs_player->ahs_state);
-                               
-                               if (ahs_player->media_download_pipeline) 
-                                       ahs_destory_media_download_pipeline(ahs_player);
-                               
-                               g_get_current_time (&time);
-                               ahs_player->seg_end_time = (time.tv_sec * 1000000)+ time.tv_usec;
-                               debug_log ("end time in usec = %"G_GUINT64_FORMAT"\n", ahs_player->seg_end_time);
-
-                               diff = ahs_player->seg_end_time - ahs_player->seg_start_time;
-                               
-                               ahs_player->download_rate = (guint)((ahs_player->seg_size * 8 * 1000000) / diff);
-
-                               ahs_player->cache_frag_count++;
-
-                               
-                               g_print("***********  frag_cnt = %d and download rate = %d bps **************\n", ahs_player->cache_frag_count, ahs_player->download_rate);
-
-                               /* first initial fragments go with least possible bit-rate */
-                               if (ahs_player->cache_frag_count == DEFAULT_FRAGMENTS_CACHE)
-                               {
-                                       debug_log ("=======================================\n");
-                                       debug_log (" \t Done with caching initial %d fragments\n", ahs_player->cache_frag_count);
-                                       debug_log ("=======================================\n");
-                               }
-                               
-                               if (ahs_player->cache_frag_count >= DEFAULT_FRAGMENTS_CACHE)
-                               {
-                                       ahs_switch_playlist (ahs_player, ahs_player->download_rate);                            
-                               }
-
-                               ahs_player->seg_size = 0;
-
-                               g_mutex_lock (ahs_player->media_mutex);
-                               g_cond_broadcast (ahs_player->media_eos_cond);
-                               g_mutex_unlock (ahs_player->media_mutex);
-
-                               debug_log ("Signaled media ts EOS...\n");
-
-                       }
-                       break;
-
-               case GST_MESSAGE_ERROR:
-                       {
-                               GError *error = NULL;
-                               gchar* debug = NULL;
-                               GstMessage *new_msg = NULL;
-                               gboolean ret = FALSE;
-                               
-                               /* 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 ((GstAppSrc *)ahs_player->appsrc), error, debug);
-                               
-                               ret = gst_element_post_message ((GstAppSrc *)ahs_player->appsrc, new_msg);
-                               
-                               //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_FREEIF( debug );
-                               g_error_free( error );
-                       }
-                       break;
-
-               default:
-                       //debug_warning("unhandled message\n");
-                       break;
-       }
-       //debug_log (">>>\n");
-       return bret;
-}
-
-static gboolean 
-ahs_determining_next_file_load (mm_player_ahs_t *ahs_player, gboolean *is_ready)
-{
-       debug_log ("<<<\n");
-       gboolean bret = TRUE;
-       
-       if (ahs_player->ahs_state == AHS_STATE_PREPARE_MANIFEST) 
-       {
-               debug_log ("STATE is not ready to download next file");
-               return FALSE;
-       }
-               
-       if (MM_PLAYER_URI_TYPE_HLS == ahs_player->uri_type)
-       {
-               bret = hls_determining_next_file_load (ahs_player->ahs_client, is_ready);
-       }
-
-       debug_log (">>>\n");
-       return bret;
-}
-
-
-static gboolean
-ahs_set_current_manifest (mm_player_ahs_t *ahs_player)
-{
-       gboolean bret = TRUE;
-       
-       bret = hls_set_current_playlist (ahs_player->ahs_client);
-       if (FALSE == bret)
-       {
-               debug_error ("ERROR in setting current playlist....");
-               return FALSE;
-       }
-
-       return bret;
-}
-
-static gchar* 
-ahs_get_current_manifest (mm_player_ahs_t *ahs_player)
-{
-       return hls_get_current_playlist (ahs_player->ahs_client);
-}
-
-static gboolean
-ahs_switch_playlist (mm_player_ahs_t *ahs_player, guint download_rate)
-{
-       if ((MM_PLAYER_URI_TYPE_HLS == ahs_player->uri_type) && (hls_can_switch (ahs_player->ahs_client)))
-       {
-               ahs_player->need_bw_switch = FALSE;
-               
-               hls_switch_playlist (ahs_player->ahs_client, download_rate, &ahs_player->need_bw_switch);
-
-               debug_log ("Need BW Switch = %d\n", ahs_player->need_bw_switch);
-               
-               if (ahs_player->cur_mf_uri)
-               {
-                       g_free (ahs_player->cur_mf_uri);
-                       ahs_player->cur_mf_uri = NULL;
-               }
-
-               ahs_player->cur_mf_uri = g_strdup(ahs_get_current_manifest(ahs_player));
-                                                       
-               /* Start downloading sub playlist */
-
-               g_mutex_lock (ahs_player->state_lock);
-               ahs_player->ahs_state = AHS_STATE_PREPARE_MANIFEST;
-               g_mutex_unlock (ahs_player->state_lock);        
-                       
-       }
-
-       return TRUE;
-       
-}
-
-static gboolean 
-ahs_get_next_media_uri (mm_player_ahs_t *ahs_player, gchar **media_uri, gchar **key_uri, char **iv)
-{
-       if (MM_PLAYER_URI_TYPE_HLS == ahs_player->uri_type)
-       {
-               return hls_get_next_media_fragment (ahs_player->ahs_client, media_uri, key_uri, iv);
-       }
-       
-       return TRUE;
-}
-
-static gboolean
-ahs_is_buffer_discontinuous (mm_player_ahs_t *ahs_player)
-{
-       if (MM_PLAYER_URI_TYPE_HLS == ahs_player->uri_type)
-       {
-               return hls_is_buffer_discontinuous (ahs_player->ahs_client);
-       }
-       else
-       {
-               return FALSE;
-       }
-}
-
-
-static gboolean
-ahs_clear_discontinuous (mm_player_ahs_t *ahs_player)
-{
-       if (MM_PLAYER_URI_TYPE_HLS == ahs_player->uri_type)
-       {
-               return hls_clear_discontinuous (ahs_player->ahs_client);
-       }
-       else
-       {
-               return FALSE;
-       }
-}
-
-static gboolean
-ahs_decrypt_media (mm_player_ahs_t *ahs_player,GstBuffer *InBuf, GstBuffer **OutBuf)
-{
-       if (MM_PLAYER_URI_TYPE_HLS == ahs_player->uri_type)
-       {
-               return hls_decrypt_media_fragment (ahs_player->ahs_client, InBuf, OutBuf);
-       }
-
-       return TRUE;
-}
-
-gboolean
-ahs_check_allow_cache (mm_player_ahs_t *ahs_player)
-{
-       if (MM_PLAYER_URI_TYPE_HLS == ahs_player->uri_type)
-       {
-               return hls_check_allow_cache (ahs_player->ahs_client);
-       }
-       return FALSE;
-}
-
-gboolean
-ahs_store_media_presentation (mm_player_ahs_t *ahs_player, unsigned char *buffer, unsigned int buffer_len)
-{
-       if (MM_PLAYER_URI_TYPE_HLS == ahs_player->uri_type)
-       {
-               return hls_store_media_presentation (ahs_player->ahs_client, buffer, buffer_len);
-       }
-}
-
-mm_player_ahs_t * __mm_player_ahs_create ()
-{
-       g_print ("\n >>>>>>>>>>>CREATE AHS download\n");
-
-       mm_player_ahs_t *ahs_player = NULL;
-       
-       ahs_player = (mm_player_ahs_t *) malloc (sizeof (mm_player_ahs_t));
-       if (NULL == ahs_player)
-       {
-               debug_error ("Failed to created ahs_player handle...\n");
-               goto ERROR;
-       }
-       
-       ahs_player->manifest_mutex = g_mutex_new ();
-       if (NULL == ahs_player->manifest_mutex)
-       {
-               goto ERROR;
-       }
-       ahs_player->manifest_eos_cond = g_cond_new ();
-       if (NULL == ahs_player->manifest_eos_cond)
-       {
-               goto ERROR;
-       }
-       ahs_player->manifest_exit_cond = g_cond_new ();
-       if (NULL == ahs_player->manifest_exit_cond)
-       {
-               goto ERROR;
-       }
-       ahs_player->manifest_update_cond = g_cond_new ();
-       if (NULL == ahs_player->manifest_update_cond)
-       {
-               goto ERROR;
-       }
-       ahs_player->media_mutex = g_mutex_new ();
-       if (NULL == ahs_player->media_mutex)
-       {
-               goto ERROR;
-       }
-       ahs_player->media_start_cond = g_cond_new ();
-       if (NULL == ahs_player->media_start_cond)
-       {
-               goto ERROR;
-       }
-       ahs_player->media_eos_cond = g_cond_new ();
-       if (NULL == ahs_player->media_eos_cond)
-       {
-               goto ERROR;
-       }
-       ahs_player->key_eos_cond = g_cond_new ();
-       if (NULL == ahs_player->key_eos_cond)
-       {
-               goto ERROR;
-       }
-       ahs_player->state_lock = g_mutex_new ();
-       if (NULL == ahs_player->state_lock)
-       {
-               goto ERROR;
-       }
-       
-       ahs_player->uri_type = MM_PLAYER_URI_TYPE_NONE;
-       ahs_player->is_initialized = FALSE;
-       ahs_player->main_mf_uri = NULL;
-       ahs_player->cur_mf_uri = NULL;
-       ahs_player->cur_media_uri = NULL;
-       ahs_player->appsrc = NULL;
-       ahs_player->manifest_thread = NULL;
-       ahs_player->media_thread = NULL;
-       /* manifest related variables */
-       ahs_player->manifest_thread = NULL;
-       ahs_player->manifest_thread_exit = FALSE;
-       ahs_player->manifest_download_pipeline = NULL;
-       ahs_player->manifest_download_src = NULL;
-       ahs_player->manifest_download_sink = NULL;      
-
-       memset (ahs_player->ahs_manifest_dmp_location, 0, HLS_POSIX_PATH_MAX);
-
-       /* media related variables */
-       ahs_player->media_thread = NULL;
-       ahs_player->media_thread_exit = FALSE;
-
-       ahs_player->media_download_pipeline = NULL;
-       ahs_player->media_download_src = NULL;
-       ahs_player->media_download_sink = NULL;
-
-       /* key related variables */
-       ahs_player->cur_key_uri = NULL;
-       memset (ahs_player->ahs_key_dmp_location, 0, 256);
-       ahs_player->key_download_pipeline = NULL;
-       ahs_player->key_download_src = NULL;
-       ahs_player->key_download_sink = NULL;
-
-       ahs_player->seg_start_time = 0;     /* segment start time in usec*/
-       ahs_player->seg_end_time = 0;
-       ahs_player->seg_size = 0;
-       ahs_player->cache_frag_count = 0;
-       
-       ahs_player->hls_is_wait_for_reload = FALSE;
-
-       g_print ("\n >>>>>>>>>>>CREATE AHS download DONE\n");
-
-       return ahs_player;
-
-ERROR:
-       MMPLAYER_FREEIF(ahs_player);
-   
-       if (ahs_player->manifest_mutex)
-               g_mutex_free(ahs_player->manifest_mutex);
-
-       if ( ahs_player->manifest_eos_cond ) 
-               g_cond_free ( ahs_player->manifest_eos_cond );
-       
-       if ( ahs_player->manifest_exit_cond ) 
-               g_cond_free ( ahs_player->manifest_exit_cond );
-
-       if ( ahs_player->manifest_update_cond )
-               g_cond_free ( ahs_player->manifest_update_cond );
-
-       if (ahs_player->media_mutex)
-               g_mutex_free(ahs_player->media_mutex);
-
-       if ( ahs_player->media_start_cond )
-               g_cond_free ( ahs_player->media_start_cond );
-
-       if ( ahs_player->media_eos_cond )
-               g_cond_free ( ahs_player->media_eos_cond );
-
-       if ( ahs_player->key_eos_cond )
-               g_cond_free ( ahs_player->key_eos_cond );
-
-       if (ahs_player->state_lock)
-               g_mutex_free(ahs_player->state_lock);
-
-       return NULL;
-       
-       
-}
-
-gboolean __mm_player_ahs_initialize (mm_player_ahs_t *ahs_player, int uri_type, char *uri, GstElement *appsrc)
-{
-       gchar *system_ua = NULL;
-
-       debug_log ("<<<\n");
-
-       if (NULL == ahs_player)
-       {
-               debug_error (" Invalid argument\n");
-               return FALSE;
-       }
-
-       g_print ("\n\n Initialize \n\n");
-
-       ahs_player->user_agent = NULL;
-
-       system_ua = (char *)(vconf_get_str(VCONFKEY_ADMIN_UAGENT));
-
-       if (system_ua)
-       {
-               ahs_player->user_agent = g_strdup(system_ua);
-               debug_log ("hls user-agent = %s\n", ahs_player->user_agent);
-       }
-
-       /* initialize ahs common variables */
-       ahs_player->uri_type = uri_type;
-       ahs_player->main_mf_uri = g_strdup (uri);
-       ahs_player->cur_mf_uri = g_strdup (uri);
-       ahs_player->appsrc = appsrc;
-       ahs_player->ahs_state = AHS_STATE_STOP;
-       ahs_player->need_bw_switch = FALSE;
-       
-       if (MM_PLAYER_URI_TYPE_HLS == ahs_player->uri_type)
-       {
-               /* http live streaming */
-               ahs_player->ahs_client = __mm_player_hls_create ();
-               if (NULL == ahs_player->ahs_client)
-               {
-                       return FALSE;
-               }
-               __mm_player_hls_initialize (ahs_player->ahs_client, ahs_player->main_mf_uri);
-       }
-
-       debug_log (">>>\n");
-       
-       ahs_player->is_initialized = TRUE;
-
-       return TRUE;
-}
-
-gboolean __mm_player_ahs_start (mm_player_ahs_t *ahs_player)
-{
-       gboolean bret = TRUE;
-
-       debug_log ("<<<\n");
-
-       if (NULL == ahs_player)
-       {
-               debug_error (" Invalid argument\n");
-               return FALSE;
-       }
-       
-       g_print ("\n >>>>>>>>>>> AHS download START\n");
-
-       /* download manifest file */
-       if (!ahs_create_manifest_download_pipeline (ahs_player))
-               return FALSE;
-
-       ahs_player->ahs_state = AHS_STATE_PREPARE_MANIFEST;
-
-       ahs_player->manifest_thread = g_thread_create (manifest_update_thread, (gpointer)ahs_player, TRUE, NULL);
-
-       if ( !ahs_player->manifest_thread ) 
-       {
-               debug_error("failed to create thread : manifest\n");
-               goto ERROR;
-       }
-       
-       /* media download thread */
-       ahs_player->media_thread = g_thread_create (media_download_thread, (gpointer)ahs_player, TRUE, NULL);
-
-       if ( !ahs_player->media_thread ) 
-       {
-               debug_error("failed to create thread : media\n");
-               goto ERROR;
-       }
-
-       g_print ("\n >>>>>>>>>>> AHS download START DONE\n");
-
-       debug_log (">>>\n");
-
-       return bret;
-
-ERROR:
-
-       if (ahs_player->manifest_thread)
-       {
-               g_thread_join( ahs_player->manifest_thread);
-               ahs_player->manifest_thread = NULL;
-       }
-
-       if (ahs_player->media_thread)
-       {
-               g_thread_join( ahs_player->media_thread);
-               ahs_player->media_thread = NULL;
-       }
-       
-       return FALSE;
-}
-
-gboolean __mm_player_ahs_pause (mm_player_ahs_t *ahs_player)
-{
-       gboolean bret = TRUE;
-
-       debug_log ("<<<\n");
-       
-       if (NULL == ahs_player)
-       {
-               debug_error (" Invalid argument\n");
-               return FALSE;
-       }
-
-       g_print ("\n\n\n PAUSED \n\n\n");
-
-       g_mutex_lock (ahs_player->state_lock);
-       if (AHS_STATE_MEDIA_STREAMING != ahs_player->ahs_state)
-       {
-               g_print ("Pipeline is not in playing state...\n");
-               g_mutex_unlock (ahs_player->state_lock);
-               return TRUE;
-       }
-       g_mutex_unlock (ahs_player->state_lock);
-
-       if (ahs_client_is_live (ahs_player))
-       {
-               g_print ("Live playlist flush now");
-       }
-
-       return bret;
-
-}
-
-gboolean __mm_player_ahs_deinitialize (mm_player_ahs_t *ahs_player)
-{
-       debug_log ("<<<\n");
-
-       g_print ("\n >>>>>>>>>>> AHS deinitalize \n");
-
-       if (NULL == ahs_player)
-       {
-               debug_error (" Invalid argument\n");
-               return FALSE;
-       }
-
-       if (FALSE == ahs_player->is_initialized)
-       {
-               debug_log ("already de-initlialized\n");
-               g_print ("\n\n######## already de-initlialized\n");
-
-               return TRUE;
-       }
-       
-       ahs_player->need_bw_switch = FALSE;
-       ahs_player->hls_is_wait_for_reload= FALSE;
-
-       ahs_player->appsrc = NULL;
-       
-       if (MM_PLAYER_URI_TYPE_HLS == ahs_player->uri_type)
-       {
-               if (ahs_player->ahs_client)
-               {
-                       __mm_player_hls_destroy (ahs_player->ahs_client);
-                       ahs_player->ahs_client = NULL;
-               }
-       }
-
-       /* manifest related variables */
-       ahs_player->manifest_thread = NULL;
-       ahs_player->manifest_thread_exit = TRUE;
-       ahs_player->uri_type = MM_PLAYER_URI_TYPE_NONE;
-       
-
-       /* media related variables */
-       ahs_player->media_thread = NULL;
-       ahs_player->media_thread_exit = TRUE;
-
-       
-       ahs_player->is_initialized = FALSE;
-
-       if (ahs_player->ahs_manifest_dmp_location)
-               g_unlink(ahs_player->ahs_manifest_dmp_location);
-       
-       g_print ("\n >>>>>>>>>>> AHS deinitalize DONE \n");
-       debug_log (">>>\n");
-
-       return TRUE;
-}
-
-gboolean __mm_player_ahs_stop (mm_player_ahs_t *ahs_player)
-{
-       GstFlowReturn fret = GST_FLOW_OK;
-
-       debug_fenter ();
-
-       if (NULL == ahs_player)
-       {
-               debug_error ("Invalid argument...\n");
-               return FALSE;
-       }
-       
-       if (ahs_player->ahs_state == AHS_STATE_STOP)
-       {
-               debug_log ("Already in AHS STOP state...\n");
-               return TRUE;
-       }
-       
-       if (ahs_player->appsrc)
-       {
-               debug_log ("Push EOS to playback pipeline\n");
-               // TODO: try to send FLUSH event instead of EOS
-               fret = gst_app_src_end_of_stream ((GstAppSrc *)ahs_player->appsrc);
-               if (fret != GST_FLOW_OK)
-               {
-                       debug_error ("Error in pushing EOS to appsrc: reason - %s\n", gst_flow_get_name(fret));
-               } 
-       }
-       
-       ahs_player->ahs_state = AHS_STATE_STOP;
-
-       if (ahs_player->media_thread)
-       {
-               g_mutex_lock (ahs_player->media_mutex);
-               ahs_player->media_thread_exit = TRUE;
-               g_mutex_unlock (ahs_player->media_mutex);
-
-               g_cond_broadcast (ahs_player->manifest_eos_cond);               
-               g_cond_broadcast (ahs_player->media_eos_cond);
-               g_cond_broadcast (ahs_player->media_start_cond);
-               g_cond_broadcast (ahs_player->key_eos_cond);
-
-               debug_log ("waiting for media thread to finish\n");
-               g_thread_join (ahs_player->media_thread);
-               ahs_player->media_thread = NULL;
-               debug_log("media thread released\n");           
-       }       
-
-       if (ahs_player->manifest_thread)
-       {
-               g_mutex_lock (ahs_player->manifest_mutex);
-               ahs_player->manifest_thread_exit = TRUE;
-               g_mutex_unlock (ahs_player->manifest_mutex);
-               
-               g_cond_broadcast (ahs_player->manifest_update_cond);
-               g_cond_broadcast (ahs_player->manifest_eos_cond);
-
-               debug_log ("waiting for manifest thread to finish\n");
-               g_thread_join (ahs_player->manifest_thread);
-               ahs_player->manifest_thread = NULL;
-               debug_log("manifest thread released\n");
-       }
-
-       if (ahs_player->manifest_download_pipeline)
-               ahs_destory_manifest_download_pipeline(ahs_player);
-
-       if (ahs_player->media_download_pipeline)
-               ahs_destory_media_download_pipeline(ahs_player);
-
-       if (ahs_player->key_download_pipeline)
-               ahs_destory_key_download_pipeline(ahs_player);
-
-       debug_fleave ();
-
-       return TRUE;
-
-}
-
-gboolean __mm_player_ahs_destroy (mm_player_ahs_t *ahs_player)
-{
-       g_print ("\n >>>>>>>>>>>Destroying AHS download\n");
-       debug_log ("<<<<<\n");
-
-       if (NULL == ahs_player)
-       {
-               debug_error ("Invalid argument...\n");
-               g_print ("Invalid argument...\n");
-               return TRUE;
-       }
-
-       debug_log ("\nBroadcasting signals from destory\n\n\n");        
-
-       if (ahs_player->manifest_update_cond)
-               g_cond_broadcast (ahs_player->manifest_update_cond);
-       
-       if (ahs_player->manifest_eos_cond)
-               g_cond_broadcast (ahs_player->manifest_eos_cond);
-
-       if (ahs_player->media_eos_cond)
-               g_cond_broadcast (ahs_player->media_eos_cond);
-       
-       if (ahs_player->media_start_cond)
-               g_cond_broadcast (ahs_player->media_start_cond);
-       
-       if (ahs_player->key_eos_cond)
-               g_cond_broadcast (ahs_player->key_eos_cond);
-
-
-       g_print ("waiting for manifest thread to finish from destroy\n");
-       if (ahs_player->manifest_thread)
-       {
-               g_thread_join (ahs_player->manifest_thread);
-       }
-       g_print ("waiting for media thread to finish from destroy\n");
-       
-       if (ahs_player->media_thread)
-       {
-               g_thread_join (ahs_player->media_thread);
-       }
-       g_print ("DESTROY threads are DEAD \n");
-
-       /* initialize ahs common variables */
-       if (ahs_player->main_mf_uri)
-       {
-               g_free (ahs_player->main_mf_uri);
-               ahs_player->main_mf_uri = NULL;
-       }
-       
-       if (ahs_player->cur_mf_uri)
-       {
-               g_free (ahs_player->cur_mf_uri);
-               ahs_player->cur_mf_uri = NULL;
-       }
-       
-       if (ahs_player->cur_media_uri)
-       {
-               g_free (ahs_player->cur_media_uri);
-               ahs_player->cur_media_uri = NULL;
-       }
-       if (ahs_player->manifest_mutex)
-       {
-               g_mutex_free (ahs_player->manifest_mutex);
-               ahs_player->manifest_mutex = NULL;
-       }
-       if (ahs_player->manifest_eos_cond)
-       {
-               g_cond_free (ahs_player->manifest_eos_cond);
-               ahs_player->manifest_eos_cond = NULL;
-       }
-       if (ahs_player->manifest_exit_cond)
-       {
-               g_cond_free (ahs_player->manifest_exit_cond);
-               ahs_player->manifest_exit_cond = NULL;
-       }       
-       if (ahs_player->manifest_update_cond)
-       {
-               g_cond_free (ahs_player->manifest_update_cond);
-               ahs_player->manifest_update_cond = NULL;
-       }
-       if (ahs_player->media_mutex)
-       {
-               g_mutex_free (ahs_player->media_mutex);
-               ahs_player->media_mutex = NULL;
-       }
-       if (ahs_player->media_eos_cond)
-       {
-               g_cond_free (ahs_player->media_eos_cond);
-               ahs_player->media_eos_cond = NULL;
-       }
-       if (ahs_player->media_start_cond)
-       {
-               g_cond_free (ahs_player->media_start_cond);
-               ahs_player->media_start_cond = NULL;
-       }       
-
-       /* key related variables */
-       if (ahs_player->key_eos_cond)
-       {
-               g_cond_free (ahs_player->key_eos_cond);
-               ahs_player->key_eos_cond = NULL;
-       }       
-       if (ahs_player->cur_key_uri )
-       {
-               g_free (ahs_player->cur_key_uri);
-               ahs_player->cur_key_uri = NULL;
-       }
-
-       if (ahs_player->ahs_client)
-       {
-               __mm_player_hls_destroy(ahs_player->ahs_client);
-               ahs_player->ahs_client = NULL;
-       }
-
-       MMPLAYER_FREEIF(ahs_player->user_agent);
-
-       free (ahs_player);
-       ahs_player = NULL;
-
-       g_print ("\n >>>>>>>>>>>Destroying AHS download DONE\n");
-
-       debug_log (">>>>>\n");
-       
-       return TRUE;
-
-}
-
-
diff --git a/src/mm_player_ahs_hls.c b/src/mm_player_ahs_hls.c
deleted file mode 100755 (executable)
index 78f173e..0000000
+++ /dev/null
@@ -1,738 +0,0 @@
-/*
- * 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>,
- * naveen cherukuri <naveen.ch@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_player_ahs_hls.h"
-
-static const float update_interval_factor[] = { 1, 0.5, 1.5, 3 };
-#define AES_BLOCK_SIZE 16
-#define BITRATE_SWITCH_UPPER_THRESHOLD 0.4
-#define BITRATE_SWITCH_LOWER_THRESHOLD 0.1
-
-static gboolean hls_switch_to_lowerband (mm_player_hls_t * player, guint download_rate);
-static gboolean hls_switch_to_upperband (mm_player_hls_t * ahs_player, GList *next_bw_lists, guint download_rate);
-
-/* utility function for removing '\r' character in string */
-char* string_replace (char* text, int len)
-{
-       int i=0;
-       char *dst_ptr = NULL;
-       char* tmp = malloc (len);
-       if (NULL == tmp)
-       {
-               debug_error ("Failed to allocate memory...\n");
-               return NULL;
-       }
-       memset (tmp, 0, len);
-       dst_ptr = tmp;
-
-       for (i=0; i<len; i++)   {
-               if (text[i] != '\r') {
-                       *dst_ptr++ = text[i];
-               }
-       }
-       return tmp;
-}
-
-gint my_compare (gconstpointer a,  gconstpointer b)
-{
-       int first  = ((GstM3U8*)a)->bandwidth;
-       int second = ((GstM3U8*)b)->bandwidth;
-       //return second - first;
-       return first - second; // ascending sort
-}
-
-void hls_dump_mediafile (GstM3U8MediaFile* mediafile)
-{
-       debug_log ("[%d][%d][%s][%s]\n", mediafile->sequence, mediafile->duration, mediafile->title, mediafile->uri);
-}
-
-void hls_dump_m3u8 (GstM3U8* m3u8)
-{
-       debug_log ("uri = [%s]\n", m3u8->uri);
-       debug_log ("version = [%d], endlist = [%d], bandwidth = [%d], target duration = [%d], mediasequence = [%d]\n",
-                       m3u8->version, m3u8->endlist, m3u8->bandwidth, m3u8->targetduration, m3u8->mediasequence);
-       debug_log ("allow cache = %s, program_id = %d, codecs = %s\n", m3u8->allowcache, m3u8->program_id, m3u8->codecs);
-       debug_log ("width = %d, height = %d\n", m3u8->width, m3u8->height);
-       debug_log ("last data = [%s], parent = [%p]\n", m3u8->last_data, m3u8->parent);
-
-       GList* tmp = m3u8->lists;
-       while (tmp) {
-               debug_log ("################### SUB playlist ##################\n");
-               hls_dump_m3u8 (tmp->data);
-               tmp = g_list_next(tmp);
-       }
-
-       tmp = m3u8->files;
-       while (tmp) {
-               hls_dump_mediafile (tmp->data);
-               tmp = g_list_next(tmp);
-       }
-}
-
-void hls_dump_playlist (void *hls_handle)
-{
-       mm_player_hls_t *hls_player = (mm_player_hls_t *) hls_handle;
-
-       debug_log ("============================== DUMP PLAYLIST =================================\n");
-       debug_log ("update_failed_count = %d, seq = %d\n", hls_player->client->update_failed_count, hls_player->client->sequence);
-
-       if (hls_player->client->current)        
-       {
-               debug_log ("################### CURRENT playlist ##################\n");
-               hls_dump_m3u8 (hls_player->client->current);
-       }
-       debug_log ("================================    E N D    =================================\n");
-}
-
-#define MMPLAYER_DEFAULT_AUDIO_BANDWIDTH        70000 /* FIXIT */
-
-gboolean hls_parse_playlist_update_client (void *hls_handle, char* playlist)
-{
-       mm_player_hls_t *hls_player = (mm_player_hls_t *) hls_handle;
-       GError *error = NULL;
-       guint8 *data = NULL;
-       
-       debug_log ("<<<  Playlist =  [%s] \n" ,playlist);
-
-       /* prepare MMAP */
-       GMappedFile *file = g_mapped_file_new (playlist, TRUE, &error);
-       if (error) 
-       {
-               g_print ("failed to open file: %s\n", error->message);
-               g_error_free (error);
-               return FALSE;
-       }
-       
-       data = (guint8 *) g_mapped_file_get_contents (file);
-
-       /* Get replaced text (remove '\r') */
-       char* replaced_text = string_replace (data, g_mapped_file_get_length (file));
-
-       /* update with replaced text */
-       if (gst_m3u8_client_update (hls_player->client, replaced_text)) 
-       {
-               GList *my_list = NULL;
-               guint list_count = g_list_length(hls_player->client->main->lists);
-
-               debug_log("sublist count = %d\n", list_count);
-
-               if (list_count > 1)
-               {
-                       for (my_list = hls_player->client->main->lists; my_list != NULL; my_list = g_list_next (my_list))
-                       {
-                               GstM3U8 *my_m3u8 = NULL;
-
-                               my_m3u8 = (GstM3U8 *)my_list->data;
-
-                               /* check if it can be audio or not */
-                               if (my_m3u8->bandwidth < MMPLAYER_DEFAULT_AUDIO_BANDWIDTH)
-                               {
-                                       /* doesn't consider it */
-                                       hls_player->client->main->lists = g_list_remove(hls_player->client->main->lists, my_m3u8);
-                                       break;
-                               }
-
-                       }
-               }
-
-               //hls_dump_m3u8 (hls_player->client->main);
-               /* DUMP */
-               hls_dump_playlist (hls_player);
-       }
-       else 
-       {
-               g_print ("\n\n!!!!!!!!!!!!!!!! RELOADED but NO changes!!!!!!\n\n");
-       }
-
-       /* clean up */
-       g_mapped_file_unref (file);
-       
-       return TRUE;
-
-       debug_log (">>>\n");
-}
-
-
-gboolean hls_set_current_playlist (mm_player_hls_t *hls_player)
-{
-       GList* copied = NULL;
-       GList* tmp = NULL;
-       
-       debug_log ("<<<\n");
-
-       if (hls_player->client->main->endlist)  
-       {
-               debug_log ("main playlist has endlist. No need to set current playlist\n");
-               return FALSE;
-       }
-
-       copied = g_list_copy (hls_player->client->main->lists);
-       tmp = g_list_sort (copied, my_compare);
-       
-       /* Set initial bandwidth */
-       if (tmp) 
-       {
-               GstM3U8* data = (GstM3U8*)tmp->data;
-               
-               if (data) 
-               {
-                       debug_log ("Set Initial bandwidth\n");
-                       gst_m3u8_client_set_current (hls_player->client, data);
-                       debug_log ("Setting to initial BW = %d\n", data->bandwidth);
-                       tmp = g_list_next(tmp);
-               }
-               else 
-               {
-                       debug_error ("Initial media data is not valid!!!\n");
-                       g_list_free (copied);
-                       return FALSE;
-               }
-       }
-       g_list_free (copied);
-
-       debug_log (">>>\n");
-
-       return TRUE;
-}
-
-gchar  *hls_get_current_playlist (mm_player_hls_t *hls_player)
-{
-       return hls_player->client->current->uri;
-}
-
-gboolean hls_has_variant_playlist (void *hls_handle)
-{
-       mm_player_hls_t *hls_player = (mm_player_hls_t *) hls_handle;
-       
-       if ( gst_m3u8_client_has_variant_playlist (hls_player->client)) 
-       {
-               return TRUE;
-       }
-       else
-       {
-               debug_log ("playlist is simple playlist file....");
-               return FALSE;
-       }
-}
-
-gboolean hls_is_variant_playlist (void *hls_handle)
-{
-       mm_player_hls_t *hls_player = (mm_player_hls_t *) hls_handle;
-       
-       if ( gst_m3u8_client_has_variant_playlist (hls_player->client) && (hls_player->client->current->files == NULL)) 
-       {
-               return TRUE;
-       }
-       else
-       {
-               debug_log ("playlist is simple playlist file....");
-               return FALSE;
-       }
-}
-
-gboolean
-hls_downloaded_variant_playlist (void *hls_handle, gchar *cur_mf_uri)
-{
-       mm_player_hls_t *hls_player = (mm_player_hls_t *) hls_handle;
-
-       if ( gst_m3u8_client_has_variant_playlist (hls_player->client)) 
-       {
-               if (!strcmp(hls_player->client->main->uri, cur_mf_uri))
-               {
-                       debug_log ("downloaded variant master playlist...\n");
-                       return TRUE;
-               }
-               else
-               {
-                       debug_log ("downloaded slave playlist file...\n");
-                       return FALSE;
-               }
-       }
-       else
-       {
-               debug_log ("playlist is simple one...\n");
-               return FALSE;
-       }
-
-}
-
-gboolean hls_can_switch (void *hls_handle)
-{
-       mm_player_hls_t *hls_player = (mm_player_hls_t *) hls_handle;
-
-       return gst_m3u8_client_has_variant_playlist (hls_player->client);
-}
-
-
-gboolean hls_client_is_live (void *hls_handle)
-{
-       mm_player_hls_t *hls_player = (mm_player_hls_t *) hls_handle;
-       
-       return gst_m3u8_client_is_live(hls_player->client);
-}
-
-gboolean hls_playlist_update_interval (void *hls_handle, GTimeVal *next_update)
-{
-       gfloat update_factor;
-       gint count;
-       guint64 update = 0;
-       
-       mm_player_hls_t *hls_player = (mm_player_hls_t *) hls_handle;
-
-       count = hls_player->client->update_failed_count;
-       if (count < 3)
-               update_factor = update_interval_factor[count];
-       else
-               update_factor = update_interval_factor[3];
-
-       if (hls_player->client->current->targetduration == 0)
-       {
-               hls_player->client->current->targetduration = 10; //hack
-       }
-       g_time_val_add (next_update, hls_player->client->current->targetduration * update_factor * 1000000);
-
-       update = (next_update->tv_sec * 1000000)+ next_update->tv_usec;
-
-
-       return TRUE;
-}
-
-gboolean 
-hls_determining_next_file_load (void *hls_handle, gboolean *is_ready)
-{
-       mm_player_hls_t *hls_player = (mm_player_hls_t *) hls_handle;
-
-       debug_log ("<<<\n");
-       
-       if (gst_m3u8_client_is_live(hls_player->client)) 
-       {
-               /* If next file is playable, then let it start */
-               if (gst_m3u8_client_check_next_fragment (hls_player->client))   
-               {
-                       *is_ready = TRUE;
-               } 
-               else 
-               {
-                       *is_ready = FALSE;
-                       debug_log ("Not ready to play next file!!!!! wait for reloading........\n");    
-               }
-       }
-       else
-       {
-               *is_ready = TRUE;
-               debug_log ("No available media and ENDLIST exists, so Do nothing!!!! ");        
-       }
-
-       debug_log (">>>\n");
-       return FALSE;
-}
-
-
-
-static gboolean
-hls_switch_to_upperband (mm_player_hls_t * ahs_player, GList *next_bw_lists, guint download_rate)
-{
-       GstM3U8 *next_client = NULL;
-       GList *final_bw_lists = NULL;
-
-       while (1)
-       {
-              next_client = (GstM3U8 *)next_bw_lists->data;
-               if (download_rate > (next_client->bandwidth + (BITRATE_SWITCH_UPPER_THRESHOLD * next_client->bandwidth)))
-               {
-                       final_bw_lists = next_bw_lists;
-                       next_bw_lists = g_list_next (next_bw_lists);
-                       if (NULL == next_bw_lists)
-                       {
-                               debug_log ("\n****** reached max BW possible.... *********\n");
-                               ahs_player->client->main->lists = final_bw_lists;
-                               gst_m3u8_client_set_current (ahs_player->client, final_bw_lists->data);
-                               debug_log("Client is MAX FAST, switching to bitrate %d\n", ahs_player->client->current->bandwidth);     
-                               break;                          
-                       }
-               }
-               else
-               {
-                       // TODO: Wrong condition.. need to check
-                       #if 0
-                       ahs_player->client->main->lists = final_bw_lists;
-                       gst_m3u8_client_set_current (ahs_player->client, final_bw_lists->data);
-                       #endif
-                       debug_log("Client is FAST, switching to bitrate %d\n", ahs_player->client->current->bandwidth); 
-                       break;
-               }
-       }
-
-       return TRUE;
-}
-
-static gboolean
-hls_switch_to_lowerband (mm_player_hls_t * player, guint download_rate)
-{
-       GList *cur_bw_lists = player->client->main->lists;
-       GList *prev_bw_lists = NULL;
-       GList *present_bw_lists = player->client->main->lists;
-       GstM3U8 *cur_client = (GstM3U8 *)cur_bw_lists->data;;
-       GstM3U8 *present_client = NULL;
-       
-       while (1)
-       {
-               present_client = (GstM3U8 *)present_bw_lists->data;
-               
-               if (download_rate < (present_client->bandwidth + (BITRATE_SWITCH_LOWER_THRESHOLD * present_client->bandwidth)))
-               {
-                       prev_bw_lists = present_bw_lists;
-                       
-                       if(NULL == present_bw_lists->prev) 
-                       {
-                               if (cur_client->bandwidth == present_client->bandwidth)
-                               {
-                                       debug_log ("\n\n\n We are at same lower BW\n\n\n");
-                                       return TRUE;
-                               }
-                               debug_log ("\n****** reached min BW possible.... *********\n\n");
-                               player->client->main->lists = prev_bw_lists;
-                               gst_m3u8_client_set_current (player->client, prev_bw_lists->data);
-                               debug_log("Client is MAX SLOW, switching to bitrate %d\n", player->client->current->bandwidth); 
-                               return TRUE;                            
-                       }
-
-                       present_bw_lists = g_list_previous (present_bw_lists);
-
-               }
-               else
-               {
-                       player->client->main->lists = present_bw_lists;
-                       gst_m3u8_client_set_current (player->client, present_bw_lists->data);
-                       debug_log ("Client is SLOW, switching to bitrate %d\n", player->client->current->bandwidth);    
-                       break;
-               }
-       }
-
-       return TRUE;
-}
-
-gboolean hls_switch_playlist (void *hls_handle, guint download_rate, gboolean *need_bw_switch)
-{
-       mm_player_hls_t *hls_player = (mm_player_hls_t *) hls_handle;
-
-       GList *next_bw_lists = NULL;
-       GstM3U8 *next_client = NULL;
-       GList *present_bw_lists = NULL;
-       GstM3U8 *present_client = NULL;
-       GList *prev_bw_lists = NULL;
-       GstM3U8 *prev_client = NULL;
-
-       present_bw_lists = hls_player->client->main->lists;
-       present_client = (GstM3U8 *)present_bw_lists->data;
-       if (NULL == present_client)
-       {
-               g_print ("\n\n ERROR : Present client is NULL\n\n");
-               return FALSE;
-       }
-
-       next_bw_lists = g_list_next (hls_player->client->main->lists);
-       if (next_bw_lists)
-       {
-               next_client = (GstM3U8 *)next_bw_lists->data;
-       }
-       
-       prev_bw_lists = g_list_previous (hls_player->client->main->lists);
-       if (prev_bw_lists)
-       {
-               prev_client = (GstM3U8 *)prev_bw_lists->data;
-       }
-       
-       if (next_bw_lists && (download_rate > (next_client->bandwidth + (BITRATE_SWITCH_UPPER_THRESHOLD * next_client->bandwidth))))
-       {
-               /* our download rate is 40% more than next bandwidth available */
-               hls_switch_to_upperband (hls_player, next_bw_lists, download_rate);
-               g_print (">>>>>>> Need to switch to UPPER BW [ %d ]\n", hls_player->client->current->bandwidth);
-
-               *need_bw_switch = TRUE;
-       }
-       if (prev_bw_lists && (download_rate < (present_client->bandwidth + (BITRATE_SWITCH_LOWER_THRESHOLD * present_client->bandwidth))))
-       {
-               hls_switch_to_lowerband (hls_player, download_rate);    
-               g_print ("<<<<< Need to switch to LOWER BW [ %d ]\n", hls_player->client->current->bandwidth);
-               *need_bw_switch = TRUE;
-       }
-
-       return TRUE;
-}
-
-gboolean hls_get_next_media_fragment (void *hls_handle, gchar **media_uri, gchar **key_uri,  char **iv)
-{
-       mm_player_hls_t *hls_player = (mm_player_hls_t *) hls_handle;
-       GstM3U8MediaFile *next_fragment_file = NULL;
-       gboolean discontinuity = FALSE;
-       char *tmp_iv = NULL;
-          
-       /* Get Next file to download */
-       next_fragment_file = gst_m3u8_client_get_next_fragment (hls_player->client, &discontinuity);
-       if (next_fragment_file) 
-       {
-               hls_player->discontinuity = discontinuity;
-               if (discontinuity)
-                       g_print ("\n\n\n!!!!!!!!! Discontinuity in fragments.....!!!!!!!!\n\n\n");
-               
-               debug_log ("media uri = %s and key_url = %s\n",next_fragment_file->uri, next_fragment_file->key_url);
-               if (next_fragment_file->key_url)
-               {
-                       tmp_iv = *iv;
-                       int i;
-
-                       for (i = 0; i< 16; i++)
-                       {
-                               debug_log ("%x", next_fragment_file->iv[i]);
-                               tmp_iv[i] = next_fragment_file->iv[i];
-                       }
-                       *iv = tmp_iv;
-                       *key_uri = g_strdup (next_fragment_file->key_url);
-               }               
-               if (next_fragment_file->uri)
-               {
-                       *media_uri = g_strdup (next_fragment_file->uri);
-               }
-       }
-       else
-       {
-               debug_log ("\n\n ++++++++ No fragment remaining..... +++++++++\n\n");
-               return TRUE;
-       }
-       return TRUE;
-}
-
-gboolean
-hls_is_buffer_discontinuous (void *hls_handle)
-{
-       mm_player_hls_t *hls_player = (mm_player_hls_t *) hls_handle;
-
-       return hls_player->discontinuity;
-}
-
-gboolean
-hls_clear_discontinuous (void *hls_handle)
-{
-       mm_player_hls_t *hls_player = (mm_player_hls_t *) hls_handle;
-
-       hls_player->discontinuity = 0;
-
-       return TRUE;
-}
-
-gboolean
-hls_check_allow_cache (void *hls_handle)
-{
-       mm_player_hls_t *hls_player = (mm_player_hls_t *) hls_handle;
-
-       // TODO: doing intentioanlly for testing
-       return FALSE;
-
-       /* if allow_cache tag exists and if it is NO.. then dont cache media file. Otherwise, client can cache */          
-       if (gst_m3u8_client_allow_cache(hls_player->client) &&
-               (!strncmp (gst_m3u8_client_allow_cache(hls_player->client), "NO", 2)))
-       {
-               debug_log ("\nClient SHOULD NOT cache media content...\n");
-               return FALSE;
-       }
-       else
-       {
-               debug_log ("\nClient MAY cache media content...\n");
-               return TRUE;
-       }
-
-}
-
-gboolean
-hls_store_media_presentation (void *hls_handle, unsigned char *buffer, unsigned int buffer_len)
-{
-       mm_player_hls_t *hls_player = (mm_player_hls_t *) hls_handle;
-       gint fd = -1;
-       gint written = 0;
-       
-       if (NULL == hls_player->allow_cache_fd)
-       {
-               gchar *name = NULL;
-                       
-               /* make copy of the template, we don't want to change this */
-               name = g_strdup ("/tmp/XXXXXX");
-
-               g_print ("\n========> Cached filename = %s\n", name);
-               
-               fd = g_mkstemp (name);
-
-               g_free(name);
-               
-               if (fd == -1)
-               {
-                       g_print ("\n\n\nFailed to create tmp file for writing...\n\n\n");
-                       return FALSE;
-               }
-               
-               /* open the file for update/writing */
-               hls_player->allow_cache_fd = fdopen (fd, "wb+");
-               if (NULL == hls_player->allow_cache_fd)
-               {
-                       g_print ("Failed to create allow cache file ptr\n\n\n");
-                       return FALSE;
-               }
-       }
-
-
-       written = fwrite (buffer, 1, buffer_len, hls_player->allow_cache_fd);
-       debug_log ("Cache file written %d bytes ....", written);
-
-       return TRUE;
-
-}
-
-gboolean hls_decryption_initialize (void *hls_handle, gchar *key_data, unsigned char *iv)
-{
-       mm_player_hls_t *hls_player = (mm_player_hls_t *) hls_handle;
-
-       EVP_CIPHER_CTX_init(&(hls_player->decrypt));
-       EVP_DecryptInit_ex(&(hls_player->decrypt), EVP_aes_128_cbc(), NULL, key_data, iv);
-       
-       return TRUE;
-}
-
-gboolean
-hls_decrypt_media_fragment (void *hls_handle,GstBuffer *InBuf, GstBuffer **OutBuf)
-{
-       mm_player_hls_t *hls_player = (mm_player_hls_t *) hls_handle;
-
-       unsigned int inbuf_size = 0;
-       unsigned char *inbuf_data = NULL;
-       int remain = 0;
-       unsigned int out_len = 0;
-       GstBuffer *buffer = NULL;
-                                               
-       if (hls_player->remained)
-       {
-               buffer = gst_buffer_merge (hls_player->remained, InBuf);
-               if (NULL == buffer)
-               {
-                       g_print ("ERROR: Failed to merge...\n");
-                       return FALSE;
-               }
-                               
-               gst_buffer_unref (hls_player->remained);
-               hls_player->remained = NULL;
-       }
-       else
-       {
-               buffer = InBuf;
-       }
-
-       inbuf_size = GST_BUFFER_SIZE (buffer);
-       inbuf_data = GST_BUFFER_DATA (buffer);
-       
-       remain = inbuf_size % AES_BLOCK_SIZE;
-                       
-       if (remain)
-       {
-               hls_player->remained = gst_buffer_new_and_alloc (remain);
-               if (NULL == hls_player->remained)
-               {
-                       g_print ("Error: failed to allocate memory...\n");
-                       return FALSE;
-               }
-                               
-               /* copy remained portion to buffer */
-               memcpy (GST_BUFFER_DATA(hls_player->remained), inbuf_data + inbuf_size- remain, remain);
-       }
-                       
-       out_len = inbuf_size - remain + AES_BLOCK_SIZE;
-
-       *OutBuf = gst_buffer_new_and_alloc (out_len);
-       if (NULL == *OutBuf)
-       {
-               g_print ("Failed to allocate memory for OutBuf...\n");
-               return FALSE;
-       }
-                               
-       EVP_DecryptUpdate(&(hls_player->decrypt), GST_BUFFER_DATA(*OutBuf), &out_len, inbuf_data, inbuf_size - remain);
-
-       GST_BUFFER_SIZE (*OutBuf) = out_len;
-
-       return TRUE;
-
-}
-
-void * __mm_player_hls_create ()
-{
-       mm_player_hls_t *hls_player = NULL;
-       
-       hls_player = (mm_player_hls_t *) malloc (sizeof (mm_player_hls_t));
-       if (NULL == hls_player)
-       {
-               debug_error ("Failed to created ahs_player handle...\n");
-               return NULL;
-       }
-
-       return (void *)hls_player;
-}
-
-gboolean __mm_player_hls_destroy (void *hls_handle)
-{
-       mm_player_hls_t *hls_player = (mm_player_hls_t *) hls_handle;
-
-       if (hls_player->uri)
-       {
-               g_free (hls_player->uri);
-               hls_player->uri = NULL;
-       }
-       
-       if (hls_player->client)
-       {
-               gst_m3u8_client_free (hls_player->client);
-               hls_player->client = NULL;
-       }
-
-       free (hls_player);
-       
-       return TRUE;
-       
-}
-
-gboolean __mm_player_hls_initialize (void *hls_handle, gchar *uri)
-{
-       mm_player_hls_t *hls_player = (mm_player_hls_t *) hls_handle;
-
-       hls_player->uri = g_strdup (uri);
-
-       hls_player->client = gst_m3u8_client_new (hls_player->uri);
-       if (NULL == hls_player->client)
-       {
-               debug_error ("Failed to create HLS client\n");
-               return FALSE;
-       }
-       
-       hls_player->remained = NULL;
-       hls_player->allow_cache_fd = NULL;
-       
-       return TRUE;
-}
-
-
index 57628c0..33f70b4 100755 (executable)
  *
  */
 
-#include <glib.h>
 #include <mm_debug.h>
+#include <mm_error.h>
+#include "mm_player_utils.h"
 #include "mm_player_priv.h"
 #include "mm_player_asm.h"
+#include <vconf.h>
+#include <vconf-internal-sound-keys.h>
+
+#define MMPLAYER_CHECK_SESSION_SKIP(x_player_asm) \
+do \
+{ \
+       if (x_player_asm->skip_session == TRUE) \
+       { \
+               debug_log("skip session"); \
+               return MM_ERROR_NONE; \
+       } \
+}while(0);
+
+#define MMPLAYER_CHECK_SESSION_INSTANCE(x_player_asm) \
+do \
+{ \
+       if (!x_player_asm) \
+       { \
+               debug_log("no session instance");\
+               return MM_ERROR_SOUND_NOT_INITIALIZED; \
+       } \
+}while(0);
 
 static ASM_sound_events_t __mmplayer_asm_get_event_type(gint type);
 
+const gchar *
+__mmplayer_asm_get_state_name ( int state )
+{
+       switch ( state )
+       {
+               case ASM_STATE_NONE:
+                       return "NONE";
+               case ASM_STATE_PLAYING:
+                       return "PLAYING";
+               case ASM_STATE_PAUSE:
+                       return "PAUSED";
+               case ASM_STATE_STOP:
+                       return "STOP";
+               case ASM_STATE_WAITING:
+                       return "BUFFERING";
+               default:
+                       return "INVAID";
+       }
+}
+
+#define MMPLAYER_ASM_STATE_GET_NAME(state)      __mmplayer_asm_get_state_name(state)
+
 gint
 _mmplayer_asm_register(MMPlayerASM* sm, ASM_sound_cb_t callback, void* param)
 {
-       /* read mm-session type */
-       gint sessionType = MM_SESSION_TYPE_SHARE;
+       gint session_type = MM_SESSION_TYPE_MEDIA;
+       gint session_options = 0;
        gint errorcode = MM_ERROR_NONE;
        gint asm_handle = -1;
        gint event_type = ASM_EVENT_NONE;
        gint pid = -1;
 
-       debug_log("\n");
+       MMPLAYER_FENTER();
 
-       if ( ! sm )
-       {
-               debug_error("invalid session handle\n");
-               return MM_ERROR_PLAYER_NOT_INITIALIZED;
-       }
+       MMPLAYER_CHECK_SESSION_INSTANCE(sm);
+       MMPLAYER_CHECK_SESSION_SKIP(sm);
 
        /* check if it's running on the media_server */
        if ( sm->pid > 0 )
@@ -51,73 +93,66 @@ _mmplayer_asm_register(MMPlayerASM* sm, ASM_sound_cb_t callback, void* param)
                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);
+       /* read session information */
+       errorcode = _mm_session_util_read_information(pid, &session_type, &session_options);
        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;
-               }
+               debug_warning("Read Session Type failed. use default \"media\" type\n");
+               session_type = MM_SESSION_TYPE_MEDIA;
        }
 
-       /* 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 )
+       /* interpret session information */
+       event_type = __mmplayer_asm_get_event_type(session_type);
+
+       /* check if it's one of CALL series */
+       if ( event_type == ASM_EVENT_CALL ||
+               event_type == ASM_EVENT_VIDEOCALL ||
+               event_type == ASM_EVENT_VOIP)
        {
-               debug_log("session type is VIDEOCALL\n");
-               sm->event = ASM_EVENT_VIDEOCALL;
+               debug_warning("session type is one of CALL series(%d), skip registering ASM\n", session_type);
+               sm->event = event_type;
+               sm->skip_session = TRUE;
                return MM_ERROR_NONE;
        }
 
-       /* interpret session type */
-       event_type = __mmplayer_asm_get_event_type(sessionType);
-
-
-
-       /* register audio-session-manager callback */
+       /* register audio-session-manager handle and 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");
+               debug_error("ASM_register_sound() failed, error(%x)\n", errorcode);
                return errorcode;
        }
+       /* set session options */
+       if (session_options)
+       {
+               if( ! ASM_set_session_option(asm_handle, session_options, &errorcode))
+               {
+                       debug_error("ASM_set_session_options() failed, error(%x)\n", errorcode);
+                       return errorcode;
+               }
+       }
 
        /* now succeed to register our callback. take result */
        sm->handle = asm_handle;
        sm->state = ASM_STATE_NONE;
        sm->event = event_type;
 
+       MMPLAYER_FLEAVE();
+
        return MM_ERROR_NONE;
 }
 
 gint
-_mmplayer_asm_deregister(MMPlayerASM* sm)
+_mmplayer_asm_unregister(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;
-       }
+       MMPLAYER_FENTER();
+
+       MMPLAYER_CHECK_SESSION_INSTANCE(sm);
+       MMPLAYER_CHECK_SESSION_SKIP(sm);
 
        /* check if it's running on the media_server */
        if ( sm->pid > 0 )
@@ -125,88 +160,139 @@ _mmplayer_asm_deregister(MMPlayerASM* sm)
                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) )
+       if (sm->handle)
        {
-               debug_error("Unregister sound failed 0x%X\n", errorcode);
-               return MM_ERROR_POLICY_INTERNAL;
+               if( ! ASM_unregister_sound( sm->handle, event_type, &errorcode) )
+               {
+                       debug_error("Unregister sound failed 0x%X\n", errorcode);
+                       return MM_ERROR_POLICY_INTERNAL;
+               }
        }
+       debug_warning("asm unregistered");
+
+       MMPLAYER_FLEAVE();
 
        return MM_ERROR_NONE;
 }
 
-gint _mmplayer_asm_set_state(MMHandleType hplayer, ASM_sound_states_t state)
+gint _mmplayer_asm_set_state(MMHandleType hplayer, ASM_sound_states_t state, gboolean enable_safety_vol)
 {
        gint event_type = ASM_EVENT_NONE;
        gint pid = -1;
+       int vconf_safety_vol_val = 0;
        ASM_resource_t resource = ASM_RESOURCE_NONE;
        mm_player_t *player = (mm_player_t *)hplayer;
        MMPlayerASM* sm  = &player->sm;
+       MMPLAYER_FENTER();
 
-       if ( ! sm )
+       if (player->set_mode.safety_volume)
        {
-               debug_error("invalid session handle\n");
-               return MM_ERROR_PLAYER_NOT_INITIALIZED;
+               /* get safety volume */
+               if (vconf_get_int(VCONFKEY_SOUND_ENABLE_SAFETY_VOL, &vconf_safety_vol_val))
+               {
+                       debug_error ("failed to get safety volume");
+               }
+
+               if (enable_safety_vol)
+               {
+                       vconf_safety_vol_val = vconf_safety_vol_val | VCONFKEY_SOUND_SAFETY_VOL_FW_MMPLAYER;
+               }
+               else
+               {
+                       vconf_safety_vol_val = vconf_safety_vol_val & ~VCONFKEY_SOUND_SAFETY_VOL_FW_MMPLAYER;
+               }
+
+               /* set safety volume */
+               if (vconf_set_int(VCONFKEY_SOUND_ENABLE_SAFETY_VOL, vconf_safety_vol_val))
+               {
+                       debug_error ("failed to set safety volume");
+               }
+               debug_log("safety vol : %d(0:false, 1:true), current result of vconf val : 0x%x", enable_safety_vol, vconf_safety_vol_val);
        }
 
+       MMPLAYER_CHECK_SESSION_INSTANCE(sm);
+       MMPLAYER_CHECK_SESSION_SKIP(sm);
+
        /* 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 )
+       /* in case of stop, it should be stop first and post interrupt message to application */
+       if ( !sm->by_asm_cb || state == ASM_STATE_STOP)//|| sm->state == ASM_STATE_PLAYING )
        {
                int ret = 0;
                event_type = sm->event;
+               resource = sm->resource;
 
                /* 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(ASM_STATE_PLAYING == state || ASM_STATE_PAUSE == state || ASM_STATE_WAITING == state)
                {
-                       if(player->pipeline && player->pipeline->videobin)
-                               resource = ASM_RESOURCE_VIDEO_OVERLAY | ASM_RESOURCE_HW_DECODER;
+                       int surface_type = 0;
+                       mm_attrs_get_int_by_name (player->attrs, "display_surface_type", &surface_type);
+                       debug_log("surface type = %d", surface_type);
+
+                       if (player->pipeline && player->pipeline->videobin)
+                       {
+                               if(surface_type == MM_DISPLAY_SURFACE_X)
+                               {
+                                       resource = ASM_RESOURCE_VIDEO_OVERLAY | ASM_RESOURCE_HW_DECODER;
+                               }
+                               else if (surface_type == MM_DISPLAY_SURFACE_EVAS)
+                               {
+                                       resource = ASM_RESOURCE_HW_DECODER;
+                               }
+                       }
+
+                       if( __mmplayer_is_streaming (player))
+                               resource = resource | ASM_RESOURCE_STREAMING;
+
+                       /* reset */
+                       sm->keep_last_pos = FALSE;
                }
 
-               if( ! ASM_set_sound_state( sm->handle, event_type, state, resource, &ret) )
+               if( ((sm->state != state) || (sm->resource != resource)) && ! ASM_set_sound_state( sm->handle, event_type, state, resource, &ret) )
                {
+                       gint retval = MM_ERROR_POLICY_INTERNAL;
+
                        debug_error("Set state to [%d] failed 0x%X\n", state, ret);
-                       return MM_ERROR_POLICY_BLOCKED;
+                       switch(ret)
+                       {
+                               case ERR_ASM_POLICY_CANNOT_PLAY:
+                               case ERR_ASM_POLICY_CANNOT_PLAY_BY_CALL:
+                               case ERR_ASM_POLICY_CANNOT_PLAY_BY_ALARM:
+                                       retval = MM_ERROR_POLICY_BLOCKED;
+                                       break;
+                               default:
+                                       retval = MM_ERROR_POLICY_INTERNAL;
+                                       break;
+                       }
+
+                       return retval;
                }
-
-               sm->state = state;
        }
        else
        {
-               sm->by_asm_cb = 0;
-               sm->state = state;
+               sm->by_asm_cb = FALSE;
        }
 
+       sm->state = state;
+
+       /* waiting to be changed because callback can be called */
+       if (ASM_STATE_STOP == state)
+       {
+               ASM_sound_states_t session_state;
+               ASM_get_sound_state(sm->handle, event_type, &session_state, NULL);
+       }
+
+       debug_error("ASM state changed to [%s]", MMPLAYER_ASM_STATE_GET_NAME(state));
+       MMPLAYER_FLEAVE();
        return MM_ERROR_NONE;
 }
 
@@ -216,27 +302,47 @@ __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;
+       switch(type)
+       {
+               case MM_SESSION_TYPE_CALL:
+                       event_type = ASM_EVENT_CALL;
                        break;
 
-                       case MM_SESSION_TYPE_EXCLUSIVE:
-                               event_type = ASM_EVENT_EXCLUSIVE_MMPLAYER;
+               case MM_SESSION_TYPE_VIDEOCALL:
+                       event_type = ASM_EVENT_VIDEOCALL;
                        break;
 
-                       case MM_SESSION_TYPE_NOTIFY:
-                               event_type = ASM_EVENT_NOTIFY;
+               case MM_SESSION_TYPE_VOIP:
+                       event_type = ASM_EVENT_VOIP;
                        break;
-                       
-                       case MM_SESSION_TYPE_ALARM:
-                               event_type = ASM_EVENT_ALARM;
+
+               case MM_SESSION_TYPE_MEDIA:
+//             case MM_SESSION_TYPE_MEDIA_RECORD:
+                       event_type = ASM_EVENT_MEDIA_MMPLAYER;
                        break;
-                       default:
-                               debug_critical("unexpected case!\n");
-                               g_assert(0);
-               }
 
-               return event_type;
+               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;
+
+               case MM_SESSION_TYPE_RECORD_VIDEO:
+               case MM_SESSION_TYPE_RECORD_AUDIO:
+                       event_type = ASM_EVENT_MEDIA_MMPLAYER;
+                       break;
+
+               default:
+                       debug_msg("unexpected case!\n");
+                       event_type = ASM_EVENT_MEDIA_MMPLAYER;
+                       break;
+       }
+
+       return event_type;
 }
index 444066c..5c9a0c7 100755 (executable)
@@ -29,7 +29,7 @@
 #include <mm_attrs_private.h>
 #include <mm_attrs.h>
 #include <gst/interfaces/xoverlay.h>
-
+#include "mm_player_utils.h"
 #include "mm_player_priv.h"
 #include "mm_player_attrs.h"
 
@@ -67,8 +67,6 @@ _mmplayer_get_attribute(MMHandleType handle,  char **err_attr_name, const char *
        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);
@@ -81,8 +79,6 @@ _mmplayer_get_attribute(MMHandleType handle,  char **err_attr_name, const char *
        if ( result != MM_ERROR_NONE)
                debug_error("failed to get %s attribute\n", attribute_name);
 
-       debug_fleave();
-
        return result;
 }
 
@@ -92,8 +88,6 @@ _mmplayer_set_attribute(MMHandleType handle,  char **err_attr_name, const char *
        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);
@@ -117,8 +111,6 @@ _mmplayer_set_attribute(MMHandleType handle,  char **err_attr_name, const char *
                return result;
        }
 
-       debug_fleave();
-
        return result;
 }
 
@@ -129,8 +121,6 @@ _mmplayer_get_attributes_info(MMHandleType handle,  const char *attribute_name,
        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);
@@ -181,33 +171,26 @@ _mmplayer_get_attributes_info(MMHandleType handle,  const char *attribute_name,
                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 )
+                       !player->pipeline->videobin ||
+                       !player->pipeline->videobin[MMPLAYER_V_SINK].gst )
                {
-                       debug_warning("videosink element is not yet ready\n");
                        /*
                         * The attribute should be committed even though videobin is not created yet.
                         * So, true should be returned here.
@@ -218,40 +201,38 @@ __mmplayer_apply_attribute(MMHandleType handle, const char *attribute_name)
 
                if ( MM_ERROR_NONE != _mmplayer_update_video_param( player ) )
                {
-                       debug_error("failed to update video param\n");
+                       debug_error("failed to update video param");
                        return MM_ERROR_PLAYER_INTERNAL;
                }
        }
 
-       debug_fleave();
-
        return MM_ERROR_NONE;
 }
 
 MMHandleType
 _mmplayer_construct_attribute(MMHandleType handle)
 {
+       mm_player_t *player = NULL;
        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;
+       //gchar *system_ua = NULL;
 
-       debug_fenter();
+       return_val_if_fail (handle, 0);
 
-       return_if_fail(handle);
+       player = MM_PLAYER_CAST(handle);
 
        MMPlayerAttrsSpec player_attrs[] =
        {
                {
-                       "profile_uri",                  // name
+                       "profile_uri",                                  // name
                        MM_ATTRS_TYPE_STRING,           // type
-                       MM_ATTRS_FLAG_RW,               // flag
-                       (void *) NULL,                  // default value
+                       MM_ATTRS_FLAG_RW,                       // flag
+                       (void *) NULL,                          // default value
                        MM_ATTRS_VALID_TYPE_NONE,       // validity type
-                       0,                              // validity min value
-                       0                               // validity max value
+                       0,                                                      // validity min value
+                       0                                                       // validity max value
                },
                {
                        "profile_user_param",
@@ -272,10 +253,10 @@ _mmplayer_construct_attribute(MMHandleType handle)
                        MMPLAYER_MAX_INT
                },
                {
-                       "profile_async_start",
+                       "profile_prepare_async",
                        MM_ATTRS_TYPE_INT,
                        MM_ATTRS_FLAG_RW,
-                       (void *) 1,
+                       (void *) 0,
                        MM_ATTRS_VALID_TYPE_INT_RANGE,
                        0,
                        1
@@ -353,6 +334,15 @@ _mmplayer_construct_attribute(MMHandleType handle)
                        0
                },
                {
+                       "streaming_timeout",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) -1,    // DEFAULT_HTTP_TIMEOUT
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       -1,
+                       MMPLAYER_MAX_INT
+               },
+               {
                        "subtitle_uri",
                        MM_ATTRS_TYPE_STRING,
                        MM_ATTRS_FLAG_RW,
@@ -515,6 +505,15 @@ _mmplayer_construct_attribute(MMHandleType handle)
                        MMPLAYER_MAX_INT
                },
                {
+                       "content_text_track_num",
+                       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,
@@ -602,6 +601,42 @@ _mmplayer_construct_attribute(MMHandleType handle)
                        0
                },
                {
+                       "display_src_crop_x",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       MMPLAYER_MAX_INT
+               },
+               {
+                       "display_src_crop_y",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       MMPLAYER_MAX_INT
+               },
+               {
+                       "display_src_crop_width",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       MMPLAYER_MAX_INT
+               },
+               {
+                       "display_src_crop_height",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       MMPLAYER_MAX_INT
+               },
+               {
                        "display_roi_x",
                        MM_ATTRS_TYPE_INT,
                        MM_ATTRS_FLAG_RW,
@@ -638,6 +673,15 @@ _mmplayer_construct_attribute(MMHandleType handle)
                        MMPLAYER_MAX_INT
                },
                {
+                       "display_roi_mode",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) MM_DISPLAY_METHOD_CUSTOM_ROI_FULL_SCREEN,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       MM_DISPLAY_METHOD_CUSTOM_ROI_FULL_SCREEN,
+                       MM_DISPLAY_METHOD_CUSTOM_ROI_LETER_BOX
+               },
+               {
                        "display_rotation",
                        MM_ATTRS_TYPE_INT,
                        MM_ATTRS_FLAG_RW,
@@ -650,7 +694,7 @@ _mmplayer_construct_attribute(MMHandleType handle)
                        "display_visible",
                        MM_ATTRS_TYPE_INT,
                        MM_ATTRS_FLAG_RW,
-                       (void *) TRUE,
+                       (void *) FALSE,
                        MM_ATTRS_VALID_TYPE_INT_RANGE,
                        0,
                        1
@@ -674,7 +718,7 @@ _mmplayer_construct_attribute(MMHandleType handle)
                        0
                },
                {
-                       "display_overlay_ext",
+                       "display_overlay_user_data",
                        MM_ATTRS_TYPE_DATA,
                        MM_ATTRS_FLAG_RW,
                        (void *) NULL,
@@ -684,36 +728,27 @@ _mmplayer_construct_attribute(MMHandleType handle)
                },
                {
                        "display_zoom",
-                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_TYPE_DOUBLE,
                        MM_ATTRS_FLAG_RW,
                        (void *) 1,
-                       MM_ATTRS_VALID_TYPE_INT_RANGE,
-                       1,
-                       MMPLAYER_MAX_INT
+                       MM_ATTRS_VALID_TYPE_DOUBLE_RANGE,
+                       1.0,
+                       9.0
                },
                {
                        "display_surface_type",
                        MM_ATTRS_TYPE_INT,
                        MM_ATTRS_FLAG_RW,
-                       (void *) 0,
+                       (void *) MM_DISPLAY_SURFACE_NULL,
                        MM_ATTRS_VALID_TYPE_INT_RANGE,
                        MM_DISPLAY_SURFACE_X,
-                       MM_DISPLAY_SURFACE_NULL
-               },
-               {
-                       "display_surface_use_multi",
-                       MM_ATTRS_TYPE_INT,
-                       MM_ATTRS_FLAG_RW,
-                       (void *) FALSE,
-                       MM_ATTRS_VALID_TYPE_INT_RANGE,
-                       FALSE,
-                       TRUE
+                       MM_DISPLAY_SURFACE_X_EXT
                },
                {
                        "display_evas_surface_sink",
                        MM_ATTRS_TYPE_STRING,
                        MM_ATTRS_FLAG_READABLE,
-                       (void *) PLAYER_INI()->videosink_element_evas,
+                       (void *) player->ini.videosink_element_evas,
                        MM_ATTRS_VALID_TYPE_NONE,
                        0,
                        0
@@ -778,8 +813,8 @@ _mmplayer_construct_attribute(MMHandleType handle)
                        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
+                       0,
+                       MMPLAYER_MAX_INT
                },
                {
                        "sound_route",
@@ -821,7 +856,16 @@ _mmplayer_construct_attribute(MMHandleType handle)
                        "sound_priority",
                        MM_ATTRS_TYPE_INT,
                        MM_ATTRS_FLAG_RW,
-                       (void *) 0,                     // 0: normal, 1: high 2: high with sound transition
+                       (void *) 0,                     // 0: normal, 1: high 2: high with sound transition 3: mix with others regardless of priority
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       3
+               },
+               {
+                       "sound_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
@@ -839,7 +883,7 @@ _mmplayer_construct_attribute(MMHandleType handle)
                        "pcm_extraction_samplerate",    // set samplerate for pcm extraction
                        MM_ATTRS_TYPE_INT,
                        MM_ATTRS_FLAG_RW,
-                       (void *) 8000,                          // hz
+                       (void *) 44100,                         // hz
                        MM_ATTRS_VALID_TYPE_INT_RANGE,
                        0,
                        MMPLAYER_MAX_INT
@@ -933,6 +977,15 @@ _mmplayer_construct_attribute(MMHandleType handle)
                        MM_ATTRS_VALID_TYPE_NONE,
                        0,
                        0
+               },
+               {
+                       "accurate_seek",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       1
                }
        };
 
@@ -942,8 +995,8 @@ _mmplayer_construct_attribute(MMHandleType handle)
 
        if ( !base )
        {
-               debug_error("Cannot create mmplayer attribute\n");
-               goto ERROR;
+               debug_error("failed to alloc attrs constructor");
+               return 0;
        }
 
        /* initialize values of attributes */
@@ -967,8 +1020,8 @@ _mmplayer_construct_attribute(MMHandleType handle)
 
        if ( !attrs )
        {
-               debug_error("Cannot create mmplayer attribute\n");
-               goto ERROR;
+               debug_error("failed to create player attrs");
+               return 0;
        }
 
        /* set validity type and range */
@@ -982,7 +1035,7 @@ _mmplayer_construct_attribute(MMHandleType handle)
                                mmf_attrs_set_valid_range (attrs, idx,
                                                player_attrs[idx].value_min,
                                                player_attrs[idx].value_max,
-                                               player_attrs[idx].default_value);
+                                               (int)(player_attrs[idx].default_value));
                        }
                        break;
 
@@ -994,43 +1047,18 @@ _mmplayer_construct_attribute(MMHandleType handle)
                }
        }
 
-       /* 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;
-
-ERROR:
-       _mmplayer_deconstruct_attribute(handle);
-
-       return FALSE;
 }
 
 bool
 _mmplayer_deconstruct_attribute(MMHandleType handle) // @
 {
-       debug_fenter();
-
        mm_player_t *player = MM_PLAYER_CAST(handle);
 
-       return_if_fail( player );
+       return_val_if_fail ( player, FALSE );
 
        if (player->attrs)
        {
@@ -1038,5 +1066,5 @@ _mmplayer_deconstruct_attribute(MMHandleType handle) // @
                player->attrs = 0;
        }
 
-       debug_fleave();
+       return TRUE;
 }
diff --git a/src/mm_player_audioeffect.c b/src/mm_player_audioeffect.c
new file mode 100755 (executable)
index 0000000..cd4f14d
--- /dev/null
@@ -0,0 +1,993 @@
+/*
+ * 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_utils.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 hplayer, MMAudioEffectType effect_type, mmplayer_supported_audio_effect_cb foreach_cb, void *user_data)
+{
+       mm_player_t *player = NULL;
+       int result = MM_ERROR_NONE;
+       mm_sound_device_flags_e flags = MM_SOUND_DEVICE_IO_DIRECTION_OUT_FLAG | MM_SOUND_DEVICE_STATE_ACTIVATED_FLAG;
+       MMSoundDeviceList_t device_list;
+       MMSoundDevice_t device_h = NULL;
+       mm_sound_device_type_e device_type;
+       int i = 0;
+
+       MMPLAYER_FENTER();
+
+       return_val_if_fail ( hplayer, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       player = MM_PLAYER_CAST(hplayer);
+
+       /* get status if speaker is activated */
+       /* (1) get current device list */
+       result = mm_sound_get_current_device_list(flags, &device_list);
+
+       if ( result ) {
+               debug_error("mm_sound_get_current_device_list() failed [%x]!!", result);
+               MMPLAYER_FLEAVE();
+               return result;
+       }
+
+       /* (2) get device handle of device list */
+       result = mm_sound_get_next_device (device_list, &device_h);
+
+       if ( result ) {
+               debug_error("mm_sound_get_next_device() failed [%x]!!", result);
+               MMPLAYER_FLEAVE();
+               return result;
+       }
+
+       /* (3) get device type */
+       result = mm_sound_get_device_type(device_h, &device_type);
+
+       if ( result ) {
+               debug_error("mm_sound_get_device_type() failed [%x]!!", result);
+               MMPLAYER_FLEAVE();
+               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_type == MM_SOUND_DEVICE_TYPE_BUILTIN_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_type == MM_SOUND_DEVICE_TYPE_BUILTIN_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;
+       }
+
+       MMPLAYER_FLEAVE();
+
+       return result;
+
+CALLBACK_ERROR:
+       debug_error("foreach callback returned error");
+       MMPLAYER_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;
+
+       MMPLAYER_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);
+
+                               /* associate it to player handle */
+                               player->audio_effect_info.custom_ext_level_for_plugin = ext_effect_level_list;
+                       }
+               }
+
+               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);
+
+       MMPLAYER_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;
+
+       MMPLAYER_FENTER();
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       /* custom */
+       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);
+       }
+
+       MMPLAYER_FLEAVE();
+
+       return result;
+}
+
+int
+__mmplayer_audio_set_output_type (mm_player_t *player, MMAudioEffectType effect_type, int effect)
+{
+       GstElement *audio_effect_element = NULL;
+       mm_sound_device_flags_e flags = MM_SOUND_DEVICE_STATE_ACTIVATED_FLAG;
+       MMSoundDeviceList_t device_list;
+       MMSoundDevice_t device_h = NULL;
+       mm_sound_device_type_e device_type;
+       int output_type = 0;
+       int result = MM_ERROR_NONE;
+
+       MMPLAYER_FENTER();
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       audio_effect_element = player->pipeline->audiobin[MMPLAYER_A_FILTER].gst;
+
+       /* (1) get current device list */
+       result = mm_sound_get_current_device_list(flags, &device_list);
+
+       if ( result ) {
+               debug_error("mm_sound_get_current_device_list() failed [%x]!!", result);
+               MMPLAYER_FLEAVE();
+               return result;
+       }
+
+       /* (2) get device handle of device list */
+       result = mm_sound_get_next_device (device_list, &device_h);
+
+       if ( result ) {
+               debug_error("mm_sound_get_next_device() failed [%x]!!", result);
+               MMPLAYER_FLEAVE();
+               return result;
+       }
+
+       /* (3) get device type */
+       result = mm_sound_get_device_type(device_h, &device_type);
+
+       if ( result ) {
+               debug_error("mm_sound_get_device_type() failed [%x]!!", result);
+               MMPLAYER_FLEAVE();
+               return result;
+       }
+
+       /* SPEAKER case */
+       if (device_type == MM_SOUND_DEVICE_TYPE_BUILTIN_SPEAKER)
+       {
+               if ( MM_AUDIO_EFFECT_TYPE_SQUARE != effect_type ) {
+                       if (__mmplayer_is_earphone_only_effect_type(player, effect_type, effect))
+                       {
+                               debug_error("earphone is not equipped, this filter will not be applied");
+                               MMPLAYER_FLEAVE();
+                               return MM_ERROR_PLAYER_SOUND_EFFECT_INVALID_STATUS;
+                       }
+               }
+
+               output_type = MM_AUDIO_EFFECT_OUTPUT_SPK;
+       }
+       else if (device_type == MM_SOUND_DEVICE_TYPE_MIRRORING)
+       {
+               output_type = MM_AUDIO_EFFECT_OUTPUT_OTHERS;
+       }
+       else if (device_type == MM_SOUND_DEVICE_TYPE_HDMI)
+       {
+               output_type = MM_AUDIO_EFFECT_OUTPUT_HDMI;
+       }
+       else if (device_type == MM_SOUND_DEVICE_TYPE_BLUETOOTH)
+       {
+               output_type = MM_AUDIO_EFFECT_OUTPUT_BT;
+       }
+       else if (device_type == MM_SOUND_DEVICE_TYPE_USB_AUDIO)
+       {
+               output_type = MM_AUDIO_EFFECT_OUTPUT_USB_AUDIO;
+       }
+       /* Other case, include WIRED_ACCESSORY */
+       else
+       {
+               output_type = MM_AUDIO_EFFECT_OUTPUT_EAR;
+       }
+       debug_warning("output_type = %d (0:spk,1:ear,2:others)", output_type);
+
+       /* set filter output mode */
+       g_object_set(audio_effect_element, "filter-output-mode", output_type, NULL);
+
+       return result;
+}
+
+gboolean
+_mmplayer_is_supported_effect_type(mm_player_t* player, MMAudioEffectType effect_type, int effect)
+{
+       gboolean result = TRUE;
+       mm_sound_device_flags_e flags = MM_SOUND_DEVICE_STATE_ACTIVATED_FLAG;
+       MMSoundDeviceList_t device_list;
+       MMSoundDevice_t device_h = NULL;
+       mm_sound_device_type_e device_type;
+       int ret = MM_ERROR_NONE;
+
+       MMPLAYER_FENTER();
+
+       /* get status if speaker is activated */
+       /* (1) get current device list */
+       ret = mm_sound_get_current_device_list(flags, &device_list);
+       if (ret) {
+               MMPLAYER_FLEAVE();
+               debug_error("mm_sound_get_current_device_list() failed [%x]!!", ret);
+               return FALSE;
+       }
+
+       /* (2) get device handle of device list */
+       ret = mm_sound_get_next_device (device_list, &device_h);
+
+       if (ret) {
+               debug_error("mm_sound_get_next_device() failed [%x]!!", ret);
+               MMPLAYER_FLEAVE();
+               return FALSE;
+       }
+
+       /* (3) get device type */
+       ret = mm_sound_get_device_type(device_h, &device_type);
+
+       if (ret) {
+               debug_error("mm_sound_get_device_type() failed [%x]!!", ret);
+               MMPLAYER_FLEAVE();
+               return FALSE;
+       }
+
+       /* 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;
+               }
+               else
+               {
+                       if (!player->ini.audio_effect_preset_list[effect])
+                       {
+                               debug_error("this effect(%d) is not supported", effect);
+                               result = FALSE;
+                       }
+                       else
+                       {
+                               if (device_type == MM_SOUND_DEVICE_TYPE_BUILTIN_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;
+               }
+               else
+               {
+                       if (!player->ini.audio_effect_custom_list[effect])
+                       {
+                               debug_error("this custom effect(%d) is not supported", effect);
+                               result = FALSE;
+                       }
+                       else
+                       {
+                               if (device_type == MM_SOUND_DEVICE_TYPE_BUILTIN_SPEAKER &&
+                                               player->ini.audio_effect_custom_earphone_only_list[effect])
+                               {
+                               }
+                       }
+               }
+       }
+       else if (effect_type == MM_AUDIO_EFFECT_TYPE_SQUARE)
+       {
+               if (!player->ini.use_audio_effect_custom)
+               {
+                       debug_error("Square effect is not supported");
+                       result = FALSE;
+               }
+       }
+       else
+       {
+               debug_error("invalid effect type(%d)", effect_type);
+               result = FALSE;
+       }
+
+
+       MMPLAYER_FLEAVE();
+
+       return result;
+}
+
+int
+_mmplayer_audio_effect_custom_apply(mm_player_t *player)
+{
+       GstElement *audio_effect_element = NULL;
+       int result = MM_ERROR_NONE;
+
+       MMPLAYER_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 || !player->pipeline->audiobin[MMPLAYER_A_FILTER].gst )
+       {
+               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
+       {
+               audio_effect_element = player->pipeline->audiobin[MMPLAYER_A_FILTER].gst;
+
+               /* get status if speaker is activated */
+               result = __mmplayer_audio_set_output_type(player, MM_AUDIO_EFFECT_TYPE_CUSTOM, 0);
+
+               if ( result != MM_ERROR_NONE) {
+                       debug_error("failed to set output mode");
+                       MMPLAYER_FLEAVE();
+                       return result;
+               }
+
+               result = __mmplayer_set_harmony_effect(player, audio_effect_element);
+               if ( result )
+               {
+                       debug_error("_set_harmony_effect() failed(%x)", result);
+                       MMPLAYER_FLEAVE();
+                       return result;
+               }
+       }
+       player->set_mode.rich_audio = TRUE;
+
+       MMPLAYER_FLEAVE();
+
+       return result;
+}
+
+int
+_mmplayer_audio_effect_custom_update_level(mm_player_t *player)
+{
+       GstElement *audio_effect_element = NULL;
+       int result = MM_ERROR_NONE;
+       int ext_level_index = 0;
+       int count = 1;
+       int i = 0;
+       gint *custom_eq = NULL;
+       gint *custom_ext_effect_level_list = NULL;
+
+       MMPLAYER_FENTER();
+
+       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       audio_effect_element = player->pipeline->audiobin[MMPLAYER_A_FILTER].gst;
+
+       /* get custom eq effect */
+       g_object_get(audio_effect_element, "custom-eq", &custom_eq, NULL);
+
+       memcpy(player->audio_effect_info.custom_eq_level, custom_eq, sizeof(gint) * player->ini.audio_effect_custom_eq_band_num);
+
+       for (i=0; i<player->ini.audio_effect_custom_eq_band_num;i++)
+       {
+               debug_log("updated custom-eq [%d] = %d", i, player->audio_effect_info.custom_eq_level[i]);
+       }
+
+       /* get custom ext effect */
+
+       g_object_get(audio_effect_element, "custom-ext", &custom_ext_effect_level_list, NULL);
+
+       while ( count < MM_AUDIO_EFFECT_CUSTOM_NUM )
+       {
+               if ( player->ini.audio_effect_custom_list[count] )
+               {
+                       player->audio_effect_info.custom_ext_level[count-1]
+                               = custom_ext_effect_level_list[ext_level_index];
+                       debug_log("updated custom-ext [%d] = %d", count, player->audio_effect_info.custom_ext_level[count-1]);
+                       ext_level_index++;
+               }
+               count++;
+       }
+
+
+       MMPLAYER_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;
+
+       MMPLAYER_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");
+
+       MMPLAYER_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;
+
+       MMPLAYER_FENTER();
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       if ( !_mmplayer_is_supported_effect_type( player, MM_AUDIO_EFFECT_TYPE_CUSTOM, effect ) )
+       {
+               result = MM_ERROR_PLAYER_SOUND_EFFECT_NOT_SUPPORTED_FILTER;
+       }
+
+       MMPLAYER_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;
+
+       MMPLAYER_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");
+               MMPLAYER_FLEAVE();
+               return MM_ERROR_NOT_SUPPORT_API;
+       }
+
+       result = _mmplayer_audio_effect_custom_apply(player);
+
+       MMPLAYER_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;
+
+       MMPLAYER_FENTER();
+
+       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       /* check if EQ is supported */
+       if ( !_mmplayer_is_supported_effect_type( player,  MM_AUDIO_EFFECT_TYPE_CUSTOM, custom_effect_type ) )
+       {
+               MMPLAYER_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);
+       }
+
+       MMPLAYER_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;
+
+       MMPLAYER_FENTER();
+
+       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       /* check if EQ is supported */
+       if ( !_mmplayer_is_supported_effect_type( player, MM_AUDIO_EFFECT_TYPE_CUSTOM, MM_AUDIO_EFFECT_CUSTOM_EQ ) )
+       {
+               MMPLAYER_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);
+               }
+       }
+
+       MMPLAYER_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;
+
+       MMPLAYER_FENTER();
+
+       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       /* check if this effect type is supported */
+       if ( !_mmplayer_is_supported_effect_type( player, 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;
+               }
+       }
+
+       MMPLAYER_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;
+
+       MMPLAYER_FENTER();
+
+       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       /* check if EQ is supported */
+       if ( !_mmplayer_is_supported_effect_type( player, MM_AUDIO_EFFECT_TYPE_CUSTOM, MM_AUDIO_EFFECT_CUSTOM_EQ ) )
+       {
+               MMPLAYER_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);
+
+       MMPLAYER_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;
+
+       MMPLAYER_FENTER();
+
+       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       /* check if EQ is supported */
+       if ( !_mmplayer_is_supported_effect_type( player, MM_AUDIO_EFFECT_TYPE_CUSTOM, MM_AUDIO_EFFECT_CUSTOM_EQ ) )
+       {
+               MMPLAYER_FLEAVE();
+               return MM_ERROR_PLAYER_SOUND_EFFECT_NOT_SUPPORTED_FILTER;
+       }
+
+       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_INVALID_ARGUMENT;
+       }
+       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);
+       }
+
+       MMPLAYER_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;
+
+       MMPLAYER_FENTER();
+
+       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       /* check if EQ is supported */
+       if ( !_mmplayer_is_supported_effect_type( player, MM_AUDIO_EFFECT_TYPE_CUSTOM, MM_AUDIO_EFFECT_CUSTOM_EQ ) )
+       {
+               MMPLAYER_FLEAVE();
+               return MM_ERROR_PLAYER_SOUND_EFFECT_NOT_SUPPORTED_FILTER;
+       }
+
+       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_INVALID_ARGUMENT;
+       }
+       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);
+       }
+
+       MMPLAYER_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;
+
+       MMPLAYER_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( player, MM_AUDIO_EFFECT_TYPE_CUSTOM, type ) )
+       {
+               MMPLAYER_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;
+       }
+
+       MMPLAYER_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 */
+
+       MMPLAYER_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( player, MM_AUDIO_EFFECT_TYPE_CUSTOM, type ) )
+       {
+               MMPLAYER_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++;
+               }
+       }
+
+       MMPLAYER_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;
+
+       MMPLAYER_FENTER();
+
+       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       /* check if EQ is supported */
+       if ( !_mmplayer_is_supported_effect_type( player, MM_AUDIO_EFFECT_TYPE_CUSTOM, MM_AUDIO_EFFECT_CUSTOM_EQ ) )
+       {
+               MMPLAYER_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];
+               }
+       }
+       MMPLAYER_FLEAVE();
+
+       return result;
+}
index 68ac43b..774b89f 100755 (executable)
-/*\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>,\r
- * Seungbae Shin <seungbae.shin@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 void __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 void\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 (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
-\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, sizeof(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;\r
-EXIT:\r
-       g_mutex_unlock(player->capture_thread_mutex);\r
-       return;\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->s[0] * proved->e[0]);\r
-                               uvplane_size = (proved->s[1] * proved->e[1]);\r
-\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
+/*
+ * 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.
+ *
+ */
+
+/*===========================================================================================
+|                                                                                                                                                                                      |
+|  INCLUDE FILES                                                                                                                                                       |
+|                                                                                                                                                                                      |
+========================================================================================== */
+#include "mm_player_utils.h"
+#include "mm_player_capture.h"
+#include "mm_player_priv.h"
+#include "mm_player_utils.h"
+
+#include <mm_util_imgp.h>
+
+/*---------------------------------------------------------------------------
+|    LOCAL VARIABLE DEFINITIONS for internal                                                           |
+---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+|    LOCAL FUNCTION PROTOTYPES:                                                                                                |
+---------------------------------------------------------------------------*/
+static gboolean __mmplayer_video_capture_probe (GstPad *pad, GstBuffer *buffer, gpointer u_data);
+static int  __mmplayer_get_video_frame_from_buffer(mm_player_t* player, GstBuffer *buffer);
+static gpointer __mmplayer_capture_thread(gpointer data);
+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);
+static int __tile_4x2_read(int x_size, int y_size, int x_pos, int y_pos);
+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);
+
+/*===========================================================================================
+|                                                                                                                                                                                      |
+|  FUNCTION DEFINITIONS                                                                                                                                                |
+|                                                                                                                                                                                      |
+========================================================================================== */
+int
+_mmplayer_initialize_video_capture(mm_player_t* player)
+{
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       /* create capture mutex */
+       player->capture_thread_mutex = g_mutex_new();
+       if ( ! player->capture_thread_mutex )
+       {
+               debug_error("Cannot create capture mutex");
+               goto ERROR;
+       }
+
+       /* create capture cond */
+       player->capture_thread_cond = g_cond_new();
+       if ( ! player->capture_thread_cond )
+       {
+               debug_error("Cannot create capture cond");
+               goto ERROR;
+       }
+
+       player->capture_thread_exit = FALSE;
+
+       /* create video capture thread */
+       player->capture_thread =
+               g_thread_create (__mmplayer_capture_thread, (gpointer)player, TRUE, NULL);
+       if ( ! player->capture_thread )
+       {
+               goto ERROR;
+       }
+
+       return MM_ERROR_NONE;
+
+ERROR:
+       /* capture thread */
+       if ( player->capture_thread_mutex )
+               g_mutex_free ( player->capture_thread_mutex );
+
+       if ( player->capture_thread_cond )
+               g_cond_free ( player->capture_thread_cond );
+
+       return MM_ERROR_PLAYER_INTERNAL;
+}
+
+int
+_mmplayer_release_video_capture(mm_player_t* player)
+{
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       /* release capture thread */
+       if ( player->capture_thread_cond &&
+                player->capture_thread_mutex &&
+                player->capture_thread )
+       {
+               g_mutex_lock(player->capture_thread_mutex);
+               player->capture_thread_exit = TRUE;
+               g_cond_signal( player->capture_thread_cond );
+               g_mutex_unlock(player->capture_thread_mutex);
+
+               debug_log("waitting for capture thread exit");
+               g_thread_join ( player->capture_thread );
+               g_mutex_free ( player->capture_thread_mutex );
+               g_cond_free ( player->capture_thread_cond );
+               debug_log("capture thread released");
+       }
+
+       return MM_ERROR_NONE;
+}
+
+int
+_mmplayer_do_video_capture(MMHandleType hplayer)
+{
+       mm_player_t* player = (mm_player_t*) hplayer;
+       int ret = MM_ERROR_NONE;
+       GstPad *pad = NULL;
+
+       MMPLAYER_FENTER();
+
+       return_val_if_fail(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       /* capturing or not */
+       if (player->video_capture_cb_probe_id || player->capture.data || player->captured.a[0] || player->captured.a[1])
+       {
+               debug_warning("capturing... we can't do any more");
+               return MM_ERROR_PLAYER_INVALID_STATE;
+       }
+
+       /* check if video pipeline is linked or not */
+       if (!player->pipeline->videobin)
+       {
+               debug_warning("not ready to capture");
+               return MM_ERROR_PLAYER_INVALID_STATE;
+       }
+
+       /* check if drm file */
+       if (player->is_drm_file)
+       {
+               debug_warning("not supported in drm file");
+               return MM_ERROR_PLAYER_DRM_OUTPUT_PROTECTION;
+       }
+
+       if (player->state != MM_PLAYER_STATE_PLAYING)
+       {
+               if (player->state == MM_PLAYER_STATE_PAUSED) // get last buffer from video sink
+               {
+                       GstBuffer *buf = NULL;
+
+                       gst_element_get_state(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst,
+                               NULL, NULL, 5 * GST_SECOND);    //5 seconds
+
+
+                       g_object_get(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "last-buffer", &buf, NULL);
+
+                       if (buf)
+                       {
+                               ret = __mmplayer_get_video_frame_from_buffer(player, buf);
+                               gst_buffer_unref(buf);
+                       }
+                       else
+                       {
+                               debug_warning("failed to get video frame");
+                       }
+                       return ret;
+               }
+               else
+               {
+                       debug_warning("invalid state(%d) to capture", player->state);
+                       return MM_ERROR_PLAYER_INVALID_STATE;
+               }
+       }
+
+       pad = gst_element_get_static_pad(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "sink" );
+
+       /* register probe */
+       player->video_capture_cb_probe_id = gst_pad_add_buffer_probe (pad,
+               G_CALLBACK (__mmplayer_video_capture_probe), player);
+
+       gst_object_unref(GST_OBJECT(pad));
+       pad = NULL;
+
+       MMPLAYER_FLEAVE();
+
+       return ret;
+}
+
+int
+__mmplayer_handle_orientation (mm_player_t* player, int orientation, int format)
+{
+    unsigned char *src_buffer = NULL;
+    int ret = MM_ERROR_NONE;
+    unsigned char *dst_frame = NULL;
+    unsigned int dst_width = 0;
+    unsigned int dst_height = 0;
+    unsigned int dst_size = 0;
+    mm_util_img_rotate_type rot_enum = MM_UTIL_ROTATE_NUM;
+
+       player->capture.orientation = orientation;
+
+    if (orientation == 90 || orientation == 270)
+    {
+               dst_width = player->captured.h[0];
+               dst_height = player->captured.w[0];
+               debug_log ("interchange width & height");
+    }
+    else if (orientation == 180)
+    {
+               dst_width = player->captured.w[0];
+               dst_height = player->captured.h[0];
+    }
+    else if (orientation == 0)
+    {
+               debug_error ("no need handle orientation : %d", orientation);
+               player->capture.width = player->captured.w[0];
+               player->capture.height = player->captured.h[0];
+               return MM_ERROR_NONE;
+    }
+    else
+    {
+               debug_error ("wrong orientation value...");
+    }
+
+    /* height & width will be interchanged for 90 and 270 orientation */
+    ret = mm_util_get_image_size(format, dst_width, dst_height, &dst_size);
+    if (ret != MM_ERROR_NONE)
+    {
+               debug_error("failed to get destination frame size");
+               return ret;
+    }
+
+    debug_log ("before rotation : dst_width = %d and dst_height = %d", dst_width, dst_height);
+
+    dst_frame = (unsigned char*) malloc (dst_size);
+    if (!dst_frame)
+    {
+      debug_error("failed to allocate memory");
+      return MM_ERROR_PLAYER_NO_FREE_SPACE;
+    }
+
+    src_buffer = (unsigned char*)player->capture.data;
+
+       /* convert orientation degree into enum here */
+       switch(orientation)
+       {
+               case 90:
+                       rot_enum = MM_UTIL_ROTATE_90;
+               break;
+               case 180:
+                       rot_enum = MM_UTIL_ROTATE_180;
+               break;
+               case 270:
+                       rot_enum = MM_UTIL_ROTATE_270;
+               break;
+               default:
+                       debug_error("wrong rotate value");
+               break;
+       }
+
+    debug_log ("source buffer for rotation = %p and rotation = %d", src_buffer, rot_enum);
+
+    ret = mm_util_rotate_image (src_buffer, player->captured.w[0], player->captured.h[0], format,
+      dst_frame, &dst_width, &dst_height, rot_enum);
+    if (ret != MM_ERROR_NONE)
+    {
+      free(dst_frame);
+      debug_error("failed to do rotate image");
+      return ret;
+    }
+
+    debug_log ("after rotation same stride: dst_width = %d and dst_height = %d", dst_width, dst_height);
+
+    g_free (src_buffer);
+
+    player->capture.data = dst_frame;
+    player->capture.size = dst_size;
+       player->capture.orientation = orientation;
+       player->capture.width = dst_width;
+       player->capture.height= dst_height;
+
+    player->captured.w[0] = player->captured.s[0] = dst_width;
+    player->captured.h[0] = player->captured.e[0] = dst_height;
+
+    return ret;
+}
+
+
+static gpointer
+__mmplayer_capture_thread(gpointer data)
+{
+       mm_player_t* player = (mm_player_t*) data;
+       MMMessageParamType msg = {0, };
+       unsigned char * linear_y_plane = NULL;
+       unsigned char * linear_uv_plane = NULL;
+       int orientation = 0;
+       int ret = 0;
+
+       return_val_if_fail(player, NULL);
+
+       while (!player->capture_thread_exit)
+       {
+               debug_log("capture thread started. waiting for signal");
+
+               g_mutex_lock(player->capture_thread_mutex);
+               g_cond_wait( player->capture_thread_cond, player->capture_thread_mutex );
+
+               if ( player->capture_thread_exit )
+               {
+                       debug_log("exiting capture thread");
+                       goto EXIT;
+               }
+               debug_log("capture thread is recieved signal");
+
+               /* NOTE: Don't use MMPLAYER_CMD_LOCK() here.
+                * Because deadlock can be happened if other player api is used in message callback.
+                */
+               if (player->video_cs == MM_PLAYER_COLORSPACE_NV12_TILED)
+               {
+                       /* Colorspace conversion : NV12T-> NV12-> RGB888 */
+                       int ret = 0;
+                       int linear_y_plane_size;
+                       int linear_uv_plane_size;
+                       unsigned char * src_buffer = NULL;
+
+                       linear_y_plane_size = (player->captured.w[0] * player->captured.h[0]);
+                       linear_uv_plane_size = (player->captured.w[0] * player->captured.h[0]/2);
+
+                       linear_y_plane = (unsigned char*) g_try_malloc(linear_y_plane_size);
+                       if (linear_y_plane == NULL)
+                       {
+                               msg.code = MM_ERROR_PLAYER_NO_FREE_SPACE;
+                               goto ERROR;
+                       }
+
+                       linear_uv_plane = (unsigned char*) g_try_malloc(linear_uv_plane_size);
+                       if (linear_uv_plane == NULL)
+                       {
+                               msg.code = MM_ERROR_PLAYER_NO_FREE_SPACE;
+                               goto ERROR;
+                       }
+                       /* NV12 tiled to linear */
+                       __csc_tiled_to_linear_crop(linear_y_plane, player->captured.a[0], player->captured.w[0], player->captured.h[0], 0,0,0,0);
+                       __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);
+
+                       MMPLAYER_FREEIF(player->captured.a[0]);
+                       MMPLAYER_FREEIF(player->captured.a[1]);
+
+                       src_buffer = (unsigned char*) g_try_malloc(linear_y_plane_size+linear_uv_plane_size);
+
+                       if (src_buffer == NULL)
+                       {
+                               msg.code = MM_ERROR_PLAYER_NO_FREE_SPACE;
+                               goto ERROR;
+                       }
+                       memset(src_buffer, 0x00, linear_y_plane_size+linear_uv_plane_size);
+                       memcpy(src_buffer, linear_y_plane, linear_y_plane_size);
+                       memcpy(src_buffer+linear_y_plane_size, linear_uv_plane, linear_uv_plane_size);
+
+                       /* NV12 linear to RGB888 */
+                       ret = __mm_player_convert_colorspace(player, src_buffer, MM_UTIL_IMG_FMT_NV12,
+                               player->captured.w[0], player->captured.h[0], MM_UTIL_IMG_FMT_RGB888);
+
+                       if (ret != MM_ERROR_NONE)
+                       {
+                               debug_error("failed to convert nv12 linear");
+                               goto ERROR;
+                       }
+                       /* clean */
+                       MMPLAYER_FREEIF(src_buffer);
+                       MMPLAYER_FREEIF(linear_y_plane);
+                       MMPLAYER_FREEIF(linear_uv_plane);
+               } else if (MM_PLAYER_COLORSPACE_NV12 == player->video_cs) {
+                       #define MM_ALIGN(x, a)       (((x) + (a) - 1) & ~((a) - 1))
+                       int ret = 0;
+                       char *src_buffer = NULL;
+                       /* using original width otherwises, app can't know aligned to resize */
+                       int width_align = player->captured.w[0];//MM_ALIGN(player->captured.w[0], 8);
+                       int src_buffer_size = width_align * player->captured.h[0] * 3/2;
+                       int i, j;
+                       char*temp = NULL;
+                       char*dst_buf = NULL;
+
+                       if (!src_buffer_size) {
+                               debug_error("invalid data size");
+                               goto ERROR;
+                       }
+
+                       src_buffer = (char*) g_try_malloc(src_buffer_size);
+
+                       if (!src_buffer) {
+                               msg.code = MM_ERROR_PLAYER_NO_FREE_SPACE;
+                               goto ERROR;
+                       }
+
+                       memset(src_buffer, 0x00, src_buffer_size);
+
+                       temp = player->captured.a[0];
+                       dst_buf = src_buffer;
+
+                       /* set Y plane */
+                       for (i = 0; i < player->captured.h[0]; i++) {
+                               memcpy(dst_buf, temp, width_align);
+                               dst_buf += width_align;
+                               temp += player->captured.s[0];
+                       }
+
+                       temp = player->captured.a[1];
+
+                       /* set UV plane*/
+                       for (j = 0; j < player->captured.h[1]; j++) {
+                               memcpy(dst_buf, temp, width_align);
+                               dst_buf += width_align;
+                               temp += player->captured.s[0];
+                       }
+
+                       /* free captured buf */
+                       MMPLAYER_FREEIF(player->captured.a[0]);
+                       MMPLAYER_FREEIF(player->captured.a[1]);
+
+                       /* NV12 -> RGB888 */
+                       ret = __mm_player_convert_colorspace(player, (unsigned char*)src_buffer, MM_UTIL_IMG_FMT_NV12,
+                               width_align, player->captured.h[0], MM_UTIL_IMG_FMT_RGB888);
+                       if (ret != MM_ERROR_NONE)
+                       {
+                               debug_error("failed to convert nv12 linear");
+                               goto ERROR;
+                       }
+
+               }
+
+               ret = _mmplayer_get_video_rotate_angle ((MMHandleType)player, &orientation);
+               if (ret != MM_ERROR_NONE)
+               {
+                       debug_error("failed to get rotation angle");
+                       goto ERROR;
+               }
+
+               debug_log ("orientation value = %d", orientation);
+
+               ret = __mmplayer_handle_orientation (player, orientation, MM_UTIL_IMG_FMT_RGB888);
+               if (ret != MM_ERROR_NONE)
+               {
+                       debug_error("failed to convert nv12 linear");
+                       goto ERROR;
+               }
+
+               player->capture.fmt = MM_PLAYER_COLORSPACE_RGB888;
+               msg.data = &player->capture;
+               msg.size = player->capture.size;
+               msg.captured_frame.width = player->capture.width;
+               msg.captured_frame.height = player->capture.height;
+               msg.captured_frame.orientation = player->capture.orientation;
+
+               if (player->cmd >= MMPLAYER_COMMAND_START)
+               {
+                       MMPLAYER_POST_MSG( player, MM_MESSAGE_VIDEO_CAPTURED, &msg );
+                       debug_log("returned from capture message callback");
+               }
+
+               g_mutex_unlock(player->capture_thread_mutex);
+
+               MMPLAYER_FREEIF(player->capture.data);
+               continue;
+ERROR:
+               if (player->video_cs == MM_PLAYER_COLORSPACE_NV12_TILED)
+               {
+                       /* clean */
+                       MMPLAYER_FREEIF(linear_y_plane);
+                       MMPLAYER_FREEIF(linear_uv_plane);
+                       MMPLAYER_FREEIF(player->captured.a[0]);
+                       MMPLAYER_FREEIF(player->captured.a[1]);
+               }
+
+               msg.union_type = MM_MSG_UNION_CODE;
+
+               g_mutex_unlock(player->capture_thread_mutex);
+               MMPLAYER_POST_MSG( player, MM_MESSAGE_VIDEO_NOT_CAPTURED, &msg );
+       }
+       return NULL;
+EXIT:
+       g_mutex_unlock(player->capture_thread_mutex);
+       return NULL;
+}
+
+/**
+  * The output is fixed as RGB888
+  */
+static int
+__mmplayer_get_video_frame_from_buffer(mm_player_t* player, GstBuffer *buffer)
+{
+       gint yplane_size = 0;
+       gint uvplane_size = 0;
+       gint src_width = 0;
+       gint src_height = 0;
+       guint32 fourcc = 0;
+       GstCaps *caps = NULL;
+       GstStructure *structure = NULL;
+       mm_util_img_format src_fmt = MM_UTIL_IMG_FMT_YUV420;
+       mm_util_img_format dst_fmt = MM_UTIL_IMG_FMT_RGB888; // fixed
+
+       MMPLAYER_FENTER();
+
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail ( buffer, MM_ERROR_INVALID_ARGUMENT );
+
+       /* get fourcc */
+       caps = GST_BUFFER_CAPS(buffer);
+
+       return_val_if_fail ( caps, MM_ERROR_INVALID_ARGUMENT );
+       MMPLAYER_LOG_GST_CAPS_TYPE(caps);
+
+       structure = gst_caps_get_structure (caps, 0);
+
+       return_val_if_fail (structure != NULL, MM_ERROR_PLAYER_INTERNAL);
+
+       /* init capture image buffer */
+       memset(&player->capture, 0x00, sizeof(MMPlayerVideoCapture));
+
+       gst_structure_get_int (structure, "width", &src_width);
+       gst_structure_get_int (structure, "height", &src_height);
+
+       /* check rgb or yuv */
+       if (gst_structure_has_name(structure, "video/x-raw-yuv"))
+       {
+               gst_structure_get_fourcc (structure, "format", &fourcc);
+
+               switch(fourcc)
+               {
+                       /* NV12T */
+                       case GST_MAKE_FOURCC ('S', 'T', '1', '2'):
+                       {
+                               debug_msg ("captured format is ST12\n");
+
+                               MMPlayerMPlaneImage *proved = NULL;
+                               player->video_cs = MM_PLAYER_COLORSPACE_NV12_TILED;
+
+                               /* get video frame info from proved buffer */
+                               proved = (MMPlayerMPlaneImage *)GST_BUFFER_MALLOCDATA(buffer);
+
+                               if ( !proved || !proved->a[0] || !proved->a[1] )
+                                       return MM_ERROR_PLAYER_INTERNAL;
+
+                               yplane_size = proved->y_size;
+                               uvplane_size = proved->uv_size;
+
+                               debug_msg ("yplane_size=%d, uvplane_size=%d\n", yplane_size, uvplane_size);
+                               memset(&player->captured, 0x00, sizeof(MMPlayerMPlaneImage));
+                               memcpy(&player->captured, proved, sizeof(MMPlayerMPlaneImage));
+
+                               player->captured.a[0] = g_try_malloc(yplane_size);
+                               if ( !player->captured.a[0] )
+                                       return MM_ERROR_SOUND_NO_FREE_SPACE;
+
+                               player->captured.a[1] = g_try_malloc(uvplane_size);
+                               if ( !player->captured.a[1] )
+                                       return MM_ERROR_SOUND_NO_FREE_SPACE;
+
+                               memcpy(player->captured.a[0], proved->a[0], yplane_size);
+                               memcpy(player->captured.a[1], proved->a[1], uvplane_size);
+
+                               goto DONE;
+                       }
+                       break;
+
+                       case GST_MAKE_FOURCC ('S', 'N', '1', '2'):
+                       {
+                               MMPlayerMPlaneImage *proved = NULL;
+                               player->video_cs = MM_PLAYER_COLORSPACE_NV12;
+
+                               /* get video frame info from proved buffer */
+                               proved = (MMPlayerMPlaneImage *)GST_BUFFER_MALLOCDATA(buffer);
+
+                               if (!proved || !proved->a[0] || !proved->a[1])
+                                       return MM_ERROR_PLAYER_INTERNAL;
+
+                               memset(&player->captured, 0x00, sizeof(MMPlayerMPlaneImage));
+                               memcpy(&player->captured, proved, sizeof(MMPlayerMPlaneImage));
+
+                               player->captured.y_size = proved->s[0] * proved->h[0]; // must get data including padding
+                               player->captured.uv_size = proved->s[0] * proved->h[1];
+
+                               debug_msg ("y plane_size : %d, uv plane_size : %d", player->captured.y_size, player->captured.uv_size);
+
+                               player->captured.a[0] = g_try_malloc(player->captured.y_size);
+
+                               if ( !player->captured.a[0] ) {
+                                       return MM_ERROR_SOUND_NO_FREE_SPACE;
+                               }
+
+                               player->captured.a[1] = g_try_malloc(player->captured.uv_size);
+
+                               if ( !player->captured.a[1] ) {
+                                       return MM_ERROR_SOUND_NO_FREE_SPACE;
+                               }
+
+                               memcpy(player->captured.a[0], proved->a[0], player->captured.y_size);
+                               memcpy(player->captured.a[1], proved->a[1], player->captured.uv_size);
+
+                               goto DONE;
+                       }
+                       break;
+
+                       case GST_MAKE_FOURCC ('I', '4', '2', '0'):
+                       {
+                               src_fmt = MM_UTIL_IMG_FMT_I420;
+                       }
+                       break;
+
+                       default:
+                       {
+                               goto UNKNOWN;
+                       }
+                       break;
+               }
+       }
+       else if (gst_structure_has_name(structure, "video/x-raw-rgb"))
+       {
+               gint bpp;
+               gint depth;
+               gint endianess;
+               gint blue_mask;
+               gboolean bigendian = FALSE;
+               gboolean isbluefirst = FALSE;
+
+            /**
+               * The followings will be considered.
+               * RGBx, xRGB, BGRx, xBGR
+               * RGB888, BGR888
+               * RGB565
+               *
+               */
+               gst_structure_get_int (structure, "bpp", &bpp);
+               gst_structure_get_int (structure, "depth", &depth);
+               gst_structure_get_int (structure, "endianness", &endianess);
+               gst_structure_get_int (structure, "blue_mask", &blue_mask);
+
+               if (endianess == 4321)
+                       bigendian = TRUE;
+
+               if (blue_mask == -16777216)
+                       isbluefirst = TRUE;
+
+               switch(bpp)
+               {
+                       case 32:
+                       {
+                               switch(depth)
+                               {
+                                       case 32:
+                                       case 24:
+                                               if (bigendian && isbluefirst)
+                                                       src_fmt = MM_UTIL_IMG_FMT_BGRX8888;
+                                               break;
+                                       default:
+                                               goto UNKNOWN;
+                                               break;
+                               }
+                       }
+                       break;
+
+                       case 24:
+                       default:
+                       {
+                               goto UNKNOWN;
+                       }
+                       break;
+               }
+       }
+       else
+       {
+               goto UNKNOWN;
+       }
+       __mm_player_convert_colorspace(player, GST_BUFFER_DATA(buffer), src_fmt, src_width, src_height, dst_fmt);
+
+DONE:
+       /* do convert colorspace */
+       g_cond_signal( player->capture_thread_cond );
+
+       MMPLAYER_FLEAVE();
+
+       return MM_ERROR_NONE;
+
+UNKNOWN:
+       return MM_ERROR_PLAYER_INTERNAL;
+}
+
+static gboolean
+__mmplayer_video_capture_probe (GstPad *pad, GstBuffer *buffer, gpointer u_data)
+{
+       mm_player_t* player = (mm_player_t*) u_data;
+       int ret = MM_ERROR_NONE;
+
+       return_val_if_fail ( buffer, FALSE);
+       MMPLAYER_FENTER();
+
+       ret = __mmplayer_get_video_frame_from_buffer(player, buffer);
+
+       if ( ret != MM_ERROR_NONE)
+       {
+               debug_error("failed to get video frame");
+       }
+
+       /* remove probe to be called at one time */
+       if (player->video_capture_cb_probe_id)
+       {
+               gst_pad_remove_buffer_probe (pad, player->video_capture_cb_probe_id);
+               player->video_capture_cb_probe_id = 0;
+       }
+
+       MMPLAYER_FLEAVE();
+
+       return TRUE;
+}
+
+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)
+{
+       unsigned char *dst_data = NULL;
+       unsigned int dst_size;
+       int ret = MM_ERROR_NONE;
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_INTERNAL);
+       ret = mm_util_get_image_size(dst_fmt, src_w, src_h, &dst_size);
+
+       if (ret != MM_ERROR_NONE)
+       {
+               debug_error("failed to get image size for capture, %d\n", ret);
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       secure_debug_log("width: %d, height: %d to capture, dest size: %d\n", src_w, src_h, dst_size);
+
+       dst_data = (unsigned char*)g_malloc0(dst_size);
+
+       if (!dst_data)
+       {
+               debug_error("no free space to capture\n");
+               return MM_ERROR_PLAYER_NO_FREE_SPACE;
+       }
+
+       ret = mm_util_convert_colorspace(src_data, src_w, src_h, src_fmt, dst_data, dst_fmt);
+
+       if (ret != MM_ERROR_NONE)
+       {
+               debug_error("failed to convert for capture, %d\n", ret);
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       player->capture.size = dst_size;
+       player->capture.data = dst_data;
+
+       return MM_ERROR_NONE;
+}
+
+/*
+ * Get tiled address of position(x,y)
+ *
+ * @param x_size
+ *   width of tiled[in]
+ *
+ * @param y_size
+ *   height of tiled[in]
+ *
+ * @param x_pos
+ *   x position of tield[in]
+ *
+ * @param src_size
+ *   y position of tield[in]
+ *
+ * @return
+ *   address of tiled data
+ */
+static int
+__tile_4x2_read(int x_size, int y_size, int x_pos, int y_pos)
+{
+    int pixel_x_m1, pixel_y_m1;
+    int roundup_x;
+    int linear_addr0, linear_addr1, bank_addr ;
+    int x_addr;
+    int trans_addr;
+
+    pixel_x_m1 = x_size -1;
+    pixel_y_m1 = y_size -1;
+
+    roundup_x = ((pixel_x_m1 >> 7) + 1);
+
+    x_addr = x_pos >> 2;
+
+    if ((y_size <= y_pos+32) && ( y_pos < y_size) &&
+        (((pixel_y_m1 >> 5) & 0x1) == 0) && (((y_pos >> 5) & 0x1) == 0)) {
+        linear_addr0 = (((y_pos & 0x1f) <<4) | (x_addr & 0xf));
+        linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x + ((x_addr >> 6) & 0x3f));
+
+        if (((x_addr >> 5) & 0x1) == ((y_pos >> 5) & 0x1))
+            bank_addr = ((x_addr >> 4) & 0x1);
+        else
+            bank_addr = 0x2 | ((x_addr >> 4) & 0x1);
+    } else {
+        linear_addr0 = (((y_pos & 0x1f) << 4) | (x_addr & 0xf));
+        linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x + ((x_addr >> 5) & 0x7f));
+
+        if (((x_addr >> 5) & 0x1) == ((y_pos >> 5) & 0x1))
+            bank_addr = ((x_addr >> 4) & 0x1);
+        else
+            bank_addr = 0x2 | ((x_addr >> 4) & 0x1);
+    }
+
+    linear_addr0 = linear_addr0 << 2;
+    trans_addr = (linear_addr1 <<13) | (bank_addr << 11) | linear_addr0;
+
+    return trans_addr;
+}
+
+/*
+ * Converts tiled data to linear
+ * Crops left, top, right, buttom
+ * 1. Y of NV12T to Y of YUV420P
+ * 2. Y of NV12T to Y of YUV420S
+ * 3. UV of NV12T to UV of YUV420S
+ *
+ * @param yuv420_dest
+ *   Y or UV plane address of YUV420[out]
+ *
+ * @param nv12t_src
+ *   Y or UV plane address of NV12T[in]
+ *
+ * @param yuv420_width
+ *   Width of YUV420[in]
+ *
+ * @param yuv420_height
+ *   Y: Height of YUV420, UV: Height/2 of YUV420[in]
+ *
+ * @param left
+ *   Crop size of left
+ *
+ * @param top
+ *   Crop size of top
+ *
+ * @param right
+ *   Crop size of right
+ *
+ * @param buttom
+ *   Crop size of buttom
+ */
+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)
+{
+    int i, j;
+    int tiled_offset = 0, tiled_offset1 = 0;
+    int linear_offset = 0;
+    int temp1 = 0, temp2 = 0, temp3 = 0, temp4 = 0;
+
+    temp3 = yuv420_width-right;
+    temp1 = temp3-left;
+    /* real width is greater than or equal 256 */
+    if (temp1 >= 256) {
+        for (i=top; i<yuv420_height-buttom; i=i+1) {
+            j = left;
+            temp3 = (j>>8)<<8;
+            temp3 = temp3>>6;
+            temp4 = i>>5;
+            if (temp4 & 0x1) {
+                /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */
+                tiled_offset = temp4-1;
+                temp1 = ((yuv420_width+127)>>7)<<7;
+                tiled_offset = tiled_offset*(temp1>>6);
+                tiled_offset = tiled_offset+temp3;
+                tiled_offset = tiled_offset+2;
+                temp1 = (temp3>>2)<<2;
+                tiled_offset = tiled_offset+temp1;
+                tiled_offset = tiled_offset<<11;
+                tiled_offset1 = tiled_offset+2048*2;
+                temp4 = 8;
+            } else {
+                temp2 = ((yuv420_height+31)>>5)<<5;
+                if ((i+32)<temp2) {
+                    /* even1 fomula: x+((x+2)>>2)<<2+x_block_num*y */
+                    temp1 = temp3+2;
+                    temp1 = (temp1>>2)<<2;
+                    tiled_offset = temp3+temp1;
+                    temp1 = ((yuv420_width+127)>>7)<<7;
+                    tiled_offset = tiled_offset+temp4*(temp1>>6);
+                    tiled_offset = tiled_offset<<11;
+                    tiled_offset1 = tiled_offset+2048*6;
+                    temp4 = 8;
+                } else {
+                    /* even2 fomula: x+x_block_num*y */
+                    temp1 = ((yuv420_width+127)>>7)<<7;
+                    tiled_offset = temp4*(temp1>>6);
+                    tiled_offset = tiled_offset+temp3;
+                    tiled_offset = tiled_offset<<11;
+                    tiled_offset1 = tiled_offset+2048*2;
+                    temp4 = 4;
+                }
+            }
+
+            temp1 = i&0x1F;
+            tiled_offset = tiled_offset+64*(temp1);
+            tiled_offset1 = tiled_offset1+64*(temp1);
+            temp2 = yuv420_width-left-right;
+            linear_offset = temp2*(i-top);
+            temp3 = ((j+256)>>8)<<8;
+            temp3 = temp3-j;
+            temp1 = left&0x3F;
+            if (temp3 > 192) {
+                memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset+temp1, 64-temp1);
+                temp2 = ((left+63)>>6)<<6;
+                temp3 = ((yuv420_width-right)>>6)<<6;
+                if (temp2 == temp3) {
+                    temp2 = yuv420_width-right-(64-temp1);
+                }
+                memcpy(yuv420_dest+linear_offset+64-temp1, nv12t_src+tiled_offset+2048, 64);
+                memcpy(yuv420_dest+linear_offset+128-temp1, nv12t_src+tiled_offset1, 64);
+                memcpy(yuv420_dest+linear_offset+192-temp1, nv12t_src+tiled_offset1+2048, 64);
+                linear_offset = linear_offset+256-temp1;
+            } else if (temp3 > 128) {
+                memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset+2048+temp1, 64-temp1);
+                memcpy(yuv420_dest+linear_offset+64-temp1, nv12t_src+tiled_offset1, 64);
+                memcpy(yuv420_dest+linear_offset+128-temp1, nv12t_src+tiled_offset1+2048, 64);
+                linear_offset = linear_offset+192-temp1;
+            } else if (temp3 > 64) {
+                memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset1+temp1, 64-temp1);
+                memcpy(yuv420_dest+linear_offset+64-temp1, nv12t_src+tiled_offset1+2048, 64);
+                linear_offset = linear_offset+128-temp1;
+            } else if (temp3 > 0) {
+                memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset1+2048+temp1, 64-temp1);
+                linear_offset = linear_offset+64-temp1;
+            }
+
+            tiled_offset = tiled_offset+temp4*2048;
+            j = (left>>8)<<8;
+            j = j + 256;
+            temp2 = yuv420_width-right-256;
+            for (; j<=temp2; j=j+256) {
+                memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
+                tiled_offset1 = tiled_offset1+temp4*2048;
+                memcpy(yuv420_dest+linear_offset+64, nv12t_src+tiled_offset+2048, 64);
+                memcpy(yuv420_dest+linear_offset+128, nv12t_src+tiled_offset1, 64);
+                tiled_offset = tiled_offset+temp4*2048;
+                memcpy(yuv420_dest+linear_offset+192, nv12t_src+tiled_offset1+2048, 64);
+                linear_offset = linear_offset+256;
+            }
+
+            tiled_offset1 = tiled_offset1+temp4*2048;
+            temp2 = yuv420_width-right-j;
+            if (temp2 > 192) {
+                memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
+                memcpy(yuv420_dest+linear_offset+64, nv12t_src+tiled_offset+2048, 64);
+                memcpy(yuv420_dest+linear_offset+128, nv12t_src+tiled_offset1, 64);
+                memcpy(yuv420_dest+linear_offset+192, nv12t_src+tiled_offset1+2048, temp2-192);
+            } else if (temp2 > 128) {
+                memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
+                memcpy(yuv420_dest+linear_offset+64, nv12t_src+tiled_offset+2048, 64);
+                memcpy(yuv420_dest+linear_offset+128, nv12t_src+tiled_offset1, temp2-128);
+            } else if (temp2 > 64) {
+                memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
+                memcpy(yuv420_dest+linear_offset+64, nv12t_src+tiled_offset+2048, temp2-64);
+            } else {
+                memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, temp2);
+            }
+        }
+    } else if (temp1 >= 64) {
+        for (i=top; i<(yuv420_height-buttom); i=i+1) {
+            j = left;
+            tiled_offset = __tile_4x2_read(yuv420_width, yuv420_height, j, i);
+            temp2 = ((j+64)>>6)<<6;
+            temp2 = temp2-j;
+            linear_offset = temp1*(i-top);
+            temp4 = j&0x3;
+            tiled_offset = tiled_offset+temp4;
+            memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, temp2);
+            linear_offset = linear_offset+temp2;
+            j = j+temp2;
+            if ((j+64) <= temp3) {
+                tiled_offset = __tile_4x2_read(yuv420_width, yuv420_height, j, i);
+                memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
+                linear_offset = linear_offset+64;
+                j = j+64;
+            }
+            if ((j+64) <= temp3) {
+                tiled_offset = __tile_4x2_read(yuv420_width, yuv420_height, j, i);
+                memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
+                linear_offset = linear_offset+64;
+                j = j+64;
+            }
+            if (j < temp3) {
+                tiled_offset = __tile_4x2_read(yuv420_width, yuv420_height, j, i);
+                temp2 = temp3-j;
+                memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, temp2);
+            }
+        }
+    } else {
+        for (i=top; i<(yuv420_height-buttom); i=i+1) {
+            linear_offset = temp1*(i-top);
+            for (j=left; j<(yuv420_width-right); j=j+2) {
+                tiled_offset = __tile_4x2_read(yuv420_width, yuv420_height, j, i);
+                temp4 = j&0x3;
+                tiled_offset = tiled_offset+temp4;
+                memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 2);
+                linear_offset = linear_offset+2;
+            }
+        }
+    }
+}
index 919c0e3..9f6ae61 100755 (executable)
 #include <mm_error.h>
 #include <glib/gstdio.h>
 
-/* global variables here */
-static mm_player_ini_t g_player_ini;
-
 /* internal functions, macros here */
+#ifdef MM_PLAYER_DEFAULT_INI
 static gboolean        __generate_default_ini(void);
-static void    __get_string_list(gchar** out_list, gchar* str);
+#endif
+static void    __get_element_list(mm_player_ini_t* ini, gchar* str, int keyword_type);
 
-static void __mm_player_ini_force_setting(void);
 static void __mm_player_ini_check_ini_status(void);
 
 /* macro */
-#define MMPLAYER_INI_GET_STRING( x_item, x_ini, x_default ) \
+#define MMPLAYER_INI_GET_STRING( x_dict, x_item, x_ini, x_default ) \
 do \
 { \
-       gchar* str = iniparser_getstring(dict, x_ini, x_default); \
+       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 ); \
+               strncpy ( x_item, str, PLAYER_INI_MAX_STRLEN -1 ); \
        } \
        else \
        { \
-               strcpy ( x_item, x_default ); \
+               strncpy ( x_item, x_default, PLAYER_INI_MAX_STRLEN -1 ); \
        } \
 }while(0)
 
+#define MMPLAYER_INI_GET_COLOR( 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 ) ) \
+  { \
+    x_item = (guint) strtoul(str, NULL, 16); \
+  } \
+  else \
+  { \
+    x_item = (guint) strtoul(x_default, NULL, 16); \
+  } \
+}while(0)
+
 /* x_ini is the list of index to set TRUE at x_list[index] */
-#define MMPLAYER_INI_GET_BOOLEAN_FROM_LIST( x_list, x_list_max, x_ini, x_default ) \
+#define MMPLAYER_INI_GET_BOOLEAN_FROM_LIST( x_dict, x_list, x_list_max, x_ini, x_default ) \
 do \
 { \
                int index = 0; \
@@ -69,7 +84,7 @@ do \
                char *usr_ptr = NULL; \
                char *token = NULL; \
                gchar temp_arr[PLAYER_INI_MAX_STRLEN] = {0}; \
-               MMPLAYER_INI_GET_STRING(temp_arr, x_ini, x_default); \
+               MMPLAYER_INI_GET_STRING( x_dict, temp_arr, x_ini, x_default); \
                token = strtok_r( temp_arr, delimiters, &usr_ptr ); \
                while (token) \
                { \
@@ -87,7 +102,7 @@ do \
 }while(0)
 
 /* x_ini is the list of value to be set at x_list[index] */
-#define MMPLAYER_INI_GET_INT_FROM_LIST( x_list, x_list_max, x_ini, x_default ) \
+#define MMPLAYER_INI_GET_INT_FROM_LIST( x_dict, x_list, x_list_max, x_ini, x_default ) \
 do \
 { \
                int index = 0; \
@@ -96,7 +111,7 @@ do \
                char *usr_ptr = NULL; \
                char *token = NULL; \
                gchar temp_arr[PLAYER_INI_MAX_STRLEN] = {0}; \
-               MMPLAYER_INI_GET_STRING(temp_arr, x_ini, x_default); \
+               MMPLAYER_INI_GET_STRING(x_dict, temp_arr, x_ini, x_default); \
                token = strtok_r( temp_arr, delimiters, &usr_ptr ); \
                while (token) \
                { \
@@ -115,24 +130,12 @@ do \
                } \
 }while(0)
 
-int 
-mm_player_ini_load(void)
+int
+mm_player_ini_load(mm_player_ini_t* ini)
 {
-       static gboolean loaded = FALSE;
        dictionary * dict = NULL;
        gint idx = 0;
 
-       if ( loaded )
-               return MM_ERROR_NONE;
-
-       dict = NULL;
-
-       /* 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 */
@@ -141,281 +144,374 @@ mm_player_ini_load(void)
        /* if no file exists. create one with set of default values */
        if ( !dict )
        {
-               #if 0
+#ifdef MM_PLAYER_DEFAULT_INI
                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);      
+                       dict = iniparser_load(MM_PLAYER_INI_DEFAULT_PATH);
                }
-               #else
-               debug_log("No inifile found. \n");
-
+#else
+               debug_log("No ini file found. \n");
                return MM_ERROR_FILE_NOT_FOUND;
-               #endif
-       }
 #endif
+       }
 
        /* get ini values */
-       memset( &g_player_ini, 0, sizeof(mm_player_ini_t) );
+       memset( 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.video_surface = DEFAULT_VIDEO_SURFACE;
-               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( g_player_ini.videosink_element_x, "general:videosink element x", DEFAULT_VIDEOSINK_X);
-               MMPLAYER_INI_GET_STRING( g_player_ini.videosink_element_evas, "general:videosink element evas", DEFAULT_VIDEOSINK_EVAS);
-               MMPLAYER_INI_GET_STRING( g_player_ini.videosink_element_fake, "general:videosink element fake", DEFAULT_VIDEOSINK_FAKE);
-               MMPLAYER_INI_GET_STRING( g_player_ini.name_of_drmsrc, "general:drmsrc element", DEFAULT_DRMSRC );
-               MMPLAYER_INI_GET_STRING( g_player_ini.name_of_audiosink, "general:audiosink element", DEFAULT_AUDIOSINK );
-               MMPLAYER_INI_GET_STRING( 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( g_player_ini.gst_param[0], "general:gstparam1", DEFAULT_GST_PARAM );
-               MMPLAYER_INI_GET_STRING( g_player_ini.gst_param[1], "general:gstparam2", DEFAULT_GST_PARAM );
-               MMPLAYER_INI_GET_STRING( g_player_ini.gst_param[2], "general:gstparam3", DEFAULT_GST_PARAM );
-               MMPLAYER_INI_GET_STRING( g_player_ini.gst_param[3], "general:gstparam4", DEFAULT_GST_PARAM );
-               MMPLAYER_INI_GET_STRING( g_player_ini.gst_param[4], "general:gstparam5", DEFAULT_GST_PARAM );
-
-               /* audio filter (Preset)*/
-               g_player_ini.use_audio_filter_preset = iniparser_getboolean(dict, "sound effect:audio filter preset", DEFAULT_USE_AUDIO_FILTER_PRESET);
-               if (g_player_ini.use_audio_filter_preset)
-               {
-                       MMPLAYER_INI_GET_BOOLEAN_FROM_LIST( g_player_ini.audio_filter_preset_list, MM_AUDIO_FILTER_PRESET_NUM,
-                                       "sound effect:audio filter preset list", DEFAULT_AUDIO_FILTER_PRESET_LIST );
-                       MMPLAYER_INI_GET_BOOLEAN_FROM_LIST( g_player_ini.audio_filter_preset_earphone_only_list, MM_AUDIO_FILTER_PRESET_NUM,
-                                       "sound effect:audio filter preset earphone only", DEFAULT_AUDIO_FILTER_PRESET_LIST_EARPHONE_ONLY );
-               }
-               /* for audio filter custom (EQ / Extension filters) */
-               g_player_ini.use_audio_filter_custom = iniparser_getboolean(dict, "sound effect:audio filter custom", DEFAULT_USE_AUDIO_FILTER_CUSTOM);
-               if (g_player_ini.use_audio_filter_custom)
-               {
-                       MMPLAYER_INI_GET_BOOLEAN_FROM_LIST( g_player_ini.audio_filter_custom_list, MM_AUDIO_FILTER_CUSTOM_NUM,
-                                       "sound effect:audio filter custom list", DEFAULT_AUDIO_FILTER_CUSTOM_LIST );
-                       MMPLAYER_INI_GET_BOOLEAN_FROM_LIST( g_player_ini.audio_filter_custom_earphone_only_list, MM_AUDIO_FILTER_CUSTOM_NUM,
-                                       "sound effect:audio filter custom earphone only", DEFAULT_AUDIO_FILTER_CUSTOM_LIST_EARPHONE_ONLY );
-                       /* for audio filter custom : EQ */
-                       if (g_player_ini.audio_filter_custom_list[MM_AUDIO_FILTER_CUSTOM_EQ])
-                       {
-                               g_player_ini.audio_filter_custom_eq_num = iniparser_getint(dict, "sound effect:audio filter eq num",
-                                               DEFAULT_AUDIO_FILTER_CUSTOM_EQ_NUM);
-                               if (g_player_ini.audio_filter_custom_eq_num < DEFAULT_AUDIO_FILTER_CUSTOM_EQ_NUM || g_player_ini.audio_filter_custom_eq_num > MM_AUDIO_FILTER_EQ_BAND_MAX)
-                               {
-                                       debug_error("audio_filter_custom_eq_num(%d) is not valid range(%d - %d), set the value %d",
-                                               g_player_ini.audio_filter_custom_eq_num, DEFAULT_AUDIO_FILTER_CUSTOM_EQ_NUM, MM_AUDIO_FILTER_EQ_BAND_MAX, DEFAULT_AUDIO_FILTER_CUSTOM_EQ_NUM);
-                                       g_player_ini.audio_filter_custom_eq_num = DEFAULT_AUDIO_FILTER_CUSTOM_EQ_NUM;
-                               }
-                       }
-                       /* for audio filter custom : extension filters */
-                       g_player_ini.audio_filter_custom_ext_num = iniparser_getint(dict, "sound effect:audio filter ext num",
-                                       DEFAULT_AUDIO_FILTER_CUSTOM_EXT_NUM);
-                       if (g_player_ini.audio_filter_custom_ext_num > 0)
-                       {
-                               MMPLAYER_INI_GET_INT_FROM_LIST( g_player_ini.audio_filter_custom_min_level_list, MM_AUDIO_FILTER_CUSTOM_NUM,
-                                               "sound effect:audio filter custom min list", DEFAULT_AUDIO_FILTER_CUSTOM_LIST );
-                               MMPLAYER_INI_GET_INT_FROM_LIST( g_player_ini.audio_filter_custom_max_level_list, MM_AUDIO_FILTER_CUSTOM_NUM,
-                                               "sound effect:audio filter custom max list", DEFAULT_AUDIO_FILTER_CUSTOM_LIST );
-                       }
-               }
-#if 0
-               int i;
-               for (i=0; i<MM_AUDIO_FILTER_PRESET_NUM; i++)
-               {
-                       debug_log("audio_filter_preset_list: %d (is it for earphone only?(%d))\n", g_player_ini.audio_filter_preset_list[i], g_player_ini.audio_filter_preset_earphone_only_list[i]);
-               }
-               for (i=0; i<MM_AUDIO_FILTER_CUSTOM_NUM; i++)
-               {
-                       debug_log("audio_filter_custom_list : %d (is it for earphone only?(%d))\n", g_player_ini.audio_filter_custom_list[i], g_player_ini.audio_filter_custom_earphone_only_list[i]);
-               }
-               debug_log("audio_filter_custom : eq_num(%d), ext_num(%d)\n", g_player_ini.audio_filter_custom_eq_num, g_player_ini.audio_filter_custom_ext_num )
-               for (i=0; i<MM_AUDIO_FILTER_CUSTOM_NUM; i++)
-               {
-                       debug_log("aaudio_filter_custom_level_min_max_list : min(%d), max(%d)\n", g_player_ini.audio_filter_custom_min_level_list[i], g_player_ini.audio_filter_custom_max_level_list[i]);
-               }
-#endif
+               ini->disable_segtrap = iniparser_getboolean(dict, "general:disable segtrap", DEFAULT_DISABLE_SEGTRAP);
+               ini->skip_rescan = iniparser_getboolean(dict, "general:skip rescan", DEFAULT_SKIP_RESCAN);
+               ini->generate_dot = iniparser_getboolean(dict, "general:generate dot", DEFAULT_GENERATE_DOT);
+               ini->provide_clock_for_music = iniparser_getboolean(dict, "general:provide clock for music", DEFAULT_PROVIDE_CLOCK_FOR_MUSIC);
+               ini->provide_clock_for_movie = iniparser_getboolean(dict, "general:provide clock for movie", DEFAULT_PROVIDE_CLOCK_FOR_MOVIE);
+               ini->live_state_change_timeout = iniparser_getint(dict, "general:live state change timeout", DEFAULT_LIVE_STATE_CHANGE_TIMEOUT);
+               ini->localplayback_state_change_timeout = iniparser_getint(dict, "general:localplayback state change timeout", DEFAULT_LOCALPLAYBACK_STATE_CHANGE_TIMEOUT);
+               ini->eos_delay = iniparser_getint(dict, "general:eos delay", DEFAULT_EOS_DELAY);
+               ini->async_start = iniparser_getboolean(dict, "general:async start", DEFAULT_ASYNC_START);
+               ini->multiple_codec_supported = iniparser_getboolean(dict, "general:multiple codec supported", DEFAULT_MULTIPLE_CODEC_SUPPORTED);
+
+               ini->delay_before_repeat = iniparser_getint(dict, "general:delay before repeat", DEFAULT_DELAY_BEFORE_REPEAT);
+
+               MMPLAYER_INI_GET_STRING(dict, ini->videosink_element_x, "general:videosink element x", DEFAULT_VIDEOSINK_X);
+               MMPLAYER_INI_GET_STRING(dict, ini->videosink_element_evas, "general:videosink element evas", DEFAULT_VIDEOSINK_EVAS);
+               MMPLAYER_INI_GET_STRING(dict, ini->videosink_element_fake, "general:videosink element fake", DEFAULT_VIDEOSINK_FAKE);
+               MMPLAYER_INI_GET_STRING(dict, ini->name_of_drmsrc, "general:drmsrc element", DEFAULT_DRMSRC );
+               MMPLAYER_INI_GET_STRING(dict, ini->name_of_audio_resampler, "general:audio resampler element", DEFAULT_AUDIORESAMPLER );
+               MMPLAYER_INI_GET_STRING(dict, ini->name_of_audiosink, "general:audiosink element", DEFAULT_AUDIOSINK );
+               MMPLAYER_INI_GET_STRING(dict, ini->name_of_video_converter, "general:video converter element", DEFAULT_VIDEO_CONVERTER );
+
+               __get_element_list(ini,
+                       iniparser_getstring(dict, "general:element exclude keyword", DEFAULT_EXCLUDE_KEYWORD), KEYWORD_EXCLUDE);
+
+               MMPLAYER_INI_GET_STRING(dict, ini->gst_param[0], "general:gstparam1", DEFAULT_GST_PARAM );
+               MMPLAYER_INI_GET_STRING(dict, ini->gst_param[1], "general:gstparam2", DEFAULT_GST_PARAM );
+               MMPLAYER_INI_GET_STRING(dict, ini->gst_param[2], "general:gstparam3", DEFAULT_GST_PARAM );
+               MMPLAYER_INI_GET_STRING(dict, ini->gst_param[3], "general:gstparam4", DEFAULT_GST_PARAM );
+               MMPLAYER_INI_GET_STRING(dict, ini->gst_param[4], "general:gstparam5", DEFAULT_GST_PARAM );
 
                /* http streaming */
-               MMPLAYER_INI_GET_STRING( g_player_ini.name_of_httpsrc, "http streaming:httpsrc element", DEFAULT_HTTPSRC );
-               MMPLAYER_INI_GET_STRING( 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);
+               MMPLAYER_INI_GET_STRING( dict, ini->name_of_httpsrc, "http streaming:httpsrc element", DEFAULT_HTTPSRC );
+               MMPLAYER_INI_GET_STRING( dict, ini->http_file_buffer_path, "http streaming:http file buffer path", DEFAULT_HTTP_FILE_BUFFER_PATH );
+               ini->http_buffering_limit = iniparser_getdouble(dict, "http streaming:http buffering high limit", DEFAULT_HTTP_BUFFERING_LIMIT);
+               ini->http_max_size_bytes = iniparser_getint(dict, "http streaming:http max size bytes", DEFAULT_HTTP_MAX_SIZE_BYTES);
+               ini->http_buffering_time = iniparser_getdouble(dict, "http streaming:http buffering time", DEFAULT_HTTP_BUFFERING_TIME);
+               ini->http_timeout = iniparser_getint(dict, "http streaming:http timeout", DEFAULT_HTTP_TIMEOUT);
 
                /* rtsp streaming */
-               MMPLAYER_INI_GET_STRING( 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);
+               MMPLAYER_INI_GET_STRING( dict, ini->name_of_rtspsrc, "rtsp streaming:rtspsrc element", DEFAULT_RTSPSRC );
+               ini->rtsp_buffering_time = iniparser_getint(dict, "rtsp streaming:rtsp buffering time", DEFAULT_RTSP_BUFFERING);
+               ini->rtsp_rebuffering_time = iniparser_getint(dict, "rtsp streaming:rtsp rebuffering time", DEFAULT_RTSP_REBUFFERING);
+               ini->rtsp_do_typefinding = iniparser_getboolean(dict, "rtsp streaming:rtsp do typefinding", DEFAULT_RTSP_DO_TYPEFINDING);
+               ini->rtsp_error_concealment = iniparser_getboolean(dict, "rtsp streaming:rtsp error concealment", DEFAULT_RTSP_ERROR_CONCEALMENT);
 
                /* hw accelation */
-               g_player_ini.use_video_hw_accel = iniparser_getboolean(dict, "hw accelation:use video hw accel", DEFAULT_USE_VIDEO_HW_ACCEL);
-               
+               ini->use_video_hw_accel = iniparser_getboolean(dict, "hw accelation:use video hw accel", DEFAULT_USE_VIDEO_HW_ACCEL);
+
                /* priority */
-               g_player_ini.use_priority_setting = iniparser_getboolean(dict, "priority:use priority setting", DEFAULT_USE_PRIORITY_SETTING);
-               g_player_ini.demux_priority = iniparser_getint(dict, "priority:demux", DEFAULT_PRIORITY_DEMUX);
-               g_player_ini.videosink_priority = iniparser_getint(dict, "priority:videosink", DEFAULT_PRIORITY_VIDEO_SINK);
-               g_player_ini.audiosink_priority = iniparser_getint(dict, "priority:audiosink", DEFAULT_PRIORITY_AUDIO_SINK);
-               g_player_ini.ringbuffer_priority = iniparser_getint(dict, "priority:ringbuffer", DEFAULT_PRIORITY_RINGBUFFER);
-       }       
+               ini->use_priority_setting = iniparser_getboolean(dict, "priority:use priority setting", DEFAULT_USE_PRIORITY_SETTING);
+               ini->demux_priority = iniparser_getint(dict, "priority:demux", DEFAULT_PRIORITY_DEMUX);
+               ini->videosink_priority = iniparser_getint(dict, "priority:videosink", DEFAULT_PRIORITY_VIDEO_SINK);
+               ini->audiosink_priority = iniparser_getint(dict, "priority:audiosink", DEFAULT_PRIORITY_AUDIO_SINK);
+               ini->ringbuffer_priority = iniparser_getint(dict, "priority:ringbuffer", DEFAULT_PRIORITY_RINGBUFFER);
+
+               /* subtitle */
+               ini->mirroring_width = iniparser_getint(dict, "subtitle:mirroring width", DEFAULT_MIRRORING_WIDTH);
+               ini->mirroring_height = iniparser_getint(dict, "subtitle:mirroring height", DEFAULT_MIRRORING_HEIGHT);
+               MMPLAYER_INI_GET_COLOR( dict, ini->font_color, "subtitle:font color", DEFAULT_FONT_COLOR );
+               MMPLAYER_INI_GET_COLOR( dict, ini->font_background_color, "subtitle:font background color", DEFAULT_FONT_BACKGROUND_COLOR );
+               ini->external_subtitle = iniparser_getboolean(dict, "subtitle:external subtitle", DEFAULT_EXTERNAL_SUBTITLE);
+
+               /* dump buffer for debug */
+               __get_element_list(ini,
+                       iniparser_getstring(dict, "general:dump element keyword", DEFAULT_EXCLUDE_KEYWORD), KEYWORD_DUMP);
+
+               MMPLAYER_INI_GET_STRING(dict, ini->dump_element_path, "general:dump element path", DEFAULT_DUMP_ELEMENT_PATH);
+       }
        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.use_audio_filter_preset = DEFAULT_USE_AUDIO_FILTER_PRESET;
-               g_player_ini.use_audio_filter_custom = DEFAULT_USE_AUDIO_FILTER_CUSTOM;
-               g_player_ini.skip_rescan = DEFAULT_SKIP_RESCAN;
-               g_player_ini.video_surface = DEFAULT_VIDEO_SURFACE;
-               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 );
+               ini->disable_segtrap = DEFAULT_DISABLE_SEGTRAP;
+               ini->skip_rescan = DEFAULT_SKIP_RESCAN;
+               strncpy( ini->videosink_element_x, DEFAULT_VIDEOSINK_X, PLAYER_INI_MAX_STRLEN - 1 );
+               strncpy( ini->videosink_element_evas, DEFAULT_VIDEOSINK_EVAS, PLAYER_INI_MAX_STRLEN - 1 );
+               strncpy( ini->videosink_element_fake, DEFAULT_VIDEOSINK_FAKE, PLAYER_INI_MAX_STRLEN - 1 );
+               ini->generate_dot = DEFAULT_GENERATE_DOT;
+               ini->provide_clock_for_music = DEFAULT_PROVIDE_CLOCK_FOR_MUSIC;
+               ini->provide_clock_for_movie = DEFAULT_PROVIDE_CLOCK_FOR_MOVIE;
+               ini->live_state_change_timeout = DEFAULT_LIVE_STATE_CHANGE_TIMEOUT;
+               ini->localplayback_state_change_timeout = DEFAULT_LOCALPLAYBACK_STATE_CHANGE_TIMEOUT;
+               ini->eos_delay = DEFAULT_EOS_DELAY;
+               ini->multiple_codec_supported = DEFAULT_MULTIPLE_CODEC_SUPPORTED;
+               ini->async_start = DEFAULT_ASYNC_START;
+               ini->delay_before_repeat = DEFAULT_DELAY_BEFORE_REPEAT;
+
+               strncpy( ini->name_of_drmsrc, DEFAULT_DRMSRC, PLAYER_INI_MAX_STRLEN - 1 );
+               strncpy( ini->name_of_audio_resampler, DEFAULT_AUDIORESAMPLER, PLAYER_INI_MAX_STRLEN -1 );
+               strncpy( ini->name_of_audiosink, DEFAULT_AUDIOSINK, PLAYER_INI_MAX_STRLEN -1 );
+               strncpy( 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);
+                       __get_element_list(ini, DEFAULT_EXCLUDE_KEYWORD, KEYWORD_EXCLUDE);
                }
 
 
-               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 );
+               strncpy( ini->gst_param[0], DEFAULT_GST_PARAM, PLAYER_INI_MAX_PARAM_STRLEN - 1 );
+               strncpy( ini->gst_param[1], DEFAULT_GST_PARAM, PLAYER_INI_MAX_PARAM_STRLEN - 1 );
+               strncpy( ini->gst_param[2], DEFAULT_GST_PARAM, PLAYER_INI_MAX_PARAM_STRLEN - 1 );
+               strncpy( ini->gst_param[3], DEFAULT_GST_PARAM, PLAYER_INI_MAX_PARAM_STRLEN - 1 );
+               strncpy( 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;
-               
+               strncpy( ini->name_of_httpsrc, DEFAULT_HTTPSRC, PLAYER_INI_MAX_STRLEN - 1 );
+               strncpy( ini->http_file_buffer_path, DEFAULT_HTTP_FILE_BUFFER_PATH, PLAYER_INI_MAX_STRLEN - 1 );
+               ini->http_buffering_limit = DEFAULT_HTTP_BUFFERING_LIMIT;
+               ini->http_max_size_bytes = DEFAULT_HTTP_MAX_SIZE_BYTES;
+               ini->http_buffering_time = DEFAULT_HTTP_BUFFERING_TIME;
+               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;
+               strncpy( ini->name_of_rtspsrc, DEFAULT_RTSPSRC, PLAYER_INI_MAX_STRLEN - 1 );
+               ini->rtsp_buffering_time = DEFAULT_RTSP_BUFFERING;
+               ini->rtsp_rebuffering_time = DEFAULT_RTSP_REBUFFERING;
+               ini->rtsp_do_typefinding = DEFAULT_RTSP_DO_TYPEFINDING;
+               ini->rtsp_error_concealment = DEFAULT_RTSP_ERROR_CONCEALMENT;
 
                /* hw accelation */
-               g_player_ini.use_video_hw_accel = DEFAULT_USE_VIDEO_HW_ACCEL;
+               ini->use_video_hw_accel = DEFAULT_USE_VIDEO_HW_ACCEL;
 
                /* priority  */
-               g_player_ini.use_priority_setting = DEFAULT_USE_PRIORITY_SETTING;
-               g_player_ini.demux_priority = DEFAULT_PRIORITY_DEMUX;
-               g_player_ini.videosink_priority = DEFAULT_PRIORITY_VIDEO_SINK;
-               g_player_ini.audiosink_priority = DEFAULT_PRIORITY_AUDIO_SINK;
-               g_player_ini.ringbuffer_priority = DEFAULT_PRIORITY_RINGBUFFER;
+               ini->use_priority_setting = DEFAULT_USE_PRIORITY_SETTING;
+               ini->demux_priority = DEFAULT_PRIORITY_DEMUX;
+               ini->videosink_priority = DEFAULT_PRIORITY_VIDEO_SINK;
+               ini->audiosink_priority = DEFAULT_PRIORITY_AUDIO_SINK;
+               ini->ringbuffer_priority = DEFAULT_PRIORITY_RINGBUFFER;
+
+               /* subtitle */
+               ini->external_subtitle = DEFAULT_EXTERNAL_SUBTITLE;
+               ini->mirroring_width = DEFAULT_MIRRORING_WIDTH;
+               ini->mirroring_height = DEFAULT_MIRRORING_HEIGHT;
+               MMPLAYER_INI_GET_COLOR( dict, ini->font_color, "subtitle:font color", DEFAULT_FONT_COLOR );
+               MMPLAYER_INI_GET_COLOR( dict, ini->font_background_color, "subtitle:font background color", DEFAULT_FONT_BACKGROUND_COLOR );
+
+               /* dump buffer for debug */
+               __get_element_list(ini, DEFAULT_DUMP_ELEMENT_KEYWORD, KEYWORD_DUMP);
+               strncpy(ini->dump_element_path, DEFAULT_DUMP_ELEMENT_PATH, PLAYER_INI_MAX_STRLEN - 1);
        }
 
        /* free dict as we got our own structure */
        iniparser_freedict (dict);
 
-       loaded = TRUE;
-
-       /* The simulator uses a separate ini file. */
-       //__mm_player_ini_force_setting();
-
-
        /* dump structure */
        debug_log("player settings -----------------------------------\n");
 
        /* general */
-       debug_log("use_decodebin : %d\n", g_player_ini.use_decodebin);
-       debug_log("use_audio_filter_preset : %d\n", g_player_ini.use_audio_filter_preset);
-       debug_log("use_audio_filter_custom : %d\n", g_player_ini.use_audio_filter_custom);
-       debug_log("disable_segtrap : %d\n", g_player_ini.disable_segtrap);
-       debug_log("skip rescan : %d\n", g_player_ini.skip_rescan);
-       debug_log("video surface(0:X, 1:EVAS, 2:GL, 3:NULL) : %d\n", g_player_ini.video_surface);
-       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("disable_segtrap : %d\n", ini->disable_segtrap);
+       debug_log("skip rescan : %d\n", ini->skip_rescan);
+       debug_log("videosink element x: %s\n", ini->videosink_element_x);
+       debug_log("videosink element evas: %s\n", ini->videosink_element_evas);
+       debug_log("videosink element fake: %s\n", ini->videosink_element_fake);
+       debug_log("generate_dot : %d\n", ini->generate_dot);
+       debug_log("provide_clock for music : %d\n", ini->provide_clock_for_music);
+       debug_log("provide_clock for movie : %d\n", ini->provide_clock_for_movie);
+       debug_log("live_state_change_timeout(sec) : %d\n", ini->live_state_change_timeout);
+       debug_log("localplayback_state_change_timeout(sec) : %d\n", ini->localplayback_state_change_timeout);
+       debug_log("eos_delay(msec) : %d\n", ini->eos_delay);
+       debug_log("delay_before_repeat(msec) : %d\n", ini->delay_before_repeat);
+       debug_log("name_of_drmsrc : %s\n", ini->name_of_drmsrc);
+       debug_log("name_of_audioresampler : %s\n", ini->name_of_audio_resampler);
+       debug_log("name_of_audiosink : %s\n", ini->name_of_audiosink);
+       debug_log("name_of_video_converter : %s\n", ini->name_of_video_converter);
+       debug_log("async_start : %d\n", ini->async_start);
+       debug_log("multiple_codec_supported : %d\n", ini->multiple_codec_supported);
+
+       debug_log("gst_param1 : %s\n", ini->gst_param[0]);
+       debug_log("gst_param2 : %s\n", ini->gst_param[1]);
+       debug_log("gst_param3 : %s\n", ini->gst_param[2]);
+       debug_log("gst_param4 : %s\n", ini->gst_param[3]);
+       debug_log("gst_param5 : %s\n", ini->gst_param[4]);
+
+       for ( idx = 0; ini->exclude_element_keyword[idx][0] != '\0'; idx++ )
+       {
+               debug_log("exclude_element_keyword [%d] : %s\n", idx, ini->exclude_element_keyword[idx]);
+       }
+
+       for ( idx = 0; ini->dump_element_keyword[idx][0] != '\0'; idx++ )
        {
-               debug_log("exclude_element_keyword [%d] : %s\n", idx, g_player_ini.exclude_element_keyword[idx]);
+               debug_log("dump_element_keyword [%d] : %s\n", idx, ini->dump_element_keyword[idx]);
        }
-       
+
+       /* subtitle */
+       debug_log("external subtitle : %d\n", ini->external_subtitle);
+
        /* 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);
-       
+       debug_log("name_of_httpsrc : %s\n", ini->name_of_httpsrc);
+       debug_log("http_file_buffer_path : %s \n", ini->http_file_buffer_path);
+       debug_log("http_buffering_limit : %f \n", ini->http_buffering_limit);
+       debug_log("http_max_size_bytes : %d \n", ini->http_max_size_bytes);
+       debug_log("http_buffering_time : %f \n", ini->http_buffering_time);
+       debug_log("http_timeout : %d \n", 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("name_of_rtspsrc : %s\n", ini->name_of_rtspsrc);
+       debug_log("rtsp_buffering_time(msec) : %d\n", ini->rtsp_buffering_time);
+       debug_log("rtsp_rebuffering_time(msec) : %d\n", ini->rtsp_rebuffering_time);
+       debug_log("rtsp_do_typefinding : %d \n", ini->rtsp_do_typefinding);
+       debug_log("rtsp_error_concealment : %d \n", ini->rtsp_error_concealment);
 
        /* hw accel */
-       debug_log("use_video_hw_accel : %d\n", g_player_ini.use_video_hw_accel);
+       debug_log("use_video_hw_accel : %d\n", ini->use_video_hw_accel);
 
        /* priority */
-       debug_log("use_priority_setting : %d\n", g_player_ini.use_priority_setting);
-       debug_log("demux_priority : %d\n", g_player_ini.demux_priority);
-       debug_log("audiosink_priority : %d\n", g_player_ini.audiosink_priority);
-       debug_log("videosink_priority : %d\n", g_player_ini.videosink_priority);
-       debug_log("ringbuffer_priority : %d\n", g_player_ini.ringbuffer_priority);
+       debug_log("use_priority_setting : %d\n", ini->use_priority_setting);
+       debug_log("demux_priority : %d\n", ini->demux_priority);
+       debug_log("audiosink_priority : %d\n", ini->audiosink_priority);
+       debug_log("videosink_priority : %d\n", ini->videosink_priority);
+       debug_log("ringbuffer_priority : %d\n", ini->ringbuffer_priority);
 
-       debug_log("---------------------------------------------------\n");     
+       return MM_ERROR_NONE;
+}
+
+
+int
+mm_player_audio_effect_ini_load(mm_player_ini_t* ini)
+{
+       dictionary * dict_audioeffect = NULL;
+
+       dict_audioeffect = iniparser_load(MM_PLAYER_INI_DEFAULT_AUDIOEFFECT_PATH);
+       if ( !dict_audioeffect )
+       {
+               debug_error("No audio effect ini file found. \n");
+               return MM_ERROR_FILE_NOT_FOUND;
+       }
+
+       /* audio effect element name */
+       MMPLAYER_INI_GET_STRING( dict_audioeffect, ini->name_of_audio_effect, "audio effect:audio effect element", DEFAULT_AUDIO_EFFECT_ELEMENT );
+       if (!ini->name_of_audio_effect[0])
+       {
+               debug_warning("could not parse name of audio effect. \n");
+               iniparser_freedict (dict_audioeffect);
+               /* NOTE : in this case, we are not going to create audio filter element */
+               return MM_ERROR_NONE;
+       }
+
+       /* audio effect (Preset)*/
+       ini->use_audio_effect_preset = iniparser_getboolean(dict_audioeffect, "audio effect:audio effect preset", DEFAULT_USE_AUDIO_EFFECT_PRESET);
+       if (ini->use_audio_effect_preset)
+       {
+               MMPLAYER_INI_GET_BOOLEAN_FROM_LIST( dict_audioeffect, 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, 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) */
+       ini->use_audio_effect_custom = iniparser_getboolean(dict_audioeffect, "audio effect:audio effect custom", DEFAULT_USE_AUDIO_EFFECT_CUSTOM);
+       if (ini->use_audio_effect_custom)
+       {
+               MMPLAYER_INI_GET_BOOLEAN_FROM_LIST( dict_audioeffect, 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, 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 (ini->audio_effect_custom_list[MM_AUDIO_EFFECT_CUSTOM_EQ])
+               {
+                       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 (ini->audio_effect_custom_eq_band_num < DEFAULT_AUDIO_EFFECT_CUSTOM_EQ_BAND_NUM ||
+                                       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",
+                                       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);
+                               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 (ini->audio_effect_custom_eq_band_num)
+                               {
+                                       MMPLAYER_INI_GET_INT_FROM_LIST( dict_audioeffect, 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, 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 */
+               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 (ini->audio_effect_custom_eq_band_num || ini->audio_effect_custom_ext_num)
+               {
+
+                       MMPLAYER_INI_GET_INT_FROM_LIST( dict_audioeffect, 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, ini->audio_effect_custom_max_level_list, MM_AUDIO_EFFECT_CUSTOM_NUM,
+                                       "audio effect:audio effect custom max list", DEFAULT_AUDIO_EFFECT_CUSTOM_LIST );
+               }
+       }
+
+       ini->use_audio_effect_square= iniparser_getboolean(dict_audioeffect, "audio effect:audio effect square", DEFAULT_USE_AUDIO_EFFECT_SQUARE);
+       if (ini->use_audio_effect_custom)
+       {
+               ini->audio_effect_square_max_row= iniparser_getint(dict_audioeffect, "audio effect:audio effect square max row",
+                               DEFAULT_AUDIO_EFFECT_SQUARE_ROW_MAX);
+               ini->audio_effect_square_max_col= iniparser_getint(dict_audioeffect, "audio effect:audio effect square max col",
+                               DEFAULT_AUDIO_EFFECT_SQUARE_COL_MAX);
+       }
+
+       /* audio effect element name */
+       MMPLAYER_INI_GET_STRING( dict_audioeffect, ini->name_of_audio_effect_sec, "audio effect:audio effect element sec", DEFAULT_AUDIO_EFFECT_ELEMENT );
+       if (!ini->name_of_audio_effect_sec[0])
+       {
+               debug_warning("could not parse name of secondary audio effect. \n");
+       }
+
+       /* dump structure */
+       debug_log("name_of_audio_effect : %s\n", ini->name_of_audio_effect);
+       debug_log("use_audio_effect_preset : %d\n", ini->use_audio_effect_preset);
+       debug_log("use_audio_effect_custom : %d\n", ini->use_audio_effect_custom);
+       debug_log("name_of_audio_effect_sec : %s\n", ini->name_of_audio_effect_sec);
+       debug_log("Use_audio_effect_square : %d\n", ini->use_audio_effect_square);
+#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", ini->audio_effect_preset_list[i], 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", ini->audio_effect_custom_list[i], ini->audio_effect_custom_earphone_only_list[i]);
+       }
+       debug_log("audio_effect_custom : eq_band_num(%d), ext_num(%d)\n", ini->audio_effect_custom_eq_band_num, ini->audio_effect_custom_ext_num );
+       debug_log("audio_effect_custom_EQ : width(Hz) / central frequency(Hz)");
+       for (i=0; i<ini->audio_effect_custom_eq_band_num; i++)
+       {
+               debug_log("     EQ band index(%d) :  %8d / %8d", i, ini->audio_effect_custom_eq_band_width[i], 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, ini->audio_effect_custom_min_level_list[i], ini->audio_effect_custom_max_level_list[i]);
+       }
+#endif
+       iniparser_freedict (dict_audioeffect);
 
        return MM_ERROR_NONE;
+
 }
 
 
@@ -423,7 +519,7 @@ 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");
@@ -433,74 +529,17 @@ void __mm_player_ini_check_ini_status(void)
                if ( ini_buff.st_size < 5 )
                {
                        debug_warning("player.ini file size=%d, Corrupted! So, Removed\n", (int)ini_buff.st_size);
-                       
-                       g_remove( MM_PLAYER_INI_DEFAULT_PATH );
+
+                       if ( g_remove( MM_PLAYER_INI_DEFAULT_PATH ) == -1)
+                       {
+                               debug_error("failed to delete corrupted ini");
+                       }
                }
        }
 }
 
-static 
-void __mm_player_ini_force_setting(void)
-{
-       /* FIXIT : remove it when all other elements are available on simulator, SDK */
-       
-       #if ! defined(__arm__)
-               debug_warning("player is running on simulator. force to use ximagesink\n");
-               //g_player_ini.videosink_element = PLAYER_INI_VSINK_XIMAGESINK;
-               g_player_ini.use_audio_filter_preset = FALSE;
-               g_player_ini.use_audio_filter_custom = FALSE;
-
-               strcpy( g_player_ini.name_of_drmsrc, "filesrc" );
-
-               // Force setting for simulator :+:091218 
-               strcpy( g_player_ini.name_of_audiosink, "alsasink" );
-
-               
-//             __get_string_list( (gchar**) g_player_ini.exclude_element_keyword, "");
-               
-       #endif
-
-       #if defined(VDF_SDK) || defined (SEC_SDK)
-               debug_warning("player is running on SDK.\n");
-               debug_warning("So, it seems like that some plugin values are not same with those\n");
-               debug_warning("which are written in default ini file.\n");
-
-               //g_player_ini.videosink_element = PLAYER_INI_VSINK_XIMAGESINK;
-               g_player_ini.use_audio_filter_preset = FALSE;
-               g_player_ini.use_audio_filter_custom = FALSE;
-
-               strcpy( g_player_ini.name_of_drmsrc, "filesrc" );
-       #endif
-
-       #if defined(NEW_SOUND) 
-               strcpy (g_player_ini.name_of_audiosink, "soundsink"); // :+:090707
-       #endif
-
-       /* FIXIT : The HW quality of volans is not better than protector.
-        * So, it can't use same timeout value because state change(resume) is sometimes failed in volans.
-        * Thus, it should be set more than 10sec. 
-        */
-       #if defined(_MM_PROJECT_VOLANS)
-               g_player_ini.localplayback_state_change_timeout = 10;
-               debug_log("localplayback_state_change_timeout is set as 30sec by force\n");
-       #endif
-
-       #if 0
-       #if defined(_MM_PROJECT_VOLANS)
-               debug_warning("player is running on VOLANS\n");
-               g_player_ini.use_audio_filter = FALSE;          // (+)090702, disabled temporally
-       #endif
-       #endif
-       
-}
-
-mm_player_ini_t* 
-mm_player_ini_get_structure(void)
-{
-       return &g_player_ini;
-}
-
-static 
+#ifdef MM_PLAYER_DEFAULT_INI
+static
 gboolean __generate_default_ini(void)
 {
        FILE* fp = NULL;
@@ -525,16 +564,16 @@ gboolean __generate_default_ini(void)
        fclose(fp);
        return TRUE;
 }
+#endif
 
-static 
-void   __get_string_list(gchar** out_list, gchar* str)
+static
+void   __get_element_list(mm_player_ini_t* ini, gchar* str, int keyword_type)
 {
        gchar** list = NULL;
        gchar** walk = NULL;
        gint i = 0;
        gchar* strtmp = NULL;
 
-
        if ( ! str )
                return;
 
@@ -559,19 +598,45 @@ void      __get_string_list(gchar** out_list, gchar* str)
        }
 
        /* copy list */
-       for( walk = list; *walk; walk++ )
+       switch (keyword_type)
        {
-               strncpy( g_player_ini.exclude_element_keyword[i], *walk, (PLAYER_INI_MAX_STRLEN - 1) );
+               case KEYWORD_EXCLUDE:
+               {
+                       for( walk = list; *walk; walk++ )
+                       {
+                               strncpy( ini->exclude_element_keyword[i], *walk, (PLAYER_INI_MAX_STRLEN - 1) );
 
-               g_strstrip( g_player_ini.exclude_element_keyword[i] );
+                               g_strstrip( ini->exclude_element_keyword[i] );
 
-               g_player_ini.exclude_element_keyword[i][PLAYER_INI_MAX_STRLEN - 1] = '\0';
+                               ini->exclude_element_keyword[i][PLAYER_INI_MAX_STRLEN -1]= '\0';
 
-               i++;
-       }
+                               i++;
+                       }
+                       /* mark last item to NULL */
+                       ini->exclude_element_keyword[i][0] = '\0';
 
-       /* mark last item to NULL */
-       g_player_ini.exclude_element_keyword[i][0] = '\0';
+                       break;
+               }
+               case KEYWORD_DUMP:
+               {
+                       for( walk = list; *walk; walk++ )
+                       {
+                               strncpy( ini->dump_element_keyword[i], *walk, (PLAYER_INI_MAX_STRLEN - 1) );
+
+                               g_strstrip( ini->dump_element_keyword[i] );
+
+                               ini->dump_element_keyword[i][PLAYER_INI_MAX_STRLEN -1]= '\0';
+
+                               i++;
+                       }
+                       /* mark last item to NULL */
+                       ini->dump_element_keyword[i][0] = '\0';
+
+                       break;
+               }
+               default:
+                       break;
+       }
 
        g_strfreev( list );
        if (strtmp)
diff --git a/src/mm_player_m3u8.c b/src/mm_player_m3u8.c
deleted file mode 100755 (executable)
index 5886b6b..0000000
+++ /dev/null
@@ -1,772 +0,0 @@
-/* GStreamer
- * Copyright (C) 2010 Marc-Andre Lureau <marcandre.lureau@gmail.com>
- *
- * m3u8.c:
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/* This source code is taken from m3u8.c, which is licensed by GNU Library General Public License.
- * AES-128 bit decryption features are changed from m3u8.c.
- * - gst_m3u8_update and gst_m3u8_media_file_new are modified.
- * - gst_m3u8_getIV_from_mediasequence is added.
- * For convenience,
- * - gst_m3u8_client_get_next_fragment is modified.
- * - gst_m3u8_client_check_next_fragment is added.
- * File name is changed to mm_player_m3u8.c
- */
-
-#include <stdlib.h>
-#include <errno.h>
-#include <glib.h>
-
-#include "mm_player_m3u8.h"
-#include <mm_debug.h>
-#include <string.h>
-
-
-static GstM3U8 *gst_m3u8_new (void);
-static void gst_m3u8_free (GstM3U8 * m3u8);
-static gboolean gst_m3u8_update (GstM3U8 * m3u8, gchar * data,
-    gboolean * updated);
-static GstM3U8MediaFile *gst_m3u8_media_file_new (gchar * uri, gchar * title, gint duration,  gchar *key_url, gchar *IV, guint sequence);
-static void gst_m3u8_media_file_free (GstM3U8MediaFile * self);
-
-static GstM3U8 *
-gst_m3u8_new (void)
-{
-  GstM3U8 *m3u8;
-
-  m3u8 = g_new0 (GstM3U8, 1);
-
-  return m3u8;
-}
-
-static void
-gst_m3u8_set_uri (GstM3U8 * self, gchar * uri)
-{
-  g_return_if_fail (self != NULL);
-
-  if (self->uri)
-    g_free (self->uri);
-  self->uri = uri;
-}
-
-static void
-gst_m3u8_free (GstM3U8 * self)
-{
-  g_return_if_fail (self != NULL);
-
-  g_free (self->uri);
-  g_free (self->allowcache);
-  g_free (self->codecs);
-
-  g_list_foreach (self->files, (GFunc) gst_m3u8_media_file_free, NULL);
-  g_list_free (self->files);
-
-  g_free (self->last_data);
-  g_list_foreach (self->lists, (GFunc) gst_m3u8_free, NULL);
-  g_list_free (self->lists);
-
-  g_free (self);
-}
-
-static GstM3U8MediaFile *
-gst_m3u8_media_file_new (gchar * uri, gchar * title, gint duration,  gchar *key_url, gchar *IV, guint sequence)
-{
-  GstM3U8MediaFile *file;
-
-  file = g_new0 (GstM3U8MediaFile, 1);
-  file->uri = uri;
-  file->title = title;
-  file->duration = duration;
-  file->sequence = sequence;
-  memset (file->key, 0x00, sizeof (file->key));
-
-  //g_print (" uri = %s  / ", uri);
-
-  if (key_url != NULL)
-  {
-    file->key_url = g_strdup (key_url);
-  }
-  else
-    file->key_url = NULL;
-
-  if (IV != NULL)
-  {
-    memcpy (file->iv, IV, sizeof (file->iv));
-  }
-  return file;
-}
-
-static void
-gst_m3u8_media_file_free (GstM3U8MediaFile * self)
-{
-  g_return_if_fail (self != NULL);
-
-  if (self->key_url)
-    g_free (self->key_url);
-
-  g_free (self->title);
-  g_free (self->uri);
-  g_free (self);
-}
-
-static gchar *
-gst_m3u8_getIV_from_mediasequence (GstM3U8 *self)
-{
-  gchar *IV = NULL;
-  gint i = 0;
-  
-  IV = g_malloc0 (16);
-  if (NULL == IV)
-  {
-    debug_warning ("Failed to allocate memory...");
-    return NULL;
-  }
-
-  if (self->mediasequence > INT_MAX)
-  {
-    debug_warning ("media sequnece is greater than INT_MAX...yet to handle");
-  }
-
-  IV [15] = (gchar)(self->mediasequence);
-  IV [14] = (gchar)(self->mediasequence >> 8);
-  IV [13] = (gchar)(self->mediasequence >> 16);
-  IV [12] = (gchar)(self->mediasequence >> 24);
-   
-  return IV;
-}
-
-static gboolean
-int_from_string (gchar * ptr, gchar ** endptr, gint * val, gint base)
-{
-  gchar *end;
-
-  g_return_val_if_fail (ptr != NULL, FALSE);
-  g_return_val_if_fail (val != NULL, FALSE);
-
-  errno = 0;
-  *val = strtol (ptr, &end, base);
-  if ((errno == ERANGE && (*val == LONG_MAX || *val == LONG_MIN))
-      || (errno != 0 && *val == 0)) {
-//    debug_warning (g_strerror (errno));
-    return FALSE;
-  }
-
-  if (endptr)
-    *endptr = end;
-
-  return end != ptr;
-}
-
-static gboolean
-parse_attributes (gchar ** ptr, gchar ** a, gchar ** v)
-{
-  gchar *end, *p;
-
-  g_return_val_if_fail (ptr != NULL, FALSE);
-  g_return_val_if_fail (*ptr != NULL, FALSE);
-  g_return_val_if_fail (a != NULL, FALSE);
-  g_return_val_if_fail (v != NULL, FALSE);
-
-  /* [attribute=value,]* */
-
-  *a = *ptr;
-  end = p = g_utf8_strchr (*ptr, -1, ',');
-  if (end) {
-    do {
-      end = g_utf8_next_char (end);
-    } while (end && *end == ' ');
-    *p = '\0';
-  }
-
-  *v = p = g_utf8_strchr (*ptr, -1, '=');
-  if (*v) {
-    *v = g_utf8_next_char (*v);
-    *p = '\0';
-  } else {
-    debug_warning ("missing = after attribute\n");
-    return FALSE;
-  }
-
-  *ptr = end;
-  return TRUE;
-}
-
-static gint
-_m3u8_compare_uri (GstM3U8 * a, gchar * uri)
-{
-  g_return_val_if_fail (a != NULL, 0);
-  g_return_val_if_fail (uri != NULL, 0);
-
-  return g_strcmp0 (a->uri, uri);
-}
-
-static gint
-gst_m3u8_compare_playlist_by_bitrate (gconstpointer a, gconstpointer b)
-{
-  return ((GstM3U8 *) (a))->bandwidth - ((GstM3U8 *) (b))->bandwidth;
-}
-
-/*
- * @data: a m3u8 playlist text data, taking ownership
- */
-static gboolean
-gst_m3u8_update (GstM3U8 * self, gchar * data, gboolean * updated)
-{
-  gint val, duration;
-  gchar *title, *end;
-  gboolean discontinuity;
-  GstM3U8 *list;
-  gchar  *key_url = NULL;
-  gchar *IV = NULL;
-
-  g_return_val_if_fail (self != NULL, FALSE);
-  g_return_val_if_fail (data != NULL, FALSE);
-  g_return_val_if_fail (updated != NULL, FALSE);
-
-  *updated = TRUE;
-
-  /* check if the data changed since last update */
-  if (self->last_data && g_str_equal (self->last_data, data)) {
-    g_print ("\n\n\n\t\t ############ Playlist is the same as previous one ############\n\n\n\n");
-    *updated = FALSE;
-    g_free (data);
-    return TRUE;
-  }
-
-  if (!g_str_has_prefix (data, "#EXTM3U")) {
-    debug_warning ("Data doesn't start with #EXTM3U\n");
-    g_free (data);
-    return FALSE;
-  }
-
-  /* playlist has changed from last time.. update last_data */
-  g_free (self->last_data);
-  self->last_data = data;
-
-  if (self->files) {
-    g_list_foreach (self->files, (GFunc) gst_m3u8_media_file_free, NULL);
-    g_list_free (self->files);
-    self->files = NULL;
-  }
-
-  list = NULL;
-  duration = -1;
-  title = NULL;
-  key_url = NULL;
-  data += 7;
-  //data += 8;
-  while (TRUE) {
-       //g_print ("====================================\n");
-       //g_print ("data = [%s]\n", data);
-    end = g_utf8_strchr (data, -1, '\n');       /* FIXME: support \r\n */
-    if (end)
-      *end = '\0';
-
-    //g_print ("end = [%s]\n", end);
-
-
-    if (data[0] != '#') {
-      if (duration < 0 && list == NULL) {
-        debug_log ("%s: got line without EXTINF or EXTSTREAMINF, dropping\n", data);
-        goto next_line;
-      }
-
-      if (!gst_uri_is_valid (data)) {
-        gchar *slash;
-        if (!self->uri) {
-          debug_warning ("uri not set, can't build a valid uri\n");
-          goto next_line;
-        }
-        slash = g_utf8_strrchr (self->uri, -1, '/');
-        if (!slash) {
-          debug_warning ("Can't build a valid uri\n");
-          goto next_line;
-        }
-
-        *slash = '\0';
-        data = g_strdup_printf ("%s/%s", self->uri, data);
-        *slash = '/';
-      } else
-        data = g_strdup (data);
-
-      if (list != NULL) {
-        if (g_list_find_custom (self->lists, data,
-                (GCompareFunc) _m3u8_compare_uri)) {
-          debug_log ("Already have a list with this URI\n");
-          gst_m3u8_free (list);
-          g_free (data);
-        } else {
-          gst_m3u8_set_uri (list, data);
-          self->lists = g_list_append (self->lists, list);
-        }
-        list = NULL;
-      } else {
-        GstM3U8MediaFile *file;
-        gchar *send_IV = NULL;
-
-        if (key_url)   
-        {
-          debug_log ("AES-128 key url = %s", key_url);
-          if (NULL == IV)
-          {
-            /* IV is not present in EXT-X-KEY tag. Prepare IV based on mediasequence */
-            debug_log ("IV is not in EXT-X-KEY tag... generating from media_seq_num = %d", self->mediasequence);
-            send_IV = gst_m3u8_getIV_from_mediasequence (self);
-          }
-          else
-          {
-            send_IV = g_strdup (IV);   
-          }
-        }
-  
-        file =
-            gst_m3u8_media_file_new (data, title, duration, key_url, send_IV, self->mediasequence++);
-        duration = -1;
-        title = NULL;
-        g_free (send_IV);
-        self->files = g_list_append (self->files, file);
-      }
-
-    } else if (g_str_has_prefix (data, "#EXT-X-ENDLIST")) {
-      self->endlist = TRUE;
-    } else if (g_str_has_prefix (data, "#EXT-X-VERSION:")) {
-      if (int_from_string (data + 15, &data, &val, 10))
-        self->version = val;
-    } else if (g_str_has_prefix (data, "#EXT-X-STREAM-INF:")) {
-      gchar *v, *a;
-
-      if (list != NULL) {
-        debug_warning ("Found a list without a uri..., dropping\n");
-        gst_m3u8_free (list);
-      }
-
-      list = gst_m3u8_new ();
-      data = data + 18;
-      while (data && parse_attributes (&data, &a, &v)) {
-        if (g_str_equal (a, "BANDWIDTH")) {
-          if (!int_from_string (v, NULL, &list->bandwidth, 10))
-            debug_warning ("Error while reading BANDWIDTH");
-        } else if (g_str_equal (a, "PROGRAM-ID")) {
-          if (!int_from_string (v, NULL, &list->program_id, 10))
-            debug_warning ("Error while reading PROGRAM-ID");
-        } else if (g_str_equal (a, "CODECS")) {
-          g_free (list->codecs);
-          list->codecs = g_strdup (v);
-        } else if (g_str_equal (a, "RESOLUTION")) {
-          if (!int_from_string (v, &v, &list->width, 10))
-            debug_warning ("Error while reading RESOLUTION width");
-          if (!v || *v != '=') {
-            debug_warning ("Missing height\n");
-          } else {
-            v = g_utf8_next_char (v);
-            if (!int_from_string (v, NULL, &list->height, 10))
-              debug_warning ("Error while reading RESOLUTION height");
-          }
-        }
-      }
-    } else if (g_str_has_prefix (data, "#EXT-X-TARGETDURATION:")) {
-      if (int_from_string (data + 22, &data, &val, 10))
-        self->targetduration = val;
-       // g_print ("\n\n\t\t#########################\n");
-        //g_print ("\t\tTarget duration = %d\n", val);
-       // g_print ("\n\n\t\t#########################\n");
-
-    } else if (g_str_has_prefix (data, "#EXT-X-MEDIA-SEQUENCE:")) {
-      if (int_from_string (data + 22, &data, &val, 10))
-        self->mediasequence = val;
-    } else if (g_str_has_prefix (data, "#EXT-X-DISCONTINUITY")) {
-      discontinuity = TRUE;
-    } else if (g_str_has_prefix (data, "#EXT-X-PROGRAM-DATE-TIME:")) {
-      /* <YYYY-MM-DDThh:mm:ssZ> */
-      debug_log ("FIXME parse date\n");
-    } else if (g_str_has_prefix (data, "#EXT-X-ALLOW-CACHE:")) {
-      g_free (self->allowcache);
-      self->allowcache = g_strdup (data + 19);
-    } else if (g_str_has_prefix (data, "#EXTINF:")) {
-      if (!int_from_string (data + 8, &data, &val, 10)) {
-        debug_warning ("Can't read EXTINF duration\n");
-        goto next_line;
-      }
-      duration = val;
-      if (duration > self->targetduration)
-        debug_warning ("EXTINF duration > TARGETDURATION\n");
-      if (!data || *data != ',')
-        goto next_line;
-      data = g_utf8_next_char (data);
-      if (data != end) {
-        g_free (title);
-        title = g_strdup (data);
-      }
-    }else if (g_str_has_prefix (data, "#EXT-X-KEY:")){
-      gchar *val, *attr;
-
-       
-      g_print ("\n\n Found EXT-X-KEY tag...\n\n");
-      /* handling encrypted content */
-         
-      data = data + 11; /* skipping "#EXT-X-KEY:" tag */
-         
-      while (data && parse_attributes (&data, &attr, &val)) 
-      {
-        if (g_str_equal (attr, "METHOD")) 
-        {
-          if (g_str_equal (val, "NONE"))
-          {
-            g_print ("Non encrypted file...and skipping current line and going to next line\n");
-            goto next_line;
-          }
-          else if (g_str_equal (val, "AES-128"))
-          {
-            /* media files are encrypted */
-            g_print ("media files are encrypted with AES-128");
-            // TODO: indicate in flag whether encrypted files or not
-          }
-        } 
-        else if (g_str_equal (attr, "URI"))
-        {
-          gchar *end_dq = NULL;
-
-          if (val ==  NULL)
-          {
-               debug_error ("val is NULL");
-               break;
-          }
-          
-          val = val + 1; /* eliminating first double quote in url */
-          if (val ==  NULL)
-          {
-               debug_error ("val is NULL");
-               break;
-          }
-          
-          end_dq = g_utf8_strrchr (val, -1, '"');
-          if (!end_dq)
-          {
-              debug_error ("end_dq is NULL");
-              break;
-          }
-
-          *end_dq = '\0';
-
-          g_print ("Key URI = %s\n", val);
-
-          if (!gst_uri_is_valid (val)) 
-          {
-            gchar *slash;
-            if (!self->uri) 
-            {
-              debug_warning ("uri not set, can't build a valid uri");
-              goto next_line;
-            }
-            slash = g_utf8_strrchr (self->uri, -1, '/');
-            if (!slash) 
-            {
-              debug_warning ("Can't build a valid uri");
-              goto next_line;
-            }
-            *slash = '\0';
-            key_url = g_strdup_printf ("%s/%s", self->uri, val);
-            *slash = '/';
-          } 
-          else
-          {
-            key_url= g_strdup (val);
-          }
-        }
-        else if (g_str_equal (attr, "IV"))
-        {
-          gint iv_len = 0;
-          gchar tmp_byte[3];
-          gint tmp_val = 0;
-          gint idx = 0;
-
-          if (IV)
-          {
-            g_free (IV);
-            IV = NULL;
-          }
-                 
-          IV = g_malloc0 (16);
-          if (NULL == IV)
-          {
-            debug_error ("Failed to allocate memory...\n");
-            return FALSE;
-          }
-          
-          /* eliminating 0x/0X prefix */
-          val = val + 2;
-          iv_len = g_utf8_strlen(val, 0);
-          if (iv_len != 16)
-          {
-            debug_warning ("Wrong IV...");
-            return FALSE;
-          }
-          
-          while (iv_len)
-          {
-               // TODO: val need to incremented I feel.. check again 
-            g_utf8_strncpy(tmp_byte, val, 2);
-            tmp_byte[2] = '\0';
-            tmp_val = 0;
-            if (!int_from_string (tmp_byte, NULL, &tmp_val, 16))
-              debug_warning ("Error while reading PROGRAM-ID");                    
-            IV[idx] = tmp_val; 
-            idx++;
-            iv_len = iv_len - 2;
-            val = val + 2;
-          }
-        }
-      }
-
-#if 0    
-      if (g_str_has_prefix (data, "METHOD="))
-      {
-        data = data + 7;
-        if (g_str_has_prefix (data, "AES-128"))
-        {
-          g_print ("AES-128 encrypted media...\n\n");
-          data = data + 8;
-          if (g_str_has_prefix (data, "URI="))
-          {
-            gchar *dob_qu = NULL;
-            gchar  *tmp_key_url = NULL;
-
-            data = data+5;
-                       
-            dob_qu = g_utf8_strrchr (data, -1, '"');
-            *dob_qu = '\0';
-                       
-            tmp_key_url = g_strdup (data);
-            *dob_qu = '"';     
-            
-            g_print ("URI attribute = %s\n\n", tmp_key_url);
-                       
-            if (!gst_uri_is_valid (tmp_key_url)) 
-            {
-              gchar *slash;
-              if (!self->uri) {
-                debug_warning ("uri not set, can't build a valid uri");
-                goto next_line;
-              }
-              slash = g_utf8_strrchr (self->uri, -1, '/');
-              if (!slash) 
-              {
-                debug_warning ("Can't build a valid uri");
-                goto next_line;
-              }
-
-              *slash = '\0';
-              key_url = g_strdup_printf ("%s/%s", self->uri, tmp_key_url);
-              *slash = '/';
-            } 
-            else
-              key_url = g_strdup (tmp_key_url);
-
-            g_print ("\n\n======= Final key url = %s\n\n\n\n", key_url); 
-
-            data = dob_qu;
-            data = data + 2;
-                
-            if ((g_str_has_prefix (data, "IV=0x")) && (g_str_has_prefix (data, "IV=0X")))
-            {
-              data = data + 5;
-              g_print ("\n\nSize of IV = %d\n\n", sizeof (data));
-              memcpy (IV, data, sizeof (IV));
-            }
-            else
-            {
-              g_print ("\n\n\n Need to generate IV from media sequence...\n\n");
-            }
-          }
-          else
-          {
-            g_print ("No URI specified...\n\n");
-            return FALSE;
-          }
-        }
-        else if (g_str_has_prefix (data, "NONE"))
-        {
-          g_print ("\n\nNot encrypted.....\n\n\n");
-        }
-        else
-        {
-          g_print ("\n\nUnknown EXT-X-KEY METHOD attri = %s\n\n", data);
-          return FALSE;
-        }
-      }
-
-      else
-      {
-        g_print ("\n\nEXT-X-KEY without METHOD attribute...\n\n");
-        return FALSE;
-      }
-#endif
-    }
-    else {
-      debug_warning ("Ignored line: %s", data);
-    }
-
-  next_line:
-    if (!end)
-      break;
-    data = g_utf8_next_char (end);      /* skip \n */
-  }
-
-  /* redorder playlists by bitrate */
-  if (self->lists)
-    self->lists =
-        g_list_sort (self->lists,
-        (GCompareFunc) gst_m3u8_compare_playlist_by_bitrate);
-
-  return TRUE;
-}
-
-GstM3U8Client *
-gst_m3u8_client_new (const gchar * uri)
-{
-  GstM3U8Client *client;
-
-  g_return_val_if_fail (uri != NULL, NULL);
-
-  client = g_new0 (GstM3U8Client, 1);
-  client->main = gst_m3u8_new ();
-  client->current = NULL;
-  client->sequence = -1;
-  client->update_failed_count = 0;
-  gst_m3u8_set_uri (client->main, g_strdup (uri));
-
-  return client;
-}
-
-void
-gst_m3u8_client_free (GstM3U8Client * self)
-{
-  g_return_if_fail (self != NULL);
-
-  gst_m3u8_free (self->main);
-  g_free (self);
-}
-
-void
-gst_m3u8_client_set_current (GstM3U8Client * self, GstM3U8 * m3u8)
-{
-  g_return_if_fail (self != NULL);
-
-  if (m3u8 != self->current) {
-    self->current = m3u8;
-    self->update_failed_count = 0;
-  }
-}
-
-gboolean
-gst_m3u8_client_update (GstM3U8Client * self, gchar * data)
-{
-  GstM3U8 *m3u8;
-  gboolean updated = FALSE;
-
-  g_return_val_if_fail (self != NULL, FALSE);
-
-  m3u8 = self->current ? self->current : self->main;
-
- // g_print ("\n\n");
-
-  if (!gst_m3u8_update (m3u8, data, &updated))
-    return FALSE;
-
- // g_print ("\n\n");
-
-  if (!updated) {
-    self->update_failed_count++;
-    return FALSE;
-  }
-
-  /* select the first playlist, for now */
-  if (!self->current) {
-    if (self->main->lists) {
-      self->current = g_list_first (self->main->lists)->data;
-    } else {
-      self->current = self->main;
-    }
-  }
-
-  if (m3u8->files && self->sequence == -1) {
-    self->sequence =
-        GST_M3U8_MEDIA_FILE (g_list_first (m3u8->files)->data)->sequence;
-     debug_log ("Setting first sequence at %d", self->sequence);
-  }
-
-  return TRUE;
-}
-
-static gboolean
-_find_next (GstM3U8MediaFile * file, GstM3U8Client * client)
-{
-  debug_log ("Found fragment %d\n", file->sequence);
-  if (file->sequence >= client->sequence)
-    return FALSE;
-  return TRUE;
-}
-
-const GstM3U8MediaFile *
-gst_m3u8_client_get_next_fragment (GstM3U8Client * client,
-    gboolean * discontinuity)
-{
-  GList *l;
-  GstM3U8MediaFile *file;
-
-  g_return_val_if_fail (client != NULL, NULL);
-  g_return_val_if_fail (client->current != NULL, NULL);
-  g_return_val_if_fail (discontinuity != NULL, NULL);
-
-  debug_log ("Looking for fragment %d\n", client->sequence);
-  l = g_list_find_custom (client->current->files, client,
-      (GCompareFunc) _find_next);
-  if (l == NULL)
-    return NULL;
-
-  file = GST_M3U8_MEDIA_FILE (l->data);
-
-  *discontinuity = client->sequence != file->sequence;
-  client->sequence = file->sequence + 1;
-
-  return file;
-}
-
-
-const gboolean
-gst_m3u8_client_check_next_fragment (GstM3U8Client * client)
-{
-  gint left_duration = 0;
-
-  g_return_val_if_fail (client != NULL, FALSE);
-  g_return_val_if_fail (client->current != NULL, FALSE);
-
-  GList* cur = g_list_last (client->current->files);
-  while (cur && GST_M3U8_MEDIA_FILE(cur->data)->sequence >= client->sequence)
-  {
-         left_duration += GST_M3U8_MEDIA_FILE(cur->data)->duration;
-         cur = g_list_previous (cur);
-  }
-
-  debug_log ("left duration = [%d], target duration[%d] * 3 = [%d]\n",
-                 left_duration, client->current->targetduration, client->current->targetduration*3);
-
-  return (left_duration > client->current->targetduration*3)? TRUE : FALSE;
-  
-}
index 250ce0b..971f545 100755 (executable)
 ---------------------------------------------------------------------------------------*/
 
 /* It's callback to process whenever there is some changes in PD downloader. */
-static gboolean __pd_download_callback(GstBus *bus, GstMessage *msg, gpointer data);
+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 __mmplayer_pd_post_message(mm_player_t * player, enum MMMessageType msgtype, MMMessageParamType* param);
+static gboolean __pd_downloader_post_message(mm_player_t * player, enum MMMessageType msgtype, MMMessageParamType* param);
 
 /*=======================================================================================
 |  FUNCTION DEFINITIONS                                                                                                                                                              |
 =======================================================================================*/
 static gboolean
-__pd_download_callback(GstBus *bus, GstMessage *msg, gpointer data)
+__pd_downloader_callback(GstBus *bus, GstMessage *msg, gpointer data)
 {
        mm_player_t * player = NULL;
-       mm_player_pd_t *pd_downloader = NULL;
+       mm_player_pd_t *pd = NULL;
        gboolean bret = TRUE;
-       
-       debug_fenter();
+
+       MMPLAYER_FENTER();
 
        /* chech player handle */
        return_val_if_fail ( data, MM_ERROR_INVALID_ARGUMENT );
@@ -54,9 +54,9 @@ __pd_download_callback(GstBus *bus, GstMessage *msg, gpointer data)
        player = MM_PLAYER_CAST((MMHandleType)data);
 
        /* get PD downloader handle */
-       pd_downloader = MM_PLAYER_GET_PD((MMHandleType)data);
+       pd = MM_PLAYER_GET_PD((MMHandleType)data);
 
-       return_val_if_fail ( pd_downloader, MM_ERROR_INVALID_ARGUMENT );
+       return_val_if_fail ( pd, MM_ERROR_INVALID_ARGUMENT );
 
 //     g_print("%s\n", GST_MESSAGE_TYPE_NAME(msg));
 
@@ -64,36 +64,37 @@ __pd_download_callback(GstBus *bus, GstMessage *msg, gpointer data)
        {
                case GST_MESSAGE_EOS:
                        {
-                               debug_log("PD EOS received....\n");
+                               debug_log("PD Downloader EOS received....\n");
 
-                               g_object_set (G_OBJECT (pd_downloader->pushsrc), "eos", TRUE, NULL);
+                               g_object_set (G_OBJECT (pd->playback_pipeline_src), "eos", TRUE, NULL);
 
                                /* notify application that download is completed */
-                               __mmplayer_pd_post_message(player, MM_MESSAGE_PD_DOWNLOADER_END, NULL);
+                               __pd_downloader_post_message(player, MM_MESSAGE_PD_DOWNLOADER_END, NULL);
 
                                #ifdef PD_SELF_DOWNLOAD
-                               _mmplayer_pd_stop ((MMHandleType)data);
+                               _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_downloader->pushsrc), error, 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_downloader->pushsrc, new_msg);
+                               gst_element_post_message (pd->playback_pipeline_src, new_msg);
 
-                               _mmplayer_pd_stop ((MMHandleType)data);
+                               _mmplayer_unrealize_pd_downloader ((MMHandleType)data);
+                               MMPLAYER_FREEIF(debug);
+                               g_error_free( error);
                        }
                        break;
 
@@ -123,7 +124,7 @@ __pd_download_callback(GstBus *bus, GstMessage *msg, gpointer data)
                                break;
 
                        /* we only care about pipeline state changes */
-                       if (GST_MESSAGE_SRC (msg) != GST_OBJECT (pd_downloader->download_pipe))
+                       if (GST_MESSAGE_SRC (msg) != GST_OBJECT (pd->downloader_pipeline))
                                break;
 
                        src_name = gst_object_get_name (msg->src);
@@ -142,7 +143,7 @@ __pd_download_callback(GstBus *bus, GstMessage *msg, gpointer data)
 
                                case GST_STATE_PLAYING:
                                        /* notify application that download is stated */
-                                       __mmplayer_pd_post_message(player, MM_MESSAGE_PD_DOWNLOADER_START, NULL);
+                                       __pd_downloader_post_message(player, MM_MESSAGE_PD_DOWNLOADER_START, NULL);
                                        break;
 
                                default:
@@ -158,27 +159,27 @@ __pd_download_callback(GstBus *bus, GstMessage *msg, gpointer data)
                        gint64 size = 0LL;
 
                        /* get total size  of download file, (bytes) */
-                       if ( ! gst_element_query_duration( pd_downloader->download_pipe, &fmt, &size ) )
+                       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_downloader->pushsrc), err, NULL);
-                               gst_element_post_message (pd_downloader->pushsrc, new_msg);
+                               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_downloader->pushsrc), "eos", TRUE, NULL);
+                               g_object_set (G_OBJECT (pd->playback_pipeline_src), "eos", TRUE, NULL);
 
-                               _mmplayer_pd_stop ((MMHandleType)data);
+                               _mmplayer_unrealize_pd_downloader ((MMHandleType)data);
 
                                debug_error("failed to query total size for download\n");
                                break;
                        }
 
-                       pd_downloader->total_size = size;
+                       pd->total_size = size;
 
                        debug_log("PD total size : %lld bytes\n", size);
                }
@@ -189,15 +190,15 @@ __pd_download_callback(GstBus *bus, GstMessage *msg, gpointer data)
                        break;
        }
 
-       debug_fleave();
+       MMPLAYER_FLEAVE();
 
        return bret;
 }
 
-gboolean
-__mmplayer_pd_post_message(mm_player_t * player, enum MMMessageType msgtype, MMMessageParamType* param)
+
+gboolean __pd_downloader_post_message(mm_player_t * player, enum MMMessageType msgtype, MMMessageParamType* param)
 {
-       debug_fenter();
+       MMPLAYER_FENTER();
 
        return_val_if_fail( player, FALSE );
 
@@ -209,127 +210,114 @@ __mmplayer_pd_post_message(mm_player_t * player, enum MMMessageType msgtype, MMM
 
        player->pd_msg_cb(msgtype, param, player->pd_msg_cb_param);
 
-       debug_fleave();
+       MMPLAYER_FLEAVE();
 
        return TRUE;
 }
 
-gboolean _mmplayer_pd_get_status(MMHandleType handle, guint64 *current_pos, guint64 *total_size)
+
+gboolean _mmplayer_get_pd_downloader_status(MMHandleType handle, guint64 *current_pos, guint64 *total_size)
 {
-       debug_fenter();
+       MMPLAYER_FENTER();
 
-       mm_player_pd_t * pd_downloader = NULL;
+       mm_player_pd_t * pd = NULL;
        guint64 bytes = 0;
 
        return_val_if_fail(handle, MM_ERROR_INVALID_ARGUMENT);
 
-       pd_downloader = MM_PLAYER_GET_PD(handle);
+       pd = MM_PLAYER_GET_PD(handle);
 
-       return_val_if_fail(pd_downloader, MM_ERROR_INVALID_ARGUMENT);
-       return_val_if_fail(pd_downloader->download_pipe, MM_ERROR_INVALID_ARGUMENT);
+       return_val_if_fail(pd, MM_ERROR_INVALID_ARGUMENT);
+       return_val_if_fail(pd->downloader_pipeline, MM_ERROR_PLAYER_INVALID_STATE);
 
-       if ( !pd_downloader->total_size )
+       if ( !pd->total_size )
        {
                debug_warning("not ready to get total size\n");
                return FALSE;
        }
 
-       g_object_get(pd_downloader->download_sink, "current-bytes", &bytes, NULL);
+       g_object_get(pd->downloader_sink, "current-bytes", &bytes, NULL);
 
-       debug_log("PD status : %lld / %lld\n", bytes, pd_downloader->total_size);
+       debug_log("PD status : %lld / %lld\n", bytes, pd->total_size);
 
        *current_pos = bytes;
-       *total_size = pd_downloader->total_size;
+       *total_size = pd->total_size;
 
-       debug_fleave();
+       MMPLAYER_FLEAVE();
 
        return TRUE;
 }
 
-mm_player_pd_t * _mmplayer_pd_create ()
+
+mm_player_pd_t * _mmplayer_create_pd_downloader()
 {
-       debug_fenter();
+       MMPLAYER_FENTER();
 
-       mm_player_pd_t * pd_downloader = NULL;
+       mm_player_pd_t * pd = NULL;
 
        /* create PD handle */
-       pd_downloader = (mm_player_pd_t *) malloc (sizeof (mm_player_pd_t));
-       if ( !pd_downloader )
+       pd = (mm_player_pd_t *) malloc (sizeof (mm_player_pd_t));
+       if ( !pd )
        {
-               debug_error ("Failed to create pd_downloader handle...\n");
+               debug_error ("Failed to create pd downloader handle...\n");
                return FALSE;
        }
+       memset( pd, 0, sizeof (mm_player_pd_t));
 
-       debug_fleave();
+       MMPLAYER_FLEAVE();
 
-       return pd_downloader;
+       return pd;
 }
 
-gboolean _mmplayer_pd_destroy (MMHandleType handle)
+
+gboolean _mmplayer_destroy_pd_downloader (MMHandleType handle)
 {
-       debug_fenter();
+       MMPLAYER_FENTER();
 
-       mm_player_pd_t * pd_downloader = NULL;
+       mm_player_pd_t * pd = NULL;
 
        return_val_if_fail ( handle, MM_ERROR_INVALID_ARGUMENT );
 
-       pd_downloader = MM_PLAYER_GET_PD(handle);
+       pd = MM_PLAYER_GET_PD(handle);
 
-       if (pd_downloader->download_pipe)
-               _mmplayer_pd_stop (handle);
+       if (pd && pd->downloader_pipeline)
+               _mmplayer_unrealize_pd_downloader (handle);
 
        /* release PD handle */
-       MMPLAYER_FREEIF(pd_downloader);
+       MMPLAYER_FREEIF(pd);
 
-       debug_fleave();
+       MMPLAYER_FLEAVE();
 
        return TRUE;
 }
 
-gboolean _mmplayer_pd_initialize (MMHandleType handle, gchar *src_uri, gchar *dst_uri, GstElement *pushsrc)
+
+gboolean _mmplayer_realize_pd_downloader (MMHandleType handle, gchar *src_uri, gchar *dst_uri, GstElement *pushsrc)
 {
-       debug_fenter();
+       MMPLAYER_FENTER();
 
-       mm_player_pd_t * pd_downloader = NULL;
+       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_downloader = MM_PLAYER_GET_PD(handle);
+       pd = MM_PLAYER_GET_PD(handle);
 
        /* initialize */
-       pd_downloader->uri_to_download = g_strdup (src_uri);
-       pd_downloader->uri_to_save = g_strdup (dst_uri);
-       pd_downloader->pushsrc = pushsrc;
-       pd_downloader->total_size = 0LL;
-
-       debug_fleave();
-       
-       return TRUE;
-}
-
-gboolean _mmplayer_pd_deinitialize (MMHandleType handle)
-{
-       debug_fenter();
+       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;
 
-       mm_player_pd_t * pd_downloader = NULL;
-
-       return_val_if_fail ( handle, MM_ERROR_INVALID_ARGUMENT );
-
-       pd_downloader = MM_PLAYER_GET_PD(handle);
-
-       /* free */
-       MMPLAYER_FREEIF(pd_downloader->uri_to_download);
-       MMPLAYER_FREEIF(pd_downloader->uri_to_save);
-
-       debug_fleave(); 
+       MMPLAYER_FLEAVE();
 
        return TRUE;
 }
 
-gboolean _mmplayer_pd_start (MMHandleType handle)
+
+gboolean _mmplayer_start_pd_downloader (MMHandleType handle)
 {
        GstBus* bus = NULL;
        gboolean bret = FALSE;
@@ -337,75 +325,75 @@ gboolean _mmplayer_pd_start (MMHandleType handle)
        GstState cur_state;
        GstState pending_state;
 
-       debug_fenter();
+       MMPLAYER_FENTER();
 
-       mm_player_pd_t * pd_downloader = NULL;
+       mm_player_pd_t * pd = NULL;
 
        return_val_if_fail ( handle, MM_ERROR_INVALID_ARGUMENT );
 
-       pd_downloader = MM_PLAYER_GET_PD(handle);
+       pd = MM_PLAYER_GET_PD(handle);
 
        /* pipeline */
-       pd_downloader->download_pipe = gst_pipeline_new ("PD Downloader");
-       if (NULL == pd_downloader->download_pipe)
+       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->download_src = gst_element_factory_make ("souphttpsrc", "PD HTTP download source");
-       if (NULL == pd_downloader->download_src)
+       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->download_queue = gst_element_factory_make ("queue", "PD download queue");
-       if (NULL == pd_downloader->download_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->download_sink = gst_element_factory_make ("filesink", "PD download sink");
-       if (NULL == pd_downloader->download_sink)
+       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->download_sink, "sync", FALSE, NULL);
-       
+       g_object_set(pd->downloader_sink, "sync", FALSE, NULL);
+
        /* Add to bin and link */
-       gst_bin_add_many (GST_BIN (pd_downloader->download_pipe), 
-                                       pd_downloader->download_src, pd_downloader->download_queue, pd_downloader->download_sink,
+       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->download_src, pd_downloader->download_queue, pd_downloader->download_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->download_pipe));
-       gst_bus_add_watch (bus, __pd_download_callback, (gpointer)handle);
+       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->download_src), "location", pd_downloader->uri_to_download, NULL);
+       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->download_sink), "location", pd_downloader->uri_to_save, NULL);
+       g_object_set (G_OBJECT (pd->downloader_sink), "location", pd->location_to_save, NULL);
 
-       debug_log ("src location = %s, save location = %s\n", pd_downloader->uri_to_download, pd_downloader->uri_to_save);
+       secure_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->download_pipe, GST_STATE_PLAYING);
+       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...");
@@ -414,7 +402,7 @@ gboolean _mmplayer_pd_start (MMHandleType handle)
 
        debug_log ("set_state :: sret = %d\n", sret);
 
-       sret = gst_element_get_state (pd_downloader->download_pipe, &cur_state, &pending_state, GST_CLOCK_TIME_NONE);
+       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...");
@@ -423,36 +411,43 @@ gboolean _mmplayer_pd_start (MMHandleType handle)
 
        debug_log ("get-state :: sret = %d\n", sret);
 
-       debug_fleave();
+       MMPLAYER_FLEAVE();
 
        return TRUE;
 }
 
-gboolean _mmplayer_pd_stop (MMHandleType handle)
+
+gboolean _mmplayer_unrealize_pd_downloader (MMHandleType handle)
 {
-       debug_fenter();
+       MMPLAYER_FENTER();
 
-       mm_player_pd_t * pd_downloader = NULL;
+       mm_player_pd_t * pd = NULL;
 
-       return_val_if_fail ( handle, MM_ERROR_INVALID_ARGUMENT );
+       return_val_if_fail ( handle, FALSE );
 
-       pd_downloader = MM_PLAYER_GET_PD(handle);
+       pd = MM_PLAYER_GET_PD(handle);
 
-       return_val_if_fail ( pd_downloader->download_pipe, MM_ERROR_INVALID_ARGUMENT );
+       return_val_if_fail ( pd && pd->downloader_pipeline, FALSE );
 
-       gst_element_set_state (pd_downloader->download_pipe, GST_STATE_NULL);
-       gst_element_get_state (pd_downloader->download_pipe, NULL, NULL, GST_CLOCK_TIME_NONE);
+       gst_element_set_state (pd->downloader_pipeline, GST_STATE_NULL);
+       gst_element_get_state (pd->downloader_pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
 
-       pd_downloader->download_pipe = NULL;
+       gst_object_unref (G_OBJECT (pd->downloader_pipeline));
+       pd->downloader_pipeline = NULL;
 
-       debug_fleave();
+       /* free */
+       MMPLAYER_FREEIF(pd->path_read_from);
+       MMPLAYER_FREEIF(pd->location_to_save);
+
+       MMPLAYER_FLEAVE();
 
        return TRUE;
 }
 
-gint _mm_player_set_pd_message_callback(MMHandleType handle, MMMessageCallback callback, gpointer user_param)
+
+gint _mm_player_set_pd_downloader_message_cb(MMHandleType handle, MMMessageCallback callback, gpointer user_param)
 {
-       debug_fenter();
+       MMPLAYER_FENTER();
 
        mm_player_t * player = NULL;
 
@@ -468,7 +463,7 @@ gint _mm_player_set_pd_message_callback(MMHandleType handle, MMMessageCallback c
 
        debug_log("msg_cb : 0x%x     msg_cb_param : 0x%x\n", (guint)callback, (guint)user_param);
 
-       debug_fleave();
+       MMPLAYER_FLEAVE();
 
        return MM_ERROR_NONE;
 }
index 6c07122..cf0dc40 100755 (executable)
@@ -33,6 +33,7 @@
 #include <string.h>
 #include <sys/time.h>
 #include <stdlib.h>
+#include <utilX.h>
 
 #include <mm_error.h>
 #include <mm_attrs.h>
 #include "mm_player_ini.h"
 #include "mm_player_attrs.h"
 #include "mm_player_capture.h"
+#include "mm_player_utils.h"
+#include <sched.h>
+
+#include <mm_sound.h>
+
+#define MM_SMOOTH_STREAMING
 
 /*===========================================================================================
 |                                                                                                                                                                                      |
@@ -69,8 +76,8 @@
 #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_VOLUME_FACTOR_MIN                   0
+#define MM_VOLUME_FACTOR_MAX                   1.0
 
 #define MM_PLAYER_FADEOUT_TIME_DEFAULT 700000 // 700 msec
 
 #define MM_PLAYER_WMA_VNAME                            "wmaversion"
 
 #define DEFAULT_PLAYBACK_RATE                  1.0
+#define PLAYBACK_RATE_EX_AUDIO_MIN             0.5
+#define PLAYBACK_RATE_EX_AUDIO_MAX             2.0
+#define PLAYBACK_RATE_EX_VIDEO_MIN             0.5
+#define PLAYBACK_RATE_EX_VIDEO_MAX             1.5
 
-#define GST_QUEUE_DEFAULT_TIME                 2
+#define GST_QUEUE_DEFAULT_TIME                 4
 #define GST_QUEUE_HLS_TIME                             8
 
+#define DEFAULT_AUDIO_CH                               0
+
 /* 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 MMPLAYER_PLAY_SUBTITLE(player) ((player)->play_subtitle)
+#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
+#define MM_PLAYER_NAME "mmplayer"
 
-#define        LAZY_PAUSE_TIMEOUT_MSEC 700     
+//#define ENABLE_DRMSRC
 
 /*---------------------------------------------------------------------------
 |    LOCAL CONSTANT DEFINITIONS:                                                                                       |
@@ -111,84 +126,110 @@ gulong ahs_appsrc_cb_probe_id = 0;
 /*---------------------------------------------------------------------------
 |    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);
+static int             __mmplayer_set_state(mm_player_t* player, int state);
+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_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_gst_selector_blocked(GstPad* pad, gboolean blocked, gpointer data);
+static void            __mmplayer_gst_decode_pad_added(GstElement* elem, GstPad* pad, gpointer data);
+static void    __mmplayer_gst_decode_no_more_pads(GstElement* elem, gpointer data);
+static void    __mmplayer_gst_decode_callback(GstElement *decodebin, GstPad *pad, gpointer data);
+static void            __mmplayer_gst_decode_unknown_type(GstElement *elem,  GstPad* pad, GstCaps *caps, gpointer data);
+static gboolean __mmplayer_gst_decode_autoplug_continue(GstElement *bin,  GstPad* pad, GstCaps * caps,  gpointer data);
+static gint __mmplayer_gst_decode_autoplug_select(GstElement *bin,  GstPad* pad, GstCaps * caps, GstElementFactory* factory, gpointer data);
+//static GValueArray* __mmplayer_gst_decode_autoplug_factories(GstElement *bin,  GstPad* pad, GstCaps * caps,  gpointer data);
+static GValueArray* __mmplayer_gst_decode_autoplug_sort(GstElement *bin,  GstPad* pad, GstCaps * caps, GValueArray *factories, gpointer data);
+static void __mmplayer_gst_decode_pad_removed(GstElement *elem,  GstPad* new_pad, gpointer data);
+static void __mmplayer_gst_decode_drained(GstElement *bin, gpointer data);
+static void    __mmplayer_gst_element_added(GstElement* bin, GstElement* element, gpointer data);
+static GstElement * __mmplayer_create_decodebin(mm_player_t* player);
+static gboolean __mmplayer_try_to_plug_decodebin(mm_player_t* player, GstPad *srcpad, const GstCaps *caps);
 
 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_is_omx_decoder_type(mm_player_t* player); // mp3
+static void    __mmplayer_set_audio_attrs(mm_player_t* player, GstCaps* caps);
+//static void  __mmplayer_check_video_zero_cpoy(mm_player_t* player, GstElementFactory* factory);
 
 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_wfd_dynamic_pad (GstElement *element, GstPad *pad, 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_get_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 void            __mmplayer_release_misc(mm_player_t* player);
+static void            __mmplayer_release_misc_post(mm_player_t* player);
+static gboolean        __mmplayer_init_gstreamer(mm_player_t* player);
 
 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);
+static gboolean      __mmplayer_gst_handle_duration(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_video_stream_probe (GstPad *pad, GstBuffer *buffer, gpointer u_data);
+static gboolean __mmplayer_subtitle_adjust_position_probe(GstPad *pad, GstBuffer *buffer, gpointer u_data);
+static int __mmplayer_change_selector_pad (mm_player_t* player, MMPlayerTrackType type, int index);
 
 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 void            __mmplayer_handle_eos_delay( mm_player_t* player, int delay_in_ms );
+static void    __mmplayer_cancel_eos_timer( 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 int     __mmplayer_handle_missed_plugin(mm_player_t* player);
+static int             __mmplayer_check_not_supported_codec(mm_player_t* player, const gchar* factory_class, const 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_release_signal_connection(mm_player_t* player);
+static void    __mmplayer_del_sink( mm_player_t* player, GstElement* sink);
+static void    __mmplayer_release_signal_connection(mm_player_t* player, MMPlayerSignalType type);
 static void __mmplayer_set_antishock( mm_player_t* player, gboolean disable_by_force);
+static gpointer __mmplayer_next_play_thread(gpointer data);
 static gpointer __mmplayer_repeat_thread(gpointer data);
-int _mmplayer_get_track_count(MMHandleType hplayer,  MMPlayerTrackType track_type, int *count);
+static gboolean _mmplayer_update_content_attrs(mm_player_t* player, enum content_attr_flag flag);
+
+
+static gboolean __mmplayer_add_dump_buffer_probe(mm_player_t *player, GstElement *element);
+static gboolean __mmplayer_dump_buffer_probe_cb(GstPad *pad, GstBuffer *buffer, gpointer u_data);
+static void __mmplayer_release_dump_list (GList *dump_list);
 
 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);
-int            __gst_pause(mm_player_t* player, gboolean async);
-int            __gst_resume(mm_player_t* player, gboolean async);
+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);
+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 );
@@ -197,7 +238,6 @@ static gint         __gst_handle_stream_error( mm_player_t* player, GError* error, GstM
 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_get_video_frame_from_buffer(mm_player_t* player, GstBuffer *buffer);
 static int __mmplayer_set_pcm_extraction(mm_player_t* player);
 static gboolean __mmplayer_can_extract_pcm( mm_player_t* player );
 
@@ -207,20 +247,52 @@ 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);
-static void __mmplayer_set_videosink_type(mm_player_t* player);
 
 /* 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_wfd_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_dash_streaming( mm_player_t* player );
+static gboolean __is_smooth_streaming( mm_player_t* player );
 static gboolean __is_http_progressive_down(mm_player_t* player);
+static gboolean __has_suffix(mm_player_t * player, const gchar * suffix);
 
-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);
+static int __mmplayer_do_change_videosink(mm_player_t* player, const int dec_index, const char *videosink_element, MMDisplaySurfaceType surface_type, void *display_overlay);
+static void __mmplayer_remove_g_source_from_context(GMainContext *context, guint source_id);
+
+static gboolean __mmplayer_verify_next_play_path(mm_player_t *player);
+static void __mmplayer_activate_next_source(mm_player_t *player, GstState target);
+static void __mmplayer_check_pipeline(mm_player_t* player);
+static gboolean __mmplayer_deactivate_selector(mm_player_t *player, MMPlayerTrackType type);
+static void __mmplayer_deactivate_old_path(mm_player_t *player);
+static int __mmplayer_ignore_current_external_display_mode(mm_player_t* player);
+#if 0 // We'll need this in future.
+static int __mmplayer_gst_switching_element(mm_player_t *player, GstElement *search_from, const gchar *removal_name, const gchar *new_element_name);
+#endif
+
+static void __mmplayer_update_buffer_setting(mm_player_t *player, GstMessage *buffering_msg);
+static GstElement *__mmplayer_element_create_and_link(mm_player_t *player, GstPad* pad, const char* name);
+static gboolean __mmplayer_can_do_interrupt(mm_player_t *player);
+
+/* device change post proc */
+void __mmplayer_device_change_post_process(gpointer user);
+void __mmplayer_set_required_cb_score(mm_player_t* player, guint score);
+void __mmplayer_inc_cb_score(mm_player_t* player);
+void __mmplayer_post_proc_reset(mm_player_t* player);
+void __mmplayer_device_change_trigger_post_process(mm_player_t* player);
+static int __mmplayer_gst_create_plain_text_elements(mm_player_t* player);
+
+
 /*===========================================================================================
 |                                                                                                                                                                                      |
 |  FUNCTION DEFINITIONS                                                                                                                                                |
@@ -234,28 +306,26 @@ __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();
+//     MMPlayerStateType target_state = MM_PLAYER_STATE_NUM;
+//     MMPlayerStateType prev_state = MM_PLAYER_STATE_NUM;
 
        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);
+//     target_state = MMPLAYER_TARGET_STATE(player);
+//     prev_state = MMPLAYER_PREV_STATE(player);
 
        MMPLAYER_PRINT_STATE(player);
 
-       debug_log("incomming command : %d", command );
-
        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 ||
@@ -334,7 +404,7 @@ __mmplayer_check_state(mm_player_t* player, enum PlayerCommandState command)
 
                        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 )
@@ -376,8 +446,6 @@ __mmplayer_check_state(mm_player_t* player, enum PlayerCommandState command)
 
                case MMPLAYER_COMMAND_RESUME:
                {
-                       if ( MMPLAYER_IS_LIVE_STREAMING(player) )
-                               goto NO_OP;
 
                        if (player->doing_seek)
                                goto NOT_COMPLETED_SEEK;
@@ -409,20 +477,17 @@ __mmplayer_check_state(mm_player_t* player, enum PlayerCommandState command)
                default:
                break;
        }
-
-       debug_log("status OK\n");
        player->cmd = command;
 
-       debug_fenter();
        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:
@@ -441,22 +506,26 @@ __mmplayer_gst_set_state (mm_player_t* player, GstElement * element,  GstState s
        GstState element_pending_state = GST_STATE_VOID_PENDING;
        GstStateChangeReturn ret = GST_STATE_CHANGE_FAILURE;
 
-       debug_fenter();
-       
+       MMPLAYER_FENTER();
+
        return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
        return_val_if_fail ( element, MM_ERROR_INVALID_ARGUMENT );
 
-       debug_log("setting [%s] state to : %d\n", GST_ELEMENT_NAME(element),  state);
+       debug_log("setting [%s] element state to : %s\n", GST_ELEMENT_NAME(element), gst_element_state_get_name(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);
+               debug_error("failed to set [%s] state\n", GST_ELEMENT_NAME(element));
+
+               /* dump state of all element */
+               __mmplayer_dump_pipeline_state( player );
+
                return MM_ERROR_PLAYER_INTERNAL;
        }
-       
+
        /* return here so state transition to be done in async mode */
        if ( async )
        {
@@ -469,9188 +538,14143 @@ __mmplayer_gst_set_state (mm_player_t* player, GstElement * element,  GstState s
 
        if ( ret == GST_STATE_CHANGE_FAILURE || ( state != element_state ) )
        {
-               debug_error("failed to change [%s] state to [%s] within %d sec\n",
-                       GST_ELEMENT_NAME(element), 
+               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), 
+
+               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) );
 
+               /* dump state of all element */
+               __mmplayer_dump_pipeline_state( player );
+
                return MM_ERROR_PLAYER_INTERNAL;
        }
 
-       debug_log("[%s] state has changed to %s \n", 
-               GST_ELEMENT_NAME(element), 
-               gst_element_state_get_name(element_state));
+       debug_log("[%s] element state has changed\n", GST_ELEMENT_NAME(element));
+
+       MMPLAYER_FLEAVE();
 
-       debug_fleave();
-       
        return MM_ERROR_NONE;
 }
 
-
 static void
-__mmplayer_videostream_cb(GstElement *element, void *stream,
-int width, int height, gpointer data) // @
+__mmplayer_videostream_cb(GstElement *element, void *data,
+int width, int height, gpointer user_data) // @
 {
-       mm_player_t* player = (mm_player_t*)data;
-       int length = 0;
+       mm_player_t* player = (mm_player_t*)user_data;
 
        return_if_fail ( player );
 
-       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);
-       }
-}
-
-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 );
+       MMPLAYER_FENTER();
 
-       if ( ! player->need_update_content_attrs )
+       if (player->is_drm_file)
        {
-               debug_log("content attributes are already updated");
-               return TRUE;
+               MMMessageParamType msg_param = { 0, };
+               debug_warning("not supported in drm file");
+               msg_param.code = MM_ERROR_PLAYER_DRM_OUTPUT_PROTECTION;
+               MMPLAYER_POST_MSG( player, MM_MESSAGE_ERROR, &msg_param );
        }
-
-       /* get content attribute first */
-       attrs = MMPLAYER_GET_ATTRS(player);
-       if ( !attrs )
+       else if ( !player->set_mode.media_packet_video_stream && player->video_stream_cb)
        {
-               debug_error("cannot get content attribute");
-               return FALSE;
-       }
+               MMPlayerVideoStreamDataType stream;
 
-       /* 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;
-                       }
+               /* clear stream data structure */
+               memset(&stream, 0x0, sizeof(MMPlayerVideoStreamDataType));
 
-                       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;
-                       }
+               stream.data = data;
+               stream.length_total = width * height * 4; // for rgb 32bit
+               stream.height = height;
+               stream.width = width;
+               player->video_stream_cb(&stream, player->video_stream_cb_user_param);
+       }
 
-                       break;
-               }
+       MMPLAYER_FLEAVE();
+}
 
-               player->duration = dur_nsec;
-               debug_log("duration : %lld msec", GST_TIME_AS_MSECONDS(dur_nsec));
+static void
+__mmplayer_videoframe_render_error_cb(GstElement *element, void *error_id, gpointer data)
+{
+       mm_player_t* player = (mm_player_t*)data;
 
-               /* try to get streaming service type */
-               __mmplayer_update_stream_service_type( player );
+       return_if_fail ( player );
 
-               /* check duration is OK */
-               if ( dur_nsec == 0 && !MMPLAYER_IS_LIVE_STREAMING( player ) )
+       MMPLAYER_FENTER();
+
+       if (player->video_frame_render_error_cb )
+       {
+               if (player->attrs)
                {
-                       /* FIXIT : find another way to get duration here. */
-                       debug_error("finally it's failed to get duration from pipeline. progressbar will not work correctely!");
+                       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
                {
-                       player->need_update_content_dur = FALSE;
+                       debug_error("could not get surface type");
                }
-
-               /*update duration */
-               mm_attrs_set_int_by_name(attrs, "content_duration", GST_TIME_AS_MSECONDS(dur_nsec));
        }
        else
        {
-               debug_log("no ready to get or content duration already updated");
+               debug_warning("video_frame_render_error_cb was not set");
        }
 
-       /* 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;
+       MMPLAYER_FLEAVE();
+}
 
-               pad = gst_element_get_static_pad(
-                               player->pipeline->audiobin[MMPLAYER_A_CONV].gst, "sink" );
+void
+__mmplayer_device_change_post_process(gpointer user)
+{
+       mm_player_t* player = (mm_player_t*)user;
+       unsigned long position = 0;
+       MMPlayerStateType current_state = MM_PLAYER_STATE_NONE;
+       MMPlayerStateType pending_state = MM_PLAYER_STATE_NONE;
 
-               if ( pad )
-               {
-                       caps_a = gst_pad_get_negotiated_caps( pad );
+       MMPLAYER_FENTER();
 
-                       if ( caps_a )
-                       {
-                               p = gst_caps_get_structure (caps_a, 0);
+       if (! player ||
+               ! player->pipeline ||
+               ! player->pipeline->mainbin ||
+               ! player->pipeline->mainbin[MMPLAYER_M_PIPE].gst )
+       {
+               goto EXIT;
+       }
 
-                               gst_structure_get_int (p, "rate", &samplerate);
-                               mm_attrs_set_int_by_name(attrs, "content_audio_samplerate", samplerate);
+       current_state = MMPLAYER_CURRENT_STATE(player);
+       pending_state = MMPLAYER_PENDING_STATE(player);
 
-                               gst_structure_get_int (p, "channels", &channels);
-                               mm_attrs_set_int_by_name(attrs, "content_audio_channels", channels);
-                               gst_caps_unref( caps_a );
-                                       caps_a = NULL;
+       if (player->post_proc.need_pause_and_resume)
+       {
+               debug_log("pausing");
+               if ((pending_state == MM_PLAYER_STATE_PLAYING) ||
+                       ((pending_state == MM_PLAYER_STATE_NONE) && (current_state != MM_PLAYER_STATE_PAUSED)))
+                       gst_element_set_state(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_PAUSED);
+       }
 
-                               debug_log("samplerate : %d      channels : %d", samplerate, channels);
-                       }
-                       else
-                       {
-                               debug_warning("not ready to get audio caps");
-                       }
+       /* seek should be done within pause and resume */
+       if (player->post_proc.need_seek)
+       {
+               debug_log("seeking");
+               __gst_get_position(player, MM_PLAYER_POS_FORMAT_TIME, &position);
+               debug_log(">> seek to current position = %ld ms", position);
+               __gst_set_position(player, MM_PLAYER_POS_FORMAT_TIME, position, TRUE);
+       }
 
-                       gst_object_unref( pad );
-               }
-               else
-               {
-                       debug_warning("failed to get pad from audiosink");
-               }
+       if (player->post_proc.need_pause_and_resume)
+       {
+               debug_log("resuming");
+               if ((pending_state == MM_PLAYER_STATE_PLAYING) ||
+                       ((pending_state == MM_PLAYER_STATE_NONE) && (current_state != MM_PLAYER_STATE_PAUSED)))
+                       gst_element_set_state(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_PLAYING);
        }
 
-       /* update width, height, framerate */
-       if ( player->pipeline->videobin &&
-                player->pipeline->videobin[MMPLAYER_V_SINK].gst )
+       /* async */
+       if (player->post_proc.need_async)
        {
-               GstCaps *caps_v = NULL;
-               GstPad* pad = NULL;
-               gint tmpNu, tmpDe;
-               gint width, height;
+               debug_log("setting async");
+               debug_log(">> player->display_stat = %d", player->display_stat);
 
-               if (player->use_multi_surface)
+               if ((player->display_stat == MMPLAYER_DISPLAY_STATUS_HDMI_ACTIVE) ||
+                       (player->display_stat == MMPLAYER_DISPLAY_STATUS_UNKNOWN_ACTIVE))
                {
-                       /* NOTE : if v_stream_caps were deprecated, it might be implemented by using "pad-added" signal callback */
-                       if (player->v_stream_caps)
-                       {
-                               caps_v = player->v_stream_caps;
-                               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);
+                       g_object_set(G_OBJECT(player->pipeline->textbin[MMPLAYER_T_VIDEO_SINK].gst), "async", TRUE, NULL);
+               }
+               /* TODO : need some comment here */
+               else if (player->display_stat == MMPLAYER_DISPLAY_STATUS_NULL)
+               {
+                       g_object_set (G_OBJECT (player->pipeline->textbin[MMPLAYER_T_FAKE_SINK].gst), "async", TRUE, NULL);
+               }
+       }
 
-                               gst_structure_get_int (p, "height", &height);
-                               mm_attrs_set_int_by_name(attrs, "content_video_height", height);
+EXIT:
+       /* reset all */
+       __mmplayer_post_proc_reset(player);
+       return;
+}
 
-                               gst_structure_get_fraction (p, "framerate", &tmpNu, &tmpDe);
+void __mmplayer_set_required_cb_score(mm_player_t* player, guint score)
+{
+       return_if_fail(player);
+       player->post_proc.required_cb_score = score;
+       debug_log("set required score to : %d", score);
+}
 
-                               debug_log("width : %d     height : %d", width, height );
+void __mmplayer_inc_cb_score(mm_player_t* player)
+{
+       return_if_fail(player);
+       player->post_proc.cb_score++;
+       debug_log("post proc cb score increased to %d", player->post_proc.cb_score);
+}
 
-                               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 caps from v_stream_caps when using multi-surface");
-                       }
-               }
-               else
+void __mmplayer_post_proc_reset(mm_player_t* player)
+{
+       return_if_fail(player);
+
+       /* check if already triggered */
+       if (player->post_proc.id)
+       {
+               /* TODO : need to consider multiple main context. !!!! */
+               if (FALSE == g_source_remove(player->post_proc.id) )
                {
-                       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);
+                       debug_error("failed to remove exist post_proc item");
+               }
+               player->post_proc.id = 0;
+       }
 
-                                       gst_structure_get_int (p, "height", &height);
-                                       mm_attrs_set_int_by_name(attrs, "content_video_height", height);
+       memset(&player->post_proc, 0, sizeof(mm_player_post_proc_t));
 
-                                       gst_structure_get_fraction (p, "framerate", &tmpNu, &tmpDe);
+       /* set default required cb score 1 as only audio device has changed in this case.
+          if display status is changed with audio device, required cb score is set 2 in display status callback.
+          this logic bases on the assumption which audio device callback is called after calling display status callback. */
+       player->post_proc.required_cb_score = 1;
+}
 
-                                       debug_log("width : %d     height : %d", width, height );
+void
+__mmplayer_device_change_trigger_post_process(mm_player_t* player)
+{
+       return_if_fail(player);
 
-                                       gst_caps_unref( caps_v );
-                                       caps_v = NULL;
+       /* check score */
+       if ( player->post_proc.cb_score < player->post_proc.required_cb_score )
+       {
+               /* wait for next turn */
+               debug_log("wait for next turn. required cb score : %d   current score : %d\n",
+                       player->post_proc.required_cb_score, player->post_proc.cb_score);
+               return;
+       }
 
-                                       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");
-                               }
-                               if (!player->use_multi_surface)
-                               {
-                                       gst_object_unref( pad );
-                                       pad = NULL;
-                               }
-                       }
-                       else
-                       {
-                               debug_warning("failed to get pad from videosink");
-                       }
+       /* check if already triggered */
+       if (player->post_proc.id)
+       {
+               /* TODO : need to consider multiple main context. !!!! */
+               if (FALSE == g_source_remove(player->post_proc.id) )
+               {
+                       debug_error("failed to remove exist post_proc item");
                }
+               player->post_proc.id = 0;
        }
 
-       if (player->duration)
-       {
-               guint64 data_size = 0;
+       player->post_proc.id = g_idle_add((GSourceFunc)__mmplayer_device_change_post_process, (gpointer)player);
+}
 
-               if (!MMPLAYER_IS_STREAMING(player) && (player->can_support_codec & FOUND_PLUGIN_VIDEO))
-               {
-                       mm_attrs_get_string_by_name(attrs, "profile_uri", &path);
+/* NOTE : Sound module has different latency according to output device So,
+ * synchronization problem can be happened whenever device is changed.
+ * To avoid this issue, we do reset avsystem or seek as workaroud.
+ */
+static void
+__mmplayer_sound_device_info_changed_cb_func (MMSoundDevice_t device_h, int changed_info_type, void *user_data)
+{
+    int ret;
+    mm_sound_device_type_e device_type;
+       mm_player_t* player = (mm_player_t*) user_data;
 
-                       if (stat(path, &sb) == 0)
-                       {
-                               data_size = (guint64)sb.st_size;
-                       }
-               }
-               else if (MMPLAYER_IS_HTTP_STREAMING(player))
-               {
-                       data_size = player->http_content_size;
-               }
+       return_if_fail( player );
 
-               if (data_size)
-               {
-                       guint64 bitrate = 0;
-                       guint64 msec_dur = 0;
+       debug_warning("device_info_changed_cb is called, device_h[0x%x], changed_info_type[%d]\n", device_h, changed_info_type);
 
-                       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);
-               }
-       }
+       __mmplayer_inc_cb_score(player);
 
+       /* get device type with device_h*/
+       ret = mm_sound_get_device_type(device_h, &device_type);
+       if (ret) {
+               debug_error("failed to mm_sound_get_device_type()\n");
+       }
 
-       /* validate all */
-       if (  mmf_attrs_commit ( attrs ) )
+       /* do pause and resume only if video is playing  */
+       if ( player->videodec_linked && MMPLAYER_CURRENT_STATE(player) == MM_PLAYER_STATE_PLAYING )
        {
-               debug_error("failed to update attributes\n");
-               return FALSE;
-       }
+               switch (device_type)
+               {
+                       case MM_SOUND_DEVICE_TYPE_BLUETOOTH:
+                       case MM_SOUND_DEVICE_TYPE_AUDIOJACK:
+                       case MM_SOUND_DEVICE_TYPE_BUILTIN_SPEAKER:
+                       case MM_SOUND_DEVICE_TYPE_HDMI:
+                       case MM_SOUND_DEVICE_TYPE_MIRRORING:
+                       {
+                               player->post_proc.need_pause_and_resume = TRUE;
+                       }
+                       break;
 
-       player->need_update_content_attrs = FALSE;
+                       default:
+                               debug_log("do nothing");
+               }
+       }
+       debug_warning("dispatched");
 
-       return TRUE;
+       __mmplayer_device_change_trigger_post_process(player);
 }
 
-gboolean __mmplayer_update_stream_service_type( mm_player_t* player )
+static void
+__mmplayer_display_status_cb(GstElement *element, MMPlayerDisplayStatus stat, gpointer data)
 {
-       MMHandleType attrs = 0;
-       gint streaming_type = STREAMING_SERVICE_NONE;
-
-       debug_fenter();
+       mm_player_t* player = (mm_player_t*)data;
+       return_if_fail ( player );
+       MMPLAYER_FENTER();
 
-       return_val_if_fail ( player &&
-                                       player->pipeline &&
-                                       player->pipeline->mainbin &&
-                                       player->pipeline->mainbin[MMPLAYER_M_SRC].gst,
-                                       FALSE );
+       guint required_cb_score = 2;
 
-       /* streaming service type if streaming */
-       if ( ! MMPLAYER_IS_STREAMING(player) );
-               return FALSE;
+       __mmplayer_inc_cb_score(player);
+       __mmplayer_set_required_cb_score(player, required_cb_score);
 
-       if (MMPLAYER_IS_RTSP_STREAMING(player))
+       if ((player->pipeline->textbin == NULL) ||
+               (player->pipeline->textbin[MMPLAYER_T_TEXT_FAKE_IDENTITY].gst == NULL) ||
+               (player->pipeline->textbin[MMPLAYER_T_TEXT_IDENTITY].gst == NULL) ||
+               (player->pipeline->textbin[MMPLAYER_T_VIDEO_SINK].gst == NULL))
        {
-               /* get property from rtspsrc element */
-               g_object_get(G_OBJECT(player->pipeline->mainbin[MMPLAYER_M_SRC].gst), "service_type", &streaming_type, NULL);
+               debug_warning("text bin is not ready yet");
+               goto EXIT;
        }
-       else if (MMPLAYER_IS_HTTP_STREAMING(player))
+
+       if (player->is_subtitle_force_drop == TRUE)
        {
-               if ( player->duration <= 0)
-                       streaming_type = STREAMING_SERVICE_LIVE;
-               else
-                       streaming_type = STREAMING_SERVICE_VOD;                 
+               debug_warning("subtitle is dropping");
+               player->display_stat = stat;
+               goto EXIT;
        }
-               
-       player->streaming_type = streaming_type;
 
-       if ( player->streaming_type == STREAMING_SERVICE_LIVE)
+       if (stat != util_get_is_connected_external_display())
        {
-               debug_log("It's live streaming. pause/resume/seek are not working.\n");
+               debug_warning("stat is wrong!! (%d from xvimagesink)", stat);
+               goto EXIT;
        }
-       else if (player->streaming_type == STREAMING_SERVICE_LIVE)
+
+       if ((stat == MMPLAYER_DISPLAY_STATUS_HDMI_ACTIVE) || (stat == MMPLAYER_DISPLAY_STATUS_UNKNOWN_ACTIVE))
        {
-               debug_log("It's vod streaming. pause/resume/seek are working.\n");
+               MMMessageParamType msg = {0, };
+               g_object_set (G_OBJECT (player->pipeline->textbin[MMPLAYER_T_TEXT_FAKE_IDENTITY].gst), "drop-probability", (gfloat)1.0, NULL);
+               g_object_set (G_OBJECT (player->pipeline->textbin[MMPLAYER_T_TEXT_IDENTITY].gst), "drop-probability", (gfloat)0.0, NULL);
+               debug_log("external display is ACTIVE");
+
+               msg.data = NULL;
+               msg.subtitle.duration = 0;
+
+               MMPLAYER_POST_MSG( player, MM_MESSAGE_UPDATE_SUBTITLE, &msg );
        }
-       else
+       else if (stat == MMPLAYER_DISPLAY_STATUS_NULL)
        {
-               debug_warning("fail to determine streaming type. pause/resume/seek may not working properly if stream is live stream\n");
+               g_object_set (G_OBJECT (player->pipeline->textbin[MMPLAYER_T_TEXT_FAKE_IDENTITY].gst), "drop-probability", (gfloat)0.0, NULL);
+               g_object_set (G_OBJECT (player->pipeline->textbin[MMPLAYER_T_TEXT_IDENTITY].gst), "drop-probability", (gfloat)1.0, NULL); //If it is not ACTIVE...
+               debug_log("external display is NULL");
        }
 
-       /* get profile attribute */
-       attrs = MMPLAYER_GET_ATTRS(player);
-       if ( !attrs )
+       if (player->display_stat != stat)
        {
-               debug_error("cannot get content attribute\n");
-               return FALSE;
-       }
+               player->display_stat = stat;
 
-       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;
+               g_object_set(G_OBJECT(player->pipeline->textbin[MMPLAYER_T_VIDEO_SINK].gst), "async", FALSE, NULL);
+               g_object_set (G_OBJECT (player->pipeline->textbin[MMPLAYER_T_FAKE_SINK].gst), "async", FALSE, NULL);
+
+               /* setup post processing */
+               player->post_proc.need_async = TRUE;
+               player->post_proc.need_seek = TRUE;
+               player->post_proc.need_pause_and_resume = TRUE;
        }
 
-       debug_fleave();
+       MMPLAYER_FLEAVE();
 
-       return TRUE;
+EXIT:
+       __mmplayer_device_change_trigger_post_process(player);
+       return;
 }
 
-
-/* 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) // @
+static void
+__mmplayer_external_resolution_cb(GstElement *element, int width, int height, gpointer data)
 {
-       MMMessageParamType msg = {0, };
-       int asm_result = MM_ERROR_NONE;
-       int new_state = state;
-
-       debug_fenter();
+       mm_player_t* player = (mm_player_t*)data;
+       return_if_fail ( player );
+       MMPLAYER_FENTER();
 
-       return_val_if_fail ( player, FALSE );
+       if ((player->pipeline->textbin == NULL) ||
+               (player->pipeline->textbin[MMPLAYER_T_RENDER].gst == NULL) ||
+               (player->pipeline->textbin[MMPLAYER_T_VIDEO_SINK].gst == NULL))
+       {
+               debug_warning("text bin is not ready yet");
+               return;
+       }
 
-       if ( MMPLAYER_CURRENT_STATE(player) == new_state )
+       if((width==0 || height==0) && util_get_is_connected_external_display()!=MMPLAYER_DISPLAY_STATUS_NULL)
        {
-               debug_warning("already same state(%s)\n", MMPLAYER_STATE_GET_NAME(state));
-               return TRUE;
+               debug_warning("stat is wrong!! skip setting external resolution to 0");
+               return;
        }
+       debug_log("set external width and height : %d * %d", width, height);
+       g_object_set (G_OBJECT (player->pipeline->textbin[MMPLAYER_T_RENDER].gst), "external-width", width, NULL);
+       g_object_set (G_OBJECT (player->pipeline->textbin[MMPLAYER_T_RENDER].gst), "external-height", height, NULL);
 
-       /* update player states */
-       MMPLAYER_PREV_STATE(player) = MMPLAYER_CURRENT_STATE(player);
-       MMPLAYER_CURRENT_STATE(player) = new_state;
-       if ( MMPLAYER_CURRENT_STATE(player) == MMPLAYER_PENDING_STATE(player) )
-               MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_NONE;
-
-       /* print state */
-       MMPLAYER_PRINT_STATE(player);
+       g_object_set (G_OBJECT (player->pipeline->textbin[MMPLAYER_T_VIDEO_SINK].gst), "external-width", width, NULL);
+       g_object_set (G_OBJECT (player->pipeline->textbin[MMPLAYER_T_VIDEO_SINK].gst), "external-height", height, NULL);
 
-       /* post message to application */
-       if (MMPLAYER_TARGET_STATE(player) == new_state)
-       {
-               /* fill the message with state of player */
-               msg.state.previous = MMPLAYER_PREV_STATE(player);
-               msg.state.current = MMPLAYER_CURRENT_STATE(player);
+       MMPLAYER_FLEAVE();
+}
 
-               /* 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 );
-               }
+static void
+__mmplayer_hided_window_cb(GstElement *element, gboolean is_hided , gpointer data)
+{
+       mm_player_t* player = (mm_player_t*)data;
+       return_if_fail ( player );
+       MMPLAYER_FENTER();
 
-               debug_log ("player reach the target state, then do something in each state(%s).\n", 
-                       MMPLAYER_STATE_GET_NAME(MMPLAYER_TARGET_STATE(player)));
-       }
-       else
+       if ((player->pipeline->textbin == NULL) ||
+               (player->pipeline->textbin[MMPLAYER_T_VIDEO_SINK].gst == NULL))
        {
-               debug_log ("intermediate state, do nothing.\n");
-               return TRUE;
+               debug_warning("text_xvimagesink is not ready yet");
+               return;
        }
-       
-       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.
-                        */
-                       _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:
-               {
-                       /* update attributes which are only available on playing status */
-                       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");
-                               }
+       g_object_set (G_OBJECT (player->pipeline->textbin[MMPLAYER_T_VIDEO_SINK].gst), "hided-window", is_hided, NULL);
+       debug_log("update window-hide status : %d", is_hided);
 
-                               MMTA_ACUM_ITEM_END("[KPI] start media player service", FALSE);
-                               MMTA_ACUM_ITEM_END("[KPI] media player service create->playing", FALSE);
+       MMPLAYER_FLEAVE();
+}
 
-                               MMPLAYER_POST_MSG ( player, MM_MESSAGE_BEGIN_OF_STREAM, NULL );
-                               player->sent_bos = TRUE;
-                       }
-               }
-               break;
+static void
+__mmplayer_quick_panel_on_cb(GstElement *element, gboolean quick_panel_on , gpointer data)
+{
+       mm_player_t* player = (mm_player_t*)data;
+       return_if_fail ( player );
+       MMPLAYER_FENTER();
 
-               case MM_PLAYER_STATE_NONE:
-               default:
-                       debug_warning("invalid target state, there is nothing to do.\n");
-                       break;
+       if ((player->pipeline->textbin == NULL) ||
+               (player->pipeline->textbin[MMPLAYER_T_VIDEO_SINK].gst == NULL))
+       {
+               debug_warning("text_xvimagesink is not ready yet");
+               return;
        }
+       g_object_set (G_OBJECT (player->pipeline->textbin[MMPLAYER_T_VIDEO_SINK].gst), "quick-panel-on", quick_panel_on, NULL);
+       debug_log("update quick panel status : %d", quick_panel_on);
 
-       debug_fleave();
-
-       return TRUE;
+       MMPLAYER_FLEAVE();
 }
 
-
-gboolean
-__mmplayer_post_message(mm_player_t* player, enum MMMessageType msgtype, MMMessageParamType* param) // @
+static void
+__mmplayer_multiwindow_active_cb(GstElement *element, gboolean multiwindow_active , gpointer data)
 {
-       return_val_if_fail( player, FALSE );
-
-       debug_fenter();
+       mm_player_t* player = (mm_player_t*)data;
+       return_if_fail ( player );
 
-       if ( !player->msg_cb )
+       if ((player->pipeline->textbin == NULL) ||
+               (player->pipeline->textbin[MMPLAYER_T_VIDEO_SINK].gst == NULL))
        {
-               debug_warning("no msg callback. can't post\n");
-               return FALSE;
+               return;
+       }
+       if (player->last_multiwin_status != multiwindow_active)
+       {
+               g_object_set (G_OBJECT (player->pipeline->textbin[MMPLAYER_T_VIDEO_SINK].gst), "multiwindow-active", multiwindow_active, NULL);
+               player->last_multiwin_status = multiwindow_active;
+               debug_log("update multiwindow-active status : %d", multiwindow_active);
        }
-
-       //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) // @
+/* This function should be called after the pipeline goes PAUSED or higher
+state. */
+gboolean
+_mmplayer_update_content_attrs(mm_player_t* player, enum content_attr_flag flag) // @
 {
-       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));
+       static gboolean has_duration = FALSE;
+       static gboolean has_video_attrs = FALSE;
+       static gboolean has_audio_attrs = FALSE;
+       static gboolean has_bitrate = FALSE;
+       gboolean missing_only = FALSE;
+       gboolean all = FALSE;
 
-       debug_fleave();
-       
-       return state;
-}
+       GstFormat fmt  = GST_FORMAT_TIME;
+       gint64 dur_nsec = 0;
+       GstStructure* p = NULL;
+       MMHandleType attrs = 0;
+       gchar *path = NULL;
+       gint stream_service_type = STREAMING_SERVICE_NONE;
+       struct stat sb;
 
-static void
-__gst_set_async_state_change(mm_player_t* player, gboolean async)
-{
-       debug_fenter();
-       
-       return_if_fail( player && player->pipeline && player->pipeline->mainbin );
+       MMPLAYER_FENTER();
 
-       /* need only when we are using decodebin */
-       if ( ! PLAYER_INI()->use_decodebin )
-               return;
+       return_val_if_fail ( player, FALSE );
 
-       /* audio sink */
-       if ( player->pipeline->audiobin &&
-                player->pipeline->audiobin[MMPLAYER_A_SINK].gst )
+       /* check player state here */
+       if ( MMPLAYER_CURRENT_STATE(player) != MM_PLAYER_STATE_PAUSED &&
+               MMPLAYER_CURRENT_STATE(player) != MM_PLAYER_STATE_PLAYING )
        {
-               debug_log("audiosink async : %d\n", async);
-               g_object_set (G_OBJECT (player->pipeline->audiobin[MMPLAYER_A_SINK].gst), "async", async, NULL);
+               /* give warning now only */
+               debug_warning("be careful. content attributes may not available in this state ");
        }
 
-       /* video sink */
-       if ( player->pipeline->videobin &&
-                player->pipeline->videobin[MMPLAYER_V_SINK].gst )
+       /* get content attribute first */
+       attrs = MMPLAYER_GET_ATTRS(player);
+       if ( !attrs )
        {
-               debug_log("videosink async : %d\n", async);
-               g_object_set (G_OBJECT (player->pipeline->videobin[MMPLAYER_V_SINK].gst), "async", async, NULL);
+               debug_error("cannot get content attribute");
+               return FALSE;
        }
 
-       /* decodebin if enabled */
-       if ( PLAYER_INI()->use_decodebin )
+       /* get update flag */
+
+       if ( flag & ATTR_MISSING_ONLY )
        {
-               debug_log("decodebin async : %d\n", async);
-               g_object_set (G_OBJECT (player->pipeline->mainbin[MMPLAYER_M_AUTOPLUG].gst), "async-handling", async, NULL);
+               missing_only = TRUE;
+               debug_log("updating missed attr only");
        }
 
-       debug_fleave();
-}
+       if ( flag & ATTR_ALL )
+       {
+               all = TRUE;
+               has_duration = FALSE;
+               has_video_attrs = FALSE;
+               has_audio_attrs = FALSE;
+               has_bitrate = FALSE;
 
-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;
+               debug_log("updating all attrs");
+       }
 
-       return_val_if_fail ( player, NULL );
+       if ( missing_only && all )
+       {
+               debug_warning("cannot use ATTR_MISSING_ONLY and ATTR_ALL. ignoring ATTR_MISSING_ONLY flag!");
+               missing_only = FALSE;
+       }
 
-       while ( ! player->repeat_thread_exit )
+       if (  (flag & ATTR_DURATION) || (!has_duration && missing_only) || all )
        {
-               debug_log("repeat thread started. waiting for signal.\n");
-               g_cond_wait( player->repeat_thread_cond, player->repeat_thread_mutex );
+               debug_log("try to update duration");
+               has_duration = FALSE;
 
-               if ( player->repeat_thread_exit )
+               if (gst_element_query_duration(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, &fmt, &dur_nsec ))
                {
-                       debug_log("exiting repeat thread\n");
-                       break;
+                       player->duration = dur_nsec;
+                       debug_warning("duration : %lld msec", GST_TIME_AS_MSECONDS(dur_nsec));
                }
 
-               /* lock */
-               MMPLAYER_CMD_LOCK( player );
-
-               return_val_if_fail(     player, NULL );
-
-               attrs = MMPLAYER_GET_ATTRS(player);
+               /* try to get streaming service type */
+               stream_service_type = __mmplayer_get_stream_service_type( player );
+               mm_attrs_set_int_by_name ( attrs, "streaming_type", stream_service_type );
 
-               if (mm_attrs_get_int_by_name(attrs, "profile_play_count", &count) != MM_ERROR_NONE)
+               /* check duration is OK */
+               if ( dur_nsec == 0 && !MMPLAYER_IS_LIVE_STREAMING( player ) )
                {
-                       debug_error("can not get play count\n");
-                               break;
+                       /* FIXIT : find another way to get duration here. */
+                       debug_error("finally it's failed to get duration from pipeline. progressbar will not work correctely!");
                }
-
-               if ( player->section_repeat )
+               else
                {
-                       ret_value = _mmplayer_activate_section_repeat((MMHandleType)player, player->section_repeat_start, player->section_repeat_end);
+                       /*update duration */
+                       mm_attrs_set_int_by_name(attrs, "content_duration", GST_TIME_AS_MSECONDS(dur_nsec));
+                       has_duration = TRUE;
                }
-               else
+       }
+
+       if (  (flag & ATTR_AUDIO) || (!has_audio_attrs && missing_only) || all )
+       {
+               /* update audio params
+               NOTE : We need original audio params and it can be only obtained from src pad of audio
+               decoder. Below code only valid when we are not using 'resampler' just before
+               'audioconverter'. */
+
+               debug_log("try to update audio attrs");
+               has_audio_attrs = FALSE;
+
+               if ( player->pipeline->audiobin &&
+                        player->pipeline->audiobin[MMPLAYER_A_SINK].gst )
                {
-                       if ( player->playback_rate < 0.0 )
+                       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 )
                        {
-                               player->resumed_by_rewind = TRUE;
-                               _mmplayer_set_mute((MMHandleType)player, 0);
-                               MMPLAYER_POST_MSG( player, MM_MESSAGE_RESUMED_BY_REW, NULL );
-                       }
+                               caps_a = gst_pad_get_negotiated_caps( pad );
 
-                       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);
+                               if ( caps_a )
+                               {
+                                       p = gst_caps_get_structure (caps_a, 0);
 
-                       /* initialize */
-                       player->sent_bos = FALSE;
-               }
+                                       mm_attrs_get_int_by_name(attrs, "content_audio_samplerate", &samplerate);
 
-               if ( ! ret_value )
-               {
-                       debug_error("failed to set position to zero for rewind\n");
-                               continue;
-               }
+                                       gst_structure_get_int (p, "rate", &samplerate);
+                                       mm_attrs_set_int_by_name(attrs, "content_audio_samplerate", samplerate);
 
-               /* decrease play count */
-               if ( count > 1 )
-               {
-                       /* we successeded to rewind. update play count and then wait for next EOS */
-                       count--;
+                                       gst_structure_get_int (p, "channels", &channels);
+                                       mm_attrs_set_int_by_name(attrs, "content_audio_channels", channels);
 
-                       mm_attrs_set_int_by_name(attrs, "profile_play_count", count);
+                                       secure_debug_log("samplerate : %d       channels : %d", samplerate, channels);
 
-                       /* commit attribute */
-                       if ( mmf_attrs_commit ( attrs ) )
+                                       gst_caps_unref( caps_a );
+                                       caps_a = NULL;
+
+                                       has_audio_attrs = TRUE;
+                               }
+                               else
+                               {
+                                       debug_warning("not ready to get audio caps");
+                               }
+
+                               gst_object_unref( pad );
+                       }
+                       else
                        {
-                               debug_error("failed to commit attribute\n");
+                               debug_warning("failed to get pad from audiosink");
                        }
                }
+       }
 
-               /* unlock */
-               MMPLAYER_CMD_UNLOCK( player );
-       }
-
-       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 ( !player->streamer->is_buffering )
+       if ( (flag & ATTR_VIDEO) || (!has_video_attrs && missing_only) || all )
        {
-               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));
+               debug_log("try to update video attrs");
+               has_video_attrs = FALSE;
 
-               /* NOTE : if buffering has done, player has to go to target state. */
-               switch ( target_state )
+               if ( player->pipeline->videobin &&
+                        player->pipeline->videobin[MMPLAYER_V_SINK].gst )
                {
-                       case MM_PLAYER_STATE_PAUSED :
-                       {
-                               if ( MMPLAYER_IS_RTSP_STREAMING(player) )
-                                       return;
-
-                               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;
+                       GstCaps *caps_v = NULL;
+                       GstPad* pad = NULL;
+                       gint tmpNu, tmpDe;
+                       gint width, height;
 
-                       case MM_PLAYER_STATE_PLAYING :
+                       pad = gst_element_get_static_pad( player->pipeline->videobin[MMPLAYER_V_SINK].gst, "sink" );
+                       if ( pad )
                        {
-                               if ( MMPLAYER_IS_RTSP_STREAMING(player) )
+                               caps_v = gst_pad_get_negotiated_caps( pad );
+                               if (caps_v)
                                {
-                                       __gst_resume ( player, TRUE );
+                                       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);
 
-                                       /* now we can overcome 'state-lost' situation */
-                                       player->state_lost = FALSE;
+                                       gst_structure_get_int (p, "height", &height);
+                                       mm_attrs_set_int_by_name(attrs, "content_video_height", height);
 
-                                       return;
-                               }
+                                       gst_structure_get_fraction (p, "framerate", &tmpNu, &tmpDe);
 
-                               switch ( pending_state )
-                               {
-                                       case MM_PLAYER_STATE_NONE:
-                                       {
-                                               if (current_state != MM_PLAYER_STATE_PLAYING)
-                                                       __gst_resume ( player, TRUE );
-                                       }
-                                       break;
+                                       secure_debug_log("width : %d     height : %d", width, height );
 
-                                       case MM_PLAYER_STATE_PAUSED:
-                                       {
-                                               __gst_resume ( player, TRUE );
-                                       }
-                                       break;
+                                       gst_caps_unref( caps_v );
+                                       caps_v = NULL;
 
-                                       case MM_PLAYER_STATE_PLAYING:
+                                       if (tmpDe > 0)
                                        {
-                                                debug_log("player is already going to playing state, there is nothing to do.\n");
+                                               mm_attrs_set_int_by_name(attrs, "content_video_fps", tmpNu / tmpDe);
+                                               secure_debug_log("fps : %d", tmpNu / tmpDe);
                                        }
-                                       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;
+                                       has_video_attrs = TRUE;
+                               }
+                               else
+                               {
+                                       debug_log("no negitiated caps from videosink");
                                }
+                               gst_object_unref( pad );
+                               pad = NULL;
                        }
-                       break;
-
-                       case MM_PLAYER_STATE_NULL :
-                       case MM_PLAYER_STATE_READY :
-                       case MM_PLAYER_STATE_NONE :
-                       default:
+                       else
                        {
-                               debug_warning("invalid target state [%s].\n", MMPLAYER_STATE_GET_NAME(target_state) );
+                               debug_log("no videosink sink pad");
                        }
-                               break;
                }
        }
-       else
+
+
+       if ( (flag & ATTR_BITRATE) || (!has_bitrate && missing_only) || all )
        {
-               /* NOTE : in case of rtsp streaming, the src plugin provide the pipeline clock.
-                *      the src plugin is buffering, the pipeline clock stop automatically.
-                *      so don't need to pause the player.
-                */
-               if ( MMPLAYER_IS_RTSP_STREAMING(player) )
-               {
-                       player->state_lost = TRUE;
-                       return;
-               }
+               has_bitrate = FALSE;
 
-               /* 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 )
+               /* FIXIT : please make it clear the dependancy with duration/codec/uritype */
+               if (player->duration)
                {
-                       case MM_PLAYER_STATE_NONE:
+                       guint64 data_size = 0;
+
+                       if (!MMPLAYER_IS_STREAMING(player) && (player->can_support_codec & FOUND_PLUGIN_VIDEO))
                        {
-                               if (current_state != MM_PLAYER_STATE_PAUSED)
-                                       __gst_pause ( player, TRUE );
-                       }
-                       break;
+                               mm_attrs_get_string_by_name(attrs, "profile_uri", &path);
 
-                       case MM_PLAYER_STATE_PLAYING:
+                               if (stat(path, &sb) == 0)
+                               {
+                                       data_size = (guint64)sb.st_size;
+                               }
+                       }
+                       else if (MMPLAYER_IS_HTTP_STREAMING(player))
                        {
-                               __gst_pause ( player, TRUE );
+                               data_size = player->http_content_size;
                        }
-                       break;
+                       debug_log("try to update bitrate : data_size = %lld", data_size);
 
-                       case MM_PLAYER_STATE_PAUSED:
+                       if (data_size)
                        {
-                                debug_log("player is already going to paused state, there is nothing to do.\n");
+                               guint64 bitrate = 0;
+                               guint64 msec_dur = 0;
+
+                               msec_dur = GST_TIME_AS_MSECONDS(player->duration);
+                               bitrate = data_size * 8 * 1000 / msec_dur;
+                               secure_debug_log("file size : %u, video bitrate = %llu", data_size, bitrate);
+                               mm_attrs_set_int_by_name(attrs, "content_video_bitrate", bitrate);
+
+                               has_bitrate = TRUE;
                        }
-                       break;
 
-                       case MM_PLAYER_STATE_NULL:
-                       case MM_PLAYER_STATE_READY:
-                       default :
+                       if (MMPLAYER_IS_RTSP_STREAMING(player))
                        {
-                               debug_warning("invalid pending state [%s].\n", MMPLAYER_STATE_GET_NAME(pending_state) );
+                               if(player->total_bitrate)
+                               {
+                                       mm_attrs_set_int_by_name(attrs, "content_video_bitrate", player->total_bitrate);
+                                       has_bitrate = TRUE;
+                               }
                        }
-                               break;
                }
        }
+
+       /* validate all */
+       if (  mmf_attrs_commit ( attrs ) )
+       {
+               debug_error("failed to update attributes\n");
+               return FALSE;
+       }
+
+       MMPLAYER_FLEAVE();
+
+       return TRUE;
 }
 
-static gboolean
-__mmplayer_gst_callback(GstBus *bus, GstMessage *msg, gpointer data) // @
+gint __mmplayer_get_stream_service_type( mm_player_t* player )
 {
-       mm_player_t* player = (mm_player_t*) data;
-       gboolean ret = TRUE;
-       static gboolean async_done = FALSE;
+       gint streaming_type = STREAMING_SERVICE_NONE;
 
-       return_val_if_fail ( player, FALSE );
-       return_val_if_fail ( msg && GST_IS_MESSAGE(msg), FALSE );
+       MMPLAYER_FENTER();
 
-       switch ( GST_MESSAGE_TYPE( msg ) )
+       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 STREAMING_SERVICE_NONE;
+
+       if (MMPLAYER_IS_RTSP_STREAMING(player))
        {
-               case GST_MESSAGE_UNKNOWN:
-                       debug_warning("unknown message received\n");
+               /* 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))
+       {
+               streaming_type = (player->duration == 0) ?
+                       STREAMING_SERVICE_LIVE : STREAMING_SERVICE_VOD;
+       }
+
+       switch ( streaming_type )
+       {
+               case STREAMING_SERVICE_LIVE:
+                       debug_log("it's live streaming");
+               break;
+               case STREAMING_SERVICE_VOD:
+                       debug_log("it's vod streaming");
                break;
+               case STREAMING_SERVICE_NONE:
+                       debug_error("should not get here");
+               break;
+               default:
+                       debug_error("should not get here");
+       }
 
-               case GST_MESSAGE_EOS:
-               {
-                       MMHandleType attrs = 0;
-                       gint count = 0;
+       player->streaming_type = streaming_type;
+       MMPLAYER_FLEAVE();
 
-                       debug_log("GST_MESSAGE_EOS received\n");
+       return streaming_type;
+}
 
-                       /* 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");
+/* this function sets the player state and also report
+ * it to applicaton by calling callback function
+ */
+static int
+__mmplayer_set_state(mm_player_t* player, int state) // @
+{
+       MMMessageParamType msg = {0, };
+       int asm_result = MM_ERROR_NONE;
+       gboolean post_bos = FALSE;
+       gboolean interrupted_by_asm = FALSE;
+       int ret = MM_ERROR_NONE;
 
-                               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;
+       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 ret;
+       }
 
-                       /* rewind if repeat count is greater then zero */
-                       /* get play count */
-                       attrs = MMPLAYER_GET_ATTRS(player);
+       /* update player states */
+       MMPLAYER_PREV_STATE(player) = MMPLAYER_CURRENT_STATE(player);
+       MMPLAYER_CURRENT_STATE(player) = state;
 
-                       if ( attrs )
-                       {
-                               gboolean smooth_repeat = FALSE;
+       /* FIXIT : it's better to do like below code
+       if ( MMPLAYER_CURRENT_STATE(player) == MMPLAYER_TARGET_STATE(player) )
+                       MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_NONE;
+       and add more code to handling PENDING_STATE.
+       */
+       if ( MMPLAYER_CURRENT_STATE(player) == MMPLAYER_PENDING_STATE(player) )
+               MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_NONE;
 
-                               mm_attrs_get_int_by_name(attrs, "profile_play_count", &count);
-                               mm_attrs_get_int_by_name(attrs, "profile_smooth_repeat", &smooth_repeat);
+       /* print state */
+       MMPLAYER_PRINT_STATE(player);
 
-                               debug_log("remaining play count: %d, playback rate: %f\n", count, player->playback_rate);
+       /* do some FSM stuffs before posting new state to application  */
+       interrupted_by_asm = player->sm.by_asm_cb;
 
-                               if ( count > 1 || count == -1 || player->playback_rate < 0.0 ) /* default value is 1 */
+       switch ( MMPLAYER_CURRENT_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, FALSE);
+                               if ( asm_result != MM_ERROR_NONE )
                                {
-                                       if ( smooth_repeat )
+                                       debug_error("failed to set asm state to stop\n");
+                                       return MM_ERROR_POLICY_INTERNAL;
+                               }
+                       }
+               }
+               break;
+
+               case MM_PLAYER_STATE_PAUSED:
+               {
+                        if ( ! player->sent_bos )
+                        {
+                               int found = 0;
+                               #define MMPLAYER_MAX_SOUND_PRIORITY     3
+
+                               /* it's first time to update all content attrs. */
+                               _mmplayer_update_content_attrs( player, ATTR_ALL );
+                               /* set max sound priority to keep own sound and not to mute other's one */
+                               mm_attrs_get_int_by_name(player->attrs, "content_video_found", &found);
+                               if (found)
+                               {
+                                       mm_attrs_get_int_by_name(player->attrs, "content_audio_found", &found);
+                                       if (found)
                                        {
-                                               debug_log("smooth repeat enabled. seeking operation will be excuted in new thread\n");
+                                               debug_log("set max audio priority");
+                                               g_object_set(player->pipeline->audiobin[MMPLAYER_A_SINK].gst, "priority", MMPLAYER_MAX_SOUND_PRIORITY, NULL);
+                                       }
+                               }
 
-                                               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
-                                               {
+                       /* add audio callback probe if condition is satisfied */
+                       if ( ! player->audio_cb_probe_id && player->set_mode.pcm_extraction )
+                       {
+                               __mmplayer_configure_audio_callback(player);
+                               /* FIXIT : handle return value */
+                       }
 
-                                                       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 );
-                                                       }
+                       if (!MMPLAYER_IS_STREAMING(player) || (player->streamer && !player->streamer->is_buffering))
+                       {
+                               asm_result = _mmplayer_asm_set_state((MMHandleType)player, ASM_STATE_PAUSE, FALSE);
+                               if ( asm_result )
+                               {
+                                       debug_error("failed to set asm state to PAUSE\n");
+                                       return MM_ERROR_POLICY_INTERNAL;
+                               }
+                       }
+               }
+               break;
 
-                                                       ret_value = __gst_set_position( player, MM_PLAYER_POS_FORMAT_TIME, 0 );
+               case MM_PLAYER_STATE_PLAYING:
+               {
+                       /* try to get content metadata */
+                       if ( ! player->sent_bos )
+                       {
+                               /* NOTE : giving ATTR_MISSING_ONLY may have dependency with
+                                * c-api since c-api doesn't use _start() anymore. It may not work propery with
+                                * legacy mmfw-player api */
+                               _mmplayer_update_content_attrs( player, ATTR_MISSING_ONLY);
+                       }
 
-                                                       /* initialize */
-                                                       player->sent_bos = FALSE;
-                                               }
+                       if ( (player->cmd == MMPLAYER_COMMAND_START) || (player->cmd == MMPLAYER_COMMAND_RESUME) )
+                       {
+                               if (!player->sent_bos)
+                               {
+                                       __mmplayer_handle_missed_plugin ( player );
+                               }
 
-                                               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--;
+                               /* update ASM state for video and streaming buffering */
+                               asm_result = _mmplayer_asm_set_state((MMHandleType)player, ASM_STATE_PLAYING, TRUE);
+                               if (asm_result != MM_ERROR_NONE)
+                               {
+                                       if (player->pipeline->videobin)
+                                       {
+                                               MMMessageParamType msg = {0, };
 
-                                                               mm_attrs_set_int_by_name(attrs, "profile_play_count", count);
+                                               debug_error("failed to go ahead because of video conflict\n");
 
-                                                               if ( mmf_attrs_commit ( attrs ) )
-                                                                       debug_error("failed to commit attrs\n");
-                                                       }
-                                               }
+                                               msg.union_type = MM_MSG_UNION_CODE;
+                                               msg.code = MM_ERROR_POLICY_INTERRUPTED;
+                                               MMPLAYER_POST_MSG( player, MM_MESSAGE_STATE_INTERRUPTED, &msg);
 
-                                               break;
+                                               _mmplayer_unrealize((MMHandleType)player);
+                                       }
+                                       else
+                                       {
+                                               debug_error("failed to play by ASM error : 0x%X\n", asm_result);
+                                               _mmplayer_pause((MMHandleType)player);
+                                               return asm_result;
                                        }
+
+                                       return MM_ERROR_POLICY_INTERNAL;
                                }
                        }
 
-                       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 );
+                       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;
+                       }
 
-                       msg_src_element = GST_ELEMENT_NAME( GST_ELEMENT_CAST( msg->src ) );
-                       if ( gst_structure_has_name ( msg->structure, "streaming_error" ) )
+                       if ( !player->sent_bos )
                        {
-                               /* Note : the streaming error from the streaming source is handled
-                                *   using __mmplayer_handle_streaming_error.
+                               /* check audio codec field is set or not
+                                * we can get it from typefinder or codec's caps.
                                 */
-                               __mmplayer_handle_streaming_error ( player, msg );
+                               gchar *audio_codec = NULL;
+                               mm_attrs_get_string_by_name(player->attrs, "content_audio_codec", &audio_codec);
 
-                               /* 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
+                               /* 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.
                                 */
-                               __mmplayer_handle_gst_error( player, msg, error );
+                               if ( ! audio_codec )
+                               {
+                                       if ( g_strrstr(player->type, "audio/midi"))
+                                       {
+                                               audio_codec = g_strdup("MIDI");
 
-                               /* dump state of all element */
-                               __mmplayer_dump_pipeline_state( player );
+                                       }
+                                       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");
+                               }
 
-                       if (MMPLAYER_IS_HTTP_PD(player))
-                       {       
-                               _mmplayer_pd_stop ((MMHandleType)player);
+                               post_bos = TRUE;
                        }
-                       
-                       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);
+               case MM_PLAYER_STATE_NONE:
+               default:
+                       debug_warning("invalid target state, there is nothing to do.\n");
+                       break;
+       }
 
-                       MMPLAYER_POST_MSG( player, MM_MESSAGE_WARNING, NULL );
 
-                       MMPLAYER_FREEIF( debug );
-                       g_error_free( error );
-               }
-               break;
+       /* post message to application */
+       if (MMPLAYER_TARGET_STATE(player) == state)
+       {
+               /* fill the message with state of player */
+               msg.state.previous = MMPLAYER_PREV_STATE(player);
+               msg.state.current = MMPLAYER_CURRENT_STATE(player);
 
-               case GST_MESSAGE_INFO:                          debug_log("GST_MESSAGE_STATE_DIRTY\n"); break;
+               debug_log ("player reach the target state (%s)", MMPLAYER_STATE_GET_NAME(MMPLAYER_TARGET_STATE(player)));
 
-               case GST_MESSAGE_TAG:
+               /* state changed by asm callback */
+               if ( interrupted_by_asm )
                {
-                       debug_log("GST_MESSAGE_TAG\n");
-                       if ( ! __mmplayer_gst_extract_tag_from_msg( player, msg ) )
-                       {
-                               debug_warning("failed to extract tags from gstmessage\n");
-                       }
+                       msg.union_type = MM_MSG_UNION_CODE;
+                       msg.code = player->sm.event_src;
+                       MMPLAYER_POST_MSG( player, MM_MESSAGE_STATE_INTERRUPTED, &msg );
                }
-               break;
-
-               case GST_MESSAGE_BUFFERING:
+               /* state changed by usecase */
+               else
                {
-                       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) || MMPLAYER_IS_HTTP_LIVE_STREAMING(player);
-                       if (update_buffering_percent)
-                       {
-                               msg_param.connection.buffering = player->streamer->buffering_percent;
-                               MMPLAYER_POST_MSG ( player, MM_MESSAGE_BUFFERING, &msg_param );
-                       }
+                       MMPLAYER_POST_MSG( player, MM_MESSAGE_STATE_CHANGED, &msg );
                }
-               break;
+       }
+       else
+       {
+               debug_log ("intermediate state, do nothing.\n");
+               MMPLAYER_PRINT_STATE(player);
+               return ret;
+       }
 
-               case GST_MESSAGE_STATE_CHANGED:
-               {
-                       MMPlayerGstElement *mainbin;
-                       const GValue *voldstate, *vnewstate, *vpending;
-                       GstState oldstate, newstate, pending;
+       if ( post_bos )
+       {
+               MMPLAYER_POST_MSG ( player, MM_MESSAGE_BEGIN_OF_STREAM, NULL );
+               player->sent_bos = TRUE;
+       }
 
-                       if ( ! ( player->pipeline && player->pipeline->mainbin ) )
-                       {
-                               debug_error("player pipeline handle is null");
+       return ret;
+}
 
-                               break;
-                       }
+gboolean
+__mmplayer_post_message(mm_player_t* player, enum MMMessageType msgtype, MMMessageParamType* param) // @
+{
+       return_val_if_fail( player, FALSE );
 
-                       mainbin = player->pipeline->mainbin;
+       if ( !player->msg_cb )
+       {
+               return FALSE;
+       }
 
-                       /* 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");
+       //debug_log("Message (type : %d)  will be posted using msg-cb(%p). \n", msgtype, player->msg_cb);
 
-                       oldstate = (GstState)voldstate->data[0].v_int;
-                       newstate = (GstState)vnewstate->data[0].v_int;
-                       pending = (GstState)vpending->data[0].v_int;
+       player->msg_cb(msgtype, param, player->msg_cb_param);
 
-                       if (oldstate == newstate)
-                               break;
+       return TRUE;
+}
 
-                       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 ) );
+static gpointer __mmplayer_next_play_thread(gpointer data)
+{
+       mm_player_t* player = (mm_player_t*) data;
+       MMPlayerGstElement *mainbin = NULL;
 
-                       /* we only handle messages from pipeline */
-                       if( msg->src != (GstObject *)mainbin[MMPLAYER_M_PIPE].gst )
-                               break;
+       return_val_if_fail ( player, NULL );
 
-                       switch(newstate)
-                       {
-                               case GST_STATE_VOID_PENDING:
-                               break;
+       while ( ! player->next_play_thread_exit )
+       {
+               debug_log("next play thread started. waiting for signal.\n");
+               g_cond_wait( player->next_play_thread_cond, player->next_play_thread_mutex );
 
-                               case GST_STATE_NULL:
-                               break;
+               debug_log("re building pipeline for next play.\n");
 
-                               case GST_STATE_READY:
-                               break;
+               if ( player->next_play_thread_exit )
+               {
+                       MMPLAYER_PLAYBACK_UNLOCK(player);
 
-                               case GST_STATE_PAUSED:
-                               {
-                                       if ( ! player->audio_cb_probe_id && player->is_sound_extraction )
-                                               __mmplayer_configure_audio_callback(player);
-                                       
+                       debug_log("exiting next play thread\n");
+                       break;
+               }
 
-                                       if ( MMPLAYER_IS_STREAMING(player) )
-                                       {
-                                               MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_PAUSED );
+               mainbin = player->pipeline->mainbin;
 
-                                               __mm_player_streaming_set_content_bitrate(player->streamer, player->total_maximum_bitrate, player->total_bitrate);
+               MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_MUXED_S_BUFFER);
+               MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_ID3DEMUX);
+               MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_AUTOPLUG);
+               MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_TYPEFIND);
+               MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_SRC);
 
-                                               /* check pending seek and do now */
-                                               if ( player->pending_seek.is_pending )
-                                                       __gst_pending_seek ( player );
-                                       }
+               __mmplayer_activate_next_source(player, GST_STATE_PLAYING);
+       }
 
-                                       player->need_update_content_dur = TRUE;
-                               }                                       
-                               break;
+       return NULL;
+}
 
-                               case GST_STATE_PLAYING:
-                               {
+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;
 
-                                       gboolean is_async = FALSE;
+       return_val_if_fail ( player, NULL );
 
-                                       if (player->doing_seek && async_done)
-                                       {
-                                               player->doing_seek = FALSE;
-                                               async_done = FALSE;
-                                               MMPLAYER_POST_MSG ( player, MM_MESSAGE_SEEK_COMPLETED, 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 );
 
-                                       /* It should be called in case of async start only.
-                                         * don't need to call in the case of resume and sync start (currently, resume is sync.)
-                                         */
-                                       mm_attrs_get_int_by_name(player->attrs,"profile_async_start", &is_async);
-                                       if (is_async && player->cmd == MMPLAYER_COMMAND_START)
-                                               MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_PLAYING );
-                               }
-                               break;
+               if ( player->repeat_thread_exit )
+               {
+                       debug_log("exiting repeat thread\n");
+                       break;
+               }
 
-                               default:
-                               break;
-                       }
+               if ( !player->cmd_lock )
+               {
+                       debug_log("can't get cmd lock\n");
+                       return NULL;
                }
-               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"));
+               /* lock */
+               g_mutex_lock(player->cmd_lock);
 
-                               if (PLAYER_INI()->provide_clock)
-                               {
-                                       debug_log ("Provide clock is TRUE, do pause->resume\n");
-                                       __gst_pause(player, FALSE);
-                                       __gst_resume(player, FALSE);
-                               }
-                       }
+               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;
-                       
-               case GST_MESSAGE_NEW_CLOCK:
+               }
+
+               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 )
                        {
-                               GstClock *clock = NULL;
-                               gst_message_parse_new_clock (msg, &clock);
-                               debug_log("GST_MESSAGE_NEW_CLOCK : %s\n", (clock ? GST_OBJECT_NAME (clock) : "NULL"));
+                               player->resumed_by_rewind = TRUE;
+                               _mmplayer_set_mute((MMHandleType)player, 0);
+                               MMPLAYER_POST_MSG( player, MM_MESSAGE_RESUMED_BY_REW, 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;
+                       ret_value = __gst_seek( player, player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, player->playback_rate,
+                               GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET,
+                               0, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
 
-               case GST_MESSAGE_ELEMENT:
-               {
-                       debug_log("GST_MESSAGE_ELEMENT\n");
+                       /* initialize */
+                       player->sent_bos = FALSE;
                }
-               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:
+
+               if ( ! ret_value )
                {
-                       debug_log("GST_MESSAGE_DURATION\n");
+                       debug_error("failed to set position to zero for rewind\n");
+                       continue;
                }
-               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:    
+
+               /* decrease play count */
+               if ( count > 1 )
                {
-                       debug_log("GST_MESSAGE_ASYNC_DONE : %s\n", gst_element_get_name(GST_MESSAGE_SRC(msg)));
+                       /* we successeded to rewind. update play count and then wait for next EOS */
+                       count--;
 
-                       if (player->doing_seek)
+                       mm_attrs_set_int_by_name(attrs, "profile_play_count", count);
+
+                       /* commit attribute */
+                       if ( mmf_attrs_commit ( attrs ) )
                        {
-                               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;
-                               }
+                               debug_error("failed to commit attribute\n");
                        }
                }
-               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;
+               /* unlock */
+               g_mutex_unlock(player->cmd_lock);
        }
 
-       /* 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;
+       return NULL;
 }
 
-static gboolean
-__mmplayer_gst_extract_tag_from_msg(mm_player_t* player, GstMessage* msg) // @
+static void
+__mmplayer_update_buffer_setting(mm_player_t *player, GstMessage *buffering_msg)
 {
+       MMHandleType attrs = 0;
+       guint64 data_size = 0;
+       gchar* path = NULL;
+       unsigned long pos_msec = 0;
+       struct stat sb;
 
-/* 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)); \
-       } \
-}
+       return_if_fail( player && player->pipeline && player->pipeline->mainbin);
 
-#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;\
-       }\
-}
+       __gst_get_position(player, MM_PLAYER_POS_FORMAT_TIME, &pos_msec);       // update last_position
 
-#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);\
-       }\
-}
+       attrs = MMPLAYER_GET_ATTRS(player);
+       if ( !attrs )
+       {
+               debug_error("fail to get attributes.\n");
+               return;
+       }
 
-#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;\
-       }\
-}
+       if (!MMPLAYER_IS_STREAMING(player) && (player->can_support_codec & FOUND_PLUGIN_VIDEO))
+       {
+               mm_attrs_get_string_by_name(attrs, "profile_uri", &path);
 
-#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;\
-       }\
-}
+               if (stat(path, &sb) == 0)
+               {
+                       data_size = (guint64)sb.st_size;
+               }
+       }
+       else if (MMPLAYER_IS_HTTP_STREAMING(player))
+       {
+               data_size = player->http_content_size;
+       }
 
-       /* function start */
-       GstTagList* tag_list = NULL;
+       __mm_player_streaming_buffering(        player->streamer,
+                                                                               buffering_msg,
+                                                                               data_size,
+                                                                               player->last_position,
+                                                                               player->duration);
 
-       MMHandleType attrs = 0;
+       __mm_player_streaming_sync_property(player->streamer, player->pipeline->mainbin[MMPLAYER_M_AUTOPLUG].gst);
 
-       char *string = NULL;
-       guint v_uint = 0;
-       GDate *date = NULL;
-       /* album cover */
-       GstBuffer *buffer = NULL;
-       gint index = 0;
-       const GValue *value;
+       return;
+}
 
-       /* 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 );
+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;
 
-       attrs = MMPLAYER_GET_ATTRS(player);
+       return_if_fail ( player );
 
-       return_val_if_fail( attrs, FALSE );
+       prev_state = MMPLAYER_PREV_STATE(player);
+       current_state = MMPLAYER_CURRENT_STATE(player);
+       target_state = MMPLAYER_TARGET_STATE(player);
+       pending_state = MMPLAYER_PENDING_STATE(player);
 
-       /* get tag list from gst message */
-       gst_message_parse_tag(msg, &tag_list);
+       if (MMPLAYER_IS_LIVE_STREAMING(player))
+               return;
 
-       /* 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 ( !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));
 
-       if ( mmf_attrs_commit ( attrs ) )
-               debug_error("failed to commit.\n");
+               /* 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;
 
-       gst_tag_list_free(tag_list);
+                                       case MM_PLAYER_STATE_PAUSED:
+                                       {
+                                                debug_log("player is already going to paused state, there is nothing to do.\n");
+                                       }
+                                       break;
 
-       return TRUE;
-}
+                                       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;
 
-static void
-__mmplayer_gst_rtp_no_more_pads (GstElement *element,  gpointer data)  // @
-{
-       mm_player_t* player = (mm_player_t*) data;
+                       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;
 
-       debug_fenter();
+                                       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;
 
-       /* 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
+                                       case MM_PLAYER_STATE_PLAYING:
+                                       {
+                                                debug_log("player is already going to playing state, there is nothing to do.\n");
+                                       }
+                                       break;
 
-         * [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");
+                                       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;
 
-               if ( ! __mmplayer_gst_remove_fakesink( player,
-                       &player->pipeline->mainbin[MMPLAYER_M_SRC_FAKESINK]) );
+                       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)
+                               {
+                                       debug_log("set pause state during buffering\n");
+                                       __gst_pause ( player, TRUE );
 
-       /* create dot before error-return. for debugging */
-       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-no-more-pad" );
+                                       // to cover the weak-signal environment.
+                                       if (MMPLAYER_IS_RTSP_STREAMING(player))
+                                       {
+                                               unsigned long position = 0;
+                                               gint64 pos_msec = 0;
 
-       /* 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 );
+                                               debug_log("[RTSP] seek to the buffering start point\n");
 
-       player->no_more_pad = TRUE;
+                                               if (__gst_get_position(player, MM_PLAYER_POS_FORMAT_TIME, &position ))
+                                               {
+                                                       debug_error("failed to get position\n");
+                                                       break;
+                                               }
 
-       debug_fleave();
-}
+                                               /* key unit seek */
+                                               pos_msec = position * G_GINT64_CONSTANT(1000000);
 
-static gboolean
-__mmplayer_gst_remove_fakesink(mm_player_t* player, MMPlayerGstElement* fakesink) // @
-{
-       GstElement* parent = NULL;
+                                               __gst_seek(player, player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, 1.0,
+                                                                       GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET,
+                                                                       pos_msec, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
+                                       }
+                               }
+                       }
+                       break;
 
-       return_val_if_fail(player && player->pipeline && fakesink, FALSE);
+                       case MM_PLAYER_STATE_PLAYING:
+                       {
+                               __gst_pause ( player, TRUE );
+                       }
+                       break;
 
-       /* lock */
-       g_mutex_lock( player->fsink_lock );
+                       case MM_PLAYER_STATE_PAUSED:
+                       {
+                       }
+                       break;
 
-       if ( ! fakesink->gst )
-       {
-               goto ERROR;
+                       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;
+               }
        }
+}
 
-       /* get parent of fakesink */
-       parent = (GstElement*)gst_object_get_parent( (GstObject*)fakesink->gst );
-       if ( ! parent )
-       {
-               debug_log("fakesink already removed\n");
-               goto ERROR;
-       }
+static void
+__mmplayer_drop_subtitle(mm_player_t* player, gboolean is_drop)
+{
+       MMPlayerGstElement *textbin;
+       MMPLAYER_FENTER();
 
-       gst_element_set_locked_state( fakesink->gst, TRUE );
+       return_if_fail ( player &&
+                                       player->pipeline &&
+                                       player->pipeline->textbin);
 
-       /* 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");
+       return_if_fail ( player->pipeline->textbin[MMPLAYER_T_VIDEO_SINK].gst &&
+                                       player->pipeline->textbin[MMPLAYER_T_TEXT_FAKE_IDENTITY].gst &&
+                                       player->pipeline->textbin[MMPLAYER_T_TEXT_IDENTITY].gst);
 
-               /* FIXIT : should I return here? or try to proceed to next? */
-               /* return FALSE; */
-       }
+       textbin = player->pipeline->textbin;
 
-       /* remove fakesink from it's parent */
-       if ( ! gst_bin_remove( GST_BIN( parent ), fakesink->gst ) )
+       if (is_drop)
        {
-               debug_error("failed to remove fakesink\n");
+               debug_log("Drop subtitle text after getting EOS\n");
 
-               gst_object_unref( parent );
+               g_object_set(textbin[MMPLAYER_T_FAKE_SINK].gst, "async", FALSE, NULL);
+               g_object_set(textbin[MMPLAYER_T_VIDEO_SINK].gst, "async", FALSE, NULL);
+               g_object_set(textbin[MMPLAYER_T_TEXT_FAKE_IDENTITY].gst, "drop-probability", (gfloat)1.0, NULL);
+               g_object_set(textbin[MMPLAYER_T_TEXT_IDENTITY].gst, "drop-probability", (gfloat)1.0, NULL);
 
-               goto ERROR;
+               player->is_subtitle_force_drop = TRUE;
        }
+       else
+       {
+               if (player->is_subtitle_force_drop == TRUE)
+               {
+                       debug_log("Enable subtitle data path without drop\n");
 
-       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;
+                       // player->display_stat = util_get_is_connected_external_display();
 
-       debug_log("state-holder removed\n");
+                       /* if connected with external display */
+                       if ((player->display_stat == MMPLAYER_DISPLAY_STATUS_HDMI_ACTIVE) ||
+                               (player->display_stat == MMPLAYER_DISPLAY_STATUS_UNKNOWN_ACTIVE))
+                       {
+                               g_object_set(textbin[MMPLAYER_T_TEXT_FAKE_IDENTITY].gst, "drop-probability", (gfloat)1.0, NULL);
+                               g_object_set(textbin[MMPLAYER_T_TEXT_IDENTITY].gst, "drop-probability", (gfloat)0.0, NULL);
+                               g_object_set(textbin[MMPLAYER_T_VIDEO_SINK].gst, "async", TRUE, NULL);
+                               g_object_set(textbin[MMPLAYER_T_FAKE_SINK].gst, "async", FALSE, NULL);
 
-       gst_element_set_locked_state( fakesink->gst, FALSE );
+                               debug_log ("connected with external display");
+                       }
+                       else
+                       {
+                               g_object_set(textbin[MMPLAYER_T_TEXT_FAKE_IDENTITY].gst, "drop-probability", (gfloat)0.0, NULL);
+                               g_object_set(textbin[MMPLAYER_T_TEXT_IDENTITY].gst, "drop-probability", (gfloat)1.0, NULL);
+                               g_object_set(textbin[MMPLAYER_T_VIDEO_SINK].gst, "async", FALSE, NULL);
+                               g_object_set(textbin[MMPLAYER_T_FAKE_SINK].gst, "async", TRUE, NULL);
 
-       g_mutex_unlock( player->fsink_lock );
-       return TRUE;
+                               debug_log ("non-connected with external display");
+                       }
 
-ERROR:
-       if ( fakesink->gst )
-       {
-               gst_element_set_locked_state( fakesink->gst, FALSE );
+                       player->is_subtitle_force_drop = FALSE;
+               }
        }
-
-       g_mutex_unlock( player->fsink_lock );
-       return FALSE;
 }
 
-
-static void
-__mmplayer_gst_rtp_dynamic_pad (GstElement *element, GstPad *pad, gpointer data) // @
+static gboolean
+__mmplayer_gst_callback(GstBus *bus, GstMessage *msg, gpointer data) // @
 {
-       GstPad *sinkpad = NULL;
-       GstCaps* caps = NULL;
-       GstElement* new_element = NULL;
-       enum MainElementID element_id = MMPLAYER_M_NUM;
-
        mm_player_t* player = (mm_player_t*) data;
+       gboolean ret = TRUE;
+       static gboolean async_done = FALSE;
 
-       debug_fenter();
+       return_val_if_fail ( player, FALSE );
+       return_val_if_fail ( msg && GST_IS_MESSAGE(msg), FALSE );
 
-       return_if_fail( element && pad );
-       return_if_fail( player &&
-                                       player->pipeline &&
-                                       player->pipeline->mainbin );
-
-
-       /* first, check pt type which we are supporting or not */
-       if ( MMPLAYER_PT_IS_VIDEO( GST_PAD_NAME( pad ) ) )
-       {
-               /* video packet */
-               debug_log("is video stream. take it.\n");
-               element_id = MMPLAYER_M_S_VDEC;
-       }
-       else if ( MMPLAYER_PT_IS_AUDIO( GST_PAD_NAME( pad ) ) )
-       {
-               /* audio packet */
-               debug_log("is audio stream. take it.\n");
-               element_id = MMPLAYER_M_S_ADEC;
-       }
-       else
+       switch ( GST_MESSAGE_TYPE( msg ) )
        {
-               /* FIXIT : application should know this. need one more message type */
-               debug_error ("This Payload type is unknown!\n");
-               goto ERROR;
-       }
-
-       /* 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);
+               case GST_MESSAGE_UNKNOWN:
+                       debug_log("unknown message received\n");
+               break;
 
-       /* perform autoplugging if dump is disabled */
-       if ( ! new_element )
-       {
-               if ( PLAYER_INI()->rtsp_do_typefinding )
+               case GST_MESSAGE_EOS:
                {
-                       /* create autoplugging element */
-                       if( PLAYER_INI()->use_decodebin )
-                       {
-                               /* create decodebin */
-                               new_element = gst_element_factory_make("decodebin", NULL);
+                       MMHandleType attrs = 0;
+                       gint count = 0;
 
-                               g_object_set(G_OBJECT(new_element), "async-handling", TRUE, NULL);
+                       debug_log("GST_MESSAGE_EOS received\n");
 
-                       if ( ! new_element )
+                       /* 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_error("failed to create autoplug element\n");
-                               goto ERROR;
+                               debug_log("EOS received on non-playing state. ignoring it\n");
+                               break;
                        }
 
-                               /* set signal handler */
-                               MMPLAYER_SIGNAL_CONNECT(        player,
-                                                                                       G_OBJECT(new_element),
-                                                                                       "new-decoded-pad",
-                                                                                       G_CALLBACK(__mmplayer_gst_decode_callback),
-                                                                                       (gpointer)player );
-                       }
-                       else
+                       __mmplayer_drop_subtitle(player, TRUE);
+
+                       if ( (player->audio_stream_cb) && (player->set_mode.pcm_extraction) )
                        {
-                               /* create typefind */
-                               new_element = gst_element_factory_make( "typefind", NULL );
-                               if ( ! new_element )
-                               {
-                                       debug_error("failed to create typefind\n");
-                                       goto ERROR;
-                               }
+                               GstPad *pad = NULL;
 
-                               MMPLAYER_SIGNAL_CONNECT(        player,
-                                                                                       G_OBJECT(new_element),
-                                                                                       "have-type",
-                                                                                       G_CALLBACK(__mmplayer_typefind_have_type),
-                                                                                       (gpointer)player);
+                               pad = gst_element_get_static_pad (player->pipeline->audiobin[MMPLAYER_A_SINK].gst, "sink");
 
-                               /* 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");
+                               debug_log("release audio callback\n");
 
-                       caps = gst_pad_get_caps( pad );
+                               /* 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;
 
-                       MMPLAYER_CHECK_NULL( caps );
+                       }
 
-                       /* clear  previous result*/
-                       player->have_dynamic_pad = FALSE;
+                       /* rewind if repeat count is greater then zero */
+                       /* get play count */
+                       attrs = MMPLAYER_GET_ATTRS(player);
 
-                       if ( ! __mmplayer_try_to_plug( player, pad, caps ) )
+                       if ( attrs )
                        {
-                               debug_error("failed to autoplug for caps : %s\n", gst_caps_to_string( caps ) );
-                               goto ERROR;
-                       }
+                               gboolean smooth_repeat = FALSE;
 
-                       /* 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;
-                       }
+                               mm_attrs_get_int_by_name(attrs, "profile_play_count", &count);
+                               mm_attrs_get_int_by_name(attrs, "profile_smooth_repeat", &smooth_repeat);
 
-                       gst_caps_unref( caps );
-                       caps = NULL;
-               }
-       }
+                               player->play_count = count;
 
-       /* excute new_element if created*/
-       if ( new_element )
-       {
-               debug_log("adding new element to pipeline\n");
+                               debug_log("remaining play count: %d, playback rate: %f\n", count, player->playback_rate);
 
-               /* set state to READY before add to bin */
-               MMPLAYER_ELEMENT_SET_STATE( new_element, GST_STATE_READY );
+                               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");
 
-               /* 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;
-               }
+                                               g_cond_signal( player->repeat_thread_cond );
 
-               /* 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;
-               }
+                                               break;
+                                       }
+                                       else
+                                       {
+                                               gint ret_value = 0;
 
-               /* link it */
-               if ( GST_PAD_LINK_OK != GST_PAD_LINK(pad, sinkpad) )
-               {
-                       debug_error("failed to link autoplug element\n");
-                       goto ERROR;
-               }
+                                               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 );
+                                                       }
 
-               gst_object_unref (sinkpad);
-               sinkpad = NULL;
+                                                       __mmplayer_handle_eos_delay( player, player->ini.delay_before_repeat );
 
-               /* run. setting PLAYING here since streamming source is live source */
-               MMPLAYER_ELEMENT_SET_STATE( new_element, GST_STATE_PLAYING );
-       }
+                                                       /* initialize */
+                                                       player->sent_bos = FALSE;
+                                               }
 
-       /* store handle to futher manipulation */
-       player->pipeline->mainbin[element_id].id = element_id;
-       player->pipeline->mainbin[element_id].gst = new_element;
+                                               if ( MM_ERROR_NONE != ret_value )
+                                               {
+                                                       debug_error("failed to set position to zero for rewind\n");
+                                               }
 
-       debug_fleave();
+                                               /* not posting eos when repeating */
+                                               break;
+                                       }
+                               }
+                       }
 
-       return;
+                       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-eos" );
 
-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));
+                       /* post eos message to application */
+                       __mmplayer_handle_eos_delay( player, player->ini.eos_delay );
 
-       if ( sinkpad )
-               gst_object_unref(GST_OBJECT(sinkpad));
+                       /* reset last position */
+                       player->last_position = 0;
+               }
+               break;
 
-       if ( caps )
-               gst_object_unref(GST_OBJECT(caps));
+               case GST_MESSAGE_ERROR:
+               {
+                       GError *error = NULL;
+                       gchar* debug = NULL;
 
-       /* 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
-        */
-}
+                       /* 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 );
 
-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;
+                       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 );
 
-       /* check handles */
-       player = (mm_player_t*) data;
+                               /* 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 );
 
-       return_if_fail( decodebin && pad );
-       return_if_fail(player && player->pipeline && player->pipeline->mainbin);
+                               if (debug)
+                               {
+                                       debug_error ("error debug : %s", debug);
+                               }
 
-       pipeline = player->pipeline->mainbin[MMPLAYER_M_PIPE].gst;
+                       }
 
-       attrs = MMPLAYER_GET_ATTRS(player);
-       if ( !attrs )
-       {
-               debug_error("cannot get content attribute\n");
-               goto ERROR;
-       }
+                       if (MMPLAYER_IS_HTTP_PD(player))
+                       {
+                               _mmplayer_unrealize_pd_downloader ((MMHandleType)player);
+                       }
 
-       /* get mimetype from caps */
-       caps = gst_pad_get_caps( pad );
-       if ( !caps )
-       {
-               debug_error("cannot get caps from pad.\n");
-               goto ERROR;
-       }
+                       MMPLAYER_FREEIF( debug );
+                       g_error_free( error );
+               }
+               break;
 
-       str = gst_caps_get_structure( caps, 0 );
-       if ( ! str )
-       {
-               debug_error("cannot get structure from capse.\n");
-               goto ERROR;
-       }
+               case GST_MESSAGE_WARNING:
+               {
+                       char* debug = NULL;
+                       GError* error = NULL;
 
-       name = gst_structure_get_name(str);
-       if ( ! name )
-       {
-               debug_error("cannot get mimetype from structure.\n");
-               goto ERROR;
-       }
+                       gst_message_parse_warning(msg, &error, &debug);
 
-       debug_log("detected mimetype : %s\n", name);
+                       debug_log("warning : %s\n", error->message);
+                       debug_log("debug : %s\n", debug);
 
-       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;
-                               }
-                       )
+                       MMPLAYER_POST_MSG( player, MM_MESSAGE_WARNING, NULL );
 
-                       sinkbin = player->pipeline->audiobin[MMPLAYER_A_BIN].gst;
-                       debug_log("creating audiosink bin success\n");
+                       MMPLAYER_FREEIF( debug );
+                       g_error_free( error );
                }
-               else
+               break;
+
+               case GST_MESSAGE_TAG:
                {
-                       sinkbin = player->pipeline->audiobin[MMPLAYER_A_BIN].gst;
-                       debug_log("re-using audiobin\n");
+                       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;
 
-               /* FIXIT : track number shouldn't be hardcoded */
-               mm_attrs_set_int_by_name(attrs, "content_audio_track_num", 1);
+               case GST_MESSAGE_BUFFERING:
+               {
+                       MMMessageParamType msg_param = {0, };
+                       int asm_result = MM_ERROR_NONE;
 
-               player->audiosink_linked  = 1;
-               debug_msg("player->audsink_linked set to 1\n");
+                       if (!MMPLAYER_IS_STREAMING(player))
+                               break;
 
-       }
-       else if (strstr(name, "video"))
-       {
-               if (player->pipeline->videobin == NULL)
-               {
-                               __mmplayer_set_videosink_type(player);
+                       /* ignore the prev buffering message */
+                       if ((player->streamer) && (player->streamer->is_buffering == FALSE) && (player->streamer->is_buffering_done == TRUE))
+                       {
+                               gint buffer_percent = 0;
 
-                               /*      NOTE : not make videobin because application dose not want to play it even though file has video stream.
-                               */
-                               if (PLAYER_INI()->video_surface == MM_DISPLAY_SURFACE_NULL)
-                               {
-                                       debug_log("not make videobin because it dose not want\n");
-                                       goto ERROR;
-                               }
+                               gst_message_parse_buffering (msg, &buffer_percent);
 
-                       __ta__("__mmplayer_gst_create_video_pipeline",
-                               if (MM_ERROR_NONE !=  __mmplayer_gst_create_video_pipeline(player, caps) )
+                               if (buffer_percent == MAX_BUFFER_PERCENT)
                                {
-                                       debug_error("failed to create videobin. continuing without video\n");
-                                       goto ERROR;
+                                       debug_log ("Ignored all the previous buffering msg! (got %d%%)\n", buffer_percent);
+                                       player->streamer->is_buffering_done = FALSE;
                                }
-                       )
-
-                       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");
+                               break;
+                       }
 
-       }
-       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))
+                       /* update ASM state to ASM_STATE_PLAYING */
+                       /* fixed ASM_STATE_WAITING -> ASM_STATE_PLAYING for Samsunlink issue*/
+                       if ((player->streamer) && (player->streamer->is_buffering == FALSE) && (MMPLAYER_CURRENT_STATE(player) != MM_PLAYER_STATE_PAUSED))
+                       {
+                               asm_result = _mmplayer_asm_set_state((MMHandleType)player, ASM_STATE_WAITING, TRUE);
+                               if ( asm_result != MM_ERROR_NONE )
                                {
-                                       debug_error("failed to create textbin. continuing without text\n");
-                                       goto ERROR;
+                                       debug_warning("failed to set asm state to waiting, but keep going...\n");
                                }
-                       )
-
-                       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);
+                       __mmplayer_update_buffer_setting(player, msg);
 
-               player->textsink_linked  = 1;
-               debug_msg("player->textsink_linked set to 1\n");
-       }
-       else
-       {
-               debug_warning("unknown type of elementary stream! ignoring it...\n");
-               goto ERROR;
-       }
+                       __mmplayer_handle_buffering_message ( player );
 
-       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;
+                       msg_param.connection.buffering = player->streamer->buffering_percent;
+                       MMPLAYER_POST_MSG ( player, MM_MESSAGE_BUFFERING, &msg_param );
+                       if (MMPLAYER_IS_RTSP_STREAMING(player) && (player->streamer->buffering_percent >= MAX_BUFFER_PERCENT))
+                       {
+                               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;
 
-               /* add */
-               if ( FALSE == gst_bin_add( GST_BIN(pipeline), sinkbin ) )
+               case GST_MESSAGE_STATE_CHANGED:
                {
-                       debug_error("failed to add sinkbin to pipeline\n");
-                       goto ERROR;
-               }
+                       MMPlayerGstElement *mainbin;
+                       const GValue *voldstate, *vnewstate, *vpending;
+                       GstState oldstate, newstate, pending;
 
-               sinkpad = gst_element_get_static_pad( GST_ELEMENT(sinkbin), "sink" );
+                       if ( ! ( player->pipeline && player->pipeline->mainbin ) )
+                       {
+                               debug_error("player pipeline handle is null");
+                               break;
+                       }
 
-               if ( !sinkpad )
-               {
-                       debug_error("failed to get pad from sinkbin\n");
-                       goto ERROR;
-               }
+                       mainbin = player->pipeline->mainbin;
 
-               /* link */
-               if ( GST_PAD_LINK_OK != GST_PAD_LINK(pad, sinkpad) )
-               {
-                       debug_error("failed to get pad from sinkbin\n");
-                       goto ERROR;
-               }
+                       /* we only handle messages from pipeline */
+                       if( msg->src != (GstObject *)mainbin[MMPLAYER_M_PIPE].gst )
+                               break;
 
-               /* 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;
-               }
+                       /* 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");
 
-               gst_object_unref( sinkpad );
-               sinkpad = NULL;
-       }
+                       oldstate = (GstState)voldstate->data[0].v_int;
+                       newstate = (GstState)vnewstate->data[0].v_int;
+                       pending = (GstState)vpending->data[0].v_int;
 
-       /* update track number attributes */
-       if ( mmf_attrs_commit ( attrs ) )
-               debug_error("failed to commit attrs\n");
+                       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 ) );
 
-       debug_log("linking sink bin success\n");
+                       if (oldstate == newstate)
+                       {
+                               debug_log("pipeline reports state transition to old state");
+                               break;
+                       }
 
+                       switch(newstate)
+                       {
+                               case GST_STATE_VOID_PENDING:
+                               break;
 
-       /* 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--;
+                               case GST_STATE_NULL:
+                               break;
 
-       debug_log("stream count dec : %d (num of dynamic pad)\n", player->num_dynamic_pad);
+                               case GST_STATE_READY:
+                               break;
 
-       if ( ( player->no_more_pad ) && ( player->num_dynamic_pad == 0 ) )
-       {
-               __mmplayer_pipeline_complete( NULL, player );
-       }
+                               case GST_STATE_PAUSED:
+                               {
+                                       gboolean prepare_async = FALSE;
+                                       gboolean is_drm = FALSE;
 
-ERROR:
-       if ( caps )
-               gst_caps_unref( caps );
+                                       if ( ! player->audio_cb_probe_id && player->set_mode.pcm_extraction)
+                                               __mmplayer_configure_audio_callback(player);
 
-       if ( sinkpad )
-               gst_object_unref(GST_OBJECT(sinkpad));
+                                       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);
+                                       }
 
-       return;
-}
+                                       if ( MMPLAYER_IS_STREAMING(player) || prepare_async )
+                                       {
+                                               MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_PAUSED );
 
-int
-_mmplayer_update_video_param(mm_player_t* player) // @
-{
-       MMHandleType attrs = 0;
-       gint videosink_idx_x = 0;
-       gint videosink_idx_evas = 0;
-       gboolean is_first_v_sink_x = FALSE;
+                                               if (MMPLAYER_IS_STREAMING(player) && (player->streamer))
+                                               {
+                                                       __mm_player_streaming_set_content_bitrate(player->streamer,
+                                                               player->total_maximum_bitrate, player->total_bitrate);
+                                               }
+                                       }
 
-       debug_fenter();
+                                       /* NOTE : should consider streaming case */
+                                       /* check if drm file */
+                                       if ((player->pipeline->mainbin[MMPLAYER_M_SRC].gst) &&
+                                               (g_object_class_find_property(G_OBJECT_GET_CLASS(player->pipeline->mainbin[MMPLAYER_M_SRC].gst), "is-drm")))
+                                       {
+                                               g_object_get(G_OBJECT(player->pipeline->mainbin[MMPLAYER_M_SRC].gst), "is-drm", &is_drm, NULL);
 
-       /* 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 );
+                                               if (is_drm)
+                                               {
+                                                       player->is_drm_file = TRUE;
+                                               }
+                                       }
+                               }
+                               break;
 
-       attrs = MMPLAYER_GET_ATTRS(player);
-       if ( !attrs )
-       {
-               debug_error("cannot get content attribute");
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
+                               case GST_STATE_PLAYING:
+                               {
+                                       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.
+                                               if ((MMPLAYER_CURRENT_STATE(player) != MM_PLAYER_STATE_PLAYING) ||
+                                                       (MMPLAYER_PENDING_STATE(player) == MM_PLAYER_STATE_PLAYING))
+                                               {
+                                                       MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_PLAYING);
+                                               }
+                                       }
 
-       /* update display surface */
-       __mmplayer_set_videosink_type(player);
+                                       if (player->src_changed)
+                                       {
+                                               _mmplayer_update_content_attrs(player, ATTR_ALL);
+                                               player->src_changed = FALSE;
+                                       }
 
-       /* check video stream callback is used */
-       if( player->use_video_stream )
-       {
-               if (player->is_nv12_tiled)
-               {
-                       gchar *ename = NULL;
-                       int degree, width, height;
-                       degree = width = height = 0;
-                       
-                       mm_attrs_get_int_by_name(attrs, "display_width", &width);
-                       mm_attrs_get_int_by_name(attrs, "display_height", &height);
-                       mm_attrs_get_int_by_name(attrs, "display_rotation", &degree);
+                                       if (player->doing_seek && async_done)
+                                       {
+                                               player->doing_seek = FALSE;
+                                               async_done = FALSE;
+                                               MMPLAYER_POST_MSG ( player, MM_MESSAGE_SEEK_COMPLETED, NULL );
+                                       }
+                               }
+                               break;
 
-                       /* resize video frame with requested values for fimcconvert */
-                       ename = GST_PLUGIN_FEATURE_NAME(gst_element_get_factory(player->pipeline->videobin[MMPLAYER_V_CONV].gst));
+                               default:
+                               break;
+                       }
+               }
+               break;
 
-                       if (g_strrstr(ename, "fimcconvert"))
+               case GST_MESSAGE_CLOCK_LOST:
                        {
-                               if (width)
-                                       g_object_set(player->pipeline->videobin[MMPLAYER_V_CONV].gst, "src-width", width, NULL);
-
-                               if (height)
-                                       g_object_set(player->pipeline->videobin[MMPLAYER_V_CONV].gst, "src-height", height, NULL);
+                               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"));
 
-                               switch (degree)
+                               if (((player->ini.provide_clock_for_music) && (!player->videodec_linked)) ||
+                                       ((player->ini.provide_clock_for_movie) && (player->videodec_linked)))
                                {
-                                       case MM_DISPLAY_ROTATION_NONE:
-                                               degree = 0;
-                                               break;
-                                               
-                                       case MM_DISPLAY_ROTATION_90:
-                                               degree = 90;
-                                               break;
-                                               
-                                       case MM_DISPLAY_ROTATION_180:
-                                               degree = 180;
-                                               break;
-                                               
-                                       case MM_DISPLAY_ROTATION_270:
-                                               degree = 270;
-                                               break;
-                                               
-                                       default:
-                                               degree = 0;
-                                               break;
+                                       debug_log ("Provide clock is TRUE, do pause->resume\n");
+                                       __gst_pause(player, FALSE);
+                                       __gst_resume(player, FALSE);
                                }
-
-                               g_object_set(player->pipeline->videobin[MMPLAYER_V_CONV].gst, "rotate", degree, NULL);
-
-                               debug_log("updating fimcconvert - r[%d], w[%d], h[%d]", degree, width, height);
                        }
-                       else
+                       break;
+
+               case GST_MESSAGE_NEW_CLOCK:
                        {
-                               debug_error("no available video converter");
+                               GstClock *clock = NULL;
+                               gst_message_parse_new_clock (msg, &clock);
+                               debug_log("GST_MESSAGE_NEW_CLOCK : %s\n", (clock ? GST_OBJECT_NAME (clock) : "NULL"));
                        }
-               }
-               else
-               {
-                       int rotate, width, height, orientation, rotation;
+                       break;
 
-                       rotate = width = height = orientation = rotation = 0;
+               case GST_MESSAGE_ELEMENT:
+                       {
+                               const gchar *structure_name;
+                               gint count = 0;
+                               MMHandleType attrs = 0;
 
-                       debug_log("using video stream callback with memsink. player handle : [%p]", player);
+                               attrs = MMPLAYER_GET_ATTRS(player);
+                               if ( !attrs )
+                               {
+                                       debug_error("cannot get content attribute");
+                                       ret = FALSE;
+                                       break;
+                               }
 
-                       mm_attrs_get_int_by_name(attrs, "display_width", &width);
-                       mm_attrs_get_int_by_name(attrs, "display_height", &height);
-                       mm_attrs_get_int_by_name(attrs, "display_rotation", &rotation);
-                       mm_attrs_get_int_by_name(attrs, "display_orientation", &orientation);
+                               if(msg->structure == NULL)
+                                       break;
 
-                       if(rotation == MM_DISPLAY_ROTATION_NONE)    rotate = 0;
-                       else if(rotation ==MM_DISPLAY_ROTATION_90)   rotate = 90;
-                       else if(rotation ==MM_DISPLAY_ROTATION_180)  rotate = 180;
-                       else if(rotation ==MM_DISPLAY_ROTATION_270)  rotate = 270;
+                               structure_name = gst_structure_get_name(msg->structure);
+                               if(!strcmp(structure_name, "Language_list"))
+                               {
+                                       const GValue *lang_list = NULL;
+                                       lang_list = gst_structure_get_value (msg->structure, "lang_list");
+                                       if(lang_list != NULL)
+                                       {
+                                               count = g_list_length((GList *)g_value_get_pointer (lang_list));
+                                               if (count > 1)
+                                                       debug_log("Total audio tracks (from parser) = %d \n",count);
+                                       }
+                               }
 
-                       if(orientation == 1)        rotate = 90;
-                       else if(orientation == 2)   rotate = 180;
-                       else if(orientation == 3)   rotate = 270;
-                       
-                       if (width)
-                               g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "width", width, NULL);
+                               if (!strcmp (structure_name, "Ext_Sub_Language_List"))
+                               {
+                                       const GValue *lang_list = NULL;
+                                       MMPlayerLangStruct *temp = NULL;
 
-                       if (height)
-                               g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "height", height, NULL);
+                                       lang_list = gst_structure_get_value (msg->structure, "lang_list");
+                                       if (lang_list != NULL)
+                                       {
+                                               count = g_list_length ((GList *)g_value_get_pointer (lang_list));
+                                               if (count)
+                                               {
+                                                 player->subtitle_language_list = (GList *)g_value_get_pointer (lang_list);
+                                                       mm_attrs_set_int_by_name(attrs, "content_text_track_num", (gint)count);
+                                                       if (mmf_attrs_commit (attrs))
+                                                         debug_error("failed to commit.\n");
+                                                       debug_log("Total external subtitle tracks = %d \n", count);
+                                               }
+                                               while (count)
+                                               {
+                                                       temp = g_list_nth_data (player->subtitle_language_list, count - 1);
+                                                       debug_log ("value of lang_key is %s and lang_code is %s",
+                                                                               temp->language_key, temp->language_code);
+                                                       count--;
+                                               }
+                                       }
+                               }
+                               if (!strcmp (structure_name, "Int_Sub_Language_List"))
+                               {
+                                       const GValue *lang_list = NULL;
+                                       MMPlayerLangStruct *temp = NULL;
+                                       lang_list = gst_structure_get_value (msg->structure, "lang_list");
+                                       if (lang_list != NULL && !player->is_external_subtitle_present)
+                                       {
+                                               count = g_list_length ((GList *)g_value_get_pointer (lang_list));
+                                               if (count)
+                                               {
+                                                       player->subtitle_language_list = (GList *)g_value_get_pointer (lang_list);
+                                                       g_object_set (G_OBJECT (player->pipeline->mainbin[MMPLAYER_M_T_SUBMUX_INTERNAL].gst), "lang-list", player->subtitle_language_list, NULL);
+                                                       mm_attrs_set_int_by_name(attrs, "content_text_track_num", (gint)count);
+                                                       if (mmf_attrs_commit (attrs))
+                                                         debug_error("failed to commit.\n");
+                                                       debug_log("Total internal subtitle tracks = %d \n", count);
+                                               }
+                                               while (count)
+                                               {
+                                                       temp = g_list_nth_data (player->subtitle_language_list, count - 1);
+                                                       debug_log ("value of lang_key is %s and lang_code is %s",
+                                                                               temp->language_key, temp->language_code);
+                                                       count--;
+                                               }
+                                       } else if (lang_list != NULL) {
+                                         GList* internal_lang_list;
+                                         internal_lang_list = (GList *)g_value_get_pointer (lang_list);
+                                         debug_log ("it is internal & external case simultaneously");
+                                         g_object_set (G_OBJECT (player->pipeline->mainbin[MMPLAYER_M_T_SUBMUX_INTERNAL].gst), "lang-list", internal_lang_list, NULL);
+                                       } else {
+                                         debug_error ("language list is coming null");
+                                       }
+                               }
 
-                       g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "rotate", rotate,NULL);
-               }
-               
-               return MM_ERROR_NONE;
-       }
-
-       if (player->use_multi_surface)
-       {
-               is_first_v_sink_x = !strncmp(GST_ELEMENT_NAME(player->pipeline->videobin[MMPLAYER_V_SINK_EXT].gst),  "videosink_ext_evas", 18);
-               if (is_first_v_sink_x)
-               {
-                       videosink_idx_x = MMPLAYER_V_SINK;
-                       videosink_idx_evas = MMPLAYER_V_SINK_EXT;
-               }
-               else
-               {
-                       videosink_idx_x = MMPLAYER_V_SINK_EXT;
-                       videosink_idx_evas = MMPLAYER_V_SINK;
-               }
-               debug_log("use multi-surface : videosink_idx_x(%d), videosink_idx_evas(%d)", videosink_idx_x,videosink_idx_evas);
-       }
-       else
-       {
-               videosink_idx_x = videosink_idx_evas = MMPLAYER_V_SINK;
-       }
-
-       /* configuring display */
-       switch ( PLAYER_INI()->video_surface )
-       {
-               case MM_DISPLAY_SURFACE_X:
-               {
-               /* ximagesink or xvimagesink */
-                       void *xid = NULL;
-                       int zoom = 0;
-                       int degree = 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 multi-surface */
-                       if (player->use_multi_surface)
-                       {
-                               void *evas_image_object = NULL;
-                               if (is_first_v_sink_x)
-                               {
-                                       mm_attrs_get_data_by_name(attrs, "display_overlay", &xid);
-                                       mm_attrs_get_data_by_name(attrs, "display_overlay_ext", &evas_image_object);
-                               }
-                               else
-                               {
-                                       mm_attrs_get_data_by_name(attrs, "display_overlay", &evas_image_object);
-                                       mm_attrs_get_data_by_name(attrs, "display_overlay_ext", &xid);
-                               }
-                               if ( xid )
-                               {
-                                       debug_log("use multi-surface : xid %d", *(int*)xid);
-                                       gst_x_overlay_set_xwindow_id( GST_X_OVERLAY( player->pipeline->videobin[videosink_idx_x].gst ), *(int*)xid );
-                               }
-                               else
-                               {
-                                       debug_error("no xwindow");
-                                       return MM_ERROR_PLAYER_INTERNAL;
-                               }
-                               if (evas_image_object)
-                               {
-                                       g_object_set(player->pipeline->videobin[videosink_idx_evas].gst,
-                                                       "evas-object", evas_image_object,
-                                                       "visible", FALSE,
-                                                       NULL);
-                               }
-                               else
-                               {
-                                       debug_error("no evas object");
-                                       return MM_ERROR_PLAYER_INTERNAL;
-                               }
-                               debug_log("use multi-surface : evas_image_object (%x)", evas_image_object);
-                               debug_log("use multi-surface : evas visible %d", FALSE);
-                       }
-                       /* common case if using x surface */
-                       else
-                       {
-                               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.");
+                               /* custom message */
+                               if (!strcmp (structure_name, "audio_codec_not_supported")) {
+                                       MMMessageParamType msg_param = {0,};
+                                       msg_param.code = MM_ERROR_PLAYER_AUDIO_CODEC_NOT_FOUND;
+                                       MMPLAYER_POST_MSG(player, MM_MESSAGE_ERROR, &msg_param);
                                }
                        }
+                       break;
 
-                       /* if xvimagesink */
-                       if (!strcmp(PLAYER_INI()->videosink_element_x,"xvimagesink"))
+               case GST_MESSAGE_DURATION:
+               {
+                       debug_log("GST_MESSAGE_DURATION\n");
+                       ret = __mmplayer_gst_handle_duration(player, msg);
+                       if (!ret)
                        {
-                               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_rotation", &degree);
-                               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);
+                               debug_warning("failed to update duration");
+                       }
+               }
 
-                               g_object_set(player->pipeline->videobin[videosink_idx_x].gst,
-                                       "force-aspect-ratio", force_aspect_ratio,
-                                       "zoom", zoom,
-                                       "rotate", degree,
-                                       "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 );
+               break;
 
-                               debug_log("set video param : zoom %d", zoom);
-                               debug_log("set video param : rotate %d", degree);
-                               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);
-                       }
+               case GST_MESSAGE_ASYNC_START:
+               {
+                       debug_log("GST_MESSAGE_ASYNC_START : %s\n", GST_ELEMENT_NAME(GST_MESSAGE_SRC(msg)));
                }
                break;
-               case MM_DISPLAY_SURFACE_EVAS:
+
+               case GST_MESSAGE_ASYNC_DONE:
                {
-                       void *object = NULL;
-                       int scaling = 0;
-                       gboolean visible = TRUE;
+                       debug_log("GST_MESSAGE_ASYNC_DONE : %s\n", GST_ELEMENT_NAME(GST_MESSAGE_SRC(msg)));
 
-                       /* common case if using multi-surface */
-                       if (player->use_multi_surface)
-                       {
-                               void *xid = NULL;
-                               mm_attrs_get_int_by_name(attrs, "display_visible", &visible);
-                               if (is_first_v_sink_x)
-                               {
-                                       mm_attrs_get_data_by_name(attrs, "display_overlay", &xid);
-                                       mm_attrs_get_data_by_name(attrs, "display_overlay_ext", &object);
-                               }
-                               else
-                               {
-                                       mm_attrs_get_data_by_name(attrs, "display_overlay", &object);
-                                       mm_attrs_get_data_by_name(attrs, "display_overlay_ext", &xid);
-                               }
-                               if (object)
-                               {
-                                       g_object_set(player->pipeline->videobin[videosink_idx_evas].gst,
-                                                       "evas-object", object,
-                                                       "visible", visible,
-                                                       NULL);
-                                       debug_log("use multi-surface : evas-object %x", object);
-                                       debug_log("use multi-surface : evas visible %d", object);
-                               }
-                               else
-                               {
-                                       debug_error("no evas object");
-                                       return MM_ERROR_PLAYER_INTERNAL;
-                               }
-                               if (xid)
-                               {
-                                       gst_x_overlay_set_xwindow_id( GST_X_OVERLAY( player->pipeline->videobin[videosink_idx_x].gst ), *(int*)xid );
-                               }
-                               else
-                               {
-                                       debug_error("no xwindow");
-                                       return MM_ERROR_PLAYER_INTERNAL;
-                               }
-                               /* if xvimagesink */
-                               if (!strcmp(PLAYER_INI()->videosink_element_x,"xvimagesink"))
-                               {
-                                       g_object_set(player->pipeline->videobin[videosink_idx_x].gst,
-                                                       "visible", FALSE,
-                                                       NULL );
-                               }
-                               debug_log("use multi-surface : xid %d", *(int*)xid);
-                               debug_log("use multi-surface : x visible %d", FALSE);
-                       }
-                       /* common case if using evas surface */
-                       else
-                       {
-                               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[videosink_idx_evas].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;
-                               }
-                       }
+                       /* we only handle messages from pipeline */
+                       if( msg->src != (GstObject *)player->pipeline->mainbin[MMPLAYER_M_PIPE].gst )
+                               break;
 
-                       /* if evasimagesink */
-                       if (!strcmp(PLAYER_INI()->videosink_element_evas,"evasimagesink") && player->is_nv12_tiled)
+                       if( !MMPLAYER_IS_RTSP_STREAMING(player) )
                        {
-                               int width = 0;
-                               int height = 0;
-                               int no_scaling = !scaling;
-
-                               mm_attrs_get_int_by_name(attrs, "display_width", &width);
-                               mm_attrs_get_int_by_name(attrs, "display_height", &height);
-
-                               if (no_scaling)
-                               {
-                                       /* no-scaling order to fimcconvert, original width, height size of media src will be passed to sink plugin */
-                                       g_object_set(player->pipeline->videobin[MMPLAYER_V_CONV].gst,
-                                                       "src-width", 0, /* setting 0, output video width will be media src's width */
-                                                       "src-height", 0, /* setting 0, output video height will be media src's height */
-                                                       NULL);
-                               }
-                               else
+                               if (player->doing_seek)
                                {
-                                       /* scaling order to fimcconvert */
-                                       if (width)
+                                       if (MMPLAYER_TARGET_STATE(player) == MM_PLAYER_STATE_PAUSED)
                                        {
-                                               g_object_set(player->pipeline->videobin[MMPLAYER_V_CONV].gst, "src-width", width, NULL);
+                                               player->doing_seek = FALSE;
+                                               MMPLAYER_POST_MSG ( player, MM_MESSAGE_SEEK_COMPLETED, NULL );
                                        }
-                                       if (height)
+                                       else if (MMPLAYER_TARGET_STATE(player) == MM_PLAYER_STATE_PLAYING)
                                        {
-                                               g_object_set(player->pipeline->videobin[MMPLAYER_V_CONV].gst, "src-height", height, NULL);
-                                       }
-                                       debug_log("set video param : video frame scaling down to width(%d) height(%d)", width, height);
-                               }
-                               debug_log("set video param : display_evas_do_scaling %d", scaling);
-                       }
-
-                       /* 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;
+                                               if ((MMPLAYER_IS_HTTP_STREAMING(player)) &&
+                                                       (player->streamer) &&
+                                                       (player->streamer->streaming_buffer_type == BUFFER_TYPE_MUXED) &&
+                                                       (player->streamer->is_buffering == FALSE))
+                                               {
+                                                       GstQuery *query = NULL;
+                                                       gboolean busy = FALSE;
+                                                       gint percent = 0;
 
-                               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);
+                                                       if (player->streamer->buffer_handle[BUFFER_TYPE_MUXED].buffer)
+                                                       {
+                                                               query = gst_query_new_buffering ( GST_FORMAT_PERCENT );
+                                                               if ( gst_element_query (player->streamer->buffer_handle[BUFFER_TYPE_MUXED].buffer, query ) )
+                                                               {
+                                                                       gst_query_parse_buffering_percent ( query, &busy, &percent);
+                                                               }
+                                                               gst_query_unref (query);
+
+                                                               debug_log("buffered percent(%s): %d\n",
+                                                                       GST_ELEMENT_NAME(player->streamer->buffer_handle[BUFFER_TYPE_MUXED].buffer), percent);
+                                                       }
 
-                               g_object_set(player->pipeline->videobin[videosink_idx_evas].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 );
+                                                       if (percent >= 100)
+                                                       {
+                                                               player->streamer->is_buffering = FALSE;
+                                                               __mmplayer_handle_buffering_message(player);
+                                                       }
+                                               }
 
-                               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);
+                                               async_done = TRUE;
+                                       }
+                               }
                        }
                }
                break;
-               case MM_DISPLAY_SURFACE_NULL:
-               {
-                       /* do nothing */
-               }
+
+               #if 0 /* delete unnecessary logs */
+               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;
+               case GST_MESSAGE_INFO:                          debug_log("GST_MESSAGE_STATE_DIRTY\n"); 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_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_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_LATENCY:                               debug_log("GST_MESSAGE_LATENCY\n"); break;
+               #endif
+
+               default:
                break;
        }
 
-       debug_fleave();
+       /* 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 MM_ERROR_NONE;
+       return ret;
 }
 
-static int
-__mmplayer_gst_element_link_bucket(GList* element_bucket) // @
+static gboolean
+__mmplayer_gst_handle_duration(mm_player_t* player, GstMessage* msg)
 {
-       GList* bucket = element_bucket;
-       MMPlayerGstElement* element = NULL;
-       MMPlayerGstElement* prv_element = NULL;
-       gint successful_link_count = 0;
+       GstFormat format;
+       gint64 bytes = 0;
 
-       debug_fenter();
+       MMPLAYER_FENTER();
 
-       return_val_if_fail(element_bucket, -1);
+       return_val_if_fail(player, FALSE);
+       return_val_if_fail(msg, FALSE);
 
-       prv_element = (MMPlayerGstElement*)bucket->data;
-       bucket = bucket->next;
+       gst_message_parse_duration (msg, &format, &bytes);
 
-       for ( ; bucket; bucket = bucket->next )
+       if (MMPLAYER_IS_HTTP_STREAMING(player) && format == GST_FORMAT_BYTES )
        {
-               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_log("data total size of http content: %lld", bytes);
+               player->http_content_size = bytes;
+       }
+       else if (format == GST_FORMAT_TIME)
+       {
+               /* handling audio clip which has vbr. means duration is keep changing */
+               _mmplayer_update_content_attrs (player, ATTR_DURATION );
+       }
+       else
+       {
+               debug_warning("duration is neither BYTES or TIME");
+               return FALSE;
        }
 
-       debug_fleave();
+       MMPLAYER_FLEAVE();
 
-       return successful_link_count;
+       return TRUE;
 }
 
-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 ++;
-               }
-       }
+static gboolean
+__mmplayer_gst_extract_tag_from_msg(mm_player_t* player, GstMessage* msg) // @
+{
 
-       debug_fleave();
+/* 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)\
+       {\
+               secure_debug_log ( "update tag string : %s\n", string); \
+               mm_attrs_set_string_by_name(attribute, playertag, string); \
+               g_free(string);\
+               string = NULL;\
+       }\
+}
 
-       return successful_add_count;
+#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); \
+       secure_debug_log ( "update album cover data : %p, size : %d\n", GST_BUFFER_DATA(buffer), GST_BUFFER_SIZE(buffer)); \
+       MMPLAYER_FREEIF(player->album_art); \
+       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)); \
+               if (MMPLAYER_IS_HTTP_LIVE_STREAMING(player)) \
+               { \
+                       msg_param.data = (void *)player->album_art; \
+                       msg_param.size = GST_BUFFER_SIZE(buffer); \
+                       MMPLAYER_POST_MSG (player, MM_MESSAGE_IMAGE_BUFFER, &msg_param); \
+                       secure_debug_log ( "post message image buffer data : %p, size : %d\n", GST_BUFFER_DATA(buffer), 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 (!strncmp(gsttag, GST_TAG_BITRATE, strlen(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);\
+                               secure_debug_log ( "update bitrate %d[bps] of stream #%d.\n", v_uint, player->updated_bitrate_count);\
+                       }\
+               }\
+               else if (!strncmp(gsttag, GST_TAG_MAXIMUM_BITRATE, strlen(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); \
+                               secure_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);\
+               secure_debug_log ( "metainfo year : %s\n", string);\
+               MMPLAYER_FREEIF(string);\
+               g_date_free(date);\
+       }\
+}
 
-/**
- * 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 )\
+#define MMPLAYER_UPDATE_TAG_UINT64(gsttag, attribute, playertag) \
+if(gst_tag_list_get_uint64(tag_list, gsttag, &v_uint64))\
 {\
-       debug_critical("failed to create %s \n", x_factory);\
-       goto ERROR;\
-}\
+       if(v_uint64)\
+       {\
+               /* FIXIT : don't know how to store date */\
+               g_assert(1);\
+               v_uint64 = 0;\
+       }\
+}
 
-/* 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 )\
+#define MMPLAYER_UPDATE_TAG_DOUBLE(gsttag, attribute, playertag) \
+if(gst_tag_list_get_double(tag_list, gsttag, &v_double))\
+{\
+       if(v_double)\
        {\
-               debug_critical("failed to create %s \n", x_factory);\
-               goto ERROR;\
+               /* FIXIT : don't know how to store date */\
+               g_assert(1);\
+               v_double = 0;\
        }\
-       if ( x_add_bucket )\
-               element_bucket = g_list_append(element_bucket, &x_bin[x_id]);\
-} while(0);
+}
 
+       /* function start */
+       GstTagList* tag_list = NULL;
 
-/**
-  * AUDIO PIPELINE 
-  * - Local playback   : audioconvert !volume ! capsfilter ! dnse ! 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();
+       char *string = NULL;
+       guint v_uint = 0;
+       GDate *date = NULL;
+       /* album cover */
+       GstBuffer *buffer = NULL;
+       gint index = 0;
+       const GValue *value;
+       MMMessageParamType msg_param = {0, };
 
-       return_val_if_fail( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       /* currently not used. but those are needed for above macro */
+       //guint64 v_uint64 = 0;
+       //gdouble v_double = 0;
 
-       /* alloc handles */
-       audiobin = (MMPlayerGstElement*)g_malloc0(sizeof(MMPlayerGstElement) * MMPLAYER_A_NUM);
-       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;
-       }
+       return_val_if_fail( player && msg, FALSE );
 
        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);
+       return_val_if_fail( attrs, FALSE );
 
-       /* converter */
-       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CONV, "audioconvert", "audioconverter", TRUE);
+       /* get tag list from gst message */
+       gst_message_parse_tag(msg, &tag_list);
 
-       if ( ! player->is_sound_extraction )
-       {
-               /* 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);
+       /* 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 (player->sound.mute)
-               {
-                       debug_log("mute enabled\n");
-                       g_object_set(G_OBJECT (audiobin[MMPLAYER_A_VOL].gst), "mute", player->sound.mute, NULL);
-               }
+       if ( mmf_attrs_commit ( attrs ) )
+               debug_error("failed to commit.\n");
 
-               /* NOTE : streaming doesn't need capsfilter and sound effect*/
-               if ( ! MMPLAYER_IS_RTSP_STREAMING( player ) )
-               {
-                       GstCaps* caps = NULL;
+       gst_tag_list_free(tag_list);
 
-                       /*capsfilter */
-                       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CAPS_DEFAULT, "capsfilter", "audiocapsfilter", TRUE);
+       return TRUE;
+}
 
-                       caps = gst_caps_from_string(            "audio/x-raw-int, "
-                                                                                       "endianness = (int) LITTLE_ENDIAN, "
-                                                                                       "signed = (boolean) true, "
-                                                                                       "width = (int) 16, "                                                                            
-                                                                                       "depth = (int) 16"      );
+static void
+__mmplayer_gst_rtp_no_more_pads (GstElement *element,  gpointer data)  // @
+{
+       mm_player_t* player = (mm_player_t*) data;
 
-                       g_object_set (GST_ELEMENT(audiobin[MMPLAYER_A_CAPS_DEFAULT].gst), "caps", caps, NULL );
+       MMPLAYER_FENTER();
 
-                       gst_caps_unref( caps );
+       /* 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
 
-                       /* audio filter. if enabled */
-                       if ( PLAYER_INI()->use_audio_filter_preset || PLAYER_INI()->use_audio_filter_custom )
-                       {
-                               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_FILTER, "soundalive", "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);
-               }
+         * [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 ( g_strrstr(PLAYER_INI()->name_of_audiosink, "avsysaudiosink") )
+               if ( ! __mmplayer_gst_remove_fakesink( player,
+                       &player->pipeline->mainbin[MMPLAYER_M_SRC_FAKESINK]) )
                {
-                       gint volume_type = 0;
-                       gint audio_route = 0;
-                       gint sound_priority = FALSE;
-                       gint is_spk_out_only = 0;
-
-                       /* set volume table
-                        * It should be set after player creation through attribute.
-                        * But, it can not be changed during playing.
+                       /* 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.
                         */
-                       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);
-
-                       g_object_set(audiobin[MMPLAYER_A_SINK].gst,
-                                                               "volumetype", volume_type,
-                                                               "audio-route", audio_route,
-                                                               "priority", sound_priority,
-                                                               "user-route", is_spk_out_only,
-                                                               NULL);
-
-                       debug_log("audiosink property status...volume type:%d, route:%d, priority=%d, user-route=%d\n",
-                               volume_type, audio_route, sound_priority, is_spk_out_only);
+                       return;
                }
-
-               /* 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);
+       /* create dot before error-return. for debugging */
+       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-no-more-pad" );
 
-               caps_type = gst_caps_to_string(caps);
-               debug_log("resampler new caps : %s\n", caps_type);
+       player->no_more_pad = TRUE;
 
-                       g_object_set (GST_ELEMENT(audiobin[MMPLAYER_A_CAPS_DEFAULT].gst), "caps", caps, NULL );
+       MMPLAYER_FLEAVE();
+}
 
-                       /* clean */
-                       gst_caps_unref( caps );
-                       MMPLAYER_FREEIF( caps_type );
+static gboolean
+__mmplayer_gst_remove_fakesink(mm_player_t* player, MMPlayerGstElement* fakesink) // @
+{
+       GstElement* parent = NULL;
 
-               /* fake sink */
-               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_SINK, "fakesink", "fakesink", TRUE);
+       return_val_if_fail(player && player->pipeline, FALSE);
 
-               /* set sync */
-               g_object_set (G_OBJECT (audiobin[MMPLAYER_A_SINK].gst), "sync", FALSE, NULL);
+       /* if we have no fakesink. this meas we are using decodebin2 which doesn'
+       t need to add extra fakesink */
+       return_val_if_fail(fakesink, TRUE);
 
-               __mmplayer_add_sink( player, audiobin[MMPLAYER_A_SINK].gst );
-       }
+       /* lock */
+       g_mutex_lock( player->fsink_lock );
 
-       /* 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 ))
+       if ( ! fakesink->gst )
        {
-               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 )
+       /* get parent of fakesink */
+       parent = (GstElement*)gst_object_get_parent( (GstObject*)fakesink->gst );
+       if ( ! parent )
        {
-               debug_error("failed to link elements\n");
+               debug_log("fakesink already removed\n");
                goto ERROR;
        }
 
-       /* get first element's sinkpad for creating ghostpad */
-       first_element = (MMPlayerGstElement *)element_bucket->data;
+       gst_element_set_locked_state( fakesink->gst, TRUE );
 
-       pad = gst_element_get_static_pad(GST_ELEMENT(first_element->gst), "sink");
-       if ( ! pad )
+       /* 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("failed to get pad from first element of audiobin\n");
-               goto ERROR;
-       }
+               debug_error("fakesink state change failure!\n");
 
-       ghostpad = gst_ghost_pad_new("sink", pad);
-       if ( ! ghostpad )
-       {
-               debug_error("failed to create ghostpad\n");
-               goto ERROR;
+               /* FIXIT : should I return here? or try to proceed to next? */
+               /* return FALSE; */
        }
 
-       if ( FALSE == gst_element_add_pad(audiobin[MMPLAYER_A_BIN].gst, ghostpad) )
+       /* remove fakesink from it's parent */
+       if ( ! gst_bin_remove( GST_BIN( parent ), fakesink->gst ) )
        {
-               debug_error("failed to add ghostpad to audiobin\n");
-               goto ERROR;
-       }
+               debug_error("failed to remove fakesink\n");
 
-       gst_object_unref(pad);
+               gst_object_unref( parent );
 
-       if ( !player->bypass_sound_effect && (PLAYER_INI()->use_audio_filter_preset || PLAYER_INI()->use_audio_filter_custom) )
-       {
-               if ( player->audio_filter_info.filter_type == MM_AUDIO_FILTER_TYPE_PRESET )
-               {
-                       if (!_mmplayer_sound_filter_preset_apply(player, player->audio_filter_info.preset))
-                       {
-                               debug_msg("apply sound effect(preset:%d) setting success\n",player->audio_filter_info.preset);
-                       }
-               }
-               else if ( player->audio_filter_info.filter_type == MM_AUDIO_FILTER_TYPE_CUSTOM )
-               {
-                       if (!_mmplayer_sound_filter_custom_apply(player))
-                       {
-                               debug_msg("apply sound effect(custom) setting success\n");
-                       }
-               }
+               goto ERROR;
        }
 
-       /* done. free allocated variables */
-       MMPLAYER_FREEIF( device_name );
-       g_list_free(element_bucket);
+       gst_object_unref( parent );
 
-       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_log("state-holder removed\n");
 
-       debug_fleave();
+       gst_element_set_locked_state( fakesink->gst, FALSE );
 
-       return MM_ERROR_NONE;
+       g_mutex_unlock( player->fsink_lock );
+       return TRUE;
 
 ERROR:
+       if ( fakesink->gst )
+       {
+               gst_element_set_locked_state( fakesink->gst, FALSE );
+       }
 
-       debug_log("ERROR : releasing audiobin\n");
+       g_mutex_unlock( player->fsink_lock );
+       return FALSE;
+}
 
-       MMPLAYER_FREEIF( device_name );
 
-       if ( pad )
-               gst_object_unref(GST_OBJECT(pad));
+static void
+__mmplayer_gst_rtp_dynamic_pad (GstElement *element, GstPad *pad, gpointer data) // @
+{
+       GstPad *sinkpad = NULL;
+       GstCaps* caps = NULL;
+       GstElement* new_element = NULL;
+       GstStructure* str = NULL;
+       const gchar* name = NULL;
 
-       if ( ghostpad )
-               gst_object_unref(GST_OBJECT(ghostpad));
+       mm_player_t* player = (mm_player_t*) data;
 
-       g_list_free( element_bucket );
+       MMPLAYER_FENTER();
 
+       return_if_fail( element && pad );
+       return_if_fail( player &&
+                                       player->pipeline &&
+                                       player->pipeline->mainbin );
 
-       /* 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));
-                       }
-               }
-       }
+       /* 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);
 
-       /* release audiobin with it's childs */
-       if ( audiobin[MMPLAYER_A_BIN].gst )
+       /* perform autoplugging if dump is disabled */
+       if ( player->ini.rtsp_do_typefinding )
        {
-               gst_object_unref(GST_OBJECT(audiobin[MMPLAYER_A_BIN].gst));
-       }
+               /* create typefind */
+               new_element = gst_element_factory_make( "typefind", NULL );
+               if ( ! new_element )
+               {
+                       debug_error("failed to create typefind\n");
+                       goto ERROR;
+               }
 
-       MMPLAYER_FREEIF( audiobin );
+               MMPLAYER_SIGNAL_CONNECT(        player,
+                                                                       G_OBJECT(new_element),
+                                                                       MM_PLAYER_SIGNAL_TYPE_AUTOPLUG,
+                                                                       "have-type",
+                                                                       G_CALLBACK(__mmplayer_typefind_have_type),
+                                                                       (gpointer)player);
 
-       player->pipeline->audiobin = NULL;
+               /* 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");
 
-       return MM_ERROR_PLAYER_INTERNAL;
-}
+               caps = gst_pad_get_caps( pad );
 
-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;
+               MMPLAYER_CHECK_NULL( caps );
 
-       data = GST_BUFFER_DATA(buffer);
-       size = GST_BUFFER_SIZE(buffer);
+               /* clear  previous result*/
+               player->have_dynamic_pad = FALSE;
 
-       if (player->audio_stream_cb && size && data)
-               player->audio_stream_cb((void *)data, size, player->audio_stream_cb_user_param);
+               str = gst_caps_get_structure(caps, 0);
 
-       return TRUE;
-}
+               if ( ! str )
+               {
+                       debug_error ("cannot get structure from capse.\n");
+                       goto ERROR;
+               }
 
-gboolean
-__mmplayer_ahs_appsrc_probe (GstPad *pad, GstBuffer *buffer, gpointer u_data)
-{      
-       mm_player_t* player = (mm_player_t*) u_data;
+               name = gst_structure_get_name (str);
+               if ( ! name )
+               {
+                       debug_error ("cannot get mimetype from structure.\n");
+                       goto ERROR;
+               }
 
-       //g_print ("appsrc buf : timestamp = %"GST_TIME_FORMAT", duration = %"GST_TIME_FORMAT"\n", 
-       //      GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)), GST_TIME_ARGS (GST_BUFFER_DURATION(buffer)));
+               if (strstr(name, "video"))
+               {
+                       gint stype = 0;
+                       mm_attrs_get_int_by_name (player->attrs, "display_surface_type", &stype);
 
-       if (ahs_check_allow_cache (player->ahs_player))
-       {
-               ahs_store_media_presentation (player->ahs_player, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer));
-       }
-       return TRUE;
-}
+                       if (stype == MM_DISPLAY_SURFACE_NULL)
+                       {
+                               if (player->v_stream_caps)
+                               {
+                                       gst_caps_unref(player->v_stream_caps);
+                                       player->v_stream_caps = NULL;
+                               }
 
-/**
- * This function is to create video pipeline.
- *
- * @param      player          [in]    handle of player
- *             caps            [in]    src caps of decoder
- *
- * @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) : xvimagesink
-  * - evas surface  (arm) : evaspixmapsink
-  *                         fimcconvert ! evasimagesink
-  * - evas surface  (x86) : videoconvertor ! evasimagesink
-  * - multi-surface (arm) : tee name=tee ! xvimagesink tee. ! evaspixmapsink
-  */
-static int
-__mmplayer_gst_create_video_pipeline(mm_player_t* player, GstCaps* caps)
-{
-       GstPad *pad = NULL;
-       MMHandleType attrs;
-       GList*element_bucket = NULL;
-       MMPlayerGstElement* first_element = NULL;
-       MMPlayerGstElement* videobin = NULL;
-       gchar* vconv_factory = NULL;
-       char *err_name = NULL;
-       gboolean use_multi_surface = FALSE;
-       char *videosink_element = NULL;
-       char *videosink_element_ext = NULL;
+                               new_element = gst_element_factory_make("fakesink", NULL);
+                               player->num_dynamic_pad--;
+                               goto NEW_ELEMENT;
+                       }
+               }
 
-       debug_fenter();
+               /* clear  previous result*/
+               player->have_dynamic_pad = FALSE;
 
-       return_val_if_fail(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
+               if ( ! __mmplayer_try_to_plug( player, pad, caps ) )
+               {
+                       debug_error("failed to autoplug for caps");
+                       goto ERROR;
+               }
 
-       /* alloc handles */
-       videobin = (MMPlayerGstElement*)g_malloc0(sizeof(MMPlayerGstElement) * MMPLAYER_V_NUM);
-       if ( !videobin )
-               return MM_ERROR_PLAYER_NO_FREE_SPACE;
+               /* 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;
+               }
 
-       player->pipeline->videobin = videobin;
+               gst_caps_unref( caps );
+               caps = NULL;
+       }
 
-       attrs = MMPLAYER_GET_ATTRS(player);
+       NEW_ELEMENT:
 
-       /* 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 )
+       /* excute new_element if created*/
+       if ( new_element )
        {
-               debug_critical("failed to create audiobin\n");
-               goto ERROR;
-       }
-
-       mm_player_get_attribute(player, &err_name, "display_surface_use_multi", &use_multi_surface, NULL);
-       player->use_multi_surface = use_multi_surface;
-
-       if( player->use_video_stream ) // video stream callack, so send raw video data to application
-       {
-               GstStructure *str = NULL;
-               guint32 fourcc = 0;
-               gint ret = 0;
+               debug_log("adding new element to pipeline\n");
 
-               debug_log("using memsink\n");
+               /* set state to READY before add to bin */
+               MMPLAYER_ELEMENT_SET_STATE( new_element, GST_STATE_READY );
 
-               /* first, create colorspace convert */
-               if (player->is_nv12_tiled)
-               {
-                       vconv_factory = "fimcconvert";
-               }
-               else // get video converter from player ini file
+               /* add new element to the pipeline */
+               if ( FALSE == gst_bin_add( GST_BIN(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst), new_element)  )
                {
-                       if (strlen(PLAYER_INI()->name_of_video_converter) > 0)
-                       {
-                               vconv_factory = PLAYER_INI()->name_of_video_converter;
-                       }
+                       debug_error("failed to add autoplug element to bin\n");
+                       goto ERROR;
                }
 
-               if (vconv_factory)
+               /* get pad from element */
+               sinkpad = gst_element_get_static_pad ( GST_ELEMENT(new_element), "sink" );
+               if ( !sinkpad )
                {
-                       MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_CONV, vconv_factory, "video converter", TRUE);
+                       debug_error("failed to get sinkpad from autoplug element\n");
+                       goto ERROR;
                }
-               
-               /* then, create video scale to resize if needed */
-               str = gst_caps_get_structure (caps, 0);
 
-               if ( ! str )
+               /* link it */
+               if ( GST_PAD_LINK_OK != GST_PAD_LINK(pad, sinkpad) )
                {
-                       debug_error("cannot get structure\n");
+                       debug_error("failed to link autoplug element\n");
                        goto ERROR;
                }
 
-               MMPLAYER_LOG_GST_CAPS_TYPE(caps);
+               gst_object_unref (sinkpad);
+               sinkpad = NULL;
 
-               ret = gst_structure_get_fourcc (str, "format", &fourcc);
+               /* run. setting PLAYING here since streamming source is live source */
+               MMPLAYER_ELEMENT_SET_STATE( new_element, GST_STATE_PLAYING );
+       }
 
-               if ( !ret )
-                       debug_log("not fixed format at this point, and not consider this case\n")
+       MMPLAYER_FLEAVE();
 
-               /* NOTE :  if the width of I420 format is not multiple of 8, it should be resize before colorspace conversion.
-                 * so, video scale is required for this case only.
-                 */
-               if ( GST_MAKE_FOURCC ('I', '4', '2', '0') == fourcc )
-               {
-                       gint width = 0;                         //width of video
-                       gint height = 0;                        //height of video
-                       gint framerate_n = 0;           //numerator of frame rate
-                       gint framerate_d = 0;           //denominator of frame rate
-                       GstCaps* video_caps = NULL;
-                       GValue *fps = NULL;
+       return;
 
-                       /* video scale  */
-                       MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_SCALE, "videoscale", "videoscale", TRUE);
+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));
 
-                       /*to limit width as multiple of 8 */
-                       MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_CAPS, "capsfilter", "videocapsfilter", TRUE);
+       if ( sinkpad )
+               gst_object_unref(GST_OBJECT(sinkpad));
 
-                       /* get video stream caps parsed by demuxer */
-                       str = gst_caps_get_structure (player->v_stream_caps, 0);
-                       if ( ! str )
-                       {
-                               debug_error("cannot get structure\n");
-                               goto ERROR;
-                       }
+       if ( caps )
+               gst_object_unref(GST_OBJECT(caps));
 
-                       /* check the width if it's a multiple of 8 or not */
-                       ret = gst_structure_get_int (str, "width", &width);
-                       if ( ! ret )
-                       {
-                               debug_error("cannot get width\n");
-                               goto ERROR;
-                       }
-                       width = GST_ROUND_UP_8(width);
+       /* 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
+        */
+}
 
-                       ret = gst_structure_get_int(str, "height", &height);
-                       if ( ! ret )
-                       {
-                               debug_error("cannot get height\n");
-                               goto ERROR;
-                       }
 
-                       fps = gst_structure_get_value (str, "framerate");
-                       if ( ! fps )
-                       {
-                               debug_error("cannot get fps\n");
-                               goto ERROR;
-                       }
-                       framerate_n = gst_value_get_fraction_numerator (fps);
-                       framerate_d = gst_value_get_fraction_denominator (fps);
 
-                       video_caps = gst_caps_new_simple( "video/x-raw-yuv",
-                                                                                       "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('I', '4', '2', '0'),
-                                                                                       "width", G_TYPE_INT, width,
-                                                                                       "height", G_TYPE_INT, height,
-                                                                                       "framerate", GST_TYPE_FRACTION, framerate_n, framerate_d,
-                                                                                       NULL);
+/* FIXIT : check indent */
+static void
+__mmplayer_gst_wfd_dynamic_pad (GstElement *element, GstPad *pad, gpointer data) // @
+{
+  GstPad *sinkpad = NULL;
+  GstCaps* caps = NULL;
+  GstElement* new_element = NULL;
+  enum MainElementID element_id = MMPLAYER_M_NUM;
+
+  mm_player_t* player = (mm_player_t*) data;
+
+  MMPLAYER_FENTER();
+
+  return_if_fail( element && pad );
+  return_if_fail(  player &&
+          player->pipeline &&
+          player->pipeline->mainbin );
+
+  debug_log("stream count inc : %d\n", player->num_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;
+    new_element = gst_element_factory_make("rtpmp2tdepay", "wfd_rtp_depay");
+    if ( !new_element )
+    {
+      debug_error ( "failed to create wfd rtp depay element\n" );
+      goto ERROR;
+    }
+    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_log("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_log("failed to get sinkpad from autoplug element\n");
+      goto ERROR;
+    }
+    /* link it */
+    if ( GST_PAD_LINK_OK != GST_PAD_LINK(pad, sinkpad) )
+    {
+      debug_log("failed to link autoplug element\n");
+      goto ERROR;
+    }
+    gst_object_unref (sinkpad);
+    sinkpad = NULL;
+    pad = gst_element_get_static_pad ( GST_ELEMENT(new_element), "src" );
+    caps = gst_pad_get_caps( pad );
+    MMPLAYER_CHECK_NULL( caps );
+    MMPLAYER_ELEMENT_SET_STATE( new_element, GST_STATE_PLAYING );
+    /* create typefind */
+    new_element = gst_element_factory_make( "typefind", NULL );
+    if ( ! new_element )
+    {
+      debug_log("failed to create typefind\n");
+      goto ERROR;
+    }
+
+    MMPLAYER_SIGNAL_CONNECT(   player,
+                G_OBJECT(new_element),
+                MM_PLAYER_SIGNAL_TYPE_AUTOPLUG,
+                "have-type",
+                G_CALLBACK(__mmplayer_typefind_have_type),
+                (gpointer)player);
+
+    player->have_dynamic_pad = FALSE;
+  }
+
+  /* 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_log("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_log("failed to get sinkpad from autoplug element\n");
+      goto ERROR;
+    }
+
+    /* link it */
+    if ( GST_PAD_LINK_OK != GST_PAD_LINK(pad, sinkpad) )
+    {
+      debug_log("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 );
+  }
+
+  /* store handle to futher manipulation */
+  player->pipeline->mainbin[element_id].id = element_id;
+  player->pipeline->mainbin[element_id].gst = new_element;
+
+  MMPLAYER_FLEAVE();
+
+  return;
 
-                       g_object_set (GST_ELEMENT(videobin[MMPLAYER_V_CAPS].gst), "caps", video_caps, NULL );
+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));
 
-                       gst_caps_unref( video_caps );
-               }
+  if ( sinkpad )
+    gst_object_unref(GST_OBJECT(sinkpad));
 
-               /* finally, create video sink. its oupput should be BGRX8888 for application like cario surface. */
-               MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_SINK, "avsysmemsink", "videosink", TRUE);
+  if ( caps )
+    gst_object_unref(GST_OBJECT(caps));
 
-               MMPLAYER_SIGNAL_CONNECT( player,
-                                                                        videobin[MMPLAYER_V_SINK].gst,
-                                                                        "video-stream",
-                                                                        G_CALLBACK(__mmplayer_videostream_cb),
-                                                                        player );
+  /* 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_selector_blocked (GstPad* pad, gboolean blocked, gpointer data)
+{
+       debug_log ("pad blocked callback, blocked: %d", blocked);
+}
+
+static void
+__mmplayer_gst_decode_pad_added (GstElement *elem, GstPad *pad, gpointer data)
+{
+       mm_player_t* player = NULL;
+       GstElement* pipeline = NULL;
+       GstElement* selector = NULL;
+       GstElement* fakesink = NULL;
+       GstCaps* caps = NULL;
+       GstStructure* str = NULL;
+       const gchar* name = NULL;
+       GstPad* sinkpad = NULL;
+       GstPad* srcpad = NULL;
+       gboolean first_track = FALSE;
+
+       enum MainElementID elemId = MMPLAYER_M_NUM;
+
+       /* check handles */
+       player = (mm_player_t*)data;
+
+       return_if_fail (elem && pad);
+       return_if_fail (player && player->pipeline && player->pipeline->mainbin);
+
+       //debug_log ("pad-added signal handling\n");
+
+       pipeline = player->pipeline->mainbin[MMPLAYER_M_PIPE].gst;
+
+       /* get mimetype from caps */
+       caps = gst_pad_get_caps (pad);
+       if ( !caps )
+       {
+               debug_error ("cannot get caps from pad.\n");
+               goto ERROR;
        }
-       else // render video data using sink pugin like xvimagesink
+
+       str = gst_caps_get_structure (caps, 0);
+       if ( ! str )
        {
-               debug_log("using videosink");
-               
-               /*set video converter */
-               if (strlen(PLAYER_INI()->name_of_video_converter) > 0)
-               {
-                       vconv_factory = PLAYER_INI()->name_of_video_converter;
-                       gboolean nv12t_hw_enabled = FALSE;
+               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;
+       }
+
+       MMPLAYER_LOG_GST_CAPS_TYPE(caps);
+       //debug_log ("detected mimetype : %s\n", name);
 
-                       if (player->is_nv12_tiled && PLAYER_INI()->use_video_hw_accel)
-                               nv12t_hw_enabled = TRUE;
-               
-                       if ( (nv12t_hw_enabled && (PLAYER_INI()->video_surface == MM_DISPLAY_SURFACE_EVAS) && !strcmp(PLAYER_INI()->videosink_element_evas, "evasimagesink")) || (nv12t_hw_enabled && use_multi_surface && !strcmp(PLAYER_INI()->videosink_element_evas, "evasimagesink") ) )
+       if (strstr(name, "video"))
+       {
+               gint stype = 0;
+               mm_attrs_get_int_by_name (player->attrs, "display_surface_type", &stype);
+
+               /* don't make video because of not required, and not support multiple track */
+               if (stype == MM_DISPLAY_SURFACE_NULL)
+               {
+                       debug_log ("no video sink by null surface or multiple track");
+                       gchar *caps_str = gst_caps_to_string(caps);
+                       if (strstr(caps_str, "ST12") || strstr(caps_str, "SN12"))
                        {
-                               vconv_factory = "fimcconvert";
+                               player->set_mode.video_zc = TRUE;
                        }
-                       else if (nv12t_hw_enabled)
+                       MMPLAYER_FREEIF( caps_str );
+
+                       if (player->v_stream_caps)
                        {
-                               vconv_factory = NULL;
+                               gst_caps_unref(player->v_stream_caps);
+                               player->v_stream_caps = NULL;
                        }
 
-                       if (vconv_factory && !use_multi_surface)
+                       debug_log ("create fakesink instead of videobin");
+
+                       /* fake sink */
+                       fakesink = gst_element_factory_make ("fakesink", NULL);
+                       if (fakesink == NULL)
                        {
-                               MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_CONV, vconv_factory, "video converter", TRUE);
-                               debug_log("using video converter: %s", vconv_factory);
+                               debug_error ("ERROR : fakesink create error\n");
+                               goto ERROR;
                        }
-               }
 
-               /* videoscaler */ /* NOTE : ini parsing method seems to be more suitable rather than define method */
-               #if !defined(__arm__)
-               if (!use_multi_surface) /* NOTE : at now, we did not consider using multi-surface in x86 case */
-               {
-                       MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_SCALE, "videoscale", "videoscaler", TRUE);
-               }
-               #endif
+                       player->video_fakesink = fakesink;
 
-               /* set video sink */
-               switch (PLAYER_INI()->video_surface)
-               {
-                       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_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;
-               }
+                       gst_bin_add (GST_BIN(pipeline), fakesink);
 
-               if (use_multi_surface)
-               {
-                       if ( (strlen(PLAYER_INI()->videosink_element_x) > 0 ) && (strlen(PLAYER_INI()->videosink_element_evas) > 0 ) )
+                       // link
+                       sinkpad = gst_element_get_static_pad (fakesink, "sink");
+
+                       if (GST_PAD_LINK_OK != gst_pad_link(pad, sinkpad))
                        {
-                               /* create elements for multi sink usage */
-                               MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_TEE, "tee", "tee", TRUE);
-                               debug_log("using tee");
+                               debug_warning ("failed to link fakesink\n");
+                               gst_object_unref (GST_OBJECT(fakesink));
+                               goto ERROR;
+                       }
 
-                               if (vconv_factory)
-                               {
-                                       MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_CONV, vconv_factory, "video converter", TRUE);
-                                       debug_log("using video converter: %s", vconv_factory);
-                               }
+                       if (player->set_mode.media_packet_video_stream)
+                               player->video_cb_probe_id = gst_pad_add_buffer_probe (sinkpad, G_CALLBACK (__mmplayer_video_stream_probe), player);
 
-                               if (PLAYER_INI()->video_surface == MM_DISPLAY_SURFACE_X)
-                               {
-                                       videosink_element_ext = PLAYER_INI()->videosink_element_evas;
-                                       MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_SINK_EXT, videosink_element_ext, "videosink_ext_evas", TRUE);
-                               }
-                               else if (PLAYER_INI()->video_surface == MM_DISPLAY_SURFACE_EVAS)
-                               {
-                                       videosink_element_ext = PLAYER_INI()->videosink_element_x;
-                                       MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_SINK_EXT, videosink_element_ext, "videosink_ext_x", TRUE);
-                               }
-                               else
-                               {
-                                       debug_error("not normal case..multi-surface mode is only available with X and EVAS surface");
-                                       goto ERROR;
-                               }
-                               debug_log("selected videosink_ext name: %s", videosink_element_ext);
-                       }
+                       g_object_set (G_OBJECT (fakesink), "async", TRUE, NULL);
+                       g_object_set (G_OBJECT (fakesink), "sync", TRUE, NULL);
+                       gst_element_set_state (fakesink, GST_STATE_PAUSED);
+
+                       goto DONE;
                }
-               MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_SINK, videosink_element, "videosink", TRUE);
-               debug_log("selected videosink name: %s", videosink_element);
+
+               debug_log ("video selector \n");
+               elemId = MMPLAYER_M_V_INPUT_SELECTOR;
        }
+       else
+       {
+               if (strstr(name, "audio"))
+               {
+                       gint samplerate = 0;
+                       gint channels = 0;
 
-       if ( _mmplayer_update_video_param(player) != MM_ERROR_NONE)
-               goto ERROR;
+                       debug_log ("audio selector \n");
+                       elemId = MMPLAYER_M_A_INPUT_SELECTOR;
 
-       /* qos on */
-       g_object_set (G_OBJECT (videobin[MMPLAYER_V_SINK].gst), "qos", TRUE, NULL);
+                       gst_structure_get_int (str, "rate", &samplerate);
+                       gst_structure_get_int (str, "channels", &channels);
 
-       if (use_multi_surface)
-       {
-               g_object_set (G_OBJECT (videobin[MMPLAYER_V_SINK_EXT].gst), "qos", TRUE, NULL);
-               g_object_set (G_OBJECT (videobin[MMPLAYER_V_SINK].gst), "async", FALSE, NULL);
-               g_object_set (G_OBJECT (videobin[MMPLAYER_V_SINK_EXT].gst), "async", FALSE, NULL);
-       }
+                       if ((channels > 0 && samplerate == 0)) {//exclude audio decoding
+                               /* fake sink */
+                               fakesink = gst_element_factory_make ("fakesink", NULL);
+                               if (fakesink == NULL)
+                               {
+                                       debug_error ("ERROR : fakesink create error\n");
+                                       goto ERROR;
+                               }
 
-       /* store it as it's sink element */
-       __mmplayer_add_sink( player, videobin[MMPLAYER_V_SINK].gst );
-       if (use_multi_surface)
-       {
-               __mmplayer_add_sink( player, videobin[MMPLAYER_V_SINK_EXT].gst );
-       }
+                               gst_bin_add (GST_BIN(pipeline), fakesink);
 
-       /* 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;
-       }
+                               /* link */
+                               sinkpad = gst_element_get_static_pad (fakesink, "sink");
 
-       if (!use_multi_surface)
-       {
-               /* Linking elements in the bucket by added order */
-               if ( __mmplayer_gst_element_link_bucket(element_bucket) == -1 )
+                               if (GST_PAD_LINK_OK != gst_pad_link(pad, sinkpad))
+                               {
+                                       debug_warning ("failed to link fakesink\n");
+                                       gst_object_unref (GST_OBJECT(fakesink));
+                                       goto ERROR;
+                               }
+
+                               g_object_set (G_OBJECT (fakesink), "async", TRUE, NULL);
+                               g_object_set (G_OBJECT (fakesink), "sync", TRUE, NULL);
+                               gst_element_set_state (fakesink, GST_STATE_PAUSED);
+
+                               goto DONE;
+                       }
+               }
+               else if (strstr(name, "text"))
+               {
+                       debug_log ("text selector \n");
+                       elemId = MMPLAYER_M_T_SUBMUX_INTERNAL;
+               }
+               else
                {
-                       debug_error("failed to link elements\n");
+                       debug_error ("wrong elem id \n");
                        goto ERROR;
                }
        }
-       else
+
+       selector = player->pipeline->mainbin[elemId].gst;
+
+       if (selector == NULL)
        {
-               GstPad *sinkpad;
-               int i = 0;
-               for (i = 0 ; i < 2 ; i++)
+               if (strstr(name, "audio") || strstr(name, "video")) {
+                       selector = gst_element_factory_make ("input-selector", NULL);
+                       debug_log ("Creating input-selector\n");
+                       if (selector == NULL)
+                       {
+                               debug_error ("ERROR : input-selector create error\n");
+                               goto ERROR;
+                       }
+                       g_object_set (selector, "sync-streams", TRUE, NULL);
+               }
+               else
                {
-                       if (!vconv_factory)
+                       if (player->textsink_linked)
                        {
-                               sinkpad = gst_element_get_static_pad (videobin[MMPLAYER_V_SINK+i].gst, "sink");
-                               debug_log("do not need vconv");
+                               selector = gst_element_factory_make ("input-selector", "text-inselector");
+                               debug_log ("Creating input-selector\n");
                        }
                        else
                        {
-                               if (PLAYER_INI()->video_surface == MM_DISPLAY_SURFACE_X)
-                               {
-                                       if (i == 0)
-                                       {
-                                               sinkpad = gst_element_get_static_pad (videobin[MMPLAYER_V_SINK].gst, "sink");
-                                       }
-                                       else
-                                       {
-                                               sinkpad = gst_element_get_static_pad (videobin[MMPLAYER_V_CONV].gst, "sink");
-                                               GST_ELEMENT_LINK(GST_ELEMENT(videobin[MMPLAYER_V_CONV].gst), GST_ELEMENT(videobin[MMPLAYER_V_SINK_EXT].gst));
-                                       }
-                               }
-                               else
-                               {
-                                       if (i == 0)
-                                       {
-                                               sinkpad = gst_element_get_static_pad (videobin[MMPLAYER_V_CONV].gst, "sink");
-                                               GST_ELEMENT_LINK(GST_ELEMENT(videobin[MMPLAYER_V_CONV].gst), GST_ELEMENT(videobin[MMPLAYER_V_SINK].gst));
-                                       }
-                                       else
-                                       {
-                                               sinkpad = gst_element_get_static_pad (videobin[MMPLAYER_V_SINK_EXT].gst, "sink");
-                                       }
-                               }
+                               selector = gst_element_factory_make ("submux", "internal-submux");
+                               g_object_set (G_OBJECT (selector), "lang-list", player->subtitle_language_list, NULL);
+                               debug_log ("Creating submux\n");
                        }
-                       player->tee_src_pad[i] = gst_element_get_request_pad (videobin[MMPLAYER_V_TEE].gst, "src%d");
-                       if (gst_pad_link (player->tee_src_pad[i], sinkpad) != GST_PAD_LINK_OK) {
-                               debug_error("failed to link tee element with sink element(%d)",i);
+                       if (selector == NULL)
+                       {
+                               debug_error ("ERROR : input-selector create error\n");
                                goto ERROR;
                        }
-                       gst_object_unref (sinkpad);
+                       debug_log ("Created submux %p\n", selector);
                }
-       }
+               gst_bin_add (GST_BIN(pipeline), selector);
+               gst_element_set_state (selector, GST_STATE_PAUSED);
 
-       /* get first element's sinkpad for creating ghostpad */
-       first_element = (MMPlayerGstElement *)element_bucket->data;
-       if ( !first_element )
+               player->pipeline->mainbin[elemId].id = elemId;
+               player->pipeline->mainbin[elemId].gst = selector;
+
+               first_track = TRUE;
+               // player->selector[stream_type].active_pad_index = DEFAULT_TRACK;      // default
+
+               srcpad = gst_element_get_static_pad (selector, "src");
+
+               debug_log ("blocking %" GST_PTR_FORMAT, srcpad);
+               gst_pad_set_blocked_async (srcpad, TRUE, __mmplayer_gst_selector_blocked, NULL);
+       }
+       else
        {
-               debug_error("failed to get first element from bucket\n");
-               goto ERROR;
+               debug_log ("input-selector is already created.\n");
+               selector = player->pipeline->mainbin[elemId].gst;
        }
 
-       pad = gst_element_get_static_pad(GST_ELEMENT(first_element->gst), "sink");
-       if ( !pad )
+       // link
+       debug_log ("Calling request pad with selector %p \n", selector);
+       sinkpad = gst_element_get_request_pad (selector, "sink%d");
+
+       debug_log ("got pad %s:%s from selector", GST_DEBUG_PAD_NAME (sinkpad));
+
+       if (GST_PAD_LINK_OK != gst_pad_link(pad, sinkpad))
        {
-               debug_error("failed to get pad from first element\n");
+               debug_warning ("failed to link selector\n");
+               gst_object_unref (GST_OBJECT(selector));
                goto ERROR;
        }
 
-       /* create ghostpad */
-       if ( FALSE == gst_element_add_pad(videobin[MMPLAYER_V_BIN].gst, gst_ghost_pad_new("sink", pad)) )
+       if (first_track && (strstr(name, "audio") || strstr(name, "video")))
        {
-               debug_error("failed to add ghostpad to videobin\n");
-               goto ERROR;
+               debug_log ("this is first track --> active track \n");
+               g_object_set (selector, "active-pad", sinkpad, NULL);
+       } else {
+               debug_log ("subtitle is of internal type \n");
+               if(!player->textsink_linked) {
+                       g_object_set (selector, "is-internal", TRUE, NULL);
+               } else {
+                       debug_log ("this is first track --> active track \n");
+                       g_object_set (selector, "active-pad", sinkpad, NULL);
+               }
        }
-       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");
+DONE:
+ERROR:
 
-       debug_fleave();
+       if (caps)
+       {
+               gst_caps_unref (caps);
+       }
 
-       return MM_ERROR_NONE;
+       if (sinkpad)
+       {
+               gst_object_unref (GST_OBJECT(sinkpad));
+               sinkpad = NULL;
+       }
 
-ERROR:
-       debug_error("ERROR : releasing videobin\n");
+       if (srcpad)
+       {
+               gst_object_unref (GST_OBJECT(srcpad));
+               srcpad = NULL;
+       }
 
-       g_list_free( element_bucket );
+       return;
+}
 
-       if (pad)
-               gst_object_unref(GST_OBJECT(pad));
+static void __mmplayer_handle_text_decode_path(mm_player_t* player, GstElement* text_selector)
+{
+       #define DEFAULT_TRACK 0
+       GstPad* srcpad = NULL;
+       MMHandleType attrs = 0;
+       gint active_index = 0;
 
-       /* release videobin with it's childs */
-       if ( videobin[MMPLAYER_V_BIN].gst )
+       // [link] input-selector :: textbin
+       srcpad = gst_element_get_static_pad (text_selector, "src");
+       if (!srcpad)
        {
-               gst_object_unref(GST_OBJECT(videobin[MMPLAYER_V_BIN].gst));
+               debug_error("failed to get srcpad from selector\n");
+               return;
        }
 
+       debug_log ("got pad %s:%s from text selector\n", GST_DEBUG_PAD_NAME(srcpad));
 
-       MMPLAYER_FREEIF( videobin );
-
-       player->pipeline->videobin = NULL;
+       active_index = player->selector[MM_PLAYER_TRACK_TYPE_TEXT].active_pad_index;
+       if ((active_index != DEFAULT_TRACK) &&
+               (__mmplayer_change_selector_pad(player, MM_PLAYER_TRACK_TYPE_TEXT, active_index) != MM_ERROR_NONE))
+       {
+               debug_warning("failed to change text track\n");
+               player->selector[MM_PLAYER_TRACK_TYPE_TEXT].active_pad_index = DEFAULT_TRACK;
+       }
 
-       return MM_ERROR_PLAYER_INTERNAL;
-}
+       player->no_more_pad = TRUE;
+       __mmplayer_gst_decode_callback (text_selector, srcpad, player);
 
-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_log ("unblocking %" GST_PTR_FORMAT, srcpad);
+       gst_pad_set_blocked_async (srcpad, FALSE, __mmplayer_gst_selector_blocked, NULL);
 
-       debug_fenter();
+       debug_log("Total text tracks = %d \n", player->selector[MM_PLAYER_TRACK_TYPE_TEXT].total_track_num);
 
-       return_val_if_fail( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       if (player->selector[MM_PLAYER_TRACK_TYPE_TEXT].total_track_num > 0)
+               player->has_closed_caption = TRUE;
 
-       /* alloc handles */
-       textbin = (MMPlayerGstElement*)g_malloc0(sizeof(MMPlayerGstElement) * MMPLAYER_T_NUM);
-       if ( ! textbin )
+       attrs = MMPLAYER_GET_ATTRS(player);
+       if ( attrs )
        {
-               debug_error("failed to allocate memory for textbin\n");
-               return MM_ERROR_PLAYER_NO_FREE_SPACE;
+               mm_attrs_set_int_by_name(attrs, "content_text_track_num",(gint)player->selector[MM_PLAYER_TRACK_TYPE_TEXT].total_track_num);
+               if (mmf_attrs_commit (attrs))
+                       debug_error("failed to commit.\n");
+       }
+       else
+       {
+               debug_error("cannot get content attribute");
        }
 
-       /* 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 )
+       if (srcpad)
        {
-               debug_critical("failed to create textbin\n");
-               goto ERROR;
+               gst_object_unref ( GST_OBJECT(srcpad) );
+               srcpad = NULL;
        }
+}
 
-       /* take it */
-       player->pipeline->textbin = textbin;
+int _mmplayer_gst_set_audio_channel(MMHandleType hplayer, MMPlayerAudioChannel ch_idx)
+{
+       int result = MM_ERROR_NONE;
 
-       /* fakesink */
-       MMPLAYER_CREATE_ELEMENT(textbin, MMPLAYER_T_SINK, "fakesink", "text_sink", TRUE);
+       mm_player_t* player = (mm_player_t*)hplayer;
+       MMPlayerGstElement* mainbin = NULL;
+       gchar* change_pad_name = NULL;
+       GstPad* sinkpad = NULL;
+       GstCaps* caps = NULL;
 
-       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_FENTER();
 
-       MMPLAYER_SIGNAL_CONNECT( player,
-                                                       G_OBJECT(textbin[MMPLAYER_T_SINK].gst),
-                                                       "handoff",
-                                                       G_CALLBACK(__mmplayer_update_subtitle),
-                                                       (gpointer)player );
+       return_val_if_fail (player, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-       __mmplayer_add_sink (player, GST_ELEMENT(textbin[MMPLAYER_T_SINK].gst));
+       debug_log ("Change Audio mode to %d\n", ch_idx);
+       player->use_deinterleave = TRUE;
 
-       /* 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 ))
+       if ((!player->pipeline) || (!player->pipeline->mainbin))
        {
-               debug_error("failed to add elements\n");
-               goto ERROR;
+               debug_log ("pre setting : %d\n", ch_idx);
+
+               player->audio_mode.active_pad_index = ch_idx;
+               return result;
        }
 
-       /* 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 )
+       mainbin = player->pipeline->mainbin;
+
+       if (mainbin[MMPLAYER_M_A_SELECTOR].gst == NULL)
        {
-               debug_error("failed to link elements\n");
-               goto ERROR;
+               if (player->max_audio_channels < 2)
+               {
+                       debug_log ("mono channel track only\n");
+                       return result;
+               }
+
+               debug_warning ("selector doesn't exist\n");
+               return result;  /* keep playing */
        }
 
-       /* get first element's sinkpad for creating ghostpad */
-       first_element = (MMPlayerGstElement *)element_bucket->data;
+       debug_log ("total_ch_num : %d\n", player->audio_mode.total_track_num);
 
-       pad = gst_element_get_static_pad(GST_ELEMENT(first_element->gst), "sink");
-       if ( ! pad )
+       if (player->audio_mode.total_track_num < 2)
        {
-               debug_error("failed to get pad from first element of textbin\n");
-               goto ERROR;
+               debug_warning ("there is no another audio path\n");
+               return result;  /* keep playing */
        }
 
-       ghostpad = gst_ghost_pad_new("sink", pad);
-       if ( ! ghostpad )
+       if ((ch_idx < 0) || (ch_idx >= player->audio_mode.total_track_num))
        {
-               debug_error("failed to create ghostpad\n");
-               goto ERROR;
+               debug_warning ("Not a proper ch_idx : %d \n", ch_idx);
+               return result;  /* keep playing */
        }
 
-       if ( FALSE == gst_element_add_pad(textbin[MMPLAYER_T_BIN].gst, ghostpad) )
+       /*To get the new pad from the selector*/
+       change_pad_name = g_strdup_printf ("sink%d", ch_idx);
+       if (change_pad_name == NULL)
        {
-               debug_error("failed to add ghostpad to textbin\n");
-               goto ERROR;
+               debug_warning ("Pad does not exists\n");
+               goto ERROR;     /* keep playing */
        }
 
-       gst_object_unref(pad);
+       debug_log ("new active pad name: %s\n", change_pad_name);
 
+       sinkpad = gst_element_get_static_pad (mainbin[MMPLAYER_M_A_SELECTOR].gst, change_pad_name);
+       if (sinkpad == NULL)
+       {
+               //result = MM_ERROR_PLAYER_INTERNAL;
+               goto ERROR;     /* keep playing */
+       }
 
-       /* done. free allocated variables */
-       g_list_free(element_bucket);
+       debug_log ("Set Active Pad - %s:%s\n", GST_DEBUG_PAD_NAME(sinkpad));
+       g_object_set (mainbin[MMPLAYER_M_A_SELECTOR].gst, "active-pad", sinkpad, NULL);
 
-       debug_fleave();
+       caps = GST_PAD_CAPS(sinkpad);
+       MMPLAYER_LOG_GST_CAPS_TYPE(caps);
 
-       return MM_ERROR_NONE;
+       __mmplayer_set_audio_attrs (player, caps);
+       player->audio_mode.active_pad_index = ch_idx;
 
 ERROR:
 
-       debug_log("ERROR : releasing textbin\n");
+       if (sinkpad)
+               gst_object_unref (sinkpad);
 
-       if ( pad )
-               gst_object_unref(GST_OBJECT(pad));
+       MMPLAYER_FREEIF(change_pad_name);
 
-       if ( ghostpad )
-               gst_object_unref(GST_OBJECT(ghostpad));
+       MMPLAYER_FLEAVE();
+       return result;
+}
 
-       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 );
+static void
+__mmplayer_gst_deinterleave_pad_added(GstElement *elem, GstPad *pad, gpointer data)
+{
+       mm_player_t* player = (mm_player_t*)data;
+       GstElement* selector = NULL;
+       GstElement* queue = NULL;
 
-                       if ( !parent )
-                       {
-                               gst_object_unref(GST_OBJECT(textbin[i].gst));
-                               textbin[i].gst = NULL;
-                       }
-                       else
-                       {
-                               gst_object_unref(GST_OBJECT(parent));
-                       }
-               }
-       }
+       GstPad* srcpad = NULL;
+       GstPad* sinkpad = NULL;
+       gchar* caps_str= NULL;
 
-       /* release textbin with it's childs */
-       if ( textbin[MMPLAYER_T_BIN].gst )
+       MMPLAYER_FENTER();
+       return_if_fail (player && player->pipeline && player->pipeline->mainbin);
+
+       caps_str = gst_caps_to_string(GST_PAD_CAPS(pad));
+       debug_log ("deinterleave new caps : %s\n", caps_str);
+       MMPLAYER_FREEIF(caps_str);
+
+       if ((queue = __mmplayer_element_create_and_link(player, pad, "queue")) == NULL)
        {
-               gst_object_unref(GST_OBJECT(textbin[MMPLAYER_T_BIN].gst));
+               debug_error ("ERROR : queue create error\n");
+               goto ERROR;
        }
 
-       MMPLAYER_FREEIF( textbin );
+       g_object_set(G_OBJECT(queue),
+                               "max-size-buffers", 10,
+                               "max-size-bytes", 0,
+                               "max-size-time", (guint64)0,
+                               NULL);
 
-       player->pipeline->textbin = NULL;
+       selector = player->pipeline->mainbin[MMPLAYER_M_A_SELECTOR].gst;
 
-       return MM_ERROR_PLAYER_INTERNAL;
-}
+       if (!selector)
+       {
+               debug_error("there is no audio channel selector.\n");
+               goto ERROR;
+       }
 
+       srcpad = gst_element_get_static_pad (queue, "src");
+       sinkpad = gst_element_get_request_pad (selector, "sink%d");
 
-static int
-__mmplayer_gst_create_subtitle_pipeline(mm_player_t* player)
-{
-       GstBus  *bus = NULL;
-       MMPlayerGstElement* subtitlebin = NULL;
-       MMHandleType attrs = 0;
-       gchar *subtitle_uri =NULL;
-       GList*element_bucket = NULL;
+       debug_log ("link (%s:%s - %s:%s)\n", GST_DEBUG_PAD_NAME(srcpad), GST_DEBUG_PAD_NAME(sinkpad));
 
-       #define USE_MESSAGE_FOR_PLAYING_SUBTITLE 
-#ifndef USE_MESSAGE_FOR_PLAYING_SUBTITLE
-       void *xid = NULL;
-       gint width =0, height = 0;
-       gboolean silent=FALSE;
-#endif
+       if (GST_PAD_LINK_OK != gst_pad_link(srcpad, sinkpad))
+       {
+               debug_warning ("failed to link deinterleave - selector\n");
+               goto ERROR;
+       }
 
-       debug_fenter();
+       gst_element_set_state (queue, GST_STATE_PAUSED);
+       player->audio_mode.total_track_num++;
 
-       /* get mainbin */
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+ERROR:
 
-       attrs = MMPLAYER_GET_ATTRS(player);
-       if ( !attrs )
+       if (srcpad)
        {
-               debug_error("cannot get content attribute\n");
-               return MM_ERROR_PLAYER_INTERNAL;
+               gst_object_unref ( GST_OBJECT(srcpad) );
+               srcpad = NULL;
        }
 
-       mm_attrs_get_string_by_name ( attrs, "subtitle_uri", &subtitle_uri );
-       if ( !subtitle_uri || strlen(subtitle_uri) < 1)
+       if (sinkpad)
        {
-               debug_error("subtitle uri is not proper filepath.\n");
-               return MM_ERROR_PLAYER_INVALID_URI;     
+               gst_object_unref ( GST_OBJECT(sinkpad) );
+               sinkpad = NULL;
        }
-       debug_log("subtitle file path is [%s].\n", subtitle_uri);
 
+       MMPLAYER_FLEAVE();
+       return;
+}
 
-       /* alloc handles */
-       subtitlebin = (MMPlayerGstElement*)g_malloc0(sizeof(MMPlayerGstElement) * MMPLAYER_SUB_NUM);
-       if ( !subtitlebin )
-       {
-               debug_error("failed to allocate memory\n");
-               return MM_ERROR_PLAYER_NO_FREE_SPACE;
-       }
+static void
+__mmplayer_gst_deinterleave_no_more_pads (GstElement *elem, gpointer data)
+{
+       mm_player_t* player = NULL;
+       GstElement* selector = NULL;
+       GstPad* sinkpad = NULL;
+       gint active_index = 0;
+       gchar* change_pad_name = NULL;
+       GstCaps* caps = NULL;   // no need to unref
 
-       /* create bin */
-       subtitlebin[MMPLAYER_SUB_PIPE].id = MMPLAYER_SUB_PIPE;
-       subtitlebin[MMPLAYER_SUB_PIPE].gst = gst_pipeline_new("subtitlebin");
-       if ( !subtitlebin[MMPLAYER_SUB_PIPE].gst )
+       MMPLAYER_FENTER();
+       player = (mm_player_t*) data;
+
+       selector = player->pipeline->mainbin[MMPLAYER_M_A_SELECTOR].gst;
+
+       if (!selector)
        {
-               debug_error("failed to create text pipeline\n");
+               debug_error("there is no audio channel selector.\n");
                goto ERROR;
        }
-       player->pipeline->subtitlebin = subtitlebin;
 
-       /* create the text file source */
-       MMPLAYER_CREATE_ELEMENT(subtitlebin, MMPLAYER_SUB_SRC, "filesrc", "subtitle_source", TRUE);
-       g_object_set(G_OBJECT (subtitlebin[MMPLAYER_SUB_SRC].gst), "location", subtitle_uri, NULL);
+       active_index = player->audio_mode.active_pad_index;
 
-       /* queue */
-       MMPLAYER_CREATE_ELEMENT(subtitlebin, MMPLAYER_SUB_QUEUE, "queue", NULL, TRUE);
+       if (active_index != DEFAULT_AUDIO_CH)
+       {
+               gint audio_ch = DEFAULT_AUDIO_CH;
 
-       /* subparse */
-       MMPLAYER_CREATE_ELEMENT(subtitlebin, MMPLAYER_SUB_SUBPARSE, "subparse", "subtitle_parser", TRUE);
+               /*To get the new pad from the selector*/
+               change_pad_name = g_strdup_printf ("sink%d", active_index);
+               if (change_pad_name != NULL)
+               {
+                       sinkpad = gst_element_get_static_pad (selector, change_pad_name);
+                       if (sinkpad != NULL)
+                       {
+                               debug_log ("Set Active Pad - %s:%s\n", GST_DEBUG_PAD_NAME(sinkpad));
+                               g_object_set (selector, "active-pad", sinkpad, NULL);
 
-#ifndef USE_MESSAGE_FOR_PLAYING_SUBTITLE
-       /* textrender */
-       MMPLAYER_CREATE_ELEMENT(subtitlebin, MMPLAYER_SUB_TEXTRENDER, "textrender", "subtitle_render", TRUE);
+                               audio_ch = active_index;
 
-       mm_attrs_get_int_by_name(attrs,"width", &width);
-       mm_attrs_get_int_by_name(attrs,"height", &height);
-       mm_attrs_get_int_by_name(attrs,"silent", &silent);
-       g_object_set ( G_OBJECT (subtitlebin[MMPLAYER_SUB_TEXTRENDER].gst),"width", width, NULL);
-       g_object_set ( G_OBJECT (subtitlebin[MMPLAYER_SUB_TEXTRENDER].gst),"height", height, NULL);
-       g_object_set ( G_OBJECT (subtitlebin[MMPLAYER_SUB_TEXTRENDER].gst),"silent", silent, NULL);
+                               caps = GST_PAD_CAPS(sinkpad);
+                               MMPLAYER_LOG_GST_CAPS_TYPE(caps);
 
-       debug_log ( "subtitle winow size is [%dX%d].\n", width, height );
-       debug_log ( "subtitle silent is [%d].\n", silent );
+                               __mmplayer_set_audio_attrs (player, caps);
+                       }
+               }
 
-       /* converter1 */
-       MMPLAYER_CREATE_ELEMENT(subtitlebin, MMPLAYER_SUB_CONV1, "ffmpegcolorspace", "subtitle_converter1", TRUE);
+               player->audio_mode.active_pad_index = audio_ch;
+               debug_log("audio LR info (0:stereo) = %d\n", player->audio_mode.active_pad_index);
+       }
 
-       /* videofliper */
-       MMPLAYER_CREATE_ELEMENT(subtitlebin, MMPLAYER_SUB_FLIP, "videoflip", "subtitle_fliper", TRUE);
+ERROR:
 
-       /* converter2 */
-       MMPLAYER_CREATE_ELEMENT(subtitlebin, MMPLAYER_SUB_CONV2, "ffmpegcolorspace", "subtitle_converter2", TRUE);
+       if (sinkpad)
+               gst_object_unref (sinkpad);
 
-       /* text sink */
-       MMPLAYER_CREATE_ELEMENT(subtitlebin, MMPLAYER_SUB_SINK, "ximagesink", "subtitle_sink", TRUE);
+       MMPLAYER_FLEAVE();
+       return;
+}
 
-       mm_attrs_get_data_by_name(attrs, "xid", &xid);
-       if ( xid )
-       {
-               debug_log("setting subtitle xid = %d\n", *(int*)xid);
-               gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(subtitlebin[MMPLAYER_SUB_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.\n");
-       }
-#else
-       /* text sink */
-       MMPLAYER_CREATE_ELEMENT(subtitlebin, MMPLAYER_SUB_SINK, "fakesink", "subtitle_sink", TRUE);
+static void
+__mmplayer_gst_build_deinterleave_path (GstElement *elem, GstPad *pad, gpointer data)
+{
+       mm_player_t* player = NULL;
+       MMPlayerGstElement *mainbin = NULL;
 
-       g_object_set (G_OBJECT (subtitlebin[MMPLAYER_SUB_SINK].gst), "sync", TRUE, NULL);
-       g_object_set (G_OBJECT (subtitlebin[MMPLAYER_SUB_SINK].gst), "async", FALSE, NULL);
-       g_object_set (G_OBJECT (subtitlebin[MMPLAYER_SUB_SINK].gst), "signal-handoffs", TRUE, NULL);
+       GstElement* tee = NULL;
+       GstElement* stereo_queue = NULL;
+       GstElement* mono_queue = NULL;
+       GstElement* conv = NULL;
+       GstElement* filter = NULL;
+       GstElement* deinterleave = NULL;
+       GstElement* selector = NULL;
 
-       MMPLAYER_SIGNAL_CONNECT( player,
-                                                       G_OBJECT(subtitlebin[MMPLAYER_SUB_SINK].gst),
-                                                       "handoff",
-                                                       G_CALLBACK(__mmplayer_update_subtitle),
-                                                       (gpointer)player );
-#endif
+       GstPad* srcpad = NULL;
+       GstPad* selector_srcpad = NULL;
+       GstPad* sinkpad = NULL;
+       GstCaps* caps = NULL;
 
-       /* adding created elements to bin */
-       if( ! __mmplayer_gst_element_add_bucket_to_bin(GST_BIN(subtitlebin[MMPLAYER_SUB_PIPE].gst), element_bucket) )
-       {
-               debug_error("failed to add elements\n");
-               goto ERROR;
-       }
+       MMPLAYER_FENTER();
 
-       /* 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;
-       }
+       /* check handles */
+       player = (mm_player_t*) data;
 
-       /* done. free allocated variables */
-       g_list_free(element_bucket);
+       return_if_fail( elem && pad );
+       return_if_fail( player && player->pipeline && player->pipeline->mainbin );
 
-       player->play_subtitle = TRUE;
+       mainbin = player->pipeline->mainbin;
 
-       debug_fleave();
-       
-       return MM_ERROR_NONE;
+       /* tee */
+       if ((tee = __mmplayer_element_create_and_link(player, pad, "tee")) == NULL)
+       {
+               debug_error ("ERROR : tee create error\n");
+               goto ERROR;
+       }
 
+       mainbin[MMPLAYER_M_A_TEE].id = MMPLAYER_M_A_TEE;
+       mainbin[MMPLAYER_M_A_TEE].gst = tee;
 
-ERROR:
-       debug_error("ERROR : releasing text pipeline\n");
+       gst_element_set_state (tee, GST_STATE_PAUSED);
 
-       g_list_free( element_bucket );
+       /* queue */
+       srcpad = gst_element_get_request_pad (tee, "src%d");
+       if ((stereo_queue = __mmplayer_element_create_and_link(player, srcpad, "queue")) == NULL)
+       {
+               debug_error ("ERROR : stereo queue create error\n");
+               goto ERROR;
+       }
+
+       g_object_set(G_OBJECT(stereo_queue),
+                               "max-size-buffers", 10,
+                               "max-size-bytes", 0,
+                               "max-size-time", (guint64)0,
+                               NULL);
 
-       /* release subtitlebin with it's childs */
-       if ( subtitlebin[MMPLAYER_SUB_PIPE].gst )
+       player->pipeline->mainbin[MMPLAYER_M_A_Q1].id = MMPLAYER_M_A_Q1;
+       player->pipeline->mainbin[MMPLAYER_M_A_Q1].gst = stereo_queue;
+
+       if (srcpad)
        {
-               gst_object_unref(GST_OBJECT(subtitlebin[MMPLAYER_SUB_PIPE].gst));
+               gst_object_unref (GST_OBJECT(srcpad));
+               srcpad = NULL;
        }
 
-       MMPLAYER_FREEIF( subtitlebin );
+       srcpad = gst_element_get_request_pad (tee, "src%d");
 
-       player->pipeline->subtitlebin = NULL;
+       if ((mono_queue = __mmplayer_element_create_and_link(player, srcpad, "queue")) == NULL)
+       {
+               debug_error ("ERROR : mono queue create error\n");
+               goto ERROR;
+       }
 
-       return MM_ERROR_PLAYER_INTERNAL;
-}
+       g_object_set(G_OBJECT(mono_queue),
+                               "max-size-buffers", 10,
+                               "max-size-bytes", 0,
+                               "max-size-time", (guint64)0,
+                               NULL);
 
-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;
+       player->pipeline->mainbin[MMPLAYER_M_A_Q2].id = MMPLAYER_M_A_Q2;
+       player->pipeline->mainbin[MMPLAYER_M_A_Q2].gst = mono_queue;
 
-       debug_fenter();
+       gst_element_set_state (stereo_queue, GST_STATE_PAUSED);
+       gst_element_set_state (mono_queue, GST_STATE_PAUSED);
 
-       return_val_if_fail ( player, FALSE );
-       return_val_if_fail ( buffer, FALSE );
+       /* audioconvert */
+       srcpad = gst_element_get_static_pad (mono_queue, "src");
+       if ((conv = __mmplayer_element_create_and_link(player, srcpad, "audioconvert")) == NULL)
+       {
+               debug_error ("ERROR : audioconvert create error\n");
+               goto ERROR;
+       }
 
-       text = GST_BUFFER_DATA(buffer);
-       duration = GST_BUFFER_DURATION(buffer);
+       player->pipeline->mainbin[MMPLAYER_M_A_CONV].id = MMPLAYER_M_A_CONV;
+       player->pipeline->mainbin[MMPLAYER_M_A_CONV].gst = conv;
 
-       if ( player->is_subtitle_off )
+       /* caps filter */
+       if (srcpad)
        {
-               debug_log("subtitle is OFF.\n" );
-               return TRUE;
+               gst_object_unref (GST_OBJECT(srcpad));
+               srcpad = NULL;
        }
+       srcpad = gst_element_get_static_pad (conv, "src");
 
-       if ( !text )
+       if ((filter = __mmplayer_element_create_and_link(player, srcpad, "capsfilter")) == NULL)
        {
-               debug_log("There is no subtitle to be displayed.\n" );
-               return TRUE;
+               debug_error ("ERROR : capsfilter create error\n");
+               goto ERROR;
        }
 
-       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;
-}
+       player->pipeline->mainbin[MMPLAYER_M_A_FILTER].id = MMPLAYER_M_A_FILTER;
+       player->pipeline->mainbin[MMPLAYER_M_A_FILTER].gst = filter;
 
+       caps = gst_caps_from_string( "audio/x-raw-int, "
+                               "width = (int) 16, "
+                               "depth = (int) 16, "
+                               "channels = (int) 2");
 
-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;
+       g_object_set (GST_ELEMENT(player->pipeline->mainbin[MMPLAYER_M_A_FILTER].gst), "caps", caps, NULL );
+       gst_caps_unref( caps );
 
-       debug_fenter();
+       gst_element_set_state (conv, GST_STATE_PAUSED);
+       gst_element_set_state (filter, GST_STATE_PAUSED);
 
-       /* check player and subtitlebin are created */
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
-       return_val_if_fail ( MMPLAYER_PLAY_SUBTITLE(player),    MM_ERROR_PLAYER_NOT_INITIALIZED );
-
-       if (position == 0)
+       /* deinterleave */
+       if (srcpad)
        {
-               debug_log("adjusted values is 0, no need to adjust subtitle position.\n");
-               return MM_ERROR_NONE;
+               gst_object_unref (GST_OBJECT(srcpad));
+               srcpad = NULL;
        }
+       srcpad = gst_element_get_static_pad (filter, "src");
 
-       switch (format)
+       if ((deinterleave = __mmplayer_element_create_and_link(player, srcpad, "deinterleave")) == NULL)
        {
-               case MM_PLAYER_POS_FORMAT_TIME:
-               {
-                       /* check current postion */
-                       ret = gst_element_query_position( GST_ELEMENT(player->pipeline->subtitlebin[MMPLAYER_SUB_PIPE].gst), &format, &current_pos );
-                       if ( !ret )
-                       {
-                               debug_warning("fail to query current postion.\n");
-                               return MM_ERROR_PLAYER_SEEK;
-                       }
-                       else
-                       {
-                               adusted_pos = current_pos + ((gint64)position * G_GINT64_CONSTANT(1000000));
-                               if (adusted_pos < 0)
-                                       adusted_pos = G_GINT64_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;
+               debug_error ("ERROR : deinterleave create error\n");
+               goto ERROR;
+       }
 
-               case MM_PLAYER_POS_FORMAT_PERCENT:
-               {
-                       debug_warning("percent format is not supported yet.\n");
-                       return MM_ERROR_INVALID_ARGUMENT;
-               }
-               break;
+       g_object_set (deinterleave, "keep-positions", TRUE, NULL);
 
-               default:
-               {
-                       debug_warning("invalid format.\n");
-                       return MM_ERROR_INVALID_ARGUMENT;
-               }
-       }
+       MMPLAYER_SIGNAL_CONNECT (player, deinterleave, MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-added",
+                                                       G_CALLBACK (__mmplayer_gst_deinterleave_pad_added), player);
 
-       /* keep ref to the event */
-       gst_event_ref (event);
+       MMPLAYER_SIGNAL_CONNECT (player, deinterleave, MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "no-more-pads",
+                                                       G_CALLBACK (__mmplayer_gst_deinterleave_no_more_pads), player);
 
-       debug_log("sending event[%s] to sink element [%s]\n",
-                       GST_EVENT_TYPE_NAME(event), GST_ELEMENT_NAME(player->pipeline->subtitlebin[MMPLAYER_SUB_SINK].gst) );
+       player->pipeline->mainbin[MMPLAYER_M_A_DEINTERLEAVE].id = MMPLAYER_M_A_DEINTERLEAVE;
+       player->pipeline->mainbin[MMPLAYER_M_A_DEINTERLEAVE].gst = deinterleave;
 
-       if ( ret = gst_element_send_event (player->pipeline->subtitlebin[MMPLAYER_SUB_SINK].gst, event) )
+       /* selector */
+       selector = gst_element_factory_make ("input-selector", "audio-channel-selector");
+       if (selector == NULL)
        {
-               debug_log("sending event[%s] to sink element [%s] success!\n",
-                       GST_EVENT_TYPE_NAME(event), GST_ELEMENT_NAME(player->pipeline->subtitlebin[MMPLAYER_SUB_SINK].gst) );
+               debug_error ("ERROR : audio-selector create error\n");
+               goto ERROR;
        }
 
-       /* unref to the event */
-       gst_event_unref (event);
-
-
-       debug_fleave();
+       g_object_set (selector, "sync-streams", TRUE, NULL);
+       gst_bin_add (GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), selector);
 
-       return MM_ERROR_NONE;
+       player->pipeline->mainbin[MMPLAYER_M_A_SELECTOR].id = MMPLAYER_M_A_SELECTOR;
+       player->pipeline->mainbin[MMPLAYER_M_A_SELECTOR].gst = selector;
 
-}
+       selector_srcpad = gst_element_get_static_pad (selector, "src");
 
-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;
+       debug_log ("blocking %" GST_PTR_FORMAT, selector_srcpad);
+       gst_pad_set_blocked_async (selector_srcpad, TRUE, __mmplayer_gst_selector_blocked, NULL);
 
-       return_if_fail ( element );
-       return_if_fail ( buf );
+       if (srcpad)
+       {
+               gst_object_unref (GST_OBJECT(srcpad));
+               srcpad = NULL;
+       }
 
-       buffer = gst_buffer_new ();
+       srcpad = gst_element_get_static_pad(stereo_queue, "src");
+       sinkpad = gst_element_get_request_pad (selector, "sink%d");
 
-       if (buf->offset >= buf->len)
+       if (GST_PAD_LINK_OK != gst_pad_link(srcpad, sinkpad))
        {
-               debug_log("call eos appsrc\n");
-              g_signal_emit_by_name (appsrc, "end-of-stream", &ret);
-              return;
+               debug_warning ("failed to link queue_stereo - selector\n");
+               goto ERROR;
        }
 
-       if ( buf->len - buf->offset < size)
-       {
-               len = buf->len - buf->offset + buf->offset;
-       }
+       player->audio_mode.total_track_num++;
 
-       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;
+       g_object_set (selector, "active-pad", sinkpad, NULL);
+       gst_element_set_state (deinterleave, GST_STATE_PAUSED);
+       gst_element_set_state (selector, GST_STATE_PAUSED);
 
-       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);
+       __mmplayer_gst_decode_callback (selector, selector_srcpad, player);
 
-       buf->offset += len;
-}
+       debug_log ("unblocking %" GST_PTR_FORMAT, selector_srcpad);
+       gst_pad_set_blocked_async (selector_srcpad, FALSE, __mmplayer_gst_selector_blocked, NULL);
 
-static gboolean
-__gst_appsrc_seek_data_mem(GstElement *element, guint64 size, gpointer user_data) // @
-{
-       tBuffer *buf = (tBuffer *)user_data;
+ERROR:
+       if (sinkpad)
+       {
+               gst_object_unref (GST_OBJECT(sinkpad));
+               sinkpad = NULL;
+       }
 
-       return_val_if_fail ( buf, FALSE );
+       if (srcpad)
+       {
+               gst_object_unref (GST_OBJECT(srcpad));
+               srcpad = NULL;
+       }
 
-       buf->offset  = (int)size;
+       if (selector_srcpad)
+       {
+               gst_object_unref (GST_OBJECT(selector_srcpad));
+               selector_srcpad = NULL;
+       }
 
-       return TRUE;
+       MMPLAYER_FLEAVE();
+       return;
 }
 
 static void
-__gst_appsrc_feed_data(GstElement *element, guint size, gpointer user_data) // @
+__mmplayer_gst_decode_no_more_pads (GstElement *elem, gpointer data)
 {
-       mm_player_t *player  = (mm_player_t*)user_data;
+       mm_player_t* player = NULL;
+       GstPad* srcpad = NULL;
+       GstElement* video_selector = NULL;
+       GstElement* audio_selector = NULL;
+       GstElement* text_selector = NULL;
+       MMHandleType attrs = 0;
+       gint active_index = 0;
+       GstFormat fmt  = GST_FORMAT_BYTES;
+       gint64 dur_bytes = 0L;
 
-       return_if_fail ( player );
+       player = (mm_player_t*) data;
 
-       debug_msg("app-src: feed data\n");
-            
-       if(player->need_data_cb)
-               player->need_data_cb(size, player->buffer_cb_user_param);
-}
+       debug_log("no-more-pad signal handling\n");
 
-static gboolean
-__gst_appsrc_seek_data(GstElement *element, guint64 offset, gpointer user_data) // @
-{
-       mm_player_t *player  = (mm_player_t*)user_data;
+       if ((player->cmd == MMPLAYER_COMMAND_DESTROY) ||
+               (player->cmd == MMPLAYER_COMMAND_UNREALIZE))
+       {
+               debug_warning("no need to go more");
 
-       return_val_if_fail ( player, FALSE );
+               if (player->pp_rebuilding)
+               {
+                       player->pp_rebuilding = FALSE;
+                       MMPLAYER_PLAYBACK_UNLOCK(player);
+               }
 
-       debug_msg("app-src: seek data\n");
+               return;
+       }
 
-       if(player->seek_data_cb)
-               player->seek_data_cb(offset, player->buffer_cb_user_param);
+       if ((!MMPLAYER_IS_HTTP_PD(player)) &&
+               (MMPLAYER_IS_HTTP_STREAMING(player)) &&
+               (!player->pipeline->mainbin[MMPLAYER_M_DEMUXED_S_BUFFER].gst) &&
+               (player->pipeline->mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst))
+       {
+               #define ESTIMATED_BUFFER_UNIT (1*1024*1024)
 
-       return TRUE;
-}
+               if (NULL == player->streamer)
+               {
+                       debug_warning("invalid state for buffering");
+                       goto ERROR;
+               }
 
+               gdouble init_buffering_time = (gdouble)player->streamer->buffering_req.initial_second;
+               guint buffer_bytes = init_buffering_time * ESTIMATED_BUFFER_UNIT;
 
-static gboolean
-__gst_appsrc_enough_data(GstElement *element, gpointer user_data) // @
-{
-       mm_player_t *player  = (mm_player_t*)user_data;
+               buffer_bytes = MAX(buffer_bytes, player->streamer->buffer_handle[BUFFER_TYPE_MUXED].buffering_bytes);
+               debug_log("[Decodebin2] set use-buffering on Q2 (pre buffer time: %d sec, buffer size : %d)\n", (gint)init_buffering_time, buffer_bytes);
 
-       return_val_if_fail ( player, FALSE );
+               init_buffering_time = (init_buffering_time != 0)?(init_buffering_time):(player->ini.http_buffering_time);
 
-       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);
+               if ( !gst_element_query_duration(player->pipeline->mainbin[MMPLAYER_M_SRC].gst, &fmt, &dur_bytes))
+                       debug_error("fail to get duration.\n");
 
-       return TRUE;
-}
+               // enable use-buffering on queue2 instead of multiqueue (ex)audio only streaming
+               // use file information was already set on Q2 when it was created.
+               __mm_player_streaming_set_queue2(player->streamer,
+                                               player->pipeline->mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst,
+                                               TRUE,                                                           // use_buffering
+                                               buffer_bytes,
+                                               init_buffering_time,
+                                               1.0,                                                            // low percent
+                                               player->ini.http_buffering_limit,       // high percent
+                                               FALSE,
+                                               NULL,
+                                               ((dur_bytes>0)?((guint64)dur_bytes):0));
+       }
 
-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;
+       video_selector = player->pipeline->mainbin[MMPLAYER_M_V_INPUT_SELECTOR].gst;
+       audio_selector = player->pipeline->mainbin[MMPLAYER_M_A_INPUT_SELECTOR].gst;
+       text_selector = player->pipeline->mainbin[MMPLAYER_M_T_SUBMUX_INTERNAL].gst;
+
+       if (video_selector)
+       {
+               // the first track can be played only. not support track changing yet.
+               // [link] input-selector :: videobin
+               srcpad = gst_element_get_static_pad (video_selector, "src");
+               if (!srcpad)
+               {
+                       debug_error("failed to get srcpad from video selector\n");
+                       goto ERROR;
+               }
 
-       debug_fenter();
+               debug_log ("got pad %s:%s from selector\n", GST_DEBUG_PAD_NAME(srcpad));
+               if ((!text_selector) && (!audio_selector))
+                       player->no_more_pad = TRUE;
 
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+               __mmplayer_gst_decode_callback (video_selector, srcpad, player);
 
-       /* check current state */
-//     MMPLAYER_CHECK_STATE_RETURN_IF_FAIL( player, MMPLAYER_COMMAND_START );
+               debug_log ("unblocking %" GST_PTR_FORMAT, srcpad);
+               gst_pad_set_blocked_async (srcpad, FALSE, __mmplayer_gst_selector_blocked, NULL);
 
+               debug_log("Total video tracks = %d \n", player->selector[MM_PLAYER_TRACK_TYPE_VIDEO].total_track_num);
 
-       /* NOTE : we should check and create pipeline again if not created as we destroy
-        * whole pipeline when stopping in streamming playback
-        */
-       if ( ! player->pipeline )
+               gst_object_unref ( GST_OBJECT(srcpad) );
+               srcpad = NULL;
+       }
+       else
        {
-               if ( MM_ERROR_NONE != __gst_realize( player ) )
+               if ((player->pipeline->videobin) && (player->pipeline->videobin[MMPLAYER_V_BIN].gst))
                {
-                       debug_error("failed to realize before starting. only in streamming\n");
-                       return MM_ERROR_PLAYER_INTERNAL;
+                       debug_log ("There is no video track : remove videobin");
+
+                       __mmplayer_release_signal_connection( player, MM_PLAYER_SIGNAL_TYPE_VIDEOBIN );
+                       __mmplayer_del_sink ( player, player->pipeline->videobin[MMPLAYER_V_SINK].gst );
+
+                       MMPLAYER_RELEASE_ELEMENT ( player, player->pipeline->videobin, MMPLAYER_V_BIN );
+                       MMPLAYER_FREEIF ( player->pipeline->videobin )
                }
        }
 
-       debug_msg("app-src: pushing data\n");
+       if (audio_selector)
+       {
+               #define DEFAULT_TRACK 0
+               active_index = player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].active_pad_index;
+               if ((active_index != DEFAULT_TRACK) &&
+                       (__mmplayer_change_selector_pad(player, MM_PLAYER_TRACK_TYPE_AUDIO, active_index) != MM_ERROR_NONE))
+               {
+                       debug_warning("failed to change audio track\n");
+                       player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].active_pad_index = DEFAULT_TRACK;
+               }
 
-       if ( buf == NULL )
-       {
-               debug_error("buf is null\n");
-               return MM_ERROR_NONE;
-       }
+               // [link] input-selector :: audiobin
+               srcpad = gst_element_get_static_pad (audio_selector, "src");
+               if (!srcpad)
+               {
+                       debug_error("failed to get srcpad from selector\n");
+                       goto ERROR;
+               }
 
-       buffer = gst_buffer_new ();
+               debug_log ("got pad %s:%s from selector\n", GST_DEBUG_PAD_NAME(srcpad));
+               if (!text_selector)
+                       player->no_more_pad = TRUE;
 
-       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;
-       }
+               if ((player->use_deinterleave == TRUE) && (player->max_audio_channels >= 2))
+               {
+                       debug_log ("unblocking %" GST_PTR_FORMAT, srcpad);
+                       gst_pad_set_blocked_async (srcpad, FALSE, __mmplayer_gst_selector_blocked, NULL);
 
-       GST_BUFFER_DATA(buffer) = (guint8*)(buf);
-       GST_BUFFER_SIZE(buffer) = size;
+                       __mmplayer_gst_build_deinterleave_path(audio_selector, srcpad, player);
+               }
+               else
+               {
+                       __mmplayer_gst_decode_callback (audio_selector, srcpad, player);
 
-       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_log ("unblocking %" GST_PTR_FORMAT, srcpad);
+                       gst_pad_set_blocked_async (srcpad, FALSE, __mmplayer_gst_selector_blocked, NULL);
+               }
 
-       debug_fleave();
+               debug_log("Total audio tracks = %d \n", player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].total_track_num);
 
-       return ret;
-}
+               attrs = MMPLAYER_GET_ATTRS(player);
+               if ( attrs )
+               {
+                       mm_attrs_set_int_by_name(attrs, "content_audio_track_num",(gint)player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].total_track_num);
+                       if (mmf_attrs_commit (attrs))
+                               debug_error("failed to commit.\n");
+               }
+               else
+               {
+                       debug_error("cannot get content attribute");
+               }
+       }
+       else
+       {
+               if ((player->pipeline->audiobin) && (player->pipeline->audiobin[MMPLAYER_A_BIN].gst))
+               {
+                       debug_log ("There is no audio track : remove audiobin");
 
-static GstBusSyncReply
-__mmplayer_bus_sync_callback (GstBus * bus, GstMessage * message, gpointer data)
-{
-       mm_player_t *player = (mm_player_t *)data;
-       GstElement *sender = (GstElement *) GST_MESSAGE_SRC (message);
-       const gchar *name = gst_element_get_name (sender);
+                       __mmplayer_release_signal_connection( player, MM_PLAYER_SIGNAL_TYPE_AUDIOBIN );
+                       __mmplayer_del_sink ( player, player->pipeline->audiobin[MMPLAYER_A_SINK].gst );
 
-       switch (GST_MESSAGE_TYPE (message))
+                       MMPLAYER_RELEASE_ELEMENT ( player, player->pipeline->audiobin, MMPLAYER_A_BIN );
+                       MMPLAYER_FREEIF ( player->pipeline->audiobin )
+               }
+       }
+
+       if (text_selector)
        {
-               case GST_MESSAGE_TAG:
-                       __mmplayer_gst_extract_tag_from_msg(player, message);
-                       break;
+               __mmplayer_handle_text_decode_path(player, text_selector);
+       }
 
-               case GST_MESSAGE_DURATION:
-                               if (MMPLAYER_IS_STREAMING(player))
-                               {
-                                       GstFormat format;
-                                       gint64 bytes = 0;
+       MMPLAYER_FLEAVE();
 
-                                       gst_message_parse_duration (message, &format, &bytes);
-                                       if (format == GST_FORMAT_BYTES)
-                                       {
-                                               debug_log("data total size of http content: %lld", bytes);
-                                               player->http_content_size = bytes;
-                                       }
-                               }
-                               else
-                               {
-                                       player->need_update_content_attrs = TRUE;
-                                       _mmplayer_update_content_attrs(player);
-                               }
-               default:
-                       return GST_BUS_PASS;
+ERROR:
+       if (srcpad)
+       {
+               gst_object_unref ( GST_OBJECT(srcpad) );
+               srcpad = NULL;
        }
 
-       debug_log("GST_MESSAGE_TAG from %s", name);
-       gst_message_unref (message);
-
-       return GST_BUS_DROP;
+       if (player->pp_rebuilding)
+       {
+               player->pp_rebuilding = FALSE;
+               MMPLAYER_PLAYBACK_UNLOCK(player);
+       }
 }
 
-/**
- * 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) // @
+static void
+__mmplayer_gst_decode_callback(GstElement *elem, GstPad *pad, gpointer data) // @
 {
-       GstBus  *bus = NULL;
-       MMPlayerGstElement *mainbin = NULL;
+       mm_player_t* player = NULL;
        MMHandleType attrs = 0;
-       GstElement* element = NULL;
-       GList* element_bucket = NULL;
-       gboolean need_state_holder = TRUE;
-       gint i = 0;
+       GstElement* pipeline = NULL;
+       GstCaps* caps = NULL;
+       gchar* caps_str = NULL;
+       GstStructure* str = NULL;
+       const gchar* name = NULL;
+       GstPad* sinkpad = NULL;
+       GstElement* sinkbin = NULL;
+       gboolean reusing = FALSE;
+       GstElement *text_selector = NULL;
+
+       /* check handles */
+       player = (mm_player_t*) data;
 
-       debug_fenter();
+       return_if_fail( elem && pad );
+       return_if_fail(player && player->pipeline && player->pipeline->mainbin);
 
-       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       pipeline = player->pipeline->mainbin[MMPLAYER_M_PIPE].gst;
 
-       /* get profile attribute */
        attrs = MMPLAYER_GET_ATTRS(player);
        if ( !attrs )
        {
                debug_error("cannot get content attribute\n");
-               goto INIT_ERROR;
+               goto ERROR;
        }
 
-       /* create pipeline handles */
-       if ( player->pipeline )
+       /* get mimetype from caps */
+       caps = gst_pad_get_caps( pad );
+       if ( !caps )
        {
-               debug_warning("pipeline should be released before create new one\n");
-               goto INIT_ERROR;
+               debug_error("cannot get caps from pad.\n");
+               goto ERROR;
        }
+       caps_str = gst_caps_to_string(caps);
 
-       player->pipeline = (MMPlayerGstPipelineInfo*) g_malloc0( sizeof(MMPlayerGstPipelineInfo) );
-       if (player->pipeline == NULL)
-               goto INIT_ERROR;
-
-       memset( player->pipeline, 0, sizeof(MMPlayerGstPipelineInfo) );
-
+       str = gst_caps_get_structure( caps, 0 );
+       if ( ! str )
+       {
+               debug_error("cannot get structure from capse.\n");
+               goto ERROR;
+       }
 
-       /* 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 )
+       name = gst_structure_get_name(str);
+       if ( ! name )
        {
-               debug_error("failed to create pipeline\n");
-               goto INIT_ERROR;
+               debug_error("cannot get mimetype from structure.\n");
+               goto ERROR;
        }
 
+       //debug_log("detected mimetype : %s\n", name);
 
-       /* create source element */
-       switch ( player->profile.uri_type )
+       if (strstr(name, "audio"))
        {
-               /* rtsp streamming */
-               case MM_PLAYER_URI_TYPE_URL_RTSP:
+               if (player->pipeline->audiobin == NULL)
                {
-                       gint udp_timeout, network_bandwidth;
-                       gchar *user_agent, *wap_profile;
-
-                       element = gst_element_factory_make(PLAYER_INI()->name_of_rtspsrc, "streaming_source");
-
-                       if ( !element )
+                       if (MM_ERROR_NONE !=  __mmplayer_gst_create_audio_pipeline(player))
                        {
-                               debug_critical("failed to create streaming source element\n");
-                               break;
+                               debug_error("failed to create audiobin. continuing without audio\n");
+                               goto ERROR;
                        }
 
-                       debug_log("using streamming source [%s].\n", PLAYER_INI()->name_of_rtspsrc);
+                       sinkbin = player->pipeline->audiobin[MMPLAYER_A_BIN].gst;
+                       debug_log("creating audiosink bin success\n");
+               }
+               else
+               {
+                       reusing = TRUE;
+                       sinkbin = player->pipeline->audiobin[MMPLAYER_A_BIN].gst;
+                       debug_log("reusing audiobin\n");
+                       _mmplayer_update_content_attrs( player, ATTR_AUDIO);
+               }
 
-                       /* make it zero */
-                       udp_timeout = network_bandwidth = 0;
-                       user_agent = wap_profile = NULL;
+               if (player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].total_track_num <= 0) // should not update if content have multi audio tracks
+                       mm_attrs_set_int_by_name(attrs, "content_audio_track_num", 1);
 
-                       /* get attribute */
-                       mm_attrs_get_int_by_name ( attrs,"streaming_udp_timeout", &udp_timeout );
-                       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 );
+               player->audiosink_linked  = 1;
 
-                       debug_log("setting streaming source ----------------\n");
-                       debug_log("udp_timeout : %d\n", udp_timeout);
-                       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");
+               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 (strstr(caps_str, "ST12") || strstr(caps_str, "SN12"))
+               {
+                       player->set_mode.video_zc = TRUE;
+               }
 
-                       /* setting property to streaming source */
-                       g_object_set(G_OBJECT(element), "location", player->profile.uri, NULL);
-                       g_object_set(G_OBJECT(element), "timeout", udp_timeout, 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);
+               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);
 
-                       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 );
+                       if (surface_type == MM_DISPLAY_SURFACE_NULL)
+                       {
+                               debug_log("not make videobin because it dose not want\n");
+                               goto ERROR;
+                       }
 
-                       player->no_more_pad = FALSE;
-                       player->num_dynamic_pad = 0;
+                       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;
+                       }
 
-                       /* NOTE : we cannot determine it yet. this filed will be filled by
-                        * _mmplayer_update_content_attrs() after START.
-                        */
-                       player->streaming_type = STREAMING_SERVICE_NONE;
+                       sinkbin = player->pipeline->videobin[MMPLAYER_V_BIN].gst;
+                       debug_log("creating videosink bin success\n");
                }
-               break;
-
-               /* http streaming*/
-               case MM_PLAYER_URI_TYPE_URL_HTTP:
+               else
                {
-                       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;
+                       reusing = TRUE;
+                       sinkbin = player->pipeline->videobin[MMPLAYER_V_BIN].gst;
+                       debug_log("re-using videobin\n");
+                       _mmplayer_update_content_attrs( player, ATTR_VIDEO);
+               }
 
-                       debug_log("http playback, PD mode : %d\n", player->pd_mode);
+               /* FIXIT : track number shouldn't be hardcoded */
+               mm_attrs_set_int_by_name(attrs, "content_video_track_num", 1);
+               player->videosink_linked  = 1;
 
-                       if ( ! MMPLAYER_IS_HTTP_PD(player) )
+               /* NOTE : intermediate code before doing H/W subtitle compositon */
+               if ( player->use_textoverlay && player->play_subtitle )
+               {
+                       debug_log("using textoverlay for external subtitle");
+                       /* check text bin has created well */
+                       if ( player->pipeline && player->pipeline->textbin )
                        {
-                               element = gst_element_factory_make(PLAYER_INI()->name_of_httpsrc, "http_streaming_source");
-                               if ( !element )
+                               /* get sinkpad from textoverlay */
+                               sinkpad = gst_element_get_static_pad(
+                                       GST_ELEMENT(player->pipeline->textbin[MMPLAYER_T_BIN].gst),
+                                       "video_sink" );
+                               if ( ! sinkpad )
                                {
-                                       debug_critical("failed to create http streaming source element[%s].\n", PLAYER_INI()->name_of_httpsrc);
-                                       break;
+                                       debug_error("failed to get sink pad from textoverlay");
+                                       goto ERROR;
                                }
-                               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)
+                               /* link new pad with textoverlay first */
+                               if ( GST_PAD_LINK_OK != GST_PAD_LINK(pad, sinkpad) )
                                {
-                                       gchar *path = NULL;
-                                       
-                                       mm_attrs_get_string_by_name ( attrs, "pd_location", &path );
-                                       
-                                       MMPLAYER_FREEIF(player->pd_file_location);
-
-                                       debug_log("PD Location : %s\n", path);
-
-                                       if ( path )
-                                       {
-                                               player->pd_file_location = g_strdup(path);
-                                       }
-                                       else
-                                       {
-                                               debug_error("can't find pd location so, it should be set \n");
-                                               return MM_ERROR_PLAYER_FILE_NOT_FOUND;  
-                                       }
+                                       debug_error("failed to get pad from sinkbin\n");
+                                       goto ERROR;
                                }
 
-                               element = gst_element_factory_make("pdpushsrc", "PD pushsrc");
-                               if ( !element )
+                               gst_object_unref(sinkpad);
+                               sinkpad = NULL;
+
+                               /* alright, override pad to textbin.src for futher link */
+                               pad = gst_element_get_static_pad(
+                                       GST_ELEMENT(player->pipeline->textbin[MMPLAYER_T_BIN].gst),
+                                       "src" );
+                               if ( ! pad )
                                {
-                                       debug_critical("failed to create PD push source element[%s].\n", "pdpushsrc");
-                                       break;
+                                       debug_error("failed to get sink pad from textoverlay");
+                                       goto ERROR;
                                }
-
-                               g_object_set(G_OBJECT(element), "location", player->pd_file_location, NULL);
                        }
-                       
-                       player->streaming_type = STREAMING_SERVICE_NONE;
+                       else
+                       {
+                               debug_error("should not reach here.");
+                               goto ERROR;
+                       }
                }
-               break;
 
-               /* file source */
-               case MM_PLAYER_URI_TYPE_FILE:
+               sinkpad = gst_element_get_static_pad( GST_ELEMENT(sinkbin), "sink" );
+               if ( !sinkpad )
                {
-                       char* drmsrc = PLAYER_INI()->name_of_drmsrc;
-
-                       debug_log("using [%s] for 'file://' handler.\n", drmsrc);
+                       debug_error("failed to get pad from sinkbin\n");
+                       goto ERROR;
+               }
+       }
+       else if (strstr(name, "text"))
+       {
+               if (player->pipeline->textbin == NULL)
+               {
+                       MMPlayerGstElement* mainbin = NULL;
 
-                       element = gst_element_factory_make(drmsrc, "source");
-                       if ( !element )
+                       if (MM_ERROR_NONE !=  __mmplayer_gst_create_text_pipeline(player))
                        {
-                               debug_critical("failed to create %s\n", drmsrc);
-                               break;
+                               debug_error("failed to create textbin. continuing without text\n");
+                               goto ERROR;
                        }
 
-                       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;
+                       sinkbin = player->pipeline->textbin[MMPLAYER_T_BIN].gst;
+                       debug_log("creating textink bin success\n");
 
-#ifdef NO_USE_GST_HLSDEMUX
-               case MM_PLAYER_URI_TYPE_HLS:
-               {
-                       guint64 stream_type = GST_APP_STREAM_TYPE_STREAM;
+                       /* FIXIT : track number shouldn't be hardcoded */
+                       mm_attrs_set_int_by_name(attrs, "content_text_track_num", 1);
 
-                       debug_log("hsl src is selected\n");
+                       player->textsink_linked  = 1;
+                       debug_msg("player->textsink_linked set to 1\n");
 
-                       element = gst_element_factory_make("appsrc", "hls-source");
-                       if ( !element )
+                       sinkpad = gst_element_get_static_pad( GST_ELEMENT(sinkbin), "text_sink" );
+                       if ( !sinkpad )
                        {
-                               debug_critical("failed to create appsrc element\n");
-                               break;
+                               debug_error("failed to get pad from sinkbin\n");
+                               goto ERROR;
                        }
-                       g_object_set( element, "stream-type", stream_type, NULL );
 
-                       // TODO: need to set time based limit instead of bytes (or) remove constraint.... need to investigate more 
-                       g_object_set( element, "max-bytes", 500000, NULL ); // Naveen made queue as un-limited
+                       mainbin = player->pipeline->mainbin;
+
+                       if (!mainbin[MMPLAYER_M_T_INPUT_SELECTOR].gst)
+                       {
+                         /* input selector */
+                         text_selector = gst_element_factory_make("input-selector", "subtitle_inselector");
+                         if ( !text_selector )
+                         {
+                           debug_error ( "failed to create subtitle input selector element\n" );
+                           goto ERROR;
+                         }
+                         g_object_set (text_selector, "sync-streams", TRUE, NULL);
+
+                         mainbin[MMPLAYER_M_T_INPUT_SELECTOR].id = MMPLAYER_M_T_INPUT_SELECTOR;
+                         mainbin[MMPLAYER_M_T_INPUT_SELECTOR].gst = text_selector;
+
+                         /* warm up */
+                         if (GST_STATE_CHANGE_FAILURE == gst_element_set_state (text_selector, GST_STATE_READY))
+                         {
+                           debug_error("failed to set state(READY) to sinkbin\n");
+                           goto ERROR;
+                         }
+
+                         if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), text_selector))
+                         {
+                           debug_warning("failed to add subtitle input selector\n");
+                           goto ERROR;
+                         }
+
+                         debug_log ("created element input-selector");
+
+                       }
+                       else
+                       {
+                         debug_log ("already having subtitle input selector");
+                         text_selector = mainbin[MMPLAYER_M_T_INPUT_SELECTOR].gst;
+                       }
                }
-               break;
-#endif
-               /* appsrc */
-               case MM_PLAYER_URI_TYPE_BUFF:
+               else
                {
-                       guint64 stream_type = GST_APP_STREAM_TYPE_STREAM;
+                       if (!player->textsink_linked)
+                       {
+                               debug_log("re-using textbin\n");
 
-                       debug_log("mem src is selected\n");
+                               reusing = TRUE;
+                               sinkbin = player->pipeline->textbin[MMPLAYER_T_BIN].gst;
 
-                       element = gst_element_factory_make("appsrc", "buff-source");
-                       if ( !element )
+                               player->textsink_linked  = 1;
+                               debug_msg("player->textsink_linked set to 1\n");
+                       }
+                       else
                        {
-                               debug_critical("failed to create appsrc element\n");
-                               break;
+                               debug_log("ignoring internal subtutle since external subtitle is available");
                        }
+               }
+       }
+       else
+       {
+               debug_warning("unknown type of elementary stream! ignoring it...\n");
+               goto ERROR;
+       }
 
-                       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 );
+       if ( sinkbin )
+       {
+               if(!reusing)
+               {
+                       /* 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;
+                       }
 
-                       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);
+                       /* Added for multi audio support to avoid adding audio bin again*/
+                       /* add */
+                       if ( FALSE == gst_bin_add( GST_BIN(pipeline), sinkbin ) )
+                       {
+                               debug_error("failed to add sinkbin to pipeline\n");
+                               goto ERROR;
+                       }
                }
-               break;
 
-               /* appsrc */
-               case MM_PLAYER_URI_TYPE_MEM:
+               if (text_selector)
                {
-                       guint64 stream_type = GST_APP_STREAM_TYPE_RANDOM_ACCESS;
+                 GstPad *srcpad = NULL;
+
+                 srcpad =  gst_element_get_static_pad(player->pipeline->mainbin[MMPLAYER_M_T_INPUT_SELECTOR].gst,"src");
+                 if (!srcpad)
+                 {
+                   debug_error ("failed to get source pad");
+                   goto ERROR;
+                 }
+
+                 /* link input selector & textbin */
+                 if (gst_pad_link(srcpad,sinkpad)!= 0)
+                 {
+                   debug_warning("failed to link input selector and textbin ghost pad\n");
+                   goto ERROR;
+                 }
+
+                 sinkpad = gst_element_get_request_pad (player->pipeline->mainbin[MMPLAYER_M_T_INPUT_SELECTOR].gst, "sink0");
+                 if (sinkpad == NULL)
+                 {
+                   debug_error ("failed to get request pad from input selector");;
+                   goto ERROR;
+                 }
+               }
 
-                       debug_log("mem src is selected\n");
+               /* link */
+               if (GST_PAD_LINK_OK != GST_PAD_LINK (pad, sinkpad))
+               {
+                       debug_error("failed to get pad from sinkbin\n");
+                       goto ERROR;
+               }
 
-                       element = gst_element_factory_make("appsrc", "mem-source");
-                       if ( !element )
+               if (!reusing)
+               {
+                       /* run */
+                       if (GST_STATE_CHANGE_FAILURE == gst_element_set_state (sinkbin, GST_STATE_PAUSED))
                        {
-                               debug_critical("failed to create appsrc element\n");
-                               break;
+                               debug_error("failed to set state(PLAYING) to sinkbin\n");
+                               goto ERROR;
                        }
 
-                       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 );
+                       if (text_selector)
+                       {
+                         if (GST_STATE_CHANGE_FAILURE == gst_element_set_state (text_selector, GST_STATE_PAUSED))
+                         {
+                           debug_error("failed to set state(READY) to sinkbin\n");
+                           goto ERROR;
+                         }
+                       }
                }
-               break;
-               case MM_PLAYER_URI_TYPE_URL:
-               break;
-
-               case MM_PLAYER_URI_TYPE_TEMP:
-               break;
 
-               case MM_PLAYER_URI_TYPE_NONE:
-               default:
-               break;
+               gst_object_unref (sinkpad);
+               sinkpad = NULL;
        }
 
-       /* check source element is OK */
-       if ( ! element )
-       {
-               debug_critical("no source element was created.\n");
-               goto INIT_ERROR;
-       }
+       debug_log ("linking sink bin success\n");
 
-       /* 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]);
+       /* 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 */
+       if (player->num_dynamic_pad)
+               player->num_dynamic_pad--;
 
-       if (MMPLAYER_IS_STREAMING(player) || (player->profile.uri_type == MM_PLAYER_URI_TYPE_HLS))
-       {
-               player->streamer = __mm_player_streaming_create();
-               __mm_player_streaming_initialize(player->streamer);
-       }
+       debug_log ("no more pads: %d stream count dec : %d (num of dynamic pad)\n", player->no_more_pad, player->num_dynamic_pad);
 
-       if ( player->profile.uri_type == MM_PLAYER_URI_TYPE_HLS )
+       if ((player->no_more_pad) && (player->num_dynamic_pad == 0))
        {
-               debug_log ("adding appsrc's pad probe...\n");
-               GstPad *pad = NULL;
-              pad = gst_element_get_static_pad(mainbin[MMPLAYER_M_SRC].gst, "src" );
-
-               /* register probe */
-               ahs_appsrc_cb_probe_id = gst_pad_add_buffer_probe (pad, 
-                       G_CALLBACK (__mmplayer_ahs_appsrc_probe), player);
-                               
-               gst_object_unref(pad);
-               pad = NULL;
-       }
-
-       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);
+               __mmplayer_pipeline_complete (NULL, player);
        }
 
-       /* create autoplugging element if src element is not a streamming src */
-       if ( player->profile.uri_type != MM_PLAYER_URI_TYPE_URL_RTSP )
+       /* FIXIT : please leave a note why this code is needed */
+       if(MMPLAYER_IS_WFD_STREAMING( player ))
        {
-               element = NULL;
+               player->no_more_pad = TRUE;
+       }
 
-               if( PLAYER_INI()->use_decodebin )
-               {
-                       /* create decodebin */
-                       element = gst_element_factory_make("decodebin", "decodebin");
+ERROR:
 
-                       g_object_set(G_OBJECT(element), "async-handling", TRUE, NULL);
+       MMPLAYER_FREEIF(caps_str);
 
-                       /* set signal handler */
-                       MMPLAYER_SIGNAL_CONNECT( player, G_OBJECT(element), "new-decoded-pad",
-                                       G_CALLBACK(__mmplayer_gst_decode_callback), player);
+       if ( caps )
+               gst_caps_unref( caps );
 
-                       /* 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 );
-               }
+       if ( sinkpad )
+               gst_object_unref(GST_OBJECT(sinkpad));
 
-               /* check autoplug element is OK */
-               if ( ! element )
-               {
-                       debug_critical("can not create autoplug element\n");
-                       goto INIT_ERROR;
-               }
+       /* flusing out new attributes */
+       if (  mmf_attrs_commit ( attrs ) )
+       {
+               debug_error("failed to comit attributes\n");
+       }
 
-               mainbin[MMPLAYER_M_AUTOPLUG].id = MMPLAYER_M_AUTOPLUG;
-               mainbin[MMPLAYER_M_AUTOPLUG].gst = element;
+       return;
+}
 
-               element_bucket = g_list_append(element_bucket, &mainbin[MMPLAYER_M_AUTOPLUG]);
-       }
+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;
+       int rotation_type = -1;
+       #define ROTATION_USING_SINK 0
+       #define ROTATION_USING_CUSTOM 1
+       #define ROTATION_USING_FLIP     2
 
+       return_val_if_fail(player, FALSE);
+       return_val_if_fail(value, FALSE);
+       return_val_if_fail(rotation_angle >= 0, FALSE);
 
-       /* add elements to pipeline */
-       if( !__mmplayer_gst_element_add_bucket_to_bin(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), element_bucket))
+       if (rotation_angle >= 360)
        {
-               debug_error("Failed to add elements to pipeline\n");
-               goto INIT_ERROR;
+               dest_angle = rotation_angle - 360;
        }
 
-
-       /* linking elements in the bucket by added order. */
-       if ( __mmplayer_gst_element_link_bucket(element_bucket) == -1 )
+       /* chech if supported or not */
+       if ( dest_angle % 90 )
        {
-               debug_error("Failed to link some elements\n");
-               goto INIT_ERROR;
+               debug_log("not supported rotation angle = %d", rotation_angle);
+               return FALSE;
        }
 
-
-       /* create fakesink element for keeping the pipeline state PAUSED. if needed */
-       if ( need_state_holder )
+       /*
+         * xvimagesink only     (A)
+         * custom_convert - no xv (e.g. memsink, evasimagesink  (B)
+         * videoflip - avsysmemsink (C)
+         */
+       if (player->set_mode.video_zc)
        {
-               /* 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)
+               if (player->pipeline->videobin[MMPLAYER_V_CONV].gst) // B
                {
-                       debug_error ("fakesink element could not be created\n");
-                       goto INIT_ERROR;
+                       rotation_type = ROTATION_USING_CUSTOM;
                }
-               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) )
+               else // A
                {
-                       debug_error("failed to add fakesink to bin\n");
-                       goto INIT_ERROR;
+                       rotation_type = ROTATION_USING_SINK;
                }
        }
-
-       /* 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 )
+       else
        {
-               debug_error ("cannot get bus from pipeline.\n");
-               goto INIT_ERROR;
-       }
-       player->bus_watcher = gst_bus_add_watch(bus, (GstBusFunc)__mmplayer_gst_callback, player);
+               int surface_type = 0;
+               rotation_type = ROTATION_USING_FLIP;
 
-       /* Note : check whether subtitle atrribute uri is set. If uri is set, then create the text pipeline */
-       if ( __mmplayer_check_subtitle ( player ) )
-       {
-               debug_log("try to create subtitle pipeline \n");
+               mm_attrs_get_int_by_name(player->attrs, "display_surface_type", &surface_type);
+               debug_log("check display surface type attribute: %d", surface_type);
 
-               if ( MM_ERROR_NONE != __mmplayer_gst_create_subtitle_pipeline(player) )
-                       debug_error("fail to create subtitle pipeline")
+               if ((surface_type == MM_DISPLAY_SURFACE_X) ||
+                       (surface_type == MM_DISPLAY_SURFACE_EVAS && !strcmp(player->ini.videosink_element_evas, "evaspixmapsink")))
+               {
+                       rotation_type = ROTATION_USING_SINK;
+               }
                else
-                       debug_log("subtitle pipeline is created successfully\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:
+               {
+                       rotation_type = ROTATION_USING_FLIP; //C
+               }
 
-       __mmplayer_gst_destroy_pipeline(player);
-       g_list_free(element_bucket);
+               debug_log("using %d type for rotation", rotation_type);
+       }
 
-       /* release element which are not added to bin */
-       for ( i = 1; i < MMPLAYER_M_NUM; i++ )  /* NOTE : skip pipeline */
+       /* get property value for setting */
+       switch(rotation_type)
        {
-               if ( mainbin[i].gst )
-               {
-                       GstObject* parent = NULL;
-                       parent = gst_element_get_parent( mainbin[i].gst );
-
-                       if ( !parent )
+               case ROTATION_USING_SINK: // xvimagesink, pixmap
                        {
-                               gst_object_unref(GST_OBJECT(mainbin[i].gst));
-                               mainbin[i].gst = NULL;
+                               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;
+                               }
                        }
-                       else
+                       break;
+               case ROTATION_USING_CUSTOM:
                        {
-                               gst_object_unref(GST_OBJECT(parent));
+                               gchar *ename = NULL;
+                               ename = GST_PLUGIN_FEATURE_NAME(gst_element_get_factory(player->pipeline->videobin[MMPLAYER_V_CONV].gst));
+
+                               if (g_strrstr(ename, "fimcconvert"))
+                               {
+                                       switch (dest_angle)
+                                       {
+                                               case 0:
+                                                       break;
+                                               case 90:
+                                                       pro_value = 90; // clockwise 90
+                                                       break;
+                                               case 180:
+                                                       pro_value = 180;
+                                                       break;
+                                               case 270:
+                                                       pro_value = 270; // counter-clockwise 90
+                                                       break;
+                                       }
+                               }
                        }
-               }
-       }
+                       break;
+               case ROTATION_USING_FLIP: // videoflip
+                       {
+                                       switch (dest_angle)
+                                       {
 
-       /* release pipeline with it's childs */
-       if ( mainbin[MMPLAYER_M_PIPE].gst )
-       {
-               gst_object_unref(GST_OBJECT(mainbin[MMPLAYER_M_PIPE].gst));
+                                               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;
        }
 
-       MMPLAYER_FREEIF( player->pipeline );
-       MMPLAYER_FREEIF( mainbin );
+       debug_log("setting rotation property value : %d, used rotation type : %d", pro_value, rotation_type);
 
-       return MM_ERROR_PLAYER_INTERNAL;
-}
+       *value = pro_value;
 
+       return TRUE;
+}
 
-static int
-__mmplayer_gst_destroy_pipeline(mm_player_t* player) // @
+int
+_mmplayer_update_video_param(mm_player_t* player) // @
 {
-       gint timeout = 0;
-       int ret = MM_ERROR_NONE;
-       int i = 0;
+       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();
-       
-       return_val_if_fail ( player, MM_ERROR_INVALID_HANDLE );
+       MMPLAYER_FENTER();
 
-       /* cleanup stuffs */
-       MMPLAYER_FREEIF(player->type);
-       player->have_dynamic_pad = FALSE;
-       player->no_more_pad = FALSE;
-       player->num_dynamic_pad = 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->not_found_demuxer = 0;
-       if (player->v_stream_caps)
+       /* 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 )
        {
-               gst_caps_unref(player->v_stream_caps);
-               player->v_stream_caps = NULL;
+               debug_error("cannot get content attribute");
+               return MM_ERROR_PLAYER_INTERNAL;
        }
-       
-       player->state_lost = FALSE;
-       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;
+       /* update user roation */
+       mm_attrs_get_int_by_name(attrs, "display_rotation", &user_angle_type);
 
-       if (ahs_appsrc_cb_probe_id )
+       /* get angle with user type */
+       switch(user_angle_type)
        {
-               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;
+               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;
        }
 
-       /* free request pads for multi-surface */
-       if (player->use_multi_surface && player->pipeline && player->pipeline->videobin[MMPLAYER_V_TEE].gst)
+       /* get original orientation */
+       if (player->v_stream_caps)
        {
-               for (i = 0 ; i < 2 ; i++)
+               GstStructure *str = NULL;
+
+               str = gst_caps_get_structure (player->v_stream_caps, 0);
+               if ( !gst_structure_get_int (str, "orientation", &org_angle))
                {
-                       if (player->tee_src_pad[i])
-                       {
-                               gst_element_release_request_pad (player->pipeline->videobin[MMPLAYER_V_TEE].gst, player->tee_src_pad[i]);
-                               gst_object_unref(player->tee_src_pad[i]);
-                       }
+                       debug_log ("missing 'orientation' field in video caps");
                }
-               player->use_multi_surface = FALSE;
-               debug_log("release request pads from TEE, and unref TEE's src pads");
        }
 
-       if ( player->sink_elements )
-               g_list_free ( player->sink_elements );
-       player->sink_elements = NULL;
+       debug_log("check user angle: %d, orientation: %d", user_angle, org_angle);
 
-       /* cleanup unlinked mime type */
-       MMPLAYER_FREEIF(player->unlinked_audio_mime);
-       MMPLAYER_FREEIF(player->unlinked_video_mime);
-       MMPLAYER_FREEIF(player->unlinked_demuxer_mime); 
+       /* check video stream callback is used */
+       if(!player->set_mode.media_packet_video_stream && player->use_video_stream )
+       {
+               if (player->set_mode.video_zc)
+               {
+                       gchar *ename = NULL;
+                       int width = 0;
+                       int height = 0;
 
-       /* cleanup running stuffs */
-       __mmplayer_cancel_delayed_eos( player );
+                       mm_attrs_get_int_by_name(attrs, "display_width", &width);
+                       mm_attrs_get_int_by_name(attrs, "display_height", &height);
 
-       /* cleanup gst stuffs */
-       if ( player->pipeline )
-       {
-               MMPlayerGstElement* mainbin = player->pipeline->mainbin;
-               GstTagList* tag_list = player->pipeline->tag_list;
-               GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (mainbin[MMPLAYER_M_PIPE].gst));
+                       /* resize video frame with requested values for fimcconvert */
+                       ename = GST_PLUGIN_FEATURE_NAME(gst_element_get_factory(player->pipeline->videobin[MMPLAYER_V_CONV].gst));
 
-               /* first we need to disconnect all signal hander */
-               __mmplayer_release_signal_connection( player );
+                       if (ename && g_strrstr(ename, "fimcconvert"))
+                       {
+                               if (width)
+                                       g_object_set(player->pipeline->videobin[MMPLAYER_V_CONV].gst, "dst-width", width, NULL);
 
-               /* disconnecting bus watch */
-               if ( player->bus_watcher )
-                       g_source_remove( player->bus_watcher );
-               player->bus_watcher = 0;
+                               if (height)
+                                       g_object_set(player->pipeline->videobin[MMPLAYER_V_CONV].gst, "dst-height", height, NULL);
 
-               gst_bus_set_sync_handler (bus, NULL, NULL);
+                               /* NOTE: fimcconvert does not manage index of src buffer from upstream src-plugin, decoder gives frame information in output buffer with no ordering */
+                               g_object_set(player->pipeline->videobin[MMPLAYER_V_CONV].gst, "src-rand-idx", TRUE, NULL);
 
-               if ( mainbin )
-               {
-                       MMPlayerGstElement* audiobin = player->pipeline->audiobin;
-                       MMPlayerGstElement* videobin = player->pipeline->videobin;
-                       MMPlayerGstElement* textbin = player->pipeline->textbin;
-                       MMPlayerGstElement* subtitlebin = player->pipeline->subtitlebin;
+                               /* get rotation value to set */
+                               __mmplayer_get_property_value_for_rotation(player, org_angle+user_angle, &rotation_value);
 
-                       debug_log("pipeline status before set state to NULL\n");
-                       __mmplayer_dump_pipeline_state( player );
+                               g_object_set(player->pipeline->videobin[MMPLAYER_V_CONV].gst, "rotate", rotation_value, NULL);
 
-                       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("updating fimcconvert - r[%d], w[%d], h[%d]", rotation_value, width, height);
                        }
+               }
+               else
+               {
+                       debug_log("using video stream callback with memsink. player handle : [%p]", player);
 
-                       debug_log("pipeline status before unrefering pipeline\n");
-                       __mmplayer_dump_pipeline_state( player );
+                       /* get rotation value to set */
+                       __mmplayer_get_property_value_for_rotation(player, org_angle+user_angle, &rotation_value);
 
-                       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 );
+                       g_object_set(player->pipeline->videobin[MMPLAYER_V_FLIP].gst, "method", rotation_value, NULL);
                }
 
-               if ( tag_list )
-                       gst_tag_list_free(tag_list);
-
-               MMPLAYER_FREEIF( player->pipeline );
+               return MM_ERROR_NONE;
        }
 
-       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;
+       /* 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);
 
-       debug_fenter();
+       /* configuring display */
+       switch ( surface_type )
+       {
+               case MM_DISPLAY_SURFACE_X:
+               {
+                       /* ximagesink or xvimagesink */
+                       void *xid = NULL;
+                       double zoom = 0;
+                       int display_method = 0;
+                       int roi_x = 0;
+                       int roi_y = 0;
+                       int roi_w = 0;
+                       int roi_h = 0;
+                       int src_crop_x = 0;
+                       int src_crop_y = 0;
+                       int src_crop_w = 0;
+                       int src_crop_h = 0;
+                       int force_aspect_ratio = 0;
+                       gboolean visible = TRUE;
 
-       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+                       /* common case if using x surface */
+                       mm_attrs_get_data_by_name(attrs, "display_overlay", &xid);
+                       if ( xid )
+                       {
+                               int xwin_id = 0;
+                               xwin_id = *(int*)xid;
+                               debug_log("set video param : xid %d", *(int*)xid);
+                               if (xwin_id)
+                               {
+                                       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.");
+                       }
 
-       MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_READY;
-       MMPLAYER_PRINT_STATE(player);   
+                       /* 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_double_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_src_crop_x", &src_crop_x);
+                               mm_attrs_get_int_by_name(attrs, "display_src_crop_y", &src_crop_y);
+                               mm_attrs_get_int_by_name(attrs, "display_src_crop_width", &src_crop_w);
+                               mm_attrs_get_int_by_name(attrs, "display_src_crop_height", &src_crop_h);
+                               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);
+                               #define DEFAULT_DISPLAY_MODE    2       // TV only, PRI_VIDEO_OFF_AND_SEC_VIDEO_FULL_SCREEN
 
-       __ta__("__mmplayer_gst_create_pipeline",
-               ret = __mmplayer_gst_create_pipeline(player);
-               if ( ret )
-               {
-                       debug_critical("failed to create pipeline\n");
-                       return ret;
-               }
-       )
+                               /* setting for cropping media source */
+                               if (src_crop_w && src_crop_h)
+                               {
+                                       g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst,
+                                               "src-crop-x", src_crop_x,
+                                               "src-crop-y", src_crop_y,
+                                               "src-crop-w", src_crop_w,
+                                               "src-crop-h", src_crop_h,
+                                               NULL );
+                               }
 
-       /* 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);
+                               /* setting for ROI mode */
+                               if (display_method == 5)        // 5 for ROI mode
+                               {
+                                       int roi_mode = 0;
+                                       mm_attrs_get_int_by_name(attrs, "display_roi_mode", &roi_mode);
+                                       g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst,
+                                               "dst-roi-mode", roi_mode,
+                                               "dst-roi-x", roi_x,
+                                               "dst-roi-y", roi_y,
+                                               "dst-roi-w", roi_w,
+                                               "dst-roi-h", roi_h,
+                                               NULL );
+                                       /* get rotation value to set,
+                                          do not use org_angle because ROI mode in xvimagesink needs both a rotation value and an orientation value */
+                                       __mmplayer_get_property_value_for_rotation(player, user_angle, &rotation_value);
+                               }
+                               else
+                               {
+                                       /* get rotation value to set */
+                                       __mmplayer_get_property_value_for_rotation(player, org_angle+user_angle, &rotation_value);
+                               }
 
-       if (MMPLAYER_PLAY_SUBTITLE(player))
-               ret = __mmplayer_gst_set_state(player,
-                                       player->pipeline->subtitlebin[MMPLAYER_SUB_PIPE].gst, GST_STATE_READY, FALSE, timeout);
+                               g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst,
+                                       "force-aspect-ratio", force_aspect_ratio,
+                                       "zoom", (float)zoom,
+                                       "orientation", org_angle/90, // setting for orientation of media, it is used for ROI/ZOOM feature in xvimagesink
+                                       "rotate", rotation_value,
+                                       "handle-events", TRUE,
+                                       "display-geometry-method", display_method,
+                                       "draw-borders", FALSE,
+                                       "visible", visible,
+                                       "display-mode", DEFAULT_DISPLAY_MODE,
+                                       NULL );
 
-       if ( ret != MM_ERROR_NONE )
-       {
-               /* return error if failed to set state */
-               debug_error("failed to set state PAUSED (live : READY).\n");
+                               debug_log("set video param : zoom %lf, rotate %d, method %d visible %d", zoom, rotation_value, display_method, visible);
+                               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, display mode %d", force_aspect_ratio, DEFAULT_DISPLAY_MODE);
+                       }
+               }
+               break;
+               case MM_DISPLAY_SURFACE_EVAS:
+               {
+                       void *object = NULL;
+                       int scaling = 0;
+                       gboolean visible = TRUE;
+                       int display_method = 0;
 
-               /* dump state of all element */
-               __mmplayer_dump_pipeline_state( player );
+                       /* 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);
+                       mm_attrs_get_int_by_name(attrs, "display_method", &display_method);
 
-               return ret;
-       }
-       else 
-       {
-               MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_READY );
-       }
+                       /* if evasimagesink */
+                       if (!strcmp(player->ini.videosink_element_evas,"evasimagesink"))
+                       {
+                               if (object)
+                               {
+                                       /* if it is evasimagesink, we are not supporting rotation */
+                                       if (user_angle_type!=MM_DISPLAY_ROTATION_NONE)
+                                       {
+                                               mm_attrs_set_int_by_name(attrs, "display_rotation", MM_DISPLAY_ROTATION_NONE);
+                                               if (mmf_attrs_commit (attrs)) /* return -1 if error */
+                                                       debug_error("failed to commit\n");
+                                               debug_warning("unsupported feature");
+                                               return MM_ERROR_NOT_SUPPORT_API;
+                                       }
+                                       __mmplayer_get_property_value_for_rotation(player, org_angle+user_angle, &rotation_value);
+                                       g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst,
+                                                       "evas-object", object,
+                                                       "visible", visible,
+                                                       "display-geometry-method", display_method,
+                                                       "rotate", rotation_value,
+                                                       NULL);
+                                       debug_log("set video param : method %d", display_method);
+                                       debug_log("set video param : evas-object %x, visible %d", object, visible);
+                                       debug_log("set video param : evas-object %x, rotate %d", object, rotation_value);
+                               }
+                               else
+                               {
+                                       debug_error("no evas object");
+                                       return MM_ERROR_PLAYER_INTERNAL;
+                               }
 
-       /* create dot before error-return. for debugging */
-       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-realize" );
 
-       debug_fleave();
+                               /* if evasimagesink using converter */
+                               if (player->set_mode.video_zc && player->pipeline->videobin[MMPLAYER_V_CONV].gst)
+                               {
+                                       int width = 0;
+                                       int height = 0;
+                                       int no_scaling = !scaling;
 
-       return ret;
-}
+                                       mm_attrs_get_int_by_name(attrs, "display_width", &width);
+                                       mm_attrs_get_int_by_name(attrs, "display_height", &height);
 
-static int __gst_unrealize(mm_player_t* player) // @
-{
-       int ret = MM_ERROR_NONE;
+                                       /* NOTE: fimcconvert does not manage index of src buffer from upstream src-plugin, decoder gives frame information in output buffer with no ordering */
+                                       g_object_set(player->pipeline->videobin[MMPLAYER_V_CONV].gst, "src-rand-idx", TRUE, NULL);
+                                       g_object_set(player->pipeline->videobin[MMPLAYER_V_CONV].gst, "dst-buffer-num", 5, NULL);
 
-       debug_fenter();
+                                       if (no_scaling)
+                                       {
+                                               /* no-scaling order to fimcconvert, original width, height size of media src will be passed to sink plugin */
+                                               g_object_set(player->pipeline->videobin[MMPLAYER_V_CONV].gst,
+                                                               "dst-width", 0, /* setting 0, output video width will be media src's width */
+                                                               "dst-height", 0, /* setting 0, output video height will be media src's height */
+                                                               NULL);
+                                       }
+                                       else
+                                       {
+                                               /* scaling order to fimcconvert */
+                                               if (width)
+                                               {
+                                                       g_object_set(player->pipeline->videobin[MMPLAYER_V_CONV].gst, "dst-width", width, NULL);
+                                               }
+                                               if (height)
+                                               {
+                                                       g_object_set(player->pipeline->videobin[MMPLAYER_V_CONV].gst, "dst-height", height, NULL);
+                                               }
+                                               debug_log("set video param : video frame scaling down to width(%d) height(%d)", width, height);
+                                       }
+                                       debug_log("set video param : display_evas_do_scaling %d", scaling);
+                               }
+                       }
 
-       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+                       /* if evaspixmapsink */
+                       if (!strcmp(player->ini.videosink_element_evas,"evaspixmapsink"))
+                       {
+                               if (object)
+                               {
+                                       __mmplayer_get_property_value_for_rotation(player, org_angle+user_angle, &rotation_value);
+                                       g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst,
+                                                       "evas-object", object,
+                                                       "visible", visible,
+                                                       "display-geometry-method", display_method,
+                                                       "rotate", rotation_value,
+                                                       NULL);
+                                       debug_log("set video param : method %d", display_method);
+                                       debug_log("set video param : evas-object %x, visible %d", object, visible);
+                                       debug_log("set video param : evas-object %x, rotate %d", object, rotation_value);
+                               }
+                               else
+                               {
+                                       debug_error("no evas object");
+                                       return MM_ERROR_PLAYER_INTERNAL;
+                               }
 
-       MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_NULL;
-       MMPLAYER_PRINT_STATE(player);   
+                               int display_method = 0;
+                               int roi_x = 0;
+                               int roi_y = 0;
+                               int roi_w = 0;
+                               int roi_h = 0;
+                               int origin_size = !scaling;
 
-       player->use_video_stream = FALSE;
-       player->video_stream_cb = NULL;
-       player->video_stream_cb_user_param = NULL;
+                               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);
 
-       player->audio_stream_cb = NULL;
-       player->audio_stream_cb_user_param = NULL;
+                               /* get rotation value to set */
+                               __mmplayer_get_property_value_for_rotation(player, org_angle+user_angle, &rotation_value);
 
-       player->audio_buffer_cb = NULL;
-       player->audio_buffer_cb_user_param = NULL;
+                               g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst,
+                                       "origin-size", origin_size,
+                                       "rotate", rotation_value,
+                                       "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 );
 
-       player->sent_bos = FALSE;
-       player->playback_rate = DEFAULT_PLAYBACK_RATE;
+                               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 : display_evas_do_scaling %d (origin-size %d)", scaling, origin_size);
+                       }
+               }
+               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;
 
-       /* clean found parsers */
-       if (player->parsers)
-       {
-               g_list_free(player->parsers);
-               player->parsers = NULL;
-       }
+                       /* if xvimagesink */
+                       if (strcmp(player->ini.videosink_element_x,"xvimagesink"))
+                       {
+                               debug_error("videosink is not xvimagesink");
+                               return MM_ERROR_PLAYER_INTERNAL;
+                       }
 
-       MMPLAYER_FREEIF(player->album_art);
+                       /* 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);
+                       mm_attrs_get_int_by_name(attrs, "display_visible", &visible);
 
-       /* destroy pipeline */
-       ret = __mmplayer_gst_destroy_pipeline( player );
-       if ( ret != MM_ERROR_NONE )
-       {
-               debug_error("failed to destory pipeline\n");
-               return ret;
-       }
-       else 
-       {
-               MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_NULL );
+                       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;
+                       }
+                       /* get rotation value to set */
+                       __mmplayer_get_property_value_for_rotation(player, org_angle+user_angle, &rotation_value);
+
+                       debug_log("set video param : rotate %d, method %d, visible %d", rotation_value, display_method, 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,
+                               "rotate", rotation_value,
+                               "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();
+       MMPLAYER_FLEAVE();
 
-       return ret;
+       return MM_ERROR_NONE;
 }
 
-static int __gst_pending_seek ( mm_player_t* player )
+static int
+__mmplayer_gst_element_link_bucket(GList* element_bucket) // @
 {
-       MMPlayerStateType current_state = MM_PLAYER_STATE_NONE;
-       MMPlayerStateType pending_state = MM_PLAYER_STATE_NONE;
-       int ret = MM_ERROR_NONE;
-
-       debug_fenter();
+       GList* bucket = element_bucket;
+       MMPlayerGstElement* element = NULL;
+       MMPlayerGstElement* prv_element = NULL;
+       gint successful_link_count = 0;
 
-       return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       MMPLAYER_FENTER();
 
-       if ( !player->pending_seek.is_pending )
-       {
-               debug_log("pending seek is not reserved. nothing to do.\n" );
-               return ret;
-       }
+       return_val_if_fail(element_bucket, -1);
 
-       /* check player state if player could pending seek or not. */
-       current_state = MMPLAYER_CURRENT_STATE(player);
-       pending_state = MMPLAYER_PENDING_STATE(player);
+       prv_element = (MMPlayerGstElement*)bucket->data;
+       bucket = bucket->next;
 
-       if ( current_state != MM_PLAYER_STATE_PAUSED && current_state != MM_PLAYER_STATE_PLAYING  )
+       for ( ; bucket; bucket = bucket->next )
        {
-               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 );
-       
-       if ( MM_ERROR_NONE != ret )
-               debug_error("failed to seek pending postion. just keep staying current position.\n");
+               element = (MMPlayerGstElement*)bucket->data;
 
-       player->pending_seek.is_pending = FALSE;
-
-       debug_fleave();
-
-       return ret;
-}
-
-
-static int __gst_start(mm_player_t* player) // @
-{
-       gboolean sound_extraction = 0;
-       gboolean async = FALSE;
-       gint timeout = 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))
-       {
-               ret = __gst_pause(player, FALSE);
-               if ( ret != MM_ERROR_NONE )
-               {
-                       debug_error("failed to set state to PAUSED for pending seek\n");
-                       return ret;
-               }
-                       
-               if ( sound_extraction )
+               if ( element && element->gst )
                {
-                       debug_log("setting pcm extraction\n");
-
-                       ret = __mmplayer_set_pcm_extraction(player);
-                       if ( MM_ERROR_NONE != ret )
+                       if ( GST_ELEMENT_LINK(GST_ELEMENT(prv_element->gst), GST_ELEMENT(element->gst)) )
                        {
-                               debug_warning("failed to set pcm extraction\n");
-                               return ret;
+                               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
-               {                       
-                       if ( MM_ERROR_NONE != __gst_pending_seek(player) )
+                       else
                        {
-                               debug_warning("failed to seek pending postion. starting from the begin of content.\n");
+                               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;
                        }
                }
-       }
 
-       MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_PLAYING;
+               prv_element = element;
+       }
 
-       MMPLAYER_PRINT_STATE(player);   
+       MMPLAYER_FLEAVE();
 
-       /* NOTE : note that current variant of rtspsrc has their own buffering mechanism.
-         * their keeping rtp packets without gst timestamping. there's no easy way to export buffering mechanism to plugin-level. and
-         * application also not ready. thus, just for now. state transition to PLAYING will done in asyn mode.
-         * please do not confused with async property hack which done by __gst_set_async_state_change()
-         */
-       /* NOTE : testing async start when local playback also */
+       return successful_link_count;
+}
 
-       mm_attrs_get_int_by_name(player->attrs,"profile_async_start", &async);
-       debug_log("start mode : %s", (async ? "async" : "sync"));
+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;
 
-       /* 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 );
+       MMPLAYER_FENTER();
 
-       if (MMPLAYER_PLAY_SUBTITLE(player))
-               ret = __mmplayer_gst_set_state(player,
-                       player->pipeline->subtitlebin[MMPLAYER_SUB_PIPE].gst, GST_STATE_PLAYING, FALSE, timeout );
+       return_val_if_fail(element_bucket, 0);
+       return_val_if_fail(bin, 0);
 
-       if (ret == MM_ERROR_NONE)
+       for ( ; bucket; bucket = bucket->next )
        {
-               if (!async)
-               {
-                       guint duration = 0;
-                       debug_log("sync state changing is completed");
+               element = (MMPlayerGstElement*)bucket->data;
 
-                       mm_attrs_get_int_by_name(player->attrs, "content_duration", &duration);
-                       if (!duration)
+               if ( element && element->gst )
+               {
+                       if( !gst_bin_add(bin, GST_ELEMENT(element->gst)) )
                        {
-                               debug_warning("try to update duration more");
-                               player->need_update_content_attrs = TRUE;
-                               player->need_update_content_dur = TRUE;
-                               _mmplayer_update_content_attrs(player);
+                               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;
                        }
-
-                       MMPLAYER_SET_STATE(player, MM_PLAYER_STATE_PLAYING);
+                       successful_add_count ++;
                }
        }
-       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();
+       MMPLAYER_FLEAVE();
 
-       return ret;
+       return successful_add_count;
 }
 
-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();
-}
+/**
+ * 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_error("failed to create %s \n", x_factory);\
+       goto ERROR;\
+}\
 
-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);       
+#define MMPLAYER_CREATE_ELEMENT_ADD_BIN(x_bin, x_id, x_factory, x_name, y_bin, x_player) \
+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_error("failed to create %s \n", x_factory);\
+       goto ERROR;\
+}\
+else\
+{\
+       if (x_player->ini.set_dump_element_flag)\
+               __mmplayer_add_dump_buffer_probe(x_player, x_bin[x_id].gst);\
+}\
+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;\
+}\
 
-       debug_fleave();
-}
+/* macro for code readability. just for sinkbin-creation functions */
+#define MMPLAYER_CREATE_ELEMENT(x_bin, x_id, x_factory, x_name, x_add_bucket, x_player) \
+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_error("failed to create %s \n", x_factory);\
+               goto ERROR;\
+       }\
+       else\
+       {\
+               if (x_player->ini.set_dump_element_flag)\
+                       __mmplayer_add_dump_buffer_probe(x_player, x_bin[x_id].gst);\
+       }\
+       if ( x_add_bucket )\
+               element_bucket = g_list_append(element_bucket, &x_bin[x_id]);\
+} while(0);
 
-static int __gst_stop(mm_player_t* player) // @
+/**
+  * AUDIO PIPELINE
+  * - Local playback   : audiotp !audioconvert ! volume ! capsfilter ! audioeffect ! audioeffect_sec ! audiosink
+  * - Streaming        : audiotp !audioconvert !volume ! audiosink
+  * - PCM extraction : audiotp !audioconvert ! audioresample ! capsfilter ! fakesink
+  */
+static int
+__mmplayer_gst_create_audio_pipeline(mm_player_t* player)
 {
-       GstStateChangeReturn change_ret = GST_STATE_CHANGE_SUCCESS;
+       MMPlayerGstElement* first_element = NULL;
+       MMPlayerGstElement* audiobin = NULL;
        MMHandleType attrs = 0;
-       gboolean fadewown = FALSE;
-       gboolean rewind = FALSE;
-       gint timeout = 0;
-       int ret = MM_ERROR_NONE;
-
-       debug_fenter();
+       GstPad *pad = NULL;
+       GstPad *ghostpad = NULL;
+       GList* element_bucket = NULL;
+       gboolean link_audio_sink_now = TRUE;
+       int i =0;
 
-       return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       MMPLAYER_FENTER();
 
-       MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_READY;
-       MMPLAYER_PRINT_STATE(player);   
+       return_val_if_fail( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
 
-       attrs = MMPLAYER_GET_ATTRS(player);
-       if ( !attrs )
+       /* alloc handles */
+       audiobin = (MMPlayerGstElement*)g_malloc0(sizeof(MMPlayerGstElement) * MMPLAYER_A_NUM);
+       if ( ! audiobin )
        {
-               debug_error("cannot get content attribute\n");
-               return MM_ERROR_PLAYER_INTERNAL;
+               debug_error("failed to allocate memory for audiobin\n");
+               return MM_ERROR_PLAYER_NO_FREE_SPACE;
        }
 
-       mm_attrs_get_int_by_name(attrs,"sound_fadedown", &fadewown);
-
-       /* enable fadedown */
-       if (fadewown)
-               __mmplayer_do_sound_fadedown(player, MM_PLAYER_FADEOUT_TIME_DEFAULT);
+       attrs = MMPLAYER_GET_ATTRS(player);
 
-       /* 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 )
+       /* 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 )
        {
-               ret = __mmplayer_gst_set_state(player, 
-                       player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_READY, FALSE, timeout );
+               debug_error("failed to create audiobin\n");
+               goto ERROR;
        }
-       else
-       {
-               ret = __mmplayer_gst_set_state( player,
-                       player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_PAUSED, FALSE, timeout );
 
-               if (MMPLAYER_PLAY_SUBTITLE(player))
-                       ret = __mmplayer_gst_set_state( player,
-                               player->pipeline->subtitlebin[MMPLAYER_SUB_PIPE].gst, GST_STATE_PAUSED, FALSE, timeout );
+       /* take it */
+       player->pipeline->audiobin = audiobin;
 
-               if ( !MMPLAYER_IS_STREAMING(player))
-                       rewind = TRUE;
-       }
+       player->set_mode.pcm_extraction = __mmplayer_can_extract_pcm(player);
 
-       /* disable fadeout */
-       if (fadewown)
-               __mmplayer_undo_sound_fadedown(player);
+       /* Adding audiotp plugin for reverse trickplay feature */
+       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_TP, "audiotp", "audio trickplay", TRUE, player);
+
+       /* converter */
+       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CONV, "audioconvert", "audio converter", TRUE, player);
 
+       /* resampler */
+       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_RESAMPLER,  player->ini.name_of_audio_resampler, "audio resampler", TRUE, player);
 
-       /* return if set_state has failed */
-       if ( ret != MM_ERROR_NONE )
+       if (player->set_mode.pcm_extraction) // pcm extraction only and no sound output
        {
-               debug_error("failed to set state.\n");
+               int dst_samplerate = 0;
+               int dst_channels = 0;
+               int dst_depth = 0;
+               char *caps_str = NULL;
+               GstCaps* caps = NULL;
 
-               /* dump state of all element. don't care it success or not */
-               __mmplayer_dump_pipeline_state( player );
+               /* 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);
 
-               return ret;
-       }
+               /* capsfilter */
+               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CAPS_DEFAULT, "capsfilter", "audio capsfilter", TRUE, player);
+               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_str = gst_caps_to_string(caps);
+               debug_log("new caps : %s\n", caps_str);
 
-       /* 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;
-               }
-       }
+               g_object_set (GST_ELEMENT(audiobin[MMPLAYER_A_CAPS_DEFAULT].gst), "caps", caps, NULL );
 
-       /* initialize */
-       player->sent_bos = FALSE;
+               /* clean */
+               gst_caps_unref( caps );
+               MMPLAYER_FREEIF( caps_str );
 
-       /* wait for seek to complete */
-       change_ret = gst_element_get_state (player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, NULL, NULL, timeout * GST_SECOND);
-       if (MMPLAYER_PLAY_SUBTITLE(player))
-               change_ret = gst_element_get_state (player->pipeline->subtitlebin[MMPLAYER_SUB_PIPE].gst, NULL, NULL, timeout * GST_SECOND);
+               /* fake sink */
+               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_SINK, "fakesink", "fakesink", TRUE, player);
 
-       if ( change_ret == GST_STATE_CHANGE_SUCCESS || change_ret == GST_STATE_CHANGE_NO_PREROLL )
-       {
-               MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_READY );
+               /* set sync */
+               g_object_set (G_OBJECT (audiobin[MMPLAYER_A_SINK].gst), "sync", FALSE, NULL);
        }
-       else
+       else // normal playback
        {
-               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" );
+               typedef enum
+               {
+                       GST_BASE_AUDIO_SINK_SLAVE_RESAMPLE = 0,
+                       GST_BASE_AUDIO_SINK_SLAVE_SKEW,
+                       GST_BASE_AUDIO_SINK_SLAVE_NONE
+               } GstBaseAudioSinkSlaveMethod;
 
-       debug_fleave(); 
+               //GstCaps* caps = NULL;
+               gint channels = 0;
 
-       return ret;
-}
+               /* for logical volume control */
+               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_VOL, "volume", "volume", TRUE, player);
+               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);
+               }
 
-int __gst_pause(mm_player_t* player, gboolean async) // @
-{
-       gint timeout = 0;
-       int ret = MM_ERROR_NONE;
+#if 0
+               /*capsfilter */
+               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CAPS_DEFAULT, "capsfilter", "audiocapsfilter", TRUE, player);
+               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 );
+#endif
 
-       debug_fenter();
+               /* chech if multi-chennels */
+               if (player->pipeline->mainbin && player->pipeline->mainbin[MMPLAYER_M_DEMUX].gst)
+               {
+                       GstPad *srcpad = NULL;
+                       GstCaps *caps = NULL;
 
-       return_val_if_fail(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
+                       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);
+                       }
+               }
 
-       MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_PAUSED;
-       MMPLAYER_PRINT_STATE(player);   
+               /* audio effect element. if audio effect is enabled */
+               if ( (strcmp(player->ini.name_of_audio_effect, ""))
+                       && (channels <= 2)
+                       && player->ini.use_audio_effect_custom)
+               {
+                       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_FILTER, player->ini.name_of_audio_effect, "audio effect filter", TRUE, player);
 
-       if ( async )
-               debug_log("do async state transition to PAUSE.\n");
+                       debug_log("audio effect config. bypass = %d, effect type  = %d", player->bypass_audio_effect, player->audio_effect_info.effect_type);
 
-       /* set pipeline status to PAUSED */
-       timeout = MMPLAYER_STATE_CHANGE_TIMEOUT(player);
-       ret = __mmplayer_gst_set_state(player,
-               player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_PAUSED, async, timeout );
+                       if ( (!player->bypass_audio_effect)
+                               && player->ini.use_audio_effect_custom)
+                       {
+                               if ( MM_AUDIO_EFFECT_TYPE_CUSTOM == player->audio_effect_info.effect_type )
+                               {
+                                       if (!_mmplayer_audio_effect_custom_apply(player))
+                                       {
+                                               debug_msg("apply audio effect(custom) setting success\n");
+                                       }
+                               }
+                       }
 
-       if (MMPLAYER_PLAY_SUBTITLE(player))
-               ret = __mmplayer_gst_set_state(player,
-                       player->pipeline->subtitlebin[MMPLAYER_SUB_PIPE].gst, GST_STATE_PAUSED, async, timeout );
+                       if ( (strcmp(player->ini.name_of_audio_effect_sec, ""))
+                               && (player->set_mode.rich_audio) )
+                       {
+                               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_FILTER_SEC, player->ini.name_of_audio_effect_sec, "audio effect filter", TRUE, player);
+                       }
+               }
+               if (!MMPLAYER_IS_RTSP_STREAMING(player))
+               {
+                       if (player->set_mode.rich_audio && channels <= 2)
+                               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_VSP, "audiovsp", "x-speed", TRUE, player);
+               }
 
-       /* NOTE : here we are setting state PAUSED to streaming source element again. because
-        * main pipeline will not set the state of it's all childs if state of the pipeline
-        * is already PAUSED for some reason. this situaition can happen when rebuffering or
-        * buffering after seeking. in both case streaming source will send flush event and then
-        * sink elements will lost it's state and it will set the state to PAUSED by theyself.
-       */
-       if ( MMPLAYER_IS_RTSP_STREAMING( player ) && player->state_lost )
-       {
-               debug_log("setting PAUSED to streaming source again.\n");
-               gst_element_set_state(player->pipeline->mainbin[MMPLAYER_M_SRC].gst, GST_STATE_PAUSED);
-       }
+               /* create audio sink */
+               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_SINK, player->ini.name_of_audiosink, "audiosink", link_audio_sink_now, player);
 
-       if ( ret != MM_ERROR_NONE )
-       {
-               debug_error("failed to set state to PAUSED\n");
+               /* qos on */
+               g_object_set (G_OBJECT (audiobin[MMPLAYER_A_SINK].gst), "qos", TRUE, NULL);     /* qos on */
+               g_object_set (G_OBJECT (audiobin[MMPLAYER_A_SINK].gst), "slave-method", GST_BASE_AUDIO_SINK_SLAVE_NONE, NULL);
 
-               /* dump state of all element */
-               __mmplayer_dump_pipeline_state( player );
+               /* FIXIT : using system clock. isn't there another way? */
+               if (player->videodec_linked)
+               {
+                       debug_log("provide clock for movie = %s", (player->ini.provide_clock_for_movie)?"audio_clock":"sys_clock");
+                       g_object_set (G_OBJECT (audiobin[MMPLAYER_A_SINK].gst), "provide-clock", player->ini.provide_clock_for_movie,  NULL);
+               }
+               else
+               {
+                       debug_log("provide clock for music = %s", (player->ini.provide_clock_for_music)?"audio_clock":"sys_clock");
+                       g_object_set (G_OBJECT (audiobin[MMPLAYER_A_SINK].gst), "provide-clock", player->ini.provide_clock_for_music,  NULL);
+               }
 
-               return ret;
-       }
-       else
-       {       
-               if ( async == FALSE ) 
+               if ( g_strrstr(player->ini.name_of_audiosink, "avsysaudiosink") || g_strrstr(player->ini.name_of_audiosink, "pulsesink") )
                {
-                       debug_log("sync state changing is completed.");
-                       MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_PAUSED );
+                       gint volume_type = 0;
+                       gint audio_route = 0;
+                       gint sound_priority = FALSE;
+                       gint route_path = 0;
+                       gint latency_mode = 0;
+                       gint close_handle = 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", &route_path);
+                       mm_attrs_get_int_by_name(attrs, "sound_latency_mode", &latency_mode);
+
+                       if (player->sm.user_route_policy != 0) {
+                               route_path = player->sm.user_route_policy;
+                       }
+
+                       g_object_set(audiobin[MMPLAYER_A_SINK].gst,
+                                       "volumetype", volume_type,
+                                       "audio-route", audio_route,
+                                       "priority", sound_priority,
+                                       "user-route", route_path,
+                                       "latency", latency_mode,
+                                       "close-handle-on-prepare", close_handle,
+                                       NULL);
+
+                       debug_log("audiosink property status...volume type:%d, route:%d, priority=%d, user-route=%d, latency=%d, close-resource=%d\n",
+                               volume_type, audio_route, sound_priority, route_path, latency_mode, close_handle);
                }
-       } 
 
-       /* FIXIT : analyze so called "async problem" */
-       /* set async off */
-       __gst_set_async_state_change( player, TRUE);
+               /* 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 );
+       }
 
+       __mmplayer_add_sink( player, audiobin[MMPLAYER_A_SINK].gst );
 
-       /* generate dot file before returning error */
-       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-pause" );
+       /* 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;
+       }
 
-       debug_fleave();
+       /* 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;
+       }
 
-       return ret;
-}
+       /* get first element's sinkpad for creating ghostpad */
+       first_element = (MMPlayerGstElement *)element_bucket->data;
 
-int __gst_resume(mm_player_t* player, gboolean async) // @
-{
-       int ret = MM_ERROR_NONE;
-       gint timeout = 0;
+       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;
+       }
 
-       debug_fenter();
+       ghostpad = gst_ghost_pad_new("sink", pad);
+       if ( ! ghostpad )
+       {
+               debug_error("failed to create ghostpad\n");
+               goto ERROR;
+       }
 
-       return_val_if_fail(player && player->pipeline,
-               MM_ERROR_PLAYER_NOT_INITIALIZED);
+       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);
 
-       MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_PLAYING;
-       MMPLAYER_PRINT_STATE(player);   
+       g_list_free(element_bucket);
 
-       /* generate dot file before returning error */
-       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-resume" );
+       mm_attrs_set_int_by_name(attrs, "content_audio_found", TRUE);
 
-       __mmplayer_set_antishock( player , FALSE );
+       MMPLAYER_FLEAVE();
 
-       if ( async )
-               debug_log("do async state transition to PLAYING.\n");
+       return MM_ERROR_NONE;
 
-       /* 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 );
+ERROR:
 
-       if (MMPLAYER_PLAY_SUBTITLE(player))
-               ret = __mmplayer_gst_set_state(player,
-                       player->pipeline->subtitlebin[MMPLAYER_SUB_PIPE].gst, GST_STATE_PLAYING, async, timeout );
+       debug_log("ERROR : releasing audiobin\n");
 
-       /* NOTE : same reason when pausing */
-       if ( MMPLAYER_IS_RTSP_STREAMING(player) && player->state_lost )
-       {
-               debug_log("setting PLAYING to streaming source again.\n");
-               gst_element_set_state(player->pipeline->mainbin[MMPLAYER_M_SRC].gst, GST_STATE_PLAYING);
-       }
+       if ( pad )
+               gst_object_unref(GST_OBJECT(pad));
 
-       if (ret != MM_ERROR_NONE)
-       {
-               debug_error("failed to set state to PLAYING\n");
+       if ( ghostpad )
+               gst_object_unref(GST_OBJECT(ghostpad));
 
-               /* dump state of all element */
-               __mmplayer_dump_pipeline_state( player );
+       g_list_free( element_bucket );
 
-               return ret;
-       }
-       else
+       /* release element which are not added to bin */
+       for ( i = 1; i < MMPLAYER_A_NUM; i++ )  /* NOTE : skip bin */
        {
-               if (async == FALSE)
-               {       
-                       debug_log("sync state changing is completed.");
-                       MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_PLAYING );
+               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));
+                       }
                }
        }
-       
-       /* 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" );
+       /* release audiobin with it's childs */
+       if ( audiobin[MMPLAYER_A_BIN].gst )
+       {
+               gst_object_unref(GST_OBJECT(audiobin[MMPLAYER_A_BIN].gst));
+       }
 
-       debug_fleave();
+       MMPLAYER_FREEIF( audiobin );
 
-       return ret;
+       player->pipeline->audiobin = NULL;
+
+       return MM_ERROR_PLAYER_INTERNAL;
 }
 
-static int
-__gst_set_position(mm_player_t* player, int format, unsigned long position) // @
+static gboolean
+__mmplayer_audio_stream_probe (GstPad *pad, GstBuffer *buffer, gpointer u_data)
 {
-       MMPlayerStateType current_state = MM_PLAYER_STATE_NONE;
-       MMPlayerStateType pending_state = MM_PLAYER_STATE_NONE;
-       GstFormat fmt  = GST_FORMAT_TIME;
-       unsigned long dur = 0;
-       gint64 dur_msec = 0;
-       gint64 pos_msec = 0;
-       gboolean ret = TRUE;
-
-       debug_fenter();
+       mm_player_t* player = (mm_player_t*) u_data;
+       gint size;
+       guint8 *data;
 
-       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 );
+       data = GST_BUFFER_DATA(buffer);
+       size = GST_BUFFER_SIZE(buffer);
 
-       /* check player state if player could seek or not. */
-       current_state = MMPLAYER_CURRENT_STATE(player);
-       pending_state = MMPLAYER_PENDING_STATE(player);
-               
-       if ( current_state != MM_PLAYER_STATE_PLAYING && current_state != MM_PLAYER_STATE_PAUSED )
-               goto PENDING;
+       if (player->audio_stream_cb && size && data)
+               player->audio_stream_cb((void *)data, size, player->audio_stream_cb_user_param);
 
-       /* 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 == 0 )
-       {
-               ret = gst_element_query_duration( player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, &fmt, &dur_msec );
-               if ( !ret )
-                       goto SEEK_ERROR;
-               else
-                       player->duration = dur_msec;
-       }
+       return TRUE;
+}
 
-       if ( player->duration )
-       {
-               dur = GST_TIME_AS_MSECONDS(player->duration);
-               debug_log("duration is %d [msec]. \n", dur);
-       }
-       else
-       {
-               debug_error("could not get the duration. fail to seek.\n");
-               goto SEEK_ERROR;
+static gboolean
+__mmplayer_video_stream_probe (GstPad *pad, GstBuffer *buffer, gpointer user_data)
+{
+       GstCaps *caps = NULL;
+       MMPlayerVideoStreamDataType stream;
+       MMPlayerMPlaneImage *scmn_imgb = NULL;
+       GstStructure *structure = NULL;
+       unsigned int fourcc = 0;
+       mm_player_t* player = (mm_player_t*)user_data;
+
+       caps = gst_buffer_get_caps(buffer);
+       if (caps == NULL) {
+               debug_error( "Caps is NULL." );
+               return TRUE;
        }
-       
-       /* do seek */
-       switch ( format )
-       {
-               case MM_PLAYER_POS_FORMAT_TIME:
-               {
-                       /* check position is valid or not */
-                       if ( position > dur )
-                               goto INVALID_ARGS;
 
-                       debug_log("seeking to (%lu) msec\n", position);
+       //MMPLAYER_LOG_GST_CAPS_TYPE(caps);
 
-                       if (player->doing_seek)
-                       {
-                               debug_log("not completed seek");
-                               return MM_ERROR_PLAYER_DOING_SEEK;
-                       }
-                       player->doing_seek = TRUE;
+       /* clear stream data structure */
+       memset(&stream, 0x0, sizeof(MMPlayerVideoStreamDataType));
 
-                       pos_msec = 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_msec, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE );
+       structure = gst_caps_get_structure( caps, 0 );
+       gst_structure_get_int(structure, "width", &(stream.width));
+       gst_structure_get_int(structure, "height", &(stream.height));
+       gst_structure_get_fourcc(structure, "format", &fourcc);
+       stream.format = util_get_pixtype(fourcc);
+       gst_caps_unref( caps );
+       caps = NULL;
 
-                       if ( !ret  )
-                       {
-                               debug_error("failed to set position. dur[%lud]  pos[%lud]  pos_msec[%llud]\n", dur, position, pos_msec);
-                               goto SEEK_ERROR;
-                       }
-               }
-               break;
+    /*
+       debug_log( "Call video steramCb, data[%p], Width[%d],Height[%d], Format[%d]",
+                       GST_BUFFER_DATA(buffer), stream.width, stream.height, stream.format );
+    */
 
-               case MM_PLAYER_POS_FORMAT_PERCENT:
-               {
-                       if ( position < 0 && position > 100 )
-                               goto INVALID_ARGS;
+       if (stream.width == 0 || stream.height == 0) {
+               debug_error("Wrong condition!!");
+               return TRUE;
+       }
 
-                       debug_log("seeking to (%lu)%% \n", position);
+       /* set size and timestamp */
+       stream.length_total = GST_BUFFER_SIZE(buffer);
+       stream.timestamp = (unsigned int)(GST_BUFFER_TIMESTAMP(buffer)/1000000); /* nano sec -> mili sec */
 
-                       if (player->doing_seek)
-                       {
-                               debug_log("not completed seek");
-                               return MM_ERROR_PLAYER_DOING_SEEK;
-                       }
-                       player->doing_seek = TRUE;
+       //check zero-copy
+       if (player->set_mode.video_zc
+               && player->set_mode.media_packet_video_stream
+               && GST_BUFFER_MALLOCDATA(buffer)) {
+               scmn_imgb = (MMPlayerMPlaneImage *)GST_BUFFER_MALLOCDATA(buffer);
+       }
 
-                       /* FIXIT : why don't we use 'GST_FORMAT_PERCENT' */
-                       pos_msec = (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_msec, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE );
+       /* set tbm bo */
+       if (scmn_imgb) {
+               /* copy pointer of tbm bo, stride, elevation */
+               memcpy(stream.bo, scmn_imgb->bo, sizeof(void *) * MM_PLAYER_IMGB_MPLANE_MAX);
+               memcpy(stream.stride, scmn_imgb->s, sizeof(int) * MM_PLAYER_IMGB_MPLANE_MAX);
+               memcpy(stream.elevation, scmn_imgb->e, sizeof(int) * MM_PLAYER_IMGB_MPLANE_MAX);
 
-                       if ( !ret  )
-                       {
-                               debug_error("failed to set position. dur[%lud]  pos[%lud]  pos_msec[%llud]\n", dur, position, pos_msec);
-                               goto SEEK_ERROR;
-                       }
+               /*
+               int i = 0;
+               for (i = 0 ; i < BUFFER_MAX_PLANE_NUM ; i++) {
+                       debug_log("w %d, h %d, s %d, e %d, bo %p",
+                                       scmn_imgb->w[i],scmn_imgb->h[i],scmn_imgb->s[i],scmn_imgb->e[i],
+                                       scmn_imgb->bo[i]);
+                       if(scmn_imgb->bo[i])
+                               debug_log("bo size %d", tbm_bo_size(scmn_imgb->bo[i]));
                }
-               break;
+               */
 
-               default:
-                       goto INVALID_ARGS;
-                       
+               /* set gst buffer */
+               stream.internal_buffer = buffer;
+       } else {
+               stream.data = GST_BUFFER_DATA(buffer);
        }
 
+       if (player->video_stream_cb) {
+               player->video_stream_cb(&stream, player->video_stream_cb_user_param);
+       }
 
-       /* NOTE : store last seeking point to overcome some bad operation 
-         *      ( returning zero when getting current position ) of some elements 
-         */
-       player->last_position = pos_msec;
-
-       debug_log("playback rate: %f\n", player->playback_rate);
-
-       /* 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 TRUE;
+}
 
-       return MM_ERROR_NONE;
+static int
+__mmplayer_gst_create_video_filters(mm_player_t* player, GList** bucket, gboolean use_video_stream)
+{
+       gchar* video_csc = "ffmpegcolorspace"; // default colorspace converter
+       GList* element_bucket = *bucket;
 
-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(current_state), MMPLAYER_STATE_GET_NAME(pending_state), player->pending_seek.pos);
-       
-       return MM_ERROR_NONE;
-       
-INVALID_ARGS:  
-       debug_error("invalid arguments, position : %ld  dur : %ld format : %d \n", position, dur, format);
-       
-       return MM_ERROR_PLAYER_INTERNAL;
+       return_val_if_fail(player && player->pipeline && player->pipeline->videobin, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-SEEK_ERROR:
-       player->doing_seek = FALSE;
-       return MM_ERROR_PLAYER_SEEK;
+       MMPLAYER_FENTER();
 
-}
+       if (!player->set_mode.media_packet_video_stream && use_video_stream)
+       {
+               if (player->set_mode.video_zc && strlen(player->ini.name_of_video_converter) > 0)
+               {
+                       video_csc = player->ini.name_of_video_converter;
+               }
 
-#define TRICKPLAY_OFFSET GST_MSECOND
+               MMPLAYER_CREATE_ELEMENT(player->pipeline->videobin, MMPLAYER_V_CONV, video_csc, "video converter", TRUE, player);
+               debug_log("using video converter: %s", video_csc);
 
-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;
+               if ( !player->set_mode.video_zc)
+               {
+                       GstStructure *str = NULL;
+                       gint width = 0;         //width of video
+                       gint height = 0;                //height of video
+                       GstCaps* video_caps = NULL;
+                       GstStructure *structure = NULL;
 
-       return_val_if_fail( player && position && player->pipeline && player->pipeline->mainbin,
-               MM_ERROR_PLAYER_NOT_INITIALIZED );
+                       /* rotator, scaler and capsfilter */
+                       MMPLAYER_CREATE_ELEMENT(player->pipeline->videobin, MMPLAYER_V_FLIP, "videoflip", "video rotator", TRUE, player);
+                       MMPLAYER_CREATE_ELEMENT(player->pipeline->videobin, MMPLAYER_V_SCALE, "videoscale", "video scaler", TRUE, player);
+                       MMPLAYER_CREATE_ELEMENT(player->pipeline->videobin, MMPLAYER_V_CAPS, "capsfilter", "videocapsfilter", TRUE, player);
 
-       current_state = MMPLAYER_CURRENT_STATE(player);
+                       /* 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;
+                       }
 
-       /* 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);
-       }
+                       mm_attrs_get_int_by_name(player->attrs, "display_width", &width);
 
-       /* 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(" Playback rate is %f\n", player->playback_rate);
-               debug_warning ("pos_msec = %"GST_TIME_FORMAT" and ret = %d and state = %d", GST_TIME_ARGS (pos_msec), ret, current_state);
+                       if (width) {
+                               structure = gst_structure_new("video/x-raw-rgb", "width", G_TYPE_INT, width, NULL);
+                       }
 
-               if(player->playback_rate < 0.0)
-                       pos_msec = player->last_position - TRICKPLAY_OFFSET;
-               else
-                       pos_msec = player->last_position;
+                       mm_attrs_get_int_by_name(player->attrs, "display_height", &height);
 
-               if (!ret)
-                       pos_msec = player->last_position;
-               else
-                       player->last_position = pos_msec;
+                       if (height ) {
+                               if (structure) {
+                                       gst_structure_set (structure, "height", G_TYPE_INT, height, NULL);
+                               }else {
+                                       structure = gst_structure_new("video/x-raw-rgb", "height", G_TYPE_INT, height, NULL);
+                               }
+                       }
 
-               debug_warning("returning last point : %"GST_TIME_FORMAT, GST_TIME_ARGS(pos_msec));
+                       if (width ||height) {
+                               video_caps = gst_caps_new_full(structure, NULL);
+                               gst_structure_free(structure);
 
+                               g_object_set (GST_ELEMENT(player->pipeline->videobin[MMPLAYER_V_CAPS].gst), "caps", video_caps, NULL );
+                               MMPLAYER_LOG_GST_CAPS_TYPE(video_caps);
+                               gst_caps_unref(video_caps);
+                       }
+               }
        }
        else
        {
-               player->last_position = pos_msec;
-       }
-
-       switch (format) {
-               case MM_PLAYER_POS_FORMAT_TIME:
-                       *position = GST_TIME_AS_MSECONDS(pos_msec);
-                       break;
+               MMDisplaySurfaceType surface_type = MM_DISPLAY_SURFACE_NULL;
+               mm_attrs_get_int_by_name (player->attrs, "display_surface_type", (int *)&surface_type);
 
-               case MM_PLAYER_POS_FORMAT_PERCENT:
+               if (player->set_mode.video_zc)
                {
-                       int dur = 0;
-                       int pos = 0;
-
-                       dur = player->duration / GST_SECOND;
-                       if (dur <= 0)
+                       if ( (surface_type == MM_DISPLAY_SURFACE_EVAS) && ( !strcmp(player->ini.videosink_element_evas, "evasimagesink")) )
                        {
-                               debug_log ("duration is [%d], so returning position 0\n",dur);
-                               *position = 0;
+                               video_csc = player->ini.name_of_video_converter;
                        }
                        else
                        {
-                               pos = pos_msec / GST_SECOND;
-                               *position = pos * 100 / dur;
+                               video_csc = "";
                        }
-                       break;
                }
-               default:
-                       return MM_ERROR_PLAYER_INTERNAL;
-       }
 
-       debug_log("current position : %lu\n", *position);
+               if (video_csc && (strcmp(video_csc, "")))
+               {
+                       MMPLAYER_CREATE_ELEMENT(player->pipeline->videobin, MMPLAYER_V_CONV, video_csc, "video converter", TRUE, player);
+                       debug_log("using video converter: %s", video_csc);
+               }
+
+               /* set video rotator */
+               if ( !player->set_mode.video_zc )
+                       MMPLAYER_CREATE_ELEMENT(player->pipeline->videobin, MMPLAYER_V_FLIP, "videoflip", "video rotator", TRUE, player);
+
+               /* videoscaler */
+               #if !defined(__arm__)
+               MMPLAYER_CREATE_ELEMENT(player->pipeline->videobin, MMPLAYER_V_SCALE, "videoscale", "videoscaler", TRUE, player);
+               #endif
+       }
 
-       
+       *bucket = element_bucket;
+       MMPLAYER_FLEAVE();
        return MM_ERROR_NONE;
-}
 
+ERROR:
+       *bucket = NULL;
+       MMPLAYER_FLEAVE();
+       return MM_ERROR_PLAYER_INTERNAL;
+}
 
-static int     __gst_get_buffer_position(mm_player_t* player, int format, unsigned long* start_pos, unsigned long* stop_pos)
+/**
+ * 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) : xvimagesink
+  * - evas surface  (arm) : evaspixmapsink
+  *                         fimcconvert ! evasimagesink
+  * - evas surface  (x86) : videoconvertor ! videoflip ! evasimagesink
+  */
+static int
+__mmplayer_gst_create_video_pipeline(mm_player_t* player, GstCaps* caps, MMDisplaySurfaceType surface_type)
 {
-       GstElement *element = NULL;
-       GstQuery *query = NULL;
+       GstPad *pad = NULL;
+       MMHandleType attrs;
+       GList*element_bucket = NULL;
+       MMPlayerGstElement* first_element = NULL;
+       MMPlayerGstElement* videobin = NULL;
+       gchar *videosink_element = NULL;
 
-       return_val_if_fail( player && 
-               player->pipeline && 
-               player->pipeline->mainbin,
-               MM_ERROR_PLAYER_NOT_INITIALIZED );
+       MMPLAYER_FENTER();
 
-       return_val_if_fail( start_pos && stop_pos, MM_ERROR_INVALID_ARGUMENT );
+       return_val_if_fail(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-       if ( MMPLAYER_IS_HTTP_STREAMING ( player ) || MMPLAYER_IS_HTTP_LIVE_STREAMING ( player ))       
+       /* alloc handles */
+       videobin = (MMPlayerGstElement*)g_malloc0(sizeof(MMPlayerGstElement) * MMPLAYER_V_NUM);
+       if ( !videobin )
        {
-               /* 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 );
+               return MM_ERROR_PLAYER_NO_FREE_SPACE;
        }
-       else if ( MMPLAYER_IS_RTSP_STREAMING ( player ) )
+
+       player->pipeline->videobin = videobin;
+
+       attrs = MMPLAYER_GET_ATTRS(player);
+       if ( !attrs )
        {
-               debug_warning ( "it's not supported yet.\n" );
-               return MM_ERROR_NONE;
+               debug_error("cannot get content attribute");
+               return MM_ERROR_PLAYER_INTERNAL;
        }
-       else
+
+       /* 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_warning ( "it's only used for streaming case.\n" );
-               return MM_ERROR_NONE;   
+               debug_error("failed to create videobin");
+               goto ERROR;
        }
 
-       *start_pos = 0;
-       *stop_pos = 0;
-       
-       switch ( format )
+       if( player->use_video_stream ) // video stream callback, so send raw video data to application
        {
-               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;
+               debug_log("using memsink\n");
 
-                                       gst_query_parse_buffering_percent ( query, &busy, &percent);
-                                       gst_query_parse_buffering_range ( query, &format, &start, &stop, NULL );
+               if ( __mmplayer_gst_create_video_filters(player, &element_bucket, TRUE) != MM_ERROR_NONE)
+                       goto ERROR;
 
-                                       debug_log ( "buffering start %" G_GINT64_FORMAT ", stop %" G_GINT64_FORMAT "\n",  start, stop);
+               /* finally, create video sink. output will be BGRA8888. */
+               MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_SINK, "avsysmemsink", "videosink", TRUE, player);
 
-                                       if ( start != -1)
-                                               *start_pos = 100 * start / GST_FORMAT_PERCENT_MAX;
-                                       else
-                                               *start_pos = 0;
+               MMPLAYER_SIGNAL_CONNECT( player,
+                                                                        videobin[MMPLAYER_V_SINK].gst,
+                                                                        MM_PLAYER_SIGNAL_TYPE_VIDEOBIN,
+                                                                        "video-stream",
+                                                                        G_CALLBACK(__mmplayer_videostream_cb),
+                                                                        player );
+       }
+       else // render video data using sink plugin like xvimagesink
+       {
+               if ( __mmplayer_gst_create_video_filters(player, &element_bucket, FALSE) != MM_ERROR_NONE)
+                       goto ERROR;
 
-                                       if ( stop != -1)
-                                               *stop_pos = 100 * stop / GST_FORMAT_PERCENT_MAX;
-                                       else
-                                               *stop_pos = 0;
-                               }
-                               gst_query_unref (query);
+               /* 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;
+                               }
+                               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;
                }
-               break;
 
-               case MM_PLAYER_POS_FORMAT_TIME :
-                       debug_warning ( "Time format is not supported yet.\n" );
-                       break;
-                       
-               default :
-                       break;
+               MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_SINK, videosink_element, videosink_element, TRUE, player);
+               debug_log("selected videosink name: %s", videosink_element);
+               if(surface_type==MM_DISPLAY_SURFACE_X)
+               {
+                       MMPLAYER_SIGNAL_CONNECT( player,
+                                                                       videobin[MMPLAYER_V_SINK].gst,
+                                                                       MM_PLAYER_SIGNAL_TYPE_VIDEOBIN,
+                                                                       "display-status",
+                                                                       G_CALLBACK(__mmplayer_display_status_cb),
+                                                                       player );
+                       MMPLAYER_SIGNAL_CONNECT( player,
+                                                                       videobin[MMPLAYER_V_SINK].gst,
+                                                                       MM_PLAYER_SIGNAL_TYPE_VIDEOBIN,
+                                                                       "external-resolution",
+                                                                       G_CALLBACK(__mmplayer_external_resolution_cb),
+                                                                       player );
+                       MMPLAYER_SIGNAL_CONNECT( player,
+                                                                       videobin[MMPLAYER_V_SINK].gst,
+                                                                       MM_PLAYER_SIGNAL_TYPE_VIDEOBIN,
+                                                                       "hided-window",
+                                                                       G_CALLBACK(__mmplayer_hided_window_cb),
+                                                                       player );
+                       MMPLAYER_SIGNAL_CONNECT( player,
+                                                                       videobin[MMPLAYER_V_SINK].gst,
+                                                                       MM_PLAYER_SIGNAL_TYPE_VIDEOBIN,
+                                                                       "quick-panel-on",
+                                                                       G_CALLBACK(__mmplayer_quick_panel_on_cb),
+                                                                       player );
+                       MMPLAYER_SIGNAL_CONNECT( player,
+                                                                       videobin[MMPLAYER_V_SINK].gst,
+                                                                       MM_PLAYER_SIGNAL_TYPE_VIDEOBIN,
+                                                                       "multiwindow-active",
+                                                                       G_CALLBACK(__mmplayer_multiwindow_active_cb),
+                                                                       player );
+               }
+               /* 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,
+                                                                               MM_PLAYER_SIGNAL_TYPE_VIDEOBIN,
+                                                                               "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;
+               }
        }
 
-       debug_log("current buffer position : %lu~%lu \n", *start_pos, *stop_pos );
+       if ( _mmplayer_update_video_param(player) != MM_ERROR_NONE)
+               goto ERROR;
 
-       return MM_ERROR_NONE;
-}
+       /* store it as it's sink element */
+       __mmplayer_add_sink( player, videobin[MMPLAYER_V_SINK].gst );
 
-static int
-__gst_set_message_callback(mm_player_t* player, MMMessageCallback callback, gpointer user_param) // @
-{
-       debug_fenter();
+       /* 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;
+       }
 
-       if ( !player )
+       /* Linking elements in the bucket by added order */
+       if ( __mmplayer_gst_element_link_bucket(element_bucket) == -1 )
        {
-               debug_warning("set_message_callback is called with invalid player handle\n");
-               return MM_ERROR_PLAYER_NOT_INITIALIZED;
+               debug_error("failed to link elements\n");
+               goto ERROR;
        }
 
-       player->msg_cb = callback;
-       player->msg_cb_param = user_param;
+       /* 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;
+       }
 
-       debug_log("msg_cb : 0x%x     msg_cb_param : 0x%x\n", (guint)callback, (guint)user_param);
+       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;
+       }
 
-       debug_fleave();
+       /* create ghostpad */
+       player->ghost_pad_for_videobin = gst_ghost_pad_new("sink", pad);
+       if ( FALSE == gst_element_add_pad(videobin[MMPLAYER_V_BIN].gst, player->ghost_pad_for_videobin) )
+       {
+               debug_error("failed to add ghostpad to videobin\n");
+               goto ERROR;
+       }
+       gst_object_unref(pad);
 
-       return MM_ERROR_NONE;
-}
+       /* done. free allocated variables */
+       g_list_free(element_bucket);
 
-static gboolean __mmfplayer_parse_profile(const char *uri, void *param, MMPlayerParseProfile* data) // @
-{
-       gboolean ret = FALSE;
-       char *path = NULL;
+       mm_attrs_set_int_by_name(attrs, "content_video_found", TRUE);
 
-       debug_fenter();
+       MMPLAYER_FLEAVE();
 
-       return_val_if_fail ( uri , FALSE);
-       return_val_if_fail ( data , FALSE);
-       return_val_if_fail ( ( strlen(uri) <= MM_MAX_URL_LEN ), FALSE );
+       return MM_ERROR_NONE;
 
-       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);                     
+ERROR:
+       debug_error("ERROR : releasing videobin\n");
 
-                       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);
-                       
-#ifdef NO_USE_GST_HLSDEMUX
-                       if ((path = strstr(uri, "m3u")))
-                       {
-                               debug_log ("++++++++++++++++++++ M3U +++++++++++++++++++++\n");
-                               debug_log ("\n\n\n\n \t HLS profile \n\n\n");
-                               data->uri_type = MM_PLAYER_URI_TYPE_HLS;
-                       }
-                       else
-#endif
-                               data->uri_type = MM_PLAYER_URI_TYPE_URL_HTTP;
+       g_list_free( element_bucket );
 
-                       ret = TRUE;
-               }
-       }
-       else if ((path = strstr(uri, "https://")))
-       {
-               if (strlen(path)) {
-                       strcpy(data->uri, uri);
+       if (pad)
+               gst_object_unref(GST_OBJECT(pad));
 
-#ifdef NO_USE_GST_HLSDEMUX
-                       if ((path = strstr(uri, "m3u")))
-                       {
-                               debug_log ("++++++++++++++++++++ M3U +++++++++++++++++++++\n");
-                               debug_log ("\n\n\n\n \t HLS profile \n\n\n");
-                               data->uri_type = MM_PLAYER_URI_TYPE_HLS;
-                       }
-                       else
-#endif
-                               data->uri_type = MM_PLAYER_URI_TYPE_URL_HTTP;
-                       
-                       ret = TRUE;
-               }
-       }
-       else if ((path = strstr(uri, "rtspu://")))
+       /* release videobin with it's childs */
+       if ( videobin[MMPLAYER_V_BIN].gst )
        {
-               if (strlen(path)) {
-                       strcpy(data->uri, uri);
-                       data->uri_type = MM_PLAYER_URI_TYPE_URL_RTSP;
-                       ret = TRUE;
-               }
+               gst_object_unref(GST_OBJECT(videobin[MMPLAYER_V_BIN].gst));
        }
-       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,};
+       MMPLAYER_FREEIF( videobin );
 
-                       if (seperator) {
-                               if ((buffer = strstr(path, "ext="))) {
-                                       buffer += strlen("ext=");
+       player->pipeline->videobin = NULL;
 
-                                       if (strlen(buffer)) {
-                                               strcpy(ext, buffer);
+       return MM_ERROR_PLAYER_INTERNAL;
+}
 
-                                               if ((seperator = strchr(ext, ','))
-                                                       || (seperator = strchr(ext, ' '))
-                                                       || (seperator = strchr(ext, '\0'))) {
-                                                       seperator[0] = '\0';
-                                               }
-                                       }
-                               }
+static int __mmplayer_gst_create_plain_text_elements(mm_player_t* player)
+{
+       GList *element_bucket = NULL;
+       MMPlayerGstElement *textbin = player->pipeline->textbin;
 
-                               if ((buffer = strstr(path, "size="))) {
-                                       buffer += strlen("size=");
+       MMPLAYER_CREATE_ELEMENT(textbin, MMPLAYER_T_TEXT_FAKE_QUEUE, "queue", "text_f_queue", TRUE, player);
+       MMPLAYER_CREATE_ELEMENT(textbin, MMPLAYER_T_FAKE_SINK, "fakesink", "text_fakesink", TRUE, player);
+       MMPLAYER_SIGNAL_CONNECT( player,
+                                                       G_OBJECT(textbin[MMPLAYER_T_FAKE_SINK].gst),
+                                                       MM_PLAYER_SIGNAL_TYPE_TEXTBIN,
+                                                       "handoff",
+                                                       G_CALLBACK(__mmplayer_update_subtitle),
+                                                       (gpointer)player );
 
-                                       if (strlen(buffer) > 0) {
-                                               strcpy(size, buffer);
+       g_object_set (G_OBJECT (textbin[MMPLAYER_T_FAKE_SINK].gst), "async", TRUE, NULL);
+       g_object_set (G_OBJECT (textbin[MMPLAYER_T_FAKE_SINK].gst), "sync", TRUE, NULL);
+       g_object_set (G_OBJECT (textbin[MMPLAYER_T_FAKE_SINK].gst), "signal-handoffs", TRUE, NULL);
 
-                                               if ((seperator = strchr(size, ','))
-                                                       || (seperator = strchr(size, ' '))
-                                                       || (seperator = strchr(size, '\0'))) {
-                                                       seperator[0] = '\0';
-                                               }
+       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_FAKE_SINK].gst));
+       }
 
-                                               mem_size = atoi(size);
-                                       }
-                               }
-                       }
+       /* 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;
+       }
 
-                       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;
-                       }
-               }
+       /* unset sink flag from textbin. not to hold eos when video data is shorter than subtitle */
+       GST_OBJECT_FLAG_UNSET (textbin[MMPLAYER_T_BIN].gst, GST_ELEMENT_IS_SINK);
+       GST_OBJECT_FLAG_UNSET (textbin[MMPLAYER_T_FAKE_SINK].gst, GST_ELEMENT_IS_SINK);
+
+       /* 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;
        }
-       else
+
+       /* done. free allocated variables */
+       g_list_free(element_bucket);
+
+       if (textbin[MMPLAYER_T_TEXT_FAKE_QUEUE].gst)
        {
-               /* if no protocol prefix exist. check file existence and then give file:// as it's prefix */
-               if (util_exist_file_path(uri))
+               GstPad *pad = NULL;
+               GstPad *ghostpad = NULL;
+
+               pad = gst_element_get_static_pad(GST_ELEMENT(textbin[MMPLAYER_T_TEXT_FAKE_QUEUE].gst), "sink");
+               if (!pad)
                {
-                       debug_warning("uri has no protocol-prefix. giving 'file://' by default.\n");
+                       debug_error("failed to get video pad of textbin\n");
+                       return MM_ERROR_PLAYER_INTERNAL;
+               }
 
-                       sprintf( data->uri, "file://%s", uri );
+               ghostpad = gst_ghost_pad_new("text_sink", pad);
+               gst_object_unref(pad);
 
-                       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;
+               if (!ghostpad)
+               {
+                       debug_error("failed to create ghostpad of textbin\n");
+                       goto ERROR;
                }
-               else
+
+               if (!gst_element_add_pad(textbin[MMPLAYER_T_BIN].gst, ghostpad))
                {
-                       debug_error ("invalid uri, could not play..\n");
-                       data->uri_type = MM_PLAYER_URI_TYPE_NONE;
+                       debug_error("failed to add ghostpad to textbin\n");
+                       goto ERROR;
                }
        }
-       
-       if (data->uri_type == MM_PLAYER_URI_TYPE_NONE) {
-               ret = FALSE;
-       }
 
+       return MM_ERROR_NONE;
 
-       /* dump parse result */
-       debug_log("profile parsing result ---\n");
-       debug_log("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();
+ERROR:
+       g_list_free(element_bucket);
 
-       return ret;
+       return MM_ERROR_PLAYER_INTERNAL;
 }
 
-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)
+static int __mmplayer_gst_create_text_pipeline(mm_player_t* player)
 {
-       mm_player_t* player = (mm_player_t*)data;
-       int ret = MM_ERROR_NONE;
+       MMPlayerGstElement *textbin = NULL;
+       GList *element_bucket = NULL;
+       GstPad *pad = NULL;
+       GstPad *ghostpad = NULL;
+       gint i = 0;
 
-       debug_fenter();
+       MMPLAYER_FENTER();
 
-       return_val_if_fail ( player, FALSE );
+       return_val_if_fail( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
 
-       if (MMPLAYER_CURRENT_STATE(player) == MM_PLAYER_STATE_PLAYING)
+       /* alloc handles */
+       textbin = (MMPlayerGstElement*)g_malloc0(sizeof(MMPlayerGstElement) * MMPLAYER_T_NUM);
+       if ( ! textbin )
        {
-               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");
-               }       
+               debug_error("failed to allocate memory for textbin\n");
+               return MM_ERROR_PLAYER_NO_FREE_SPACE;
        }
-       else
+
+       /* 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_log ("Invalid state to proceed lazy pause\n");
+               debug_error("failed to create textbin\n");
+               goto ERROR;
        }
 
-       /* unset mute */
-       if (player->pipeline && player->pipeline->audiobin)
-               g_object_set(G_OBJECT(player->pipeline->audiobin[MMPLAYER_A_SINK].gst), "mute", 0, NULL);
+       /* take it */
+       player->pipeline->textbin = textbin;
 
-       player->sm.by_asm_cb = 0; //should be reset here
+       /* fakesink */
+       if (player->use_textoverlay)
+       {
+               debug_log ("use textoverlay for displaying \n");
 
-       debug_fleave();
+               MMPLAYER_CREATE_ELEMENT_ADD_BIN(textbin, MMPLAYER_T_TEXT_QUEUE, "queue", "text_t_queue", textbin[MMPLAYER_T_BIN].gst, player);
 
-       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;
-       MMHandleType attrs = 0;
-       int result = MM_ERROR_NONE;
-       gboolean lazy_pause = FALSE;
+               MMPLAYER_CREATE_ELEMENT_ADD_BIN(textbin, MMPLAYER_T_VIDEO_QUEUE, "queue", "text_v_queue", textbin[MMPLAYER_T_BIN].gst, player);
 
-       debug_fenter();
+               MMPLAYER_CREATE_ELEMENT_ADD_BIN(textbin, MMPLAYER_T_VIDEO_CONVERTER, "fimcconvert", "text_v_converter", textbin[MMPLAYER_T_BIN].gst, player);
 
-       return_val_if_fail ( player && player->pipeline, ASM_CB_RES_IGNORE );
-       return_val_if_fail ( player->attrs, MM_ERROR_PLAYER_INTERNAL );
+               MMPLAYER_CREATE_ELEMENT_ADD_BIN(textbin, MMPLAYER_T_OVERLAY, "textoverlay", "text_overlay", textbin[MMPLAYER_T_BIN].gst, player);
 
-       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 (!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(event_src == ASM_EVENT_SOURCE_OTHER_PLAYER_APP)
-       {
-               player->sm.event_src = ASM_EVENT_SOURCE_OTHER_APP;
-       }
-       else if(event_src == ASM_EVENT_SOURCE_EARJACK_UNPLUG )
-       {
-               int stop_by_asm = 0;
+               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;
+               }
 
-               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 (!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;
+               }
+
+               if (textbin[MMPLAYER_T_TEXT_QUEUE].gst)
                {
-                       if (PLAYER_INI()->multiple_codec_supported)
+                       pad = gst_element_get_static_pad(GST_ELEMENT(textbin[MMPLAYER_T_TEXT_QUEUE].gst), "sink");
+                       if (!pad)
                        {
-                               debug_log("video conflict but, can support to use video overlay simultaneously");
-                               result = _mmplayer_pause((MMHandleType)player);
-                               cb_res = ASM_CB_RES_PAUSE;
+                               debug_error("failed to get src pad of textbin\n");
+                               goto ERROR;
                        }
-                       else
+
+                       ghostpad = gst_ghost_pad_new("sink", pad);
+                       if (!ghostpad)
                        {
-                               debug_log("video conflict, can't support for multiple codec instance");
-                               result = _mmplayer_unrealize((MMHandleType)player);
-                               cb_res = ASM_CB_RES_STOP;
+                               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;
                        }
                }
-               return cb_res;
        }
-
-       switch(command)
+       else
        {
-               case ASM_COMMAND_PLAY:
-               case ASM_COMMAND_STOP:
-                       debug_warning ("Got unexpected asm command (%d)", command);
-               break;
-                       
-               case ASM_COMMAND_PAUSE:
+               int surface_type = 0;
+               GstCaps* caps = NULL;
+
+               debug_log ("use subtitle message for displaying \n");
+
+               mm_attrs_get_int_by_name (player->attrs, "display_surface_type", &surface_type);
+
+               switch(surface_type)
                {
-                       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_OTHER_APP)
-                       {
-                               //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)
+                       case MM_DISPLAY_SURFACE_X:
+                       {
+                               /* check whether external subtitle supported or not  */
+                               if (!player->ini.external_subtitle)
                                {
-                                       debug_warning("fail to set Pause state by asm");
-                                       cb_res = ASM_CB_RES_IGNORE;
+                                       debug_log ("not supported external subtitle\n");
+                                       if (__mmplayer_gst_create_plain_text_elements(player) != MM_ERROR_NONE)
+                                       {
+                                               debug_error("failed to make plain text elements\n");
+                                               goto ERROR;
+                                       }
                                        break;
                                }
-                               __mmplayer_undo_sound_fadedown(player);
+
+                               MMPLAYER_CREATE_ELEMENT(textbin, MMPLAYER_T_TEE, "tee", "text_tee", TRUE, player);
+                               MMPLAYER_CREATE_ELEMENT(textbin, MMPLAYER_T_TEXT_FAKE_QUEUE, "queue", "text_f_queue", TRUE, player);
+                               g_object_set (G_OBJECT (textbin[MMPLAYER_T_TEXT_FAKE_QUEUE].gst),
+                                                                               "max-size-time", (guint64)0,
+                                                                               "max-size-bytes", (guint)0,
+                                                                               "max-size-buffers", (guint)5,
+                                                                               NULL);
+
+                               MMPLAYER_CREATE_ELEMENT(textbin, MMPLAYER_T_TEXT_FAKE_IDENTITY, "identity", "text_f_identity", TRUE, player);
+                               g_object_set (G_OBJECT (textbin[MMPLAYER_T_TEXT_FAKE_IDENTITY].gst), "signal-handoffs", FALSE, NULL);
+
+                               MMPLAYER_CREATE_ELEMENT(textbin, MMPLAYER_T_FAKE_SINK, "fakesink", "text_fakesink", TRUE, player);
+                               MMPLAYER_SIGNAL_CONNECT( player,
+                                                                       G_OBJECT(textbin[MMPLAYER_T_FAKE_SINK].gst),
+                                                                               MM_PLAYER_SIGNAL_TYPE_TEXTBIN,
+                                                                       "handoff",
+                                                                       G_CALLBACK(__mmplayer_update_subtitle),
+                                                                       (gpointer)player );
+
+                               g_object_set (G_OBJECT (textbin[MMPLAYER_T_FAKE_SINK].gst), "async", FALSE, NULL);
+                               g_object_set (G_OBJECT (textbin[MMPLAYER_T_FAKE_SINK].gst), "sync", TRUE, NULL);
+                               g_object_set (G_OBJECT (textbin[MMPLAYER_T_FAKE_SINK].gst), "signal-handoffs", TRUE, NULL);
+
+                               MMPLAYER_CREATE_ELEMENT(textbin, MMPLAYER_T_TEXT_QUEUE, "queue", "text_queue", TRUE, player);
+                               g_object_set (G_OBJECT (textbin[MMPLAYER_T_TEXT_QUEUE].gst),
+                                                                               "max-size-time", (guint64)0,
+                                                                               "max-size-bytes", (guint)0,
+                                                                               "max-size-buffers", (guint)5,
+                                                                               NULL);
+
+                               MMPLAYER_CREATE_ELEMENT(textbin, MMPLAYER_T_TEXT_IDENTITY, "identity", "text_identity", TRUE, player);
+                               g_object_set (G_OBJECT (textbin[MMPLAYER_T_TEXT_IDENTITY].gst), "signal-handoffs", FALSE, NULL);
+
+                               MMPLAYER_CREATE_ELEMENT(textbin, MMPLAYER_T_RENDER, "subrender", "text_subrender", TRUE, player);
+
+                               if (player->font_desc == NULL)
+                                       g_object_set (G_OBJECT (textbin[MMPLAYER_T_RENDER].gst), "font-desc", "Tizen 42", NULL);
+                               else
+                                       g_object_set (G_OBJECT (textbin[MMPLAYER_T_RENDER].gst), "font-desc", player->font_desc, NULL);
+
+                               g_object_set (G_OBJECT (player->pipeline->textbin[MMPLAYER_T_RENDER].gst), "font-color", player->font_color, NULL);
+                               g_object_set (G_OBJECT (player->pipeline->textbin[MMPLAYER_T_RENDER].gst), "font-bg-color", player->font_bg_color, NULL);
+
+                               MMPLAYER_CREATE_ELEMENT(textbin, MMPLAYER_T_CAPSFILTER, "capsfilter", "text_capsfilter", TRUE, player);
+                               caps = gst_caps_from_string( "video/x-raw-rgb, "
+                               "width = (int) [ 1, MAX ], "
+                               "height = (int) [ 1, MAX ], "
+                               "framerate = (fraction) [ 0, MAX ], "
+                               "subtitle = (boolean) true" );
+                               g_object_set (G_OBJECT(textbin[MMPLAYER_T_CAPSFILTER].gst), "caps", caps, NULL );
+                               gst_caps_unref( caps );
+                               MMPLAYER_CREATE_ELEMENT(textbin, MMPLAYER_T_VIDEO_SINK, "xvimagesink", "text_xvimagesink", TRUE, player);
+                               g_object_set(G_OBJECT(textbin[MMPLAYER_T_VIDEO_SINK].gst), "subpicture", TRUE, NULL);
+
+                               player->display_stat = util_get_is_connected_external_display();
+
+                               if(player->display_stat == MMPLAYER_DISPLAY_STATUS_UNKNOWN_ACTIVE)
+                               {
+                                       g_object_set (G_OBJECT (textbin[MMPLAYER_T_RENDER].gst), "external-width", player->ini.mirroring_width, NULL);
+                                       g_object_set (G_OBJECT (textbin[MMPLAYER_T_RENDER].gst), "external-height", player->ini.mirroring_height, NULL);
+                                       g_object_set (G_OBJECT (textbin[MMPLAYER_T_VIDEO_SINK].gst), "external-width", player->ini.mirroring_width, NULL);
+                                       g_object_set (G_OBJECT (textbin[MMPLAYER_T_VIDEO_SINK].gst), "external-height", player->ini.mirroring_height, NULL);
+                               }
+                               g_object_set(G_OBJECT(textbin[MMPLAYER_T_VIDEO_SINK].gst), "show-preroll-frame", FALSE, NULL);
+
+                               /* if connected with external display */
+                               if ((player->display_stat == MMPLAYER_DISPLAY_STATUS_HDMI_ACTIVE) ||
+                                       (player->display_stat == MMPLAYER_DISPLAY_STATUS_UNKNOWN_ACTIVE)) {
+                                       g_object_set (G_OBJECT (textbin[MMPLAYER_T_TEXT_FAKE_IDENTITY].gst), "drop-probability", (gfloat)1.0, NULL);
+                                       g_object_set (G_OBJECT (textbin[MMPLAYER_T_TEXT_IDENTITY].gst), "drop-probability", (gfloat)0.0, NULL);
+                                       debug_warning ("connected with external display");
+                               } else {
+                                       g_object_set (G_OBJECT (textbin[MMPLAYER_T_TEXT_FAKE_IDENTITY].gst), "drop-probability", (gfloat)0.0, NULL);
+                                       g_object_set (G_OBJECT (textbin[MMPLAYER_T_TEXT_IDENTITY].gst), "drop-probability", (gfloat)1.0, NULL);
+                                       g_object_set(G_OBJECT(textbin[MMPLAYER_T_VIDEO_SINK].gst), "async", FALSE, NULL);
+                                       g_object_set (G_OBJECT (textbin[MMPLAYER_T_FAKE_SINK].gst), "async", FALSE, NULL);
+
+                                       debug_warning ("non-connected status");
+                               }
+                               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_FAKE_SINK].gst));
+                                       __mmplayer_add_sink (player, GST_ELEMENT(textbin[MMPLAYER_T_VIDEO_SINK].gst));
+                               }
+
+                               /* adding created elements to bin */
+                               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;
+                               }
+
+                               /* unset sink flag from textbin. not to hold eos when video data is shorter than subtitle */
+                               GST_OBJECT_FLAG_UNSET (textbin[MMPLAYER_T_BIN].gst, GST_ELEMENT_IS_SINK);
+                               GST_OBJECT_FLAG_UNSET (textbin[MMPLAYER_T_FAKE_SINK].gst, GST_ELEMENT_IS_SINK);
+                               GST_OBJECT_FLAG_UNSET (textbin[MMPLAYER_T_VIDEO_SINK].gst, GST_ELEMENT_IS_SINK);
+
+                               /* linking elements in the bucket by added order. */
+                               GstPad *pad, *rpad;
+
+                               rpad = gst_element_get_request_pad(textbin[MMPLAYER_T_TEE].gst, "src%d");
+                               pad = gst_element_get_static_pad(textbin[MMPLAYER_T_TEXT_FAKE_QUEUE].gst, "sink");
+                               gst_pad_link(rpad, pad);
+                               gst_object_unref(rpad);
+                               gst_object_unref(pad);
+
+                               rpad = gst_element_get_request_pad(textbin[MMPLAYER_T_TEE].gst, "src%d");
+                               pad = gst_element_get_static_pad(textbin[MMPLAYER_T_TEXT_QUEUE].gst, "sink");
+                               gst_pad_link(rpad, pad);
+                               gst_object_unref(rpad);
+                               gst_object_unref(pad);
+
+                               if (!gst_element_link_pads (textbin[MMPLAYER_T_TEXT_FAKE_QUEUE].gst, "src", textbin[MMPLAYER_T_TEXT_FAKE_IDENTITY].gst, "sink")) {
+                                       debug_error ("fake queue and identity could not be linked.\n");
+                                       goto ERROR;
+                               }
+                               if (!gst_element_link_pads (textbin[MMPLAYER_T_TEXT_FAKE_IDENTITY].gst, "src", textbin[MMPLAYER_T_FAKE_SINK].gst, "sink")) {
+                                       debug_error ("indentity and fake sink could not be linked.\n");
+                                       goto ERROR;
+                               }
+                               if (!gst_element_link_pads (textbin[MMPLAYER_T_TEXT_QUEUE].gst, "src", textbin[MMPLAYER_T_TEXT_IDENTITY].gst, "sink")) {
+                                       debug_error ("queue and identity could not be linked.\n");
+                                       goto ERROR;
+                               }
+                               if (!gst_element_link_pads (textbin[MMPLAYER_T_TEXT_IDENTITY].gst, "src", textbin[MMPLAYER_T_RENDER].gst, "sink")) {
+                                       debug_error ("identity and subrender could not be linked.\n");
+                                       goto ERROR;
+                               }
+                               if (!gst_element_link_pads (textbin[MMPLAYER_T_RENDER].gst, "src", textbin[MMPLAYER_T_CAPSFILTER].gst, "sink")) {
+                                       debug_error ("subrender and capsfilter could not be linked.\n");
+                                       goto ERROR;
+                               }
+                               if (!gst_element_link_pads (textbin[MMPLAYER_T_CAPSFILTER].gst, "src", textbin[MMPLAYER_T_VIDEO_SINK].gst, "sink")) {
+                                       debug_error ("capsfilter and xvimagesink could not be linked.\n");
+                                       goto ERROR;
+                               }
+
+                               /* done. free allocated variables */
+                               g_list_free(element_bucket);
+                               if (textbin[MMPLAYER_T_TEE].gst)
+                               {
+                                       pad = gst_element_get_static_pad(GST_ELEMENT(textbin[MMPLAYER_T_TEE].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;
+                                       }
+                               }
+
+                               break;
                        }
-                       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);
+                       case MM_DISPLAY_SURFACE_EVAS:
+                       case MM_DISPLAY_SURFACE_GL:
+                       case MM_DISPLAY_SURFACE_NULL:
+                       case MM_DISPLAY_SURFACE_X_EXT:
+                               if (__mmplayer_gst_create_plain_text_elements(player) != MM_ERROR_NONE)
+                               {
+                                       debug_error("failed to make plain text elements\n");
+                                       goto ERROR;
+                               }
+                               break;
+
+                       default:
+                               break;
+               }
+       }
+       gst_object_unref(pad);
+
+       MMPLAYER_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 );
 
-                               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);
+                       if ( !parent )
+                       {
+                               gst_object_unref(GST_OBJECT(textbin[i].gst));
+                               textbin[i].gst = NULL;
                        }
                        else
                        {
-                               //immediate pause
-                               debug_log ("immediate pause");
-                               result = _mmplayer_pause((MMHandleType)player);
+                               gst_object_unref(GST_OBJECT(parent));
                        }
-                       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;
+       /* release textbin with it's childs */
+       if ( textbin[MMPLAYER_T_BIN].gst )
+       {
+               gst_object_unref(GST_OBJECT(textbin[MMPLAYER_T_BIN].gst));
        }
 
-       if (!lazy_pause)
-               player->sm.by_asm_cb = 0;
+       MMPLAYER_FREEIF( textbin );
 
-       debug_fleave();
+       player->pipeline->textbin = NULL;
 
-       return cb_res;
+       return MM_ERROR_PLAYER_INTERNAL;
 }
 
-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);
+static int
+__mmplayer_gst_create_subtitle_src(mm_player_t* player)
+{
+       MMPlayerGstElement* mainbin = NULL;
+       MMHandleType attrs = 0;
+       GstElement *subsrc = NULL;
+       GstElement *subparse = NULL;
+       gchar *subtitle_uri =NULL;
+       const gchar *charset = NULL;
+       GstPad *sinkpad = NULL;
+       GstPad *srcpad = NULL;
+       GstPad *pad = NULL;
 
-       /* 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;
-       MMPLAYER_PRINT_STATE(player);   
+       MMPLAYER_FENTER();
 
-       /* check current state */
-       MMPLAYER_CHECK_STATE_RETURN_IF_FAIL ( player, MMPLAYER_COMMAND_CREATE );
+       /* get mainbin */
+       return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-       /* construct attributes */
-       player->attrs = _mmplayer_construct_attribute(handle);
+       mainbin = player->pipeline->mainbin;
 
-       if ( !player->attrs )
+       attrs = MMPLAYER_GET_ATTRS(player);
+       if ( !attrs )
        {
-               debug_critical("Failed to construct attributes\n");
-               goto ERROR;
+               debug_error("cannot get content attribute\n");
+               return MM_ERROR_PLAYER_INTERNAL;
        }
 
-       /* initialize gstreamer with configured parameter */
-       if ( ! __mmplayer_gstreamer_init() )
+       mm_attrs_get_string_by_name ( attrs, "subtitle_uri", &subtitle_uri );
+       if ( !subtitle_uri || strlen(subtitle_uri) < 1)
        {
-               debug_critical("Initializing gstreamer failed\n");
-               goto ERROR;
+               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);
 
-       /* 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 )
+       /* create the subtitle source */
+       subsrc = gst_element_factory_make("filesrc", "subtitle_source");
+       if ( !subsrc )
        {
-               debug_critical("Cannot create mutex for command lock\n");
+               debug_error ( "failed to create filesrc element\n" );
                goto ERROR;
        }
+       g_object_set(G_OBJECT (subsrc), "location", subtitle_uri, NULL);
 
-       /* create repeat mutex */
-       player->repeat_thread_mutex = g_mutex_new();
-       if ( ! player->repeat_thread_mutex )
+       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_critical("Cannot create repeat mutex\n");
+               debug_warning("failed to add queue\n");
                goto ERROR;
        }
 
-       /* create repeat cond */
-       player->repeat_thread_cond = g_cond_new();
-       if ( ! player->repeat_thread_cond )
+       /* subparse */
+       subparse = gst_element_factory_make("submux", "external-submux");
+       if ( !subparse )
        {
-               debug_critical("Cannot create repeat cond\n");
+               debug_error ( "failed to create subparse element\n" );
                goto ERROR;
        }
 
-       /* create repeat thread */
-       player->repeat_thread =
-               g_thread_create (__mmplayer_repeat_thread, (gpointer)player, TRUE, NULL);
-       if ( ! player->repeat_thread )
+       charset = util_get_charset(subtitle_uri);
+       if (charset)
        {
-               goto ERROR;
+               debug_log ("detected charset is %s\n", charset );
+               g_object_set (G_OBJECT (subparse), "subtitle-encoding", charset, NULL);
        }
 
-       if ( MM_ERROR_NONE != _mmplayer_initialize_video_capture(player))
+       mainbin[MMPLAYER_M_T_SUBMUX_EXTERNAL].id = MMPLAYER_M_T_SUBMUX_EXTERNAL;
+       mainbin[MMPLAYER_M_T_SUBMUX_EXTERNAL].gst = subparse;
+
+       if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), subparse))
        {
-               debug_error("failed to initialize video capture\n");
+               debug_warning("failed to add subparse\n");
                goto ERROR;
        }
+       sinkpad = gst_element_get_request_pad (subparse, "sink%d");
+       srcpad =  gst_element_get_pad(subsrc,"src");
 
-       /* register to asm */
-       if ( MM_ERROR_NONE != _mmplayer_asm_register(&player->sm, (ASM_sound_cb_t)__mmplayer_asm_callback, (void*)player) )
+       /* link filesrc & submux */
+       if (gst_pad_link (srcpad, sinkpad) != 0)
        {
-               /* 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;
+               debug_warning("failed to link subsrc and subparse\n");
+               goto ERROR;
        }
 
-       if (MMPLAYER_IS_HTTP_PD(player))
+       player->play_subtitle = TRUE;
+       player->adjust_subtitle_pos = 0;
+
+       debug_log ("play subtitle using subtitle file\n");
+
+       if (player->pipeline->textbin == NULL)
        {
-               player->pd_downloader = NULL;
-               player->pd_file_location = NULL;
-       }
+               /* if textbin is null, assuming input selector also not created */
+               GstElement *selector = NULL;
 
-       /* give default value of sound effect setting */
-       player->audio_filter_info.filter_type = MM_AUDIO_FILTER_TYPE_NONE;
-       player->bypass_sound_effect = TRUE;
+               /* input selector */
+               selector = gst_element_factory_make("input-selector", "subtitle_inselector");
+               if (!selector)
+               {
+                       debug_error ( "failed to create subtitle input selector element\n" );
+                       goto ERROR;
+               }
+               g_object_set (selector, "sync-streams", TRUE, NULL);
 
-       player->sound.volume = MM_VOLUME_FACTOR_DEFAULT;
+               mainbin[MMPLAYER_M_T_INPUT_SELECTOR].id = MMPLAYER_M_T_INPUT_SELECTOR;
+               mainbin[MMPLAYER_M_T_INPUT_SELECTOR].gst = selector;
 
-       /* initialize last position */
-       player->last_position = 0;
+               if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), selector))
+               {
+                       debug_warning("failed to add subtitle input selector\n");
+                       goto ERROR;
+               }
 
-       /* initialize missing plugin */
-       player->not_supported_codec = MISSING_PLUGIN_NONE;
+               if (MM_ERROR_NONE !=  __mmplayer_gst_create_text_pipeline(player))
+               {
+                       debug_error("failed to create textbin. continuing without text\n");
+                       goto ERROR;
+               }
 
-       /* initialize found plugin */
-       player->can_support_codec = FOUND_PLUGIN_NONE;
+               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;
+               }
 
-       player->posted_msg = FALSE;
+               debug_log ("link text input selector and textbin ghost pad");
+               if (!gst_element_link_pads (mainbin[MMPLAYER_M_T_INPUT_SELECTOR].gst, "src", player->pipeline->textbin[MMPLAYER_T_BIN].gst, "text_sink"))
+               {
+                       debug_warning("failed to link subparse and textbin\n");
+                       goto ERROR;
+               }
 
-#if 0
-       /* initialize application client id for dnse */
-       player->app_id_set_up_dnse = MM_AUDIO_FILTER_CLIENT_NONE;
-#endif
-       /* set player state to ready */
-       MMPLAYER_SET_STATE(player, MM_PLAYER_STATE_NULL);
+               sinkpad = gst_element_get_request_pad (mainbin[MMPLAYER_M_T_INPUT_SELECTOR].gst, "sink%d");
+               if (sinkpad == NULL)
+               {
+                       debug_error ("failed to get request pad");;
+                       goto ERROR;
+               }
 
-       player->section_repeat = FALSE;
-       player->section_repeat_start = 0;
-       player->section_repeat_end = 0;
-       player->is_sound_extraction     = FALSE;
-       player->playback_rate = DEFAULT_PLAYBACK_RATE;
-       player->resumed_by_rewind = FALSE;
-       player->is_nv12_tiled = FALSE;
-       player->has_many_types = FALSE;
-       player->no_more_pad = TRUE;
-       player->parsers = NULL;
-       player->pipeline_is_constructed = FALSE;
-       
-       /*initialize adaptive http streaming handle */
-       player->ahs_player = NULL;
-       
-       /* set buffering parameter for streaming */
-       for(i=0; i<MM_PLAYER_STREAM_COUNT_MAX; i++)
+               debug_log ("Set Active Pad - %s\n", GST_DEBUG_PAD_NAME(sinkpad));
+               g_object_set (player->pipeline->mainbin[MMPLAYER_M_T_INPUT_SELECTOR].gst, "active-pad", sinkpad, NULL);
+
+               player->textsink_linked  = 1;
+               player->external_text_idx = 0;
+               debug_msg("player->textsink_linked set to 1\n");
+       }
+       else
        {
-               player->bitrate[i] = 0;
-               player->maximum_bitrate[i] = 0;
+               debug_log("text bin has been created. reuse it.");
+
+               sinkpad = gst_element_get_request_pad (mainbin[MMPLAYER_M_T_INPUT_SELECTOR].gst, "sink%d");
+               if (sinkpad == NULL)
+               {
+                       debug_error ("failed to get request pad");;
+                       goto ERROR;
+               }
+
+               player->external_text_idx = 1;
        }
-       player->updated_bitrate_count = 0;
-       player->total_bitrate = 0;
-       player->updated_maximum_bitrate_count = 0;
-       player->total_maximum_bitrate = 0;
 
-       /* initialize unlinked  audio/video mime type */
-       player->unlinked_audio_mime = NULL;
-       player->unlinked_video_mime = NULL;
-       player->unlinked_demuxer_mime = NULL;
-       player->not_found_demuxer = 0;
-       
-       player->sent_bos = FALSE;
+       srcpad =  gst_element_get_pad (subparse,"src");
 
-       player->doing_seek = FALSE;
+       /* link submux & input selector */
+       if (gst_pad_link (srcpad, sinkpad) != 0)
+       {
+               debug_warning("failed to link submux and input selector\n");
+               goto ERROR;
+       }
 
-       player->lazy_pause_event_id = 0;
-       
-       player->streamer = NULL;
+       pad = gst_element_get_static_pad (player->pipeline->textbin[MMPLAYER_T_FAKE_SINK].gst, "sink");
 
-       player->play_subtitle = FALSE;
+       if (!pad)
+       {
+               debug_error("failed to get sink pad from textsink to probe data");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
 
-       player->v_stream_caps = NULL;
-       
-       /* initialize pending seek */
-       player->pending_seek.is_pending = FALSE;
-       player->pending_seek.format = MM_PLAYER_POS_FORMAT_TIME;
-       player->pending_seek.pos = 0;
+       gst_pad_add_buffer_probe(pad, G_CALLBACK(__mmplayer_subtitle_adjust_position_probe), player);
+       gst_object_unref(pad);
+       pad=NULL;
 
-       /* 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();
+       MMPLAYER_FLEAVE();
 
        return MM_ERROR_NONE;
 
 ERROR:
-       /* free lock */
-       if ( player->fsink_lock )
-               g_mutex_free( player->fsink_lock );
-       player->fsink_lock = NULL;
+       return MM_ERROR_PLAYER_INTERNAL;
+}
 
-       /* 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 );
+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;
+       guint text_size = 0;
+       gboolean ret = TRUE;
 
-               g_thread_join( player->repeat_thread );
-               player->repeat_thread = NULL;
+       MMPLAYER_FENTER();
 
-               g_mutex_free ( player->repeat_thread_mutex );
-               player->repeat_thread_mutex = NULL;
+       return_val_if_fail ( player, FALSE );
+       return_val_if_fail ( buffer, FALSE );
 
-               g_cond_free ( player->repeat_thread_cond );
-               player->repeat_thread_cond = NULL;
+       text = GST_BUFFER_DATA(buffer);
+       text_size = GST_BUFFER_SIZE(buffer);
+       duration = GST_BUFFER_DURATION(buffer);
+
+       if ( player->set_mode.subtitle_off )
+       {
+               debug_log("subtitle is OFF.\n" );
+               return TRUE;
        }
-       /* 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 );
+       if ( !text || (text_size == 0))
+       {
+               debug_log("There is no subtitle to be displayed.\n" );
+               return TRUE;
+       }
 
-       /* release attributes */
-       _mmplayer_deconstruct_attribute(handle);
+       msg.data = (void *) text;
+       msg.subtitle.duration = GST_TIME_AS_MSECONDS(duration);
 
-       return MM_ERROR_PLAYER_INTERNAL;
+       debug_log("update subtitle : [%ld msec] %s\n'", msg.subtitle.duration, (char*)msg.data );
+
+       MMPLAYER_POST_MSG( player, MM_MESSAGE_UPDATE_SUBTITLE, &msg );
+
+       MMPLAYER_FLEAVE();
+
+       return ret;
 }
 
 static gboolean
-__mmplayer_gstreamer_init(void) // @
+__mmplayer_subtitle_adjust_position_probe(GstPad *pad, GstBuffer *buffer, gpointer u_data)
 {
-       static gboolean initialized = FALSE;
-       static const int max_argc = 50;
-       gint* argc = NULL;
-       gchar** argv = NULL;
-       GError *err = NULL;
-       int i = 0;
+       mm_player_t *player = (mm_player_t *) u_data;
+       GstClockTime cur_timestamp = 0;
+       gint64 adjusted_timestamp = 0;
 
-       debug_fenter();
+       return_val_if_fail ( player, FALSE );
+       return_val_if_fail ( buffer, FALSE );
 
-       if ( initialized )
+       if ( player->set_mode.subtitle_off )
        {
-               debug_log("gstreamer already initialized.\n");
+               debug_log("subtitle is OFF.\n" );
                return TRUE;
        }
 
-       /* alloc */
-       argc = malloc( sizeof(int) );
-       argv = malloc( sizeof(gchar*) * max_argc );
-
-       if ( !argc || !argv )
-               goto ERROR;
+       if (player->adjust_subtitle_pos == 0 )
+       {
+               debug_log("nothing to do");
+               return TRUE;
+       }
 
-       memset( argv, 0, sizeof(gchar*) * max_argc );
+       cur_timestamp = GST_BUFFER_TIMESTAMP(buffer);
 
-       /* add initial */
-       *argc = 1;
-       argv[0] = g_strdup( "mmplayer" );
+       adjusted_timestamp = (gint64) cur_timestamp + ((gint64) player->adjust_subtitle_pos * G_GINT64_CONSTANT(1000000));
 
-       /* add gst_param */
-       for ( i = 0; i < 5; i++ ) /* FIXIT : num of param is now fixed to 5. make it dynamic */
+       if ( adjusted_timestamp < 0)
        {
-               if ( strlen( PLAYER_INI()->gst_param[i] ) > 0 )
-               {
-                       argv[*argc] = g_strdup( PLAYER_INI()->gst_param[i] );
-                       (*argc)++;
-               }
+               debug_log("adjusted_timestamp under zero");
+               MMPLAYER_FLEAVE();
+               return FALSE;
        }
 
-       /* we would not do fork for scanning plugins */
-       argv[*argc] = g_strdup("--gst-disable-registry-fork");
-       (*argc)++;
+       GST_BUFFER_TIMESTAMP(buffer) = (GstClockTime) adjusted_timestamp;
+       debug_log("buffer timestamp changed %" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "",
+                               GST_TIME_ARGS(cur_timestamp),
+                               GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)));
 
-       /* check disable registry scan */
-       if ( PLAYER_INI()->skip_rescan )
+       return TRUE;
+}
+static int     __gst_adjust_subtitle_position(mm_player_t* player, int format, int position)
+{
+       MMPLAYER_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)
        {
-               argv[*argc] = g_strdup("--gst-disable-registry-update");
-               (*argc)++;
+               debug_log ("nothing to do\n");
+               MMPLAYER_FLEAVE();
+               return MM_ERROR_NONE;
        }
 
-       /* check disable segtrap */
-       if ( PLAYER_INI()->disable_segtrap )
+       switch (format)
        {
-               argv[*argc] = g_strdup("--gst-disable-segtrap");
-               (*argc)++;
-       }
+               case MM_PLAYER_POS_FORMAT_TIME:
+               {
+                       /* check current postion */
+                       player->adjust_subtitle_pos = position;
 
-       debug_log("initializing gstreamer with following parameter\n");
-       debug_log("argc : %d\n", *argc);
+                       debug_log("save adjust_subtitle_pos in player") ;
+               }
+               break;
 
-       for ( i = 0; i < *argc; i++ )
-       {
-               debug_log("argv[%d] : %s\n", i, argv[i]);
+               default:
+               {
+                       debug_warning("invalid format.\n");
+                       MMPLAYER_FLEAVE();
+                       return MM_ERROR_INVALID_ARGUMENT;
+               }
        }
 
+       MMPLAYER_FLEAVE();
 
-       /* initializing gstreamer */
-       __ta__("gst_init time",
+       return MM_ERROR_NONE;
+}
 
-               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);
-                       }
+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;
 
-                       goto ERROR;
-               }
-       );
+       return_if_fail ( element );
+       return_if_fail ( buf );
 
-       /* release */
-       for ( i = 0; i < *argc; i++ )
+       buffer = gst_buffer_new ();
+       if(buffer == NULL)
+               return;
+
+       if (buf->offset >= buf->len)
        {
-               MMPLAYER_FREEIF( argv[i] );
+               debug_log("call eos appsrc\n");
+               g_signal_emit_by_name (appsrc, "end-of-stream", &ret);
+               return;
        }
 
-       MMPLAYER_FREEIF( argv );
-       MMPLAYER_FREEIF( argc );
+       if ( buf->len - buf->offset < size)
+       {
+               len = buf->len - buf->offset + buf->offset;
+       }
 
-       /* done */
-       initialized = TRUE;
+       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 );
 
-       debug_fleave();
+       buf->offset  = (int)size;
 
        return TRUE;
+}
 
-ERROR:
+static void
+__gst_appsrc_feed_data(GstElement *element, guint size, gpointer user_data) // @
+{
+       mm_player_t *player  = (mm_player_t*)user_data;
 
-       MMPLAYER_FREEIF( argv );
-       MMPLAYER_FREEIF( argc );
+       return_if_fail ( player );
 
-       return FALSE;
+       debug_msg("app-src: feed data\n");
+
+       if(player->need_data_cb)
+               player->need_data_cb(size, player->buffer_cb_user_param);
 }
 
-int 
-__mmplayer_release_extended_streaming(mm_player_t* player)
+static gboolean
+__gst_appsrc_seek_data(GstElement *element, guint64 offset, gpointer user_data) // @
 {
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       mm_player_t *player  = (mm_player_t*)user_data;
 
-       if (player->pd_downloader && MMPLAYER_IS_HTTP_PD(player))
-       {
-               _mmplayer_pd_stop ((MMHandleType)player);
-               _mmplayer_pd_deinitialize ((MMHandleType)player);
-               _mmplayer_pd_destroy((MMHandleType)player);
-       }
+       return_val_if_fail ( player, FALSE );
 
-#ifdef NO_USE_GST_HLSDEMUX
-       /* destroy can called at anytime */
-       if (MMPLAYER_IS_HTTP_LIVE_STREAMING(player))
-       {
-               if (player->ahs_player)
-               {
-                       __mm_player_ahs_stop (player->ahs_player);
-                       __mm_player_ahs_deinitialize (player->ahs_player);
-                       __mm_player_ahs_destroy(player->ahs_player);
-                       player->ahs_player = NULL;
-               }
-       }
-#endif
+       debug_msg("app-src: seek data\n");
 
-       if (MMPLAYER_IS_STREAMING(player))
-       {
-               if (player->streamer)
-               {
-                       __mm_player_streaming_deinitialize (player->streamer);
-                       __mm_player_streaming_destroy(player->streamer);
-                       player->streamer = NULL;
-               }
-       }
+       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_destroy(MMHandleType handle) // @
+_mmplayer_push_buffer(MMHandleType hplayer, unsigned char *buf, int size) // @
 {
-       mm_player_t* player = MM_PLAYER_CAST(handle);
+       mm_player_t* player = (mm_player_t*)hplayer;
+       GstBuffer *buffer = NULL;
+       GstFlowReturn gst_ret = GST_FLOW_OK;
+       int ret = MM_ERROR_NONE;
 
-       debug_fenter();
+       MMPLAYER_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 );
+       /* check current state */
+//     MMPLAYER_CHECK_STATE_RETURN_IF_FAIL( player, MMPLAYER_COMMAND_START );
 
-       __mmplayer_release_extended_streaming(player);
 
-       /* release repeat thread */
-       if ( player->repeat_thread_cond &&
-                player->repeat_thread_mutex &&
-                player->repeat_thread )
+       /* NOTE : we should check and create pipeline again if not created as we destroy
+        * whole pipeline when stopping in streamming playback
+        */
+       if ( ! player->pipeline )
        {
-               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 != __gst_realize( player ) )
+               {
+                       debug_error("failed to realize before starting. only in streamming\n");
+                       return MM_ERROR_PLAYER_INTERNAL;
+               }
        }
 
-       if (MM_ERROR_NONE != _mmplayer_release_video_capture(player))
+       debug_msg("app-src: pushing data\n");
+
+       if ( buf == NULL )
        {
-               debug_error("failed to release video capture\n");
-               return MM_ERROR_PLAYER_INTERNAL;
+               debug_error("buf is null\n");
+               return MM_ERROR_NONE;
        }
 
-       /* withdraw asm */
-       if ( MM_ERROR_NONE != _mmplayer_asm_deregister(&player->sm) )
-       {
-               debug_error("failed to deregister asm server\n");
+       buffer = gst_buffer_new ();
+       if(buffer == NULL)
                return MM_ERROR_PLAYER_INTERNAL;
-       }
 
-       /* release pipeline */
-       if ( MM_ERROR_NONE != __mmplayer_gst_destroy_pipeline( player ) )
+       if (size <= 0)
        {
-               debug_error("failed to destory pipeline\n");
-               return MM_ERROR_PLAYER_INTERNAL;
+               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;
        }
 
-       /* release attributes */
-       _mmplayer_deconstruct_attribute( handle );
+       GST_BUFFER_DATA(buffer) = (guint8*)(buf);
+       GST_BUFFER_SIZE(buffer) = size;
 
-       /* release factories */
-       __mmplayer_release_factories( player );
+       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);
 
-       /* release miscellaneous information */
-       __mmplayer_release_misc( player );
+       MMPLAYER_FLEAVE();
 
-       /* release lock */
-       if ( player->fsink_lock )
-               g_mutex_free( player->fsink_lock );
+       return ret;
+}
 
-       if ( player->msg_cb_lock )
-               g_mutex_free( player->msg_cb_lock );
+/* if retval is FALSE, it will be dropped for perfomance. */
+static gboolean
+__mmplayer_check_useful_message(mm_player_t *player, GstMessage * message)
+{
+       gboolean retval = FALSE;
 
-       if (player->lazy_pause_event_id) 
+       if ( !(player->pipeline && player->pipeline->mainbin) )
        {
-               g_source_remove (player->lazy_pause_event_id);
-               player->lazy_pause_event_id = 0;
+               debug_error("player pipeline handle is null");
+               return TRUE;
        }
 
-       debug_fleave();
-
-       return MM_ERROR_NONE;
-}
-
-
-int 
-__mmplayer_init_extended_streaming(mm_player_t* player)
-{
-       int ret = MM_ERROR_NONE;
-       
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
-
-#ifdef NO_USE_GST_HLSDEMUX
-       /* prepare adaptive http streaming */
-       if (player->profile.uri_type == MM_PLAYER_URI_TYPE_HLS)
+       switch (GST_MESSAGE_TYPE (message))
        {
-               player->ahs_player = __mm_player_ahs_create ();
-               
-               if (NULL == player->ahs_player)
-               {
-                       debug_error ("Unable to create AHS player\n");
-                       ret = MM_ERROR_PLAYER_NO_FREE_SPACE;
-               }
-               else
+               case GST_MESSAGE_TAG:
+               case GST_MESSAGE_EOS:
+               case GST_MESSAGE_ERROR:
+               case GST_MESSAGE_WARNING:
+               case GST_MESSAGE_CLOCK_LOST:
+               case GST_MESSAGE_NEW_CLOCK:
+               case GST_MESSAGE_ELEMENT:
+               case GST_MESSAGE_DURATION:
+               case GST_MESSAGE_ASYNC_START:
+                       retval = TRUE;
+                       break;
+               case GST_MESSAGE_ASYNC_DONE:
+               case GST_MESSAGE_STATE_CHANGED:
+                       /* we only handle messages from pipeline */
+                       if(( message->src == (GstObject *)player->pipeline->mainbin[MMPLAYER_M_PIPE].gst ) && (!player->pp_rebuilding))
+                               retval = TRUE;
+                       else
+                               retval = FALSE;
+                       break;
+               case GST_MESSAGE_BUFFERING:
                {
-                       if ( !__mm_player_ahs_initialize (player->ahs_player, player->profile.uri_type, 
-                               player->profile.uri, player->pipeline->mainbin[MMPLAYER_M_SRC].gst) )
+                       gint buffer_percent = 0;
+
+                       gst_message_parse_buffering (message, &buffer_percent);
+
+                       if ((MMPLAYER_IS_STREAMING(player)) &&
+                               (player->streamer) &&
+                               (player->streamer->is_buffering == TRUE) &&
+                               (buffer_percent == MAX_BUFFER_PERCENT))
                        {
-                               debug_error ("failed to initialize ahs player\n");
-                               ret = MM_ERROR_PLAYER_NO_FREE_SPACE;
+                               debug_log (">>> [%s] Buffering DONE is detected !!\n", GST_OBJECT_NAME(GST_MESSAGE_SRC(message)));
+                               player->streamer->is_buffering_done = TRUE;
                        }
+
+                       retval = TRUE;
+                       break;
                }
+               default:
+                       retval = FALSE;
+                       break;
        }
-#endif
 
-       if (MMPLAYER_IS_HTTP_PD(player))
+       return retval;
+}
+
+static GstBusSyncReply
+__mmplayer_bus_sync_callback (GstBus * bus, GstMessage * message, gpointer data)
+{
+       mm_player_t *player = (mm_player_t *)data;
+       GstBusSyncReply reply = GST_BUS_DROP;
+
+       if ( ! ( player->pipeline && player->pipeline->mainbin ) )
        {
-               gboolean bret = FALSE;
-               gchar *src_uri = NULL;
+               debug_error("player pipeline handle is null");
+               return GST_BUS_PASS;
+       }
 
-               player->pd_downloader = _mmplayer_pd_create ();
+       if (!__mmplayer_check_useful_message(player, message))
+       {
+               gst_message_unref (message);
+               return GST_BUS_DROP;
+       }
 
-               if ( !player->pd_downloader )
-               {
-                       debug_error ("Unable to create PD Downloader...");
-                       ret = MM_ERROR_PLAYER_NO_FREE_SPACE;
-               }
-               
-               if (player->pd_mode == MM_PLAYER_PD_MODE_URI)
-                       src_uri = player->profile.uri;
-               
-               bret = _mmplayer_pd_initialize ((MMHandleType)player, src_uri, player->pd_file_location, player->pipeline->mainbin[MMPLAYER_M_SRC].gst);
-               
-               if (FALSE == bret)
-               {
-                       debug_error ("Unable to create PD Downloader...");
-                       ret = MM_ERROR_PLAYER_NOT_INITIALIZED;
-               }
+       switch (GST_MESSAGE_TYPE (message))
+       {
+               case GST_MESSAGE_STATE_CHANGED:
+                       /* post directly for fast launch */
+                       if (player->sync_handler) {
+                               __mmplayer_gst_callback(NULL, message, player);
+                               reply = GST_BUS_DROP;
+                       }
+                       else {
+                               reply = GST_BUS_PASS;
+                       }
+                       break;
+               case GST_MESSAGE_TAG:
+                       __mmplayer_gst_extract_tag_from_msg(player, message);
+                       break;
+               case GST_MESSAGE_DURATION:
+                       __mmplayer_gst_handle_duration(player, message);
+                       break;
+               case GST_MESSAGE_ASYNC_DONE:
+                       /* NOTE:Don't call gst_callback directly
+                        * because previous frame can be showed even though this message is received for seek.
+                        */
+               default:
+                       reply = GST_BUS_PASS;
+                       break;
        }
 
-       return ret;
+       if (reply == GST_BUS_DROP)
+               gst_message_unref (message);
+
+       return reply;
 }
 
-int
-_mmplayer_realize(MMHandleType hplayer) // @
+/**
+ * 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) // @
 {
-       mm_player_t* player =  (mm_player_t*)hplayer;
-       char *uri =NULL;
-       void *param = NULL;
-       int application_pid = -1;
-       gboolean update_registry = FALSE;
+       GstBus  *bus = NULL;
+       MMPlayerGstElement *mainbin = NULL;
        MMHandleType attrs = 0;
-       int ret = MM_ERROR_NONE;
-
-       debug_fenter();
+       GstElement* element = NULL;
+       GList* element_bucket = NULL;
+       gboolean need_state_holder = TRUE;
+       gint i = 0;
 
-       /* check player handle */
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED )
+       MMPLAYER_FENTER();
 
-       /* check current state */
-       MMPLAYER_CHECK_STATE_RETURN_IF_FAIL( player, MMPLAYER_COMMAND_REALIZE );
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
+       /* get profile attribute */
        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;
+               debug_error("cannot get content attribute\n");
+               goto INIT_ERROR;
        }
 
-       if (player->profile.uri_type == MM_PLAYER_URI_TYPE_URL_MMS)
+       /* create pipeline handles */
+       if ( player->pipeline )
        {
-               debug_warning("mms protocol is not supported format.\n");
-               return MM_ERROR_PLAYER_NOT_SUPPORTED_FORMAT;
+               debug_warning("pipeline should be released before create new one\n");
+               goto INIT_ERROR;
        }
 
-       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;
+       player->pipeline = (MMPlayerGstPipelineInfo*) g_malloc0( sizeof(MMPlayerGstPipelineInfo) );
+       if (player->pipeline == NULL)
+               goto INIT_ERROR;
 
-       /* we need to update content attrs only the content has changed */
-       player->need_update_content_attrs = TRUE;
-       player->need_update_content_dur = FALSE;
+       memset( player->pipeline, 0, sizeof(MMPlayerGstPipelineInfo) );
 
-       /* 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();
+       /* create mainbin */
+       mainbin = (MMPlayerGstElement*) g_malloc0( sizeof(MMPlayerGstElement) * MMPLAYER_M_NUM );
+       if (mainbin == NULL)
+               goto INIT_ERROR;
 
-               /* then we have to rebuild factories */
-               __mmplayer_release_factories( player );
-               __mmplayer_init_factories(player);
-       }
+       memset( mainbin, 0, sizeof(MMPlayerGstElement) * MMPLAYER_M_NUM);
 
-       /* realize pipeline */
-       ret = __gst_realize( player );
-       if ( ret != MM_ERROR_NONE )
-       {
-               debug_error("fail to realize the player.\n");
-       }
-       else
+       /* 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 )
        {
-               __mmplayer_init_extended_streaming(player);
+               debug_error("failed to create pipeline\n");
+               goto INIT_ERROR;
        }
+       player->demux_pad_index = 0;
+       player->subtitle_language_list = NULL;
 
-       debug_fleave();
+       player->font_color = player->ini.font_color;
+       player->font_bg_color = player->ini.font_background_color;
 
-       return ret;
-}
+       player->display_stat = MMPLAYER_DISPLAY_STATUS_NULL;
+       player->is_subtitle_force_drop = FALSE;
+       player->last_multiwin_status = FALSE;
 
-int
-__mmplayer_deinit_extended_streaming(mm_player_t *player)
-{
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
-       
-       /* destroy can called at anytime */
-       if (player->pd_downloader && MMPLAYER_IS_HTTP_PD(player))
+       /* create source element */
+       switch ( player->profile.uri_type )
        {
-               //__mmplayer_pd_deinitalize (player->ahs_player);
-               _mmplayer_pd_stop ((MMHandleType)player);
-       }
+               /* rtsp streamming */
+               case MM_PLAYER_URI_TYPE_URL_RTSP:
+               {
+                       gint network_bandwidth;
+                       gchar *user_agent, *wap_profile;
 
-#ifdef NO_USE_GST_HLSDEMUX
-       /* destroy can called at anytime */
-       if (MMPLAYER_IS_HTTP_LIVE_STREAMING(player))
-       {
-               __mm_player_ahs_stop (player->ahs_player);
-               //__mm_player_ahs_deinitalize (player->ahs_player);
-       }
-#endif
-       return MM_ERROR_NONE;
+                       element = gst_element_factory_make(player->ini.name_of_rtspsrc, "streaming_source");
 
-}
+                       if ( !element )
+                       {
+                               debug_error("failed to create streaming source element\n");
+                               break;
+                       }
 
-int
-_mmplayer_unrealize(MMHandleType hplayer) // @
-{
-       mm_player_t* player = (mm_player_t*)hplayer;
-       int ret = MM_ERROR_NONE;
+                       debug_log("using streamming source [%s].\n", player->ini.name_of_rtspsrc);
 
-       debug_fenter();
+                       /* make it zero */
+                       network_bandwidth = 0;
+                       user_agent = wap_profile = NULL;
 
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED )
+                       /* 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 );
 
-       /* check current state */
-       MMPLAYER_CHECK_STATE_RETURN_IF_FAIL( player, MMPLAYER_COMMAND_UNREALIZE );
+                       secure_debug_log("user_agent : %s\n", user_agent);
+                       secure_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);
 
-       __mmplayer_deinit_extended_streaming(player);
+                       /* 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);
 
-       /* unrealize pipeline */
-       ret = __gst_unrealize( player );
+                       MMPLAYER_SIGNAL_CONNECT ( player, G_OBJECT(element), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-added",
+                               G_CALLBACK (__mmplayer_gst_rtp_dynamic_pad), player );
+                       MMPLAYER_SIGNAL_CONNECT ( player, G_OBJECT(element), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "no-more-pads",
+                               G_CALLBACK (__mmplayer_gst_rtp_no_more_pads), 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;
+                       player->use_decodebin = FALSE;
                }
-       }
+               break;
 
-       debug_fleave();
+               /* WFD streamming */
+               case MM_PLAYER_URI_TYPE_URL_WFD:
+               {
+                       element = gst_element_factory_make("wfdrtspsrc", "wfd_source");
+                       if ( !element )
+                       {
+                               debug_error("failed to create wfd streaming source element\n");
+                               break;
+                       }
+                       debug_log("using wfd streamming source wfdrtspsrc.\n");
+                       g_object_set(G_OBJECT(element), "location", player->profile.uri, NULL);
+                       g_object_set(G_OBJECT(element), "debug", TRUE, NULL);
+                       g_object_set(G_OBJECT(element), "latency", 0, NULL);
+                       MMPLAYER_SIGNAL_CONNECT ( player, G_OBJECT(element), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-added",
+                              G_CALLBACK (__mmplayer_gst_wfd_dynamic_pad), player );
 
-       return ret;
-}
+                       player->use_decodebin = FALSE;
+               }
+               break;
 
-int
-_mmplayer_set_message_callback(MMHandleType hplayer, MMMessageCallback callback, gpointer user_param) // @
-{
-       mm_player_t* player = (mm_player_t*)hplayer;
+               /* http streaming*/
+               case MM_PLAYER_URI_TYPE_URL_HTTP:
+               {
+                       gchar *user_agent, *proxy, *cookies, **cookie_list;
+                       gint http_timeout = DEFAULT_HTTP_TIMEOUT;
+                       user_agent = proxy = cookies = NULL;
+                       cookie_list = NULL;
+                       gint mode = MM_PLAYER_PD_MODE_NONE;
 
-       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+                       mm_attrs_get_int_by_name ( attrs, "pd_mode", &mode );
 
-       return __gst_set_message_callback(player, callback, user_param);
-}
+                       player->pd_mode = mode;
 
-int
-_mmplayer_get_state(MMHandleType hplayer, int* state) // @
-{
-       mm_player_t *player = (mm_player_t*)hplayer;
+                       debug_log("http playback, PD mode : %d\n", player->pd_mode);
 
-       return_val_if_fail(state, MM_ERROR_INVALID_ARGUMENT);
+                       if ( ! MMPLAYER_IS_HTTP_PD(player) )
+                       {
+                               element = gst_element_factory_make(player->ini.name_of_httpsrc, "http_streaming_source");
+                               if ( !element )
+                               {
+                                       debug_error("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);
 
-       *state = MMPLAYER_CURRENT_STATE(player);
+                               /* 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 );
+                               mm_attrs_get_int_by_name ( attrs, "streaming_timeout", &http_timeout );
 
-       return MM_ERROR_NONE;
-}
+                               if ((http_timeout == DEFAULT_HTTP_TIMEOUT) &&
+                                       (player->ini.http_timeout != DEFAULT_HTTP_TIMEOUT))
+                               {
+                                       debug_log("get timeout from ini\n");
+                                       http_timeout = player->ini.http_timeout;
+                               }
 
+                               /* get attribute */
+                               secure_debug_log("location : %s\n", player->profile.uri);
+                               secure_debug_log("cookies : %s\n", cookies);
+                               secure_debug_log("proxy : %s\n", proxy);
+                               secure_debug_log("user_agent :  %s\n",  user_agent);
+                               debug_log("timeout : %d\n",  http_timeout);
 
-int
-_mmplayer_set_volume(MMHandleType hplayer, MMPlayerVolumeType volume) // @
-{
-       mm_player_t* player = (mm_player_t*) hplayer;
-       GstElement* vol_element = NULL;
-       int i = 0;
+                               /* setting property to streaming source */
+                               g_object_set(G_OBJECT(element), "location", player->profile.uri, NULL);
+                               g_object_set(G_OBJECT(element), "timeout", http_timeout, NULL);
+                               g_object_set(G_OBJECT(element), "blocksize", (unsigned long)(64*1024), NULL);
 
-       debug_fenter();
+                               /* 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);
 
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+                               if ( MMPLAYER_URL_HAS_DASH_SUFFIX(player) )
+                               {
+                                       debug_warning("it's dash. and it's still experimental feature.");
+                               }
+                               else if (MMPLAYER_URL_HAS_HLS_SUFFIX(player) )
+                               {
+                                       debug_warning("it's hls. using decodebin");
+                               }
+                       }
+                       else // progressive download
+                       {
+                               gchar* location = NULL;
 
-       debug_log("volume [L]=%f:[R]=%f\n", 
-               volume.level[MM_VOLUME_CHANNEL_LEFT], volume.level[MM_VOLUME_CHANNEL_RIGHT]);
+                               if (player->pd_mode == MM_PLAYER_PD_MODE_URI)
+                               {
+                                       gchar *path = NULL;
 
-       /* 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;
-               }
-       }
+                                       mm_attrs_get_string_by_name ( attrs, "pd_location", &path );
 
-       /* Save volume to handle. Currently the first array element will be saved. */
-       player->sound.volume = volume.level[0];
+                                       MMPLAYER_FREEIF(player->pd_file_save_path);
 
-       /* 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");
+                                       debug_log("PD Location : %s\n", path);
 
-               /* 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;
-       }
+                                       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;
+                                       }
+                               }
 
-       /* setting volume to volume element */
-       vol_element = player->pipeline->audiobin[MMPLAYER_A_VOL].gst;
+                               element = gst_element_factory_make("pdpushsrc", "PD pushsrc");
+                               if ( !element )
+                               {
+                                       debug_error("failed to create PD push source element[%s].\n", "pdpushsrc");
+                                       break;
+                               }
 
-       if ( vol_element )
-       {
-               debug_log("volume is set [%f]\n", player->sound.volume);
-               g_object_set(vol_element, "volume", player->sound.volume, NULL);
-       }
+                               if (player->pd_mode == MM_PLAYER_PD_MODE_URI)
+                                       g_object_set(G_OBJECT(element), "location", player->pd_file_save_path, NULL);
+                               else
+                                       g_object_set(G_OBJECT(element), "location", player->profile.uri, NULL);
 
-       debug_fleave();
+                               g_object_get(element, "location", &location, NULL);
+                               debug_log("PD_LOCATION [%s].\n", location);
+                               if (location)
+                                       g_free (location);
+                       }
+               }
+               break;
 
-       return MM_ERROR_NONE;
-}
+               /* file source */
+               case MM_PLAYER_URI_TYPE_FILE:
+               {
 
+#ifdef ENABLE_DRMSRC
 
-int
-_mmplayer_get_volume(MMHandleType hplayer, MMPlayerVolumeType* volume)
-{
-       mm_player_t* player = (mm_player_t*) hplayer;
-       int i = 0;
+                       char* drmsrc = player->ini.name_of_drmsrc;
 
-       debug_fenter();
+                       debug_log("using [%s] for 'file://' handler.\n", drmsrc);
 
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
-       return_val_if_fail( volume, MM_ERROR_INVALID_ARGUMENT );
+                       element = gst_element_factory_make(drmsrc, "source");
+                       if ( !element )
+                       {
+                               debug_error("failed to create %s\n", drmsrc);
+                               break;
+                       }
+#else
+                       debug_log("using filesrc for 'file://' handler.\n");
 
-       /* returning stored volume */
-       for (i = 0; i < MM_VOLUME_CHANNEL_NUM; i++)
-               volume->level[i] = player->sound.volume;
+                       element = gst_element_factory_make("filesrc", "source");
 
-       debug_fleave();
+                       if ( !element )
+                       {
+                               debug_error("failed to create filesrc\n");
+                               break;
+                       }
+#endif
+                       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;
 
-       return MM_ERROR_NONE;
-}
+               case MM_PLAYER_URI_TYPE_SS:
+               {
+                       gint http_timeout = DEFAULT_HTTP_TIMEOUT;
+                       element = gst_element_factory_make("souphttpsrc", "http streaming source");
+                       if ( !element )
+                       {
+                               debug_error("failed to create http streaming source element[%s]", player->ini.name_of_httpsrc);
+                               break;
+                       }
 
+                       mm_attrs_get_int_by_name ( attrs, "streaming_timeout", &http_timeout );
 
+                       if ((http_timeout == DEFAULT_HTTP_TIMEOUT) &&
+                               (player->ini.http_timeout != DEFAULT_HTTP_TIMEOUT))
+                       {
+                               debug_log("get timeout from ini\n");
+                               http_timeout = player->ini.http_timeout;
+                       }
 
-int
-_mmplayer_set_mute(MMHandleType hplayer, int mute) // @
-{
-       mm_player_t* player = (mm_player_t*) hplayer;
-       GstElement* vol_element = NULL;
+                       /* setting property to streaming source */
+                       g_object_set(G_OBJECT(element), "location", player->profile.uri, NULL);
+                       g_object_set(G_OBJECT(element), "timeout", http_timeout, NULL);
+               }
+               break;
 
-       debug_fenter();
+               /* appsrc */
+               case MM_PLAYER_URI_TYPE_BUFF:
+               {
+                       guint64 stream_type = GST_APP_STREAM_TYPE_STREAM;
 
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+                       debug_log("mem src is selected\n");
 
-       debug_log("mute : %d\n", mute);
+                       element = gst_element_factory_make("appsrc", "buff-source");
+                       if ( !element )
+                       {
+                               debug_error("failed to create appsrc element\n");
+                               break;
+                       }
 
-       /* mute value shoud 0 or 1 */
-       if ( mute != 0 && mute != 1 )
-       {
-               debug_error("bad mute value\n");
+                       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 );
 
-               /* FIXIT : definitly, we need _BAD_PARAM error code */
-               return MM_ERROR_INVALID_ARGUMENT;
-       }
+                       MMPLAYER_SIGNAL_CONNECT( player, element, MM_PLAYER_SIGNAL_TYPE_OTHERS, "seek-data",
+                               G_CALLBACK(__gst_appsrc_seek_data), player);
+                       MMPLAYER_SIGNAL_CONNECT( player, element, MM_PLAYER_SIGNAL_TYPE_OTHERS, "need-data",
+                               G_CALLBACK(__gst_appsrc_feed_data), player);
+                       MMPLAYER_SIGNAL_CONNECT( player, element, MM_PLAYER_SIGNAL_TYPE_OTHERS, "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;
 
-       /* 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;
-       }
+                       debug_log("mem src is selected\n");
 
+                       element = gst_element_factory_make("appsrc", "mem-source");
+                       if ( !element )
+                       {
+                               debug_error("failed to create appsrc element\n");
+                               break;
+                       }
 
-       vol_element = player->pipeline->audiobin[MMPLAYER_A_VOL].gst;
+                       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 );
 
-       /* NOTE : volume will only created when the bt is enabled */
-       if ( vol_element )
-       {
-               g_object_set(vol_element, "mute", mute, NULL);
+                       MMPLAYER_SIGNAL_CONNECT( player, element, MM_PLAYER_SIGNAL_TYPE_OTHERS, "seek-data",
+                               G_CALLBACK(__gst_appsrc_seek_data_mem), &player->mem_buf );
+                       MMPLAYER_SIGNAL_CONNECT( player, element, MM_PLAYER_SIGNAL_TYPE_OTHERS, "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;
        }
-       else
+
+       /* check source element is OK */
+       if ( ! element )
        {
-               debug_log("volume elemnet is not created. using volume in audiosink\n");
+               debug_error("no source element was created.\n");
+               goto INIT_ERROR;
        }
 
-       player->sound.mute = mute;
+       /* 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]);
 
-       debug_fleave();
+       if ((MMPLAYER_IS_STREAMING(player)) && (player->streamer == NULL))
+       {
+               player->streamer = __mm_player_streaming_create();
+               __mm_player_streaming_initialize(player->streamer);
+       }
 
-       return MM_ERROR_NONE;
-}
+       if ( MMPLAYER_IS_HTTP_PD(player) )
+       {
+               gdouble pre_buffering_time = (gdouble)player->streamer->buffering_req.initial_second;
 
-int
-_mmplayer_get_mute(MMHandleType hplayer, int* pmute) // @
-{
-       mm_player_t* player = (mm_player_t*) hplayer;
-       GstElement* vol_element = NULL;
+               debug_log ("Picked queue2 element(pre buffer : %d sec)....\n", pre_buffering_time);
+               element = gst_element_factory_make("queue2", "queue2");
+               if ( !element )
+               {
+                       debug_error ( "failed to create http streaming buffer element\n" );
+                       goto INIT_ERROR;
+               }
 
-       debug_fenter();
+               /* take it */
+               mainbin[MMPLAYER_M_MUXED_S_BUFFER].id = MMPLAYER_M_MUXED_S_BUFFER;
+               mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst = element;
+               element_bucket = g_list_append(element_bucket, &mainbin[MMPLAYER_M_MUXED_S_BUFFER]);
 
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
-       return_val_if_fail ( pmute, MM_ERROR_INVALID_ARGUMENT );
+               pre_buffering_time = (pre_buffering_time > 0)?(pre_buffering_time):(player->ini.http_buffering_time);
 
-       /* 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;
+               __mm_player_streaming_set_queue2(player->streamer,
+                               element,
+                               TRUE,
+                               player->ini.http_max_size_bytes,
+                               pre_buffering_time,
+                               1.0,
+                               player->ini.http_buffering_limit,
+                               FALSE,
+                               NULL,
+                               0);
        }
 
+       /* create autoplugging element if src element is not a rtsp src */
+       if ((player->profile.uri_type != MM_PLAYER_URI_TYPE_URL_RTSP) &&
+               (player->profile.uri_type != MM_PLAYER_URI_TYPE_URL_WFD))
+       {
+               element = NULL;
+               enum MainElementID elemId = MMPLAYER_M_NUM;
 
-       vol_element = player->pipeline->audiobin[MMPLAYER_A_VOL].gst;
+               if ((player->use_decodebin) &&
+                       ((MMPLAYER_IS_HTTP_PD(player)) ||
+                        (!MMPLAYER_IS_HTTP_STREAMING(player))))
+               {
+                       elemId = MMPLAYER_M_AUTOPLUG;
+                       element = __mmplayer_create_decodebin(player);
+                       need_state_holder = FALSE;
+               }
+               else
+               {
+                       elemId = MMPLAYER_M_TYPEFIND;
+                       element = gst_element_factory_make("typefind", "typefinder");
+                       MMPLAYER_SIGNAL_CONNECT( player, element, MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "have-type",
+                               G_CALLBACK(__mmplayer_typefind_have_type), (gpointer)player );
+               }
 
-       if ( vol_element )
+
+               /* check autoplug element is OK */
+               if ( ! element )
+               {
+                       debug_error("can not create element (%d)\n", elemId);
+                       goto INIT_ERROR;
+               }
+
+               mainbin[elemId].id = elemId;
+               mainbin[elemId].gst = element;
+
+               element_bucket = g_list_append(element_bucket, &mainbin[elemId]);
+       }
+
+       /* add elements to pipeline */
+       if( !__mmplayer_gst_element_add_bucket_to_bin(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), element_bucket))
        {
-               g_object_get(vol_element, "mute", pmute, NULL);
-               debug_log("mute=%d\n\n", *pmute);
+               debug_error("Failed to add elements to pipeline\n");
+               goto INIT_ERROR;
        }
-       else
+
+
+       /* linking elements in the bucket by added order. */
+       if ( __mmplayer_gst_element_link_bucket(element_bucket) == -1 )
        {
-               *pmute = player->sound.mute;
+               debug_error("Failed to link some elements\n");
+               goto INIT_ERROR;
        }
 
-       debug_fleave();
 
-       return MM_ERROR_NONE;
-}
+       /* 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");
 
-int
-_mmplayer_set_videostream_cb(MMHandleType hplayer, mm_player_video_stream_callback callback, void *user_param) // @
-{
-       mm_player_t* player = (mm_player_t*) hplayer;
+               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);
 
-       debug_fenter();
+               /* take ownership of fakesink. we are reusing it */
+               gst_object_ref( mainbin[MMPLAYER_M_SRC_FAKESINK].gst );
 
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
-       return_val_if_fail ( callback, MM_ERROR_INVALID_ARGUMENT );
+               /* 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;
+               }
+       }
 
-       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);
+       /* now we have completed mainbin. take it */
+       player->pipeline->mainbin = mainbin;
 
-       debug_fleave();
+       /* 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;
+       }
 
-       return MM_ERROR_NONE;
-}
+       player->bus_watcher = gst_bus_add_watch(bus, (GstBusFunc)__mmplayer_gst_callback, player);
 
-int
-_mmplayer_set_audiostream_cb(MMHandleType hplayer, mm_player_audio_stream_callback callback, void *user_param) // @
-{
-       mm_player_t* player = (mm_player_t*) hplayer;
+       player->context.thread_default = g_main_context_get_thread_default();
 
-       debug_fenter();
+       if (NULL == player->context.thread_default)
+       {
+               player->context.thread_default = g_main_context_default();
+               debug_log("thread-default context is the global default context");
+       }
+       debug_warning("bus watcher thread context = %p, watcher : %d", player->context.thread_default, player->bus_watcher);
 
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
-       return_val_if_fail(callback, MM_ERROR_INVALID_ARGUMENT);
+       /* Note : check whether subtitle atrribute uri is set. If uri is set, then try 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");
+       }
 
-       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);
+       /* 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();
+       MMPLAYER_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;
+INIT_ERROR:
 
-       debug_fenter();
+       __mmplayer_gst_destroy_pipeline(player);
+       g_list_free(element_bucket);
 
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
-       return_val_if_fail(callback, MM_ERROR_INVALID_ARGUMENT);
+       /* 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));
+                       }
+               }
+       }
 
-       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);
+       /* release pipeline with it's childs */
+       if ( mainbin[MMPLAYER_M_PIPE].gst )
+       {
+               gst_object_unref(GST_OBJECT(mainbin[MMPLAYER_M_PIPE].gst));
+       }
 
-       debug_fleave();
+       MMPLAYER_FREEIF( player->pipeline );
+       MMPLAYER_FREEIF( mainbin );
 
-       return MM_ERROR_NONE;
+       return MM_ERROR_PLAYER_INTERNAL;
 }
 
-int
-_mmplayer_set_buffer_need_data_cb(MMHandleType hplayer, mm_player_buffer_need_data_callback callback, void *user_param) // @
+void __mmplayer_remove_g_source_from_context(GMainContext *context, guint source_id)
 {
-       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);
+       GSource *source = NULL;
 
-       player->need_data_cb = callback;
-       player->buffer_cb_user_param = user_param;
+       MMPLAYER_FENTER();
 
-       debug_log("buffer need dataHandle value is %p : %p\n", player, player->need_data_cb);
+       source = g_main_context_find_source_by_id (context, source_id);
 
-       debug_fleave();
+       if (source != NULL)
+       {
+               debug_warning("context: %p, source id: %d, source: %p", context, source_id, source);
+               g_source_destroy(source);
+       }
 
-       return MM_ERROR_NONE;
+       MMPLAYER_FLEAVE();
 }
 
-int
-_mmplayer_set_buffer_enough_data_cb(MMHandleType hplayer, mm_player_buffer_enough_data_callback callback, void *user_param) // @
+static int
+__mmplayer_gst_destroy_pipeline(mm_player_t* player) // @
 {
-       mm_player_t* player = (mm_player_t*) hplayer;
-
-       debug_fenter();
+       gint timeout = 0;
+       int ret = MM_ERROR_NONE;
 
-       return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
-       return_val_if_fail(callback, MM_ERROR_INVALID_ARGUMENT);
+       MMPLAYER_FENTER();
 
-       player->enough_data_cb = callback;
-       player->buffer_cb_user_param = user_param;
+       return_val_if_fail ( player, MM_ERROR_INVALID_HANDLE );
 
-       debug_log("buffer enough data cb Handle value is %p : %p\n", player, player->enough_data_cb);
+       /* cleanup stuffs */
+       MMPLAYER_FREEIF(player->type);
+       player->have_dynamic_pad = FALSE;
+       player->no_more_pad = FALSE;
+       player->num_dynamic_pad = 0;
+       player->demux_pad_index = 0;
+       player->subtitle_language_list = NULL;
+       player->use_deinterleave = FALSE;
+       player->pp_rebuilding = FALSE;
+       player->max_audio_channels = 0;
+       player->video_share_api_delta = 0;
+       player->video_share_clock_delta = 0;
+       player->video_hub_download_mode = 0;
 
-       debug_fleave();
-               
-       return MM_ERROR_NONE;
-}
+       MMPLAYER_FREEIF(player->font_desc);
+       player->font_color = 0;
+       player->font_bg_color = 0;
 
-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;
+       __mmplayer_post_proc_reset(player);
 
-       debug_fenter();
+       if (player->streamer)
+       {
+               __mm_player_streaming_deinitialize (player->streamer);
+               __mm_player_streaming_destroy(player->streamer);
+               player->streamer = NULL;
+       }
 
-       return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
-       return_val_if_fail(callback, MM_ERROR_INVALID_ARGUMENT);
+       /* cleanup unlinked mime type */
+       MMPLAYER_FREEIF(player->unlinked_audio_mime);
+       MMPLAYER_FREEIF(player->unlinked_video_mime);
+       MMPLAYER_FREEIF(player->unlinked_demuxer_mime);
 
-       player->seek_data_cb = callback;
-       player->buffer_cb_user_param = user_param;
+       /* cleanup running stuffs */
+       __mmplayer_cancel_eos_timer( player );
 
-       debug_log("buffer seek data cb Handle value is %p : %p\n", player, player->seek_data_cb);
+       /* remove sound cb */
+       if ( MM_ERROR_NONE != mm_sound_remove_active_device_changed_callback(MM_PLAYER_NAME))
+       {
+               debug_error("failed to mm_sound_remove_active_device_changed_callback");
+       }
 
-       debug_fleave();
+       /* cleanup gst stuffs */
+       if ( player->pipeline )
+       {
+               MMPlayerGstElement* mainbin = player->pipeline->mainbin;
+               GstTagList* tag_list = player->pipeline->tag_list;
 
-       return MM_ERROR_NONE;
-}
+               /* first we need to disconnect all signal hander */
+               __mmplayer_release_signal_connection( player, MM_PLAYER_SIGNAL_TYPE_ALL );
 
-int __mmplayer_start_extended_streaming(mm_player_t *player)
-{      
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+               /* disconnecting bus watch */
+               if ( player->bus_watcher )
+                       __mmplayer_remove_g_source_from_context(player->context.thread_default, player->bus_watcher);
+               player->bus_watcher = 0;
 
-       if (MMPLAYER_IS_HTTP_PD(player) && player->pd_downloader)
-       {
-               if (player->pd_mode == MM_PLAYER_PD_MODE_URI)
+               if ( mainbin )
                {
-                       gboolean bret = FALSE;
-                       
-                       bret = _mmplayer_pd_start ((MMHandleType)player);
-                       if (FALSE == bret)
+                       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);
+                       gst_object_unref(bus);
+
+                       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 ("ERROR while starting PD...\n");
-                               return MM_ERROR_PLAYER_NOT_INITIALIZED;
+                               debug_error("fail to change state to NULL\n");
+                               return MM_ERROR_PLAYER_INTERNAL;
                        }
-               }
-       }
-
-#ifdef NO_USE_GST_HLSDEMUX
-       if (MMPLAYER_IS_HTTP_LIVE_STREAMING(player))
-       {               
-               if ( !__mm_player_ahs_start (player->ahs_player))
-               {
-                       debug_error("failed to start ahs\n");
-                       return MM_ERROR_PLAYER_INTERNAL;
-               }
-       }
-#endif
-       return MM_ERROR_NONE;
-}
 
-int
-_mmplayer_start(MMHandleType hplayer) // @
-{
-       mm_player_t* player = (mm_player_t*) hplayer;
-       gint ret = MM_ERROR_NONE;
-       
-       debug_fenter();
+                       debug_warning("succeeded in chaning state to NULL\n");
 
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+                       gst_object_unref(GST_OBJECT(mainbin[MMPLAYER_M_PIPE].gst));
 
-       /* check current state */
-       MMPLAYER_CHECK_STATE_RETURN_IF_FAIL( player, MMPLAYER_COMMAND_START );
+                       /* free fakesink */
+                       if ( mainbin[MMPLAYER_M_SRC_FAKESINK].gst )
+                               gst_object_unref(GST_OBJECT(mainbin[MMPLAYER_M_SRC_FAKESINK].gst));
 
-       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;
+                       /* 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 );
        }
+       MMPLAYER_FREEIF(player->album_art);
 
-       if (__mmplayer_start_extended_streaming(player) != MM_ERROR_NONE)
-               return MM_ERROR_PLAYER_INTERNAL;
-       
-       /* start pipeline */
-       ret = __gst_start( player );
-       if ( ret != MM_ERROR_NONE )
+       if (player->v_stream_caps)
        {
-               debug_error("failed to start player.\n");
+               gst_caps_unref(player->v_stream_caps);
+               player->v_stream_caps = NULL;
        }
 
-       debug_fleave();
-       
-       return ret;
-}
+       if ( player->sink_elements )
+               g_list_free ( player->sink_elements );
+       player->sink_elements = NULL;
 
+       debug_warning("finished destroy pipeline\n");
 
+       MMPLAYER_FLEAVE();
 
-/* 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)
+       return ret;
+}
+
+static int __gst_realize(mm_player_t* player) // @
 {
-       MMMessageParamType msg_param;
-       memset (&msg_param, 0, sizeof(MMMessageParamType));
-       gboolean post_msg_direct = FALSE;
+       gint timeout = 0;
+       int ret = MM_ERROR_NONE;
 
-       debug_fenter();
+       MMPLAYER_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);
+       MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_READY;
 
-       if( player->not_found_demuxer )
+       ret = __mmplayer_gst_create_pipeline(player);
+       if ( ret )
        {
-               msg_param.code = MM_ERROR_PLAYER_CODEC_NOT_FOUND;
-               msg_param.data = g_strdup_printf("%s", player->unlinked_demuxer_mime);
+               debug_error("failed to create pipeline\n");
+               return ret;
+       }
 
-               MMPLAYER_POST_MSG( player, MM_MESSAGE_ERROR, &msg_param );
-               MMPLAYER_FREEIF(msg_param.data);
+       /* 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);
 
-               return MM_ERROR_NONE;
+       if ( ret != MM_ERROR_NONE )
+       {
+               /* return error if failed to set state */
+               debug_error("failed to set READY state");
+               return ret;
        }
-
-       if (player->not_supported_codec)
+       else
        {
-               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;
-               }
+               MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_READY );
+       }
 
-               if ( post_msg_direct )
-               {
-                       MMMessageParamType msg_param;
-                       memset (&msg_param, 0, sizeof(MMMessageParamType));
+       /* create dot before error-return. for debugging */
+       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-realize" );
 
-                       if ( player->not_supported_codec ==  MISSING_PLUGIN_AUDIO )
-                       {
-                               debug_warning("not found AUDIO codec, posting error code to application.\n");
+       MMPLAYER_FLEAVE();
 
-                               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");
+       return ret;
+}
 
-                               msg_param.code = MM_ERROR_PLAYER_VIDEO_CODEC_NOT_FOUND;
-                               msg_param.data = g_strdup_printf("%s", player->unlinked_video_mime);
-                       }
+static int __gst_unrealize(mm_player_t* player) // @
+{
+       int ret = MM_ERROR_NONE;
 
-                       MMPLAYER_POST_MSG( player, MM_MESSAGE_ERROR, &msg_param );
+       MMPLAYER_FENTER();
 
-                       MMPLAYER_FREEIF(msg_param.data);
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-                       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_PENDING_STATE(player) = MM_PLAYER_STATE_NULL;
+       MMPLAYER_PRINT_STATE(player);
 
-                       MMPLAYER_POST_MSG( player, MM_MESSAGE_ERROR, &msg_param );
-                       
-                       MMPLAYER_FREEIF(msg_param.data);
-               }
+       /* 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;
        }
-       
-       debug_fleave();
 
-       return MM_ERROR_NONE;
+       /* release miscellaneous information.
+          these info needs to be released after pipeline is destroyed. */
+       __mmplayer_release_misc_post( player );
+
+       MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_NULL );
+
+       MMPLAYER_FLEAVE();
+
+       return ret;
 }
 
-/* NOTE : it should be able to call 'stop' anytime*/
-int
-_mmplayer_stop(MMHandleType hplayer) // @
+static int __gst_pending_seek ( mm_player_t* player )
 {
-       mm_player_t* player = (mm_player_t*)hplayer;
+       MMPlayerStateType current_state = MM_PLAYER_STATE_NONE;
        int ret = MM_ERROR_NONE;
 
-       debug_fenter();
+       MMPLAYER_FENTER();
 
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       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);
 
-       if (MMPLAYER_IS_HTTP_LIVE_STREAMING(player))
+       if ( current_state != MM_PLAYER_STATE_PAUSED && current_state != MM_PLAYER_STATE_PLAYING  )
        {
-               __mm_player_ahs_stop (player->ahs_player);
+               debug_warning("try to pending seek in %s state, try next time. \n",
+                       MMPLAYER_STATE_GET_NAME(current_state));
+               return ret;
        }
 
-       /* check current state */
-       MMPLAYER_CHECK_STATE_RETURN_IF_FAIL( player, MMPLAYER_COMMAND_STOP );
+       debug_log("trying to play from (%lu) pending position\n", player->pending_seek.pos);
 
-       /* NOTE : application should not wait for EOS after calling STOP */
-       __mmplayer_cancel_delayed_eos( player );
+       ret = __gst_set_position ( player, player->pending_seek.format, player->pending_seek.pos, FALSE );
 
-       /* stop pipeline */
-       ret = __gst_stop( player );
+       if ( MM_ERROR_NONE != ret )
+               debug_error("failed to seek pending postion. just keep staying current position.\n");
 
-       if ( ret != MM_ERROR_NONE )
-       {
-               debug_error("failed to stop player.\n");
-       }
+       player->pending_seek.is_pending = FALSE;
 
-       debug_fleave();
+       MMPLAYER_FLEAVE();
 
        return ret;
 }
 
-
-int
-_mmplayer_pause(MMHandleType hplayer) // @
+static int __gst_start(mm_player_t* player) // @
 {
-       mm_player_t* player = (mm_player_t*)hplayer;
-       MMPlayerStateType current_state = MM_PLAYER_STATE_NONE;
-       GstFormat fmt = GST_FORMAT_TIME;
-       signed long long pos_msec = 0;
+       gboolean sound_extraction = 0;
        int ret = MM_ERROR_NONE;
 
-       debug_fenter();
+       MMPLAYER_FENTER();
 
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
 
-       /* check current state */
-       MMPLAYER_CHECK_STATE_RETURN_IF_FAIL( player, MMPLAYER_COMMAND_PAUSE );
+       /* get sound_extraction property */
+       mm_attrs_get_int_by_name(player->attrs, "pcm_extraction", &sound_extraction);
 
-       /* NOTE : store current point to overcome some bad operation
-        * ( returning zero when getting current position in paused state) of some
-        * elements
-        */
-       current_state = MMPLAYER_CURRENT_STATE(player);
-       if ( current_state == MM_PLAYER_STATE_PLAYING )
+       /* 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))
        {
-               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");
+               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");
 
-               player->last_position = pos_msec;
+                       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");
+                       }
+               }
        }
 
-       /* pause pipeline */
-       ret = __gst_pause( player, FALSE );
+       debug_log("current state before doing transition");
+       MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_PLAYING;
+       MMPLAYER_PRINT_STATE(player);
 
-       if ( MMPLAYER_IS_HTTP_LIVE_STREAMING ( 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)
        {
-               //__mm_player_ahs_pause (player->ahs_player); // Not yet implemented
+               MMPLAYER_SET_STATE(player, MM_PLAYER_STATE_PLAYING);
        }
-
-       if ( ret != MM_ERROR_NONE )
+       else
        {
-               debug_error("failed to pause player.\n");
+               debug_error("failed to set state to PLAYING");
+               return ret;
        }
 
-       debug_fleave();
+       /* generating debug info before returning error */
+       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-start" );
+
+       MMPLAYER_FLEAVE();
 
        return ret;
 }
 
-int
-_mmplayer_resume(MMHandleType hplayer)
+static void __mmplayer_do_sound_fadedown(mm_player_t* player, unsigned int time)
 {
-       mm_player_t* player = (mm_player_t*)hplayer;
-       int ret = MM_ERROR_NONE;
+       MMPLAYER_FENTER();
 
-       debug_fenter();
+       return_if_fail(player
+               && player->pipeline
+               && player->pipeline->audiobin
+               && player->pipeline->audiobin[MMPLAYER_A_SINK].gst);
 
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       g_object_set(G_OBJECT(player->pipeline->audiobin[MMPLAYER_A_SINK].gst), "mute", 2, NULL);
 
-       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 );
+       usleep(time);
 
-       /* resume pipeline */
-       ret = __gst_resume( player, FALSE );
+       MMPLAYER_FLEAVE();
+}
 
-       if ( ret != MM_ERROR_NONE )
-       {
-               debug_error("failed to resume player.\n");
-       }
+static void __mmplayer_undo_sound_fadedown(mm_player_t* player)
+{
+       MMPLAYER_FENTER();
 
+       return_if_fail(player
+               && player->pipeline
+               && player->pipeline->audiobin
+               && player->pipeline->audiobin[MMPLAYER_A_SINK].gst);
 
-       debug_fleave();
+       g_object_set(G_OBJECT(player->pipeline->audiobin[MMPLAYER_A_SINK].gst), "mute", 0, NULL);
 
-       return ret;
+       MMPLAYER_FLEAVE();
 }
 
-int
-__mmplayer_set_play_count(mm_player_t* player, gint count)
+static int __gst_stop(mm_player_t* player) // @
 {
+       GstStateChangeReturn change_ret = GST_STATE_CHANGE_SUCCESS;
        MMHandleType attrs = 0;
+       gboolean fadedown = FALSE;
+       gboolean rewind = FALSE;
+       gint timeout = 0;
+       int ret = MM_ERROR_NONE;
+       GstState state;
 
-       debug_fenter();
+       MMPLAYER_FENTER();
 
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       return_val_if_fail ( player->pipeline->mainbin, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-       attrs =  MMPLAYER_GET_ATTRS(player);
+       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("fail to get attributes.\n");
+               debug_error("cannot get content attribute\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();
+       mm_attrs_get_int_by_name(attrs, "sound_fadedown", &fadedown);
 
-       return  MM_ERROR_NONE;
-}
+       /* enable fadedown */
+       if (fadedown || player->sm.by_asm_cb)
+               __mmplayer_do_sound_fadedown(player, MM_PLAYER_FADEOUT_TIME_DEFAULT);
 
-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;
+       /* Just set state to PAUESED and the rewind. it's usual player behavior. */
+       timeout = MMPLAYER_STATE_CHANGE_TIMEOUT ( player );
 
-       debug_fenter();
+       if (player->profile.uri_type == MM_PLAYER_URI_TYPE_BUFF ||
+               player->profile.uri_type == MM_PLAYER_URI_TYPE_HLS)
+       {
+               state = GST_STATE_READY;
+       }
+       else
+       {
+               state = GST_STATE_PAUSED;
 
-       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 );
+               if ( ! MMPLAYER_IS_STREAMING(player) ||
+                       (player->streaming_type == STREAMING_SERVICE_VOD && player->videodec_linked)) {
+                       rewind = TRUE;
+               }
+       }
 
-       player->section_repeat = TRUE;
-       player->section_repeat_start = start;
-       player->section_repeat_end = end;
+       /* set gst state */
+       ret = __mmplayer_gst_set_state( player, player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, state, FALSE, timeout );
 
-       start_pos = player->section_repeat_start * G_GINT64_CONSTANT(1000000);
-       end_pos = player->section_repeat_end * G_GINT64_CONSTANT(1000000);
+       /* disable fadeout */
+       if (fadedown || player->sm.by_asm_cb)
+               __mmplayer_undo_sound_fadedown(player);
 
-       __mmplayer_set_play_count( player, infinity );
+       /* return if set_state has failed */
+       if ( ret != MM_ERROR_NONE )
+       {
+               debug_error("failed to set state.\n");
+               return ret;
+       }
 
-       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)))
+       /* rewind */
+       if ( rewind )
        {
-               debug_error("failed to activate section repeat\n");
+               if ( ! __gst_seek( player, player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, player->playback_rate,
+                               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;
+               }
+       }
 
-               return 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;
+               __mmplayer_dump_pipeline_state(player);
        }
 
-       debug_log("succeeded to set section repeat from %d to %d\n",
-               player->section_repeat_start, player->section_repeat_end);
+       /* generate dot file if enabled */
+       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-stop" );
 
-       debug_fleave();
+       MMPLAYER_FLEAVE();
 
-       return  MM_ERROR_NONE;
+       return ret;
 }
 
-static int 
-__mmplayer_set_pcm_extraction(mm_player_t* player)
+int __gst_pause(mm_player_t* player, gboolean async) // @
 {
-       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 );
+       int ret = MM_ERROR_NONE;
 
-       mm_attrs_multiple_get(player->attrs,
-               NULL,
-               "pcm_extraction_start_msec", &required_start,
-               "pcm_extraction_end_msec", &required_end,
-               NULL);
+       MMPLAYER_FENTER();
 
-       debug_log("pcm extraction required position is from [%d] to [%d] (msec)\n", required_start, required_end);
+       return_val_if_fail(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       return_val_if_fail(player->pipeline->mainbin, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-       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;
-       }
+       debug_log("current state before doing transition");
+       MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_PAUSED;
+       MMPLAYER_PRINT_STATE(player);
 
-       /* 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);
+       /* set pipeline status to PAUSED */
+       player->ignore_asyncdone = TRUE;
 
-       if (dur_msec < required_end) // FIXME
-       {
-               debug_log("invalid end pos for pcm extraction");
-               return MM_ERROR_INVALID_ARGUMENT;
-       }
+       ret = __mmplayer_gst_set_state(player,
+               player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_PAUSED, async, MMPLAYER_STATE_CHANGE_TIMEOUT(player));
 
-       start_nsec = required_start * G_GINT64_CONSTANT(1000000);
-       end_nsec = required_end * G_GINT64_CONSTANT(1000000);
+       player->ignore_asyncdone = FALSE;
 
-       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)))
+       if ( FALSE == async )
        {
-               debug_error("failed to seek for pcm extraction\n");
+               if ( ret != MM_ERROR_NONE )
+               {
+                       GstMessage *msg = NULL;
+                       GTimer *timer = NULL;
+                       gdouble MAX_TIMEOUT_SEC = 3;
 
-               return MM_ERROR_PLAYER_SEEK;
-       }
+                       debug_error("failed to set state to PAUSED");
 
-       debug_log("succeeded to set up segment extraction from [%llu] to [%llu] (nsec)\n", start_nsec, end_nsec);
+                       timer = g_timer_new();
+                       g_timer_start(timer);
 
-       debug_fleave(); 
+                       GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst));
+                       gboolean got_msg = FALSE;
+                       /* check if gst error posted or not */
+                       do
+                       {
+                               msg = gst_bus_timed_pop(bus, GST_SECOND /2);
+                               if (msg)
+                               {
+                                       if (GST_MESSAGE_TYPE(msg) == GST_MESSAGE_ERROR)
+                                       {
+                                               GError *error = NULL;
 
-       return MM_ERROR_NONE;
-}
+                                               /* parse error code */
+                                               gst_message_parse_error(msg, &error, NULL);
 
-static
-void __mmplayer_set_videosink_type(mm_player_t* player)
-{
-       int type = 0;
+                                               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 );
 
-       debug_fenter();
+                                               }
+                                               else if (error)
+                                               {
+                                                       debug_error("paring error posted from bus, domain : %s, code : %d", g_quark_to_string(error->domain), error->code);
 
-       return_if_fail( player );
+                                                       if (error->domain == GST_STREAM_ERROR)
+                                                       {
+                                                               ret = __gst_handle_stream_error( player, error, msg );
+                                                       }
+                                                       else if (error->domain == GST_RESOURCE_ERROR)
+                                                       {
+                                                               ret = __gst_handle_resource_error( player, error->code );
+                                                       }
+                                                       else if (error->domain == GST_LIBRARY_ERROR)
+                                                       {
+                                                               ret = __gst_handle_library_error( player, error->code );
+                                                       }
+                                                       else if (error->domain == GST_CORE_ERROR)
+                                                       {
+                                                               ret = __gst_handle_core_error( player, error->code );
+                                                       }
+                                               }
 
-       mm_attrs_get_int_by_name (player->attrs, "display_surface_type", &type);
-       
-       debug_log("check display surface attribute: %d\n", type);
+                                               got_msg = TRUE;
+                                               player->msg_posted = TRUE;
+                                       }
+                                       gst_message_unref(msg);
+                               }
+                       } while (!got_msg && (g_timer_elapsed(timer, NULL) < MAX_TIMEOUT_SEC));
+                       /* clean */
+                       gst_object_unref(bus);
+                       g_timer_stop (timer);
+                       g_timer_destroy (timer);
 
-       if (type >=MM_DISPLAY_SURFACE_X)
-       {
-               PLAYER_INI()->video_surface = type;
+                       return ret;
+               }
+               else if ( (!player->pipeline->videobin) && (!player->pipeline->audiobin) )
+               {
+                       if (MMPLAYER_IS_RTSP_STREAMING(player))
+                               return ret;
+                       return MM_ERROR_PLAYER_CODEC_NOT_FOUND;
+               }
+               else if ( ret== MM_ERROR_NONE)
+               {
+                       MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_PAUSED );
+               }
        }
 
-       debug_fleave();
+       /* generate dot file before returning error */
+       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-pause" );
+
+       MMPLAYER_FLEAVE();
 
-       return;
+       return ret;
 }
 
-int
-_mmplayer_deactivate_section_repeat(MMHandleType hplayer)
+int __gst_resume(mm_player_t* player, gboolean async) // @
 {
-       mm_player_t* player = (mm_player_t*)hplayer;
-       gint64 cur_pos = 0;
-       GstFormat fmt  = GST_FORMAT_TIME;
-       gint onetime = 1;
+       int ret = MM_ERROR_NONE;
+       gint timeout = 0;
 
-       debug_fenter();
+       MMPLAYER_FENTER();
 
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail(player && player->pipeline,
+               MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-       player->section_repeat = FALSE;
+       debug_log("current state before doing transition");
+       MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_PLAYING;
+       MMPLAYER_PRINT_STATE(player);
 
-       __mmplayer_set_play_count( player, onetime );
+       /* generate dot file before returning error */
+       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-resume" );
 
-       gst_element_query_position(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, &fmt, &cur_pos);
+       __mmplayer_set_antishock( player , FALSE );
 
-       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");
+       if ( async )
+               debug_log("do async state transition to PLAYING.\n");
 
-               return MM_ERROR_PLAYER_SEEK;
+       /* 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");
+               return ret;
+       }
+       else
+       {
+               if (async == FALSE)
+               {
+                       // MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_PLAYING );
+                       debug_log("update state machine to %d\n", MM_PLAYER_STATE_PLAYING);
+                       ret = __mmplayer_set_state(player, MM_PLAYER_STATE_PLAYING);
+               }
        }
 
-       debug_fenter();
+       /* generate dot file before returning error */
+       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-resume" );
+
+       MMPLAYER_FLEAVE();
 
-       return MM_ERROR_NONE;
+       return ret;
 }
 
-int
-_mmplayer_set_playspeed(MMHandleType hplayer, gdouble rate)
+static int
+__gst_set_position(mm_player_t* player, int format, unsigned long position, gboolean internal_called) // @
 {
-       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();
+       GstFormat fmt  = GST_FORMAT_TIME;
+       unsigned long dur_msec = 0;
+       gint64 dur_nsec = 0;
+       gint64 pos_nsec = 0;
+       gboolean ret = TRUE;
+       gboolean accurated = FALSE;
+       GstSeekFlags seek_flags = GST_SEEK_FLAG_FLUSH;
 
+       MMPLAYER_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 );
+       return_val_if_fail ( !MMPLAYER_IS_LIVE_STREAMING(player), MM_ERROR_PLAYER_NO_OP );
 
-       /* 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 ( 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 (player->can_support_codec & FOUND_PLUGIN_VIDEO)
-                       mute = TRUE;
+               if ( !gst_element_query_duration( player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, &fmt, &dur_nsec ))
+               {
+                       goto SEEK_ERROR;
+               }
+               player->duration = dur_nsec;
        }
-       _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);
+       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 ("pos_msec = %"GST_TIME_FORMAT" and ret = %d and state = %d", GST_TIME_ARGS (pos_msec), ret, current_state);
+       debug_log("playback rate: %f\n", player->playback_rate);
 
-       if ( ( current_state == MM_PLAYER_STATE_PAUSED )
-               || ( ! ret ))
-               //|| ( player->last_position != 0 && pos_msec == 0 ) )
+       mm_attrs_get_int_by_name(player->attrs,"accurate_seek", &accurated);
+       if (accurated)
        {
-               debug_warning("returning last point : %lld\n", player->last_position );
-               pos_msec = player->last_position;
+               seek_flags |= GST_SEEK_FLAG_ACCURATE;
        }
-
-       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)))
+       else
        {
-               debug_error("failed to set speed playback\n");
-               return MM_ERROR_PLAYER_SEEK;
+               seek_flags |= GST_SEEK_FLAG_KEY_UNIT;
        }
 
-       debug_log("succeeded to set speed playback as %fl\n", 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_fleave();
+                       debug_log("seeking to (%lu) msec, duration is %d msec\n", position, dur_msec);
 
-       return MM_ERROR_NONE;;
-}
+                       if (player->doing_seek)
+                       {
+                               debug_log("not completed seek");
+                               return MM_ERROR_PLAYER_DOING_SEEK;
+                       }
 
-int
-_mmplayer_set_position(MMHandleType hplayer, int format, int position) // @
-{
-       mm_player_t* player = (mm_player_t*)hplayer;
-       int ret = MM_ERROR_NONE;
+                       if ( !internal_called)
+                               player->doing_seek = TRUE;
 
-       debug_fenter();
+                       pos_nsec = position * G_GINT64_CONSTANT(1000000);
 
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+                       if ((MMPLAYER_IS_HTTP_STREAMING(player)) && (!player->videodec_linked))
+                       {
+                               gint64 cur_time = 0;
+                               GstFormat format = GST_FORMAT_TIME;
+
+                               /* get current position */
+                               gst_element_query_position(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, &format, &cur_time);
+
+                               /* flush */
+                               GstEvent *event = gst_event_new_seek (1.0,
+                                                               GST_FORMAT_TIME,
+                                                               (GstSeekFlags)GST_SEEK_FLAG_FLUSH,
+                                                               GST_SEEK_TYPE_SET, cur_time,
+                                                               GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
+                               if(event) {
+                                       __gst_send_event_to_sink(player, event);
+                               }
 
-       ret = __gst_set_position ( player, format, (unsigned long)position );
+                               __gst_pause( player, FALSE );
+                       }
 
-       debug_fleave(); 
+                       ret = __gst_seek ( player, player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, player->playback_rate,
+                                                       GST_FORMAT_TIME, seek_flags,
+                                                       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;
 
-       return ret;
-}
+               case MM_PLAYER_POS_FORMAT_PERCENT:
+               {
+                       debug_log("seeking to (%lu)%% \n", position);
 
-int
-_mmplayer_get_position(MMHandleType hplayer, int format, unsigned long *position) // @
-{
-       mm_player_t* player = (mm_player_t*)hplayer;
-       int ret = MM_ERROR_NONE;
+                       if (player->doing_seek)
+                       {
+                               debug_log("not completed seek");
+                               return MM_ERROR_PLAYER_DOING_SEEK;
+                       }
 
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+                       if ( !internal_called)
+                               player->doing_seek = TRUE;
 
-       ret = __gst_get_position ( player, format, position );
-       
-       return ret;
-}
+                       /* 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, player->playback_rate,
+                                                       GST_FORMAT_TIME, seek_flags,
+                                                       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;
 
-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;
+               default:
+                       goto INVALID_ARGS;
 
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       }
 
-       ret = __gst_get_buffer_position ( player, format, start_pos, stop_pos );
+       /* NOTE : store last seeking point to overcome some bad operation
+         *      ( returning zero when getting current position ) of some elements
+         */
+       player->last_position = pos_nsec;
 
-       return ret;
-}
+       /* 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 );
 
-int
-_mmplayer_adjust_subtitle_postion(MMHandleType hplayer, int format, int position) // @
-{
-       mm_player_t* player = (mm_player_t*)hplayer;
-       int ret = MM_ERROR_NONE;
+       MMPLAYER_FLEAVE();
+       return MM_ERROR_NONE;
 
-       debug_fenter();
+PENDING:
+       player->pending_seek.is_pending = TRUE;
+       player->pending_seek.format = format;
+       player->pending_seek.pos = position;
 
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       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);
 
-       ret = __gst_adjust_subtitle_position(player, format, position);
+       return MM_ERROR_NONE;
 
-       debug_fleave();
+INVALID_ARGS:
+       debug_error("invalid arguments, position : %ld  dur : %ld format : %d \n", position, dur_msec, format);
+       return MM_ERROR_INVALID_ARGUMENT;
 
-       return ret;
+SEEK_ERROR:
+       player->doing_seek = FALSE;
+       return MM_ERROR_PLAYER_SEEK;
 }
 
-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");
+#define TRICKPLAY_OFFSET GST_MSECOND
 
-               return TRUE;
-       }
+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;
 
-       debug_log("not midi.\n");
+       return_val_if_fail( player && position && player->pipeline && player->pipeline->mainbin,
+               MM_ERROR_PLAYER_NOT_INITIALIZED );
 
-       return FALSE;
-}
+       current_state = MMPLAYER_CURRENT_STATE(player);
 
-static gboolean
-__mmplayer_is_amr_type (gchar *str_caps)
-{
-       if ((g_strrstr(str_caps, "AMR")) ||
-               (g_strrstr(str_caps, "amr")))
+       /* 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 )
        {
-               return TRUE;
+               ret = gst_element_query_position(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, &fmt, &pos_msec);
        }
-       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")))
+       /* 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 ) )
        {
-               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_log ("pos_msec = %"GST_TIME_FORMAT" and ret = %d and state = %d", GST_TIME_ARGS (pos_msec), ret, current_state);
 
-       debug_fenter();
+               if(player->playback_rate < 0.0)
+                       pos_msec = player->last_position - TRICKPLAY_OFFSET;
+               else
+                       pos_msec = player->last_position;
 
-       return_if_fail( player && tf && caps );
+               if (!ret)
+                       pos_msec = player->last_position;
+               else
+                       player->last_position = pos_msec;
 
-       /* 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));
+               debug_log("returning last point : %"GST_TIME_FORMAT, GST_TIME_ARGS(pos_msec));
 
-       /* midi type should be stored because it will be used to set audio gain in avsysauiosink */
-       if ( __mmplayer_is_midi_type(player->type))
-       {
-               player->profile.play_mode = MM_PLAYER_MODE_MIDI;
        }
-       else if (__mmplayer_is_amr_type(player->type))
+       else
        {
-               player->bypass_sound_effect = FALSE;
-               if ( (PLAYER_INI()->use_audio_filter_preset || PLAYER_INI()->use_audio_filter_custom) )
+               if (player->duration > 0 && pos_msec > player->duration) {
+                       pos_msec = player->duration;
+               }
+
+               if (player->sm.keep_last_pos) {
+                       debug_log("return last pos as stop by asm, %"GST_TIME_FORMAT, GST_TIME_ARGS(player->last_position));
+                       pos_msec = player->last_position;
+               }
+               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:
                {
-                       if ( player->audio_filter_info.filter_type == MM_AUDIO_FILTER_TYPE_PRESET )
+                       gint64 dur = 0;
+                       gint64 pos = 0;
+
+                       dur = player->duration / GST_SECOND;
+                       if (dur <= 0)
                        {
-                               if (!_mmplayer_sound_filter_preset_apply(player, player->audio_filter_info.preset))
-                               {
-                                       debug_msg("apply sound effect(preset:%d) setting success\n",player->audio_filter_info.preset);
-                               }
+                               debug_log ("duration is [%d], so returning position 0\n",dur);
+                               *position = 0;
                        }
-                       else if ( player->audio_filter_info.filter_type == MM_AUDIO_FILTER_TYPE_CUSTOM )
+                       else
                        {
-                               if (!_mmplayer_sound_filter_custom_apply(player))
-                               {
-                                       debug_msg("apply sound 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 ) &&
-               ( ! MMPLAYER_IS_RTSP_STREAMING ( player ) ) &&
-               ( 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 );
+                               pos = pos_msec / GST_SECOND;
+                               *position = pos * 100 / dur;
+                       }
+                       break;
                }
+               default:
+                       return MM_ERROR_PLAYER_INTERNAL;
        }
 
-DONE:
-       gst_object_unref( GST_OBJECT(pad) );
-
-       debug_fleave(); 
-
-       return;
+       return MM_ERROR_NONE;
 }
 
-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) // @
+static int     __gst_get_buffer_position(mm_player_t* player, int format, unsigned long* start_pos, unsigned long* stop_pos)
 {
-       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;
+#define STREAMING_IS_FINISHED  0
+#define BUFFERING_MAX_PER      100
 
-       debug_fenter();
+       GstQuery *query = NULL;
 
        return_val_if_fail( player &&
                                                player->pipeline &&
                                                player->pipeline->mainbin,
-                                               FALSE );
+                                               MM_ERROR_PLAYER_NOT_INITIALIZED );
 
+       return_val_if_fail( start_pos && stop_pos, MM_ERROR_INVALID_ARGUMENT );
 
-       mainbin = player->pipeline->mainbin;
+       if (!MMPLAYER_IS_HTTP_STREAMING ( player ))
+       {
+               /* and rtsp is not ready yet. */
+               debug_warning ( "it's only used for http streaming case.\n" );
+               return MM_ERROR_NONE;
+       }
 
-       mime = gst_structure_get_name(gst_caps_get_structure(caps, 0));
+       *start_pos = 0;
+       *stop_pos = 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") )
-       {
+       switch ( format )
+       {
+               case MM_PLAYER_POS_FORMAT_PERCENT :
+               {
+                       gint start_per = -1, stop_per = -1;
+                       gint64 buffered_total = 0;
 
-               element = (GstElement*)gst_pad_get_parent(pad);
+                       unsigned long position = 0;
+                       guint curr_size_bytes = 0;
+                       gint64 buffering_left = -1;
+                       gint buffered_sec = -1;
 
+                       gint64 content_duration = player->duration;
+                       guint64 content_size = player->http_content_size;
 
-/* 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
+                       if (content_duration > 0)
+                       {
+                               if (!__gst_get_position(player, MM_PLAYER_POS_FORMAT_TIME, &position))
+                               {
+                                       debug_log ("[Time] pos %d ms / dur %d sec / %lld bytes", position, (guint)(content_duration/GST_SECOND), content_size);
+                                       start_per = 100 * (position*GST_MSECOND) / content_duration;
 
-               /* 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.
-                */
+                                       /* buffered size info from multiqueue */
+                                       if (player->pipeline->mainbin[MMPLAYER_M_DEMUXED_S_BUFFER].gst)
+                                       {
+                                               g_object_get(G_OBJECT(player->pipeline->mainbin[MMPLAYER_M_DEMUXED_S_BUFFER].gst), "curr-size-bytes", &curr_size_bytes, NULL);
+                                               debug_log ("[MQ] curr_size_bytes = %d", curr_size_bytes);
 
-               klass = gst_element_factory_get_klass( gst_element_get_factory(element) );
+                                               buffered_total += curr_size_bytes;
+                                       }
 
-               /* add queue if needed */
-               if( g_strrstr(klass, "Demux") ||
-               g_strrstr(klass, "Depayloader") ||
-                       g_strrstr(klass, "Parse") )
-               {
-                       debug_log("adding raw queue\n");
+                                       /* buffered size info from queue2 */
+                                       if (player->pipeline->mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst)
+                                       {
+                                               query = gst_query_new_buffering ( GST_FORMAT_BYTES );
+                                               if (gst_element_query(player->pipeline->mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst, query))
+                                               {
+                                                       GstBufferingMode mode;
+                                                       gint byte_in_rate = 0, byte_out_rate = 0;
+                                                       gint64 start_byte = 0, stop_byte = 0;
+                                                       guint num_of_ranges = 0;
+                                                       guint idx = 0;
+
+                                                       num_of_ranges = gst_query_get_n_buffering_ranges(query);
+                                                       for ( idx=0 ; idx<num_of_ranges ; idx++ )
+                                                       {
+                                                               gst_query_parse_nth_buffering_range (query, idx, &start_byte, &stop_byte);
+                                                               debug_log ("[Q2][range %d] %lld ~ %lld\n", idx, start_byte, stop_byte);
 
-                       queue = gst_element_factory_make("queue", NULL);
-                       if ( ! queue )
-                       {
-                               debug_warning("failed to create queue\n");
-                               goto ERROR;
-                       }
+                                                               buffered_total += (stop_byte - start_byte);
+                                                       }
 
-                       /* 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;
+                                                       gst_query_parse_buffering_stats(query, &mode, &byte_in_rate, &byte_out_rate, &buffering_left);
+                                                       debug_log ("[Q2] in_rate %d, out_rate %d, left %lld\n", byte_in_rate, byte_out_rate, buffering_left);
+                                               }
+                                               gst_query_unref (query);
+                                       }
+
+                                       if (buffering_left == STREAMING_IS_FINISHED)
+                                       {
+                                               stop_per = BUFFERING_MAX_PER;
+                                       }
+                                       else
+                                       {
+                                               guint dur_sec = (guint)(content_duration/GST_SECOND);
+                                               guint avg_byterate = (dur_sec>0)?((guint)(content_size/dur_sec)):(0);
+
+                                               if (avg_byterate > 0)
+                                                       buffered_sec = (gint)(buffered_total/avg_byterate);
+                                               else if (player->total_maximum_bitrate > 0)
+                                                       buffered_sec = (gint)(GET_BIT_FROM_BYTE(buffered_total)/(gint64)player->total_maximum_bitrate);
+                                               else if (player->total_bitrate > 0)
+                                                       buffered_sec = (gint)(GET_BIT_FROM_BYTE(buffered_total)/(gint64)player->total_bitrate);
+
+                                               if ((buffered_sec >= 0) && (dur_sec > 0))
+                                                       stop_per = start_per + (100 * buffered_sec / dur_sec);
+                                       }
+
+                                       debug_log ("[Buffered Total] %lld bytes, %d sec, per %d~%d\n", buffered_total, buffered_sec, start_per, stop_per);
+                               }
                        }
 
-                       /* add to pipeline */
-                       if ( ! gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), queue) )
+                       if (((buffered_total == 0) || (start_per < 0) || (stop_per < 0)) &&
+                               (player->pipeline->mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst))
                        {
-                               debug_warning("failed to add queue\n");
-                               goto ERROR;
-                       }
+                               query = gst_query_new_buffering ( GST_FORMAT_PERCENT );
+                               if ( gst_element_query ( player->pipeline->mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst, query ) )
+                               {
+                                       GstFormat format;
+                                       gint64 range_start_per = -1, range_stop_per = -1;
 
-                       /* link queue */
-                       queue_pad = gst_element_get_static_pad(queue, "sink");
+                                       gst_query_parse_buffering_range ( query, &format, &range_start_per, &range_stop_per, NULL );
 
-                       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;
+                                       debug_log ("[Q2] range start %" G_GINT64_FORMAT " ~ stop %" G_GINT64_FORMAT "\n",  range_start_per , range_stop_per);
 
-                       /* 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;
-                       }
+                                       if (range_start_per != -1)
+                                               start_per = (gint)(100 * range_start_per / GST_FORMAT_PERCENT_MAX);
 
-                       /* 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;
+                                       if (range_stop_per != -1)
+                                               stop_per = (gint)(100 * range_stop_per / GST_FORMAT_PERCENT_MAX);
+                               }
+                               gst_query_unref (query);
                        }
-               }
-#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;
+                       if ( start_per > 0)
+                               *start_pos = (start_per < 100)?(start_per):(100);
+                       else
+                               *start_pos = 0;
 
+                       if ( stop_per > 0)
+                               *stop_pos = (stop_per < 100)?(stop_per):(100);
+                       else
+                               *stop_pos = 0;
 
-               return TRUE;
-       }
+                       break;
+               }
+               case MM_PLAYER_POS_FORMAT_TIME :
+                       debug_warning ( "Time format is not supported yet.\n" );
+                       break;
 
-       item = player->factories;
-       for(; item != NULL ; item = item->next)
-       {
+               default :
+                       break;
+       }
 
-               GstElementFactory *factory = GST_ELEMENT_FACTORY(item->data);
-               const GList *pads;
-               gint idx = 0;
+       debug_log("current buffer position : %lu~%lu \n", *start_pos, *stop_pos );
 
-               skip = FALSE;
+       return MM_ERROR_NONE;
+}
 
-               /* 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] );
+static int
+__gst_set_message_callback(mm_player_t* player, MMMessageCallback callback, gpointer user_param) // @
+{
+       MMPLAYER_FENTER();
 
-                               skip = TRUE;
-                               break;
-                       }
-               }
+       if ( !player )
+       {
+               debug_warning("set_message_callback is called with invalid player handle\n");
+               return MM_ERROR_PLAYER_NOT_INITIALIZED;
+       }
 
-               if ( skip ) continue;
+       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);
 
-               /* check factory class for filtering */
-               klass = gst_element_factory_get_klass(GST_ELEMENT_FACTORY(factory));
+       MMPLAYER_FLEAVE();
 
-               if ( MMPLAYER_IS_RTSP_STREAMING( player ) )
-               {
-                       if ( g_strrstr(klass, "Parse") )
-                       {
-                               debug_log("streaming doesn't need any parser. skipping [%s]\n",
-                                       GST_PLUGIN_FEATURE_NAME (factory) );
+       return MM_ERROR_NONE;
+}
 
-                               continue;
-                       }
-               }
+static int __mmfplayer_parse_profile(const char *uri, void *param, MMPlayerParseProfile* data) // @
+{
+       int ret = MM_ERROR_PLAYER_INVALID_URI;
+       char *path = NULL;
 
-               /* 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) );
+       MMPLAYER_FENTER();
 
-                       continue;
-               }
+       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));
 
-               /* 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 ((path = strstr(uri, "file://")))
+       {
+               int file_stat = MM_ERROR_NONE;
 
-                       if( temp1->direction != GST_PAD_SINK ||
-                               temp1->presence != GST_PAD_ALWAYS)
-                               continue;
+               file_stat = util_exist_file_path(path + 7);
 
+               if (file_stat == MM_ERROR_NONE)
+               {
+                       strncpy(data->uri, path, MM_MAX_URL_LEN-1);
 
-                       if ( GST_IS_CAPS( &temp1->static_caps.caps) )
+                       if ( util_is_sdp_file ( path ) )
                        {
-                               /* using existing caps */
-                               static_caps = gst_caps_ref( &temp1->static_caps.caps );
+                               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
                        {
-                               /* create one */
-                               static_caps = gst_caps_from_string ( temp1->static_caps.string );
+                               data->uri_type = MM_PLAYER_URI_TYPE_FILE;
                        }
+                       ret = MM_ERROR_NONE;
+               }
+               else if (file_stat == MM_ERROR_PLAYER_PERMISSION_DENIED)
+               {
+                       data->uri_type = MM_PLAYER_URI_TYPE_NO_PERMISSION;
+               }
+               else
+               {
+                       debug_warning("could  access %s.\n", path);
+               }
+       }
+       else if ((path = strstr(uri, "buff://")))
+       {
+                       data->uri_type = MM_PLAYER_URI_TYPE_BUFF;
+                       ret = MM_ERROR_NONE;
+       }
+       else if ((path = strstr(uri, "rtsp://")))
+       {
+               if (strlen(path)) {
+                       if((path = strstr(uri, "/wfd1.0/"))) {
+                               strncpy(data->uri, uri, MM_MAX_URL_LEN-1);
+                               data->uri_type = MM_PLAYER_URI_TYPE_URL_WFD;
+                               ret = MM_ERROR_NONE;
+                               debug_log("uri is actually a wfd client path. giving it to wfdrtspsrc\n");
+                       }
+                       else {
+                               strncpy(data->uri, uri, MM_MAX_URL_LEN-1);
+                               data->uri_type = MM_PLAYER_URI_TYPE_URL_RTSP;
+                               ret = MM_ERROR_NONE;
+                       }
+               }
+       }
+       else if ((path = strstr(uri, "http://")))
+       {
+               if (strlen(path)) {
+                       strncpy(data->uri, uri, MM_MAX_URL_LEN-1);
+#ifdef MM_SMOOTH_STREAMING
+                       if (g_str_has_suffix (g_ascii_strdown(uri, strlen(uri)), ".ism/manifest") ||
+                               g_str_has_suffix (g_ascii_strdown(uri, strlen(uri)), ".isml/manifest"))
+                       {
+                               data->uri_type = MM_PLAYER_URI_TYPE_SS;
+                       }
+                       else
+#endif
+                               data->uri_type = MM_PLAYER_URI_TYPE_URL_HTTP;
 
-                       res = gst_caps_intersect(caps, static_caps);
-
-                       gst_caps_unref( static_caps );
-                       static_caps = NULL;
+                       ret = MM_ERROR_NONE;
+               }
+       }
+       else if ((path = strstr(uri, "https://")))
+       {
+               if (strlen(path)) {
+                       strncpy(data->uri, uri, MM_MAX_URL_LEN -1);
+#ifdef MM_SMOOTH_STREAMING
+               if (g_str_has_suffix (g_ascii_strdown(uri, strlen(uri)), ".ism/manifest") ||
+                               g_str_has_suffix (g_ascii_strdown(uri, strlen(uri)), ".isml/manifest"))
+                       {
+                               data->uri_type = MM_PLAYER_URI_TYPE_SS;
+                       }
+#endif
+                               data->uri_type = MM_PLAYER_URI_TYPE_URL_HTTP;
 
-                       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);
+                       ret = MM_ERROR_NONE;
+               }
+       }
+       else if ((path = strstr(uri, "rtspu://")))
+       {
+               if (strlen(path)) {
+                       strncpy(data->uri, uri, MM_MAX_URL_LEN -1);
+                       data->uri_type = MM_PLAYER_URI_TYPE_URL_RTSP;
+                       ret = MM_ERROR_NONE;
+               }
+       }
+       else if ((path = strstr(uri, "rtspr://")))
+       {
+               strncpy(data->uri, path, MM_MAX_URL_LEN -1);
+               char *separater =strstr(path, "*");
 
-                               gst_caps_unref(res);
+               if (separater) {
+                       int urgent_len = 0;
+                       char *urgent = separater + strlen("*");
 
-                               debug_log("found %s to plug\n", name_to_plug);
+                       if ((urgent_len = strlen(urgent))) {
+                               data->uri[strlen(path) - urgent_len - strlen("*")] = '\0';
+                               strncpy(data->urgent, urgent, MM_MAX_FILENAME_LEN -1);
+                               data->uri_type = MM_PLAYER_URI_TYPE_URL_RTSP;
+                               ret = MM_ERROR_NONE;
+                       }
+               }
+       }
+       else if ((path = strstr(uri, "mms://")))
+       {
+               if (strlen(path)) {
+                       strncpy(data->uri, uri, MM_MAX_URL_LEN -1);
+                       data->uri_type = MM_PLAYER_URI_TYPE_URL_MMS;
+                       ret = MM_ERROR_NONE;
+               }
+       }
+       else if ((path = strstr(uri, "mem://")))
+       {
+               if (strlen(path)) {
+                       #define MM_MAX_EXT_SIZE 100
+                       int mem_size = 0;
+                       char *buffer = NULL;
+                       char *seperator = strchr(path, ',');
+                       char ext[MM_MAX_EXT_SIZE] = {0,}, size[MM_MAX_EXT_SIZE] = {0,};
 
-                               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));
+                       if (seperator) {
+                               if ((buffer = strstr(path, "ext="))) {
+                                       buffer += strlen("ext=");
 
-                                       MMPLAYER_FREEIF(name_template);
+                                       if (strlen(buffer)) {
+                                               strncpy(ext, buffer, MM_MAX_EXT_SIZE -1);
 
-                                       continue;
+                                               if ((seperator = strchr(ext, ','))
+                                                       || (seperator = strchr(ext, ' '))
+                                                       || (seperator = strchr(ext, '\0'))) {
+                                                       seperator[0] = '\0';
+                                               }
+                                       }
                                }
 
-                               /* 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;
+                               if ((buffer = strstr(path, "size="))) {
+                                       buffer += strlen("size=");
 
-                                       for ( ; elements; elements = g_list_next(elements))
-                                       {
-                                               gchar *element_name = elements->data;
+                                       if (strlen(buffer) > 0) {
+                                               strncpy(size, buffer, MM_MAX_EXT_SIZE -1);
 
-                                               if (g_strrstr(element_name, name_to_plug))
-                                               {
-                                                       debug_log("but, %s already linked, so skipping it\n", name_to_plug);
-                                                       skip = TRUE;
+                                               if ((seperator = strchr(size, ','))
+                                                       || (seperator = strchr(size, ' '))
+                                                       || (seperator = strchr(size, '\0'))) {
+                                                       seperator[0] = '\0';
                                                }
-                                       }
-
-                                       if (skip) continue;
 
-                                       selected = g_strdup(name_to_plug);
-
-                                       player->parsers = g_list_append(player->parsers, selected);
+                                               mem_size = atoi(size);
+                                       }
                                }
+                       }
 
-                               /* 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;
-                                   }
+                       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 = MM_ERROR_NONE;
+                       }
+               }
+       }
+       else
+       {
+               int file_stat = MM_ERROR_NONE;
 
-                                       /* 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;
+               file_stat = util_exist_file_path(uri);
 
-                                               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);
+               /* if no protocol prefix exist. check file existence and then give file:// as it's prefix */
+               if (file_stat == MM_ERROR_NONE)
+               {
+                       g_snprintf(data->uri,  MM_MAX_URL_LEN, "file://%s", uri);
 
-                                               caps_type = gst_caps_to_string(caps);
+                       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 = MM_ERROR_NONE;
+               }
+               else if (file_stat == MM_ERROR_PLAYER_PERMISSION_DENIED)
+               {
+                       data->uri_type = MM_PLAYER_URI_TYPE_NO_PERMISSION;
+               }
+               else
+               {
+                       debug_error ("invalid uri, could not play..\n");
+                       data->uri_type = MM_PLAYER_URI_TYPE_NONE;
+               }
+       }
 
-                                               if ( g_strrstr( caps_type, "ST12") )
-                                                       player->is_nv12_tiled = TRUE;
+       if (data->uri_type == MM_PLAYER_URI_TYPE_NONE) {
+               ret = MM_ERROR_PLAYER_FILE_NOT_FOUND;
+       } else if (data->uri_type == MM_PLAYER_URI_TYPE_NO_PERMISSION){
+               ret = MM_ERROR_PLAYER_PERMISSION_DENIED;
+       }
 
-                                               /* clean */
-                                               MMPLAYER_FREEIF( caps_type );
-                                               gst_object_unref (src_pad);
+       /* dump parse result */
+       secure_debug_warning("incomming uri : %s\n", uri);
+       debug_log("uri_type : %d, play_mode : %d, mem : 0x%x, mem_size : %d, urgent : %s\n",
+               data->uri_type, data->play_mode, (guint)data->mem, data->mem_size, data->urgent);
 
-                                               g_object_set( G_OBJECT (new_element), "hw-accel", PLAYER_INI()->use_video_hw_accel, NULL);
-                                               g_object_set( G_OBJECT (new_element), "err-conceal", TRUE, NULL);
-                                       }
-                                       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;
+       MMPLAYER_FLEAVE();
 
-                                       /* Link is failed even though a supportable codec is found. */
-                                       __mmplayer_check_not_supported_codec(player, (gchar *)mime);
+       return ret;
+}
 
-                                       MMPLAYER_FREEIF(name_template);
-                                       debug_error("failed to call _close_link\n");
-                                       return FALSE;
-                               }
+gboolean _asm_postmsg(gpointer *data)
+{
+       mm_player_t* player = (mm_player_t*)data;
+       MMMessageParamType msg = {0, };
 
-                               MMPLAYER_FREEIF(name_template);
-                               return TRUE;
-                       }
+       MMPLAYER_FENTER();
+       return_val_if_fail ( player, FALSE );
+       debug_warning("get notified");
 
-                       gst_caps_unref(res);
+       if ((player->cmd == MMPLAYER_COMMAND_DESTROY) ||
+               (player->cmd == MMPLAYER_COMMAND_UNREALIZE))
+       {
+               debug_warning("dispatched");
+               return FALSE;
+       }
 
-                       break;
-               }
-       }
 
-       /* There is no any found codec. */
-       __mmplayer_check_not_supported_codec(player,(gchar *)mime);
+       msg.union_type = MM_MSG_UNION_CODE;
+       msg.code = player->sm.event_src;
 
-       debug_error("failed to autoplug\n");
+#if 0 // should remove
+       if (player->sm.event_src == ASM_EVENT_SOURCE_RESUMABLE_CANCELED)
+       {
+               /* fill the message with state of player */
+               msg.state.current = MMPLAYER_CURRENT_STATE(player);
+               MMPLAYER_POST_MSG( player, MM_MESSAGE_STATE_INTERRUPTED, &msg);
+               player->resumable_cancel_id = 0;
+       }
+       else
+#endif
+       {
+               MMPLAYER_POST_MSG( player, MM_MESSAGE_READY_TO_RESUME, &msg);
+               player->resume_event_id = 0;
+       }
 
-       debug_fleave();
-       
+       debug_warning("dispatched");
        return FALSE;
+}
+
+gboolean _asm_lazy_pause(gpointer *data)
+{
+       mm_player_t* player = (mm_player_t*)data;
+       int ret = MM_ERROR_NONE;
 
+       MMPLAYER_FENTER();
 
-ERROR:
+       return_val_if_fail ( player, FALSE );
 
-       /* release */
-       if ( queue )
-               gst_object_unref( queue );
+       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);
 
-       if ( queue_pad )
-               gst_object_unref( queue_pad );
+       player->sm.by_asm_cb = FALSE; //should be reset here
 
-       if ( element )
-               gst_object_unref ( element );
+       MMPLAYER_FLEAVE();
 
        return FALSE;
 }
 
-
-static
-int __mmplayer_check_not_supported_codec(mm_player_t* player, gchar* mime)
+static gboolean
+__mmplayer_can_do_interrupt(mm_player_t *player)
 {
-       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 );
-
-       if ( MMPLAYER_IS_RTSP_STREAMING(player) )
-               goto DONE;
-
-       /* 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 || !player->pipeline || !player->attrs)
        {
-               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;
-               }
+               debug_warning("not initialized");
+               goto FAILED;
        }
 
-       if( ( g_str_has_prefix(mime, "video") ) ||( g_str_has_prefix(mime, "image") ) )
+       if ((player->sm.exit_cb) || (player->set_mode.pcm_extraction))
        {
-               debug_log("can support codec=%d, vdec_linked=%d, adec_linked=%d\n",
-                       player->can_support_codec, player->videodec_linked, player->audiodec_linked);
+               debug_warning("leave from asm cb right now, %d, %d", player->sm.exit_cb, player->set_mode.pcm_extraction);
+               goto FAILED;
+       }
 
-               /* 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;
-               }
+       /* check if seeking */
+       if (player->doing_seek)
+       {
+               MMMessageParamType msg_param;
+               memset (&msg_param, 0, sizeof(MMMessageParamType));
+               msg_param.code = MM_ERROR_PLAYER_SEEK;
+               player->doing_seek = FALSE;
+               MMPLAYER_POST_MSG(player, MM_MESSAGE_ERROR, &msg_param);
+               goto FAILED;
        }
-       else if ( g_str_has_prefix(mime, "audio") )
+
+       /* check other thread */
+       if (player->cmd_lock)
        {
-               if ( ( player->can_support_codec & FOUND_PLUGIN_AUDIO ) && ( player->audiodec_linked ) )
+               if (!g_mutex_trylock(player->cmd_lock))
                {
-                       debug_log("audio plugin is already linked\n");
+                       debug_warning("locked already, cmd state : %d", player->cmd);
+
+                       /* check application command */
+                       if (player->cmd == MMPLAYER_COMMAND_START || player->cmd == MMPLAYER_COMMAND_RESUME)
+                       {
+                               debug_warning("playing.. should wait cmd lock then, will be interrupted");
+                               g_mutex_lock(player->cmd_lock);
+                               goto INTERRUPT;
+                       }
+                       debug_warning("nothing to do");
+                       goto FAILED;
                }
                else
                {
-                       debug_warning("add AUDIO to missing plugin\n");
-                       player->not_supported_codec |= MISSING_PLUGIN_AUDIO;
+                       debug_warning("can interrupt immediately");
+                       goto INTERRUPT;
                }
        }
 
-DONE:
-       debug_fleave(); 
+FAILED:
+       return FALSE;
 
-       return MM_ERROR_NONE;
+INTERRUPT:
+       return TRUE;
 }
 
-
-static void __mmplayer_pipeline_complete(GstElement *decodebin,  gpointer data) // @
+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*)data;
-
-       debug_fenter();
+       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;
 
-       return_if_fail( player );
+       debug_warning("get notified");
 
-       /* remove fakesink */
-       if ( ! __mmplayer_gst_remove_fakesink( player,
-               &player->pipeline->mainbin[MMPLAYER_M_SRC_FAKESINK]) )
+       if (!__mmplayer_can_do_interrupt(player))
        {
-               /* 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 ) &&
-               ( ! MMPLAYER_IS_RTSP_STREAMING ( player ) ) &&
-               ( player->posted_msg == FALSE ) )
-       {
-               __mmplayer_post_missed_plugin( player );
+               debug_warning("no need to interrupt, so leave");
+               goto EXIT;
        }
-       
-       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-complate" );
-}
 
-static gboolean __mmplayer_configure_audio_callback(mm_player_t* player)
-{
-       debug_fenter();
-
-       return_val_if_fail ( player, FALSE );
+       player->sm.cb_pending = TRUE;
+       debug_warning("asm event src type : %d, command : 0x%x", event_src, command);
 
+       player->sm.by_asm_cb = TRUE;
+       player->sm.event_src = event_src;
 
-       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)
+       /* first, check event source */
+       if(event_src == ASM_EVENT_SOURCE_EARJACK_UNPLUG)
        {
-               debug_warning("audio callback is not supported for video");
-               return FALSE;
+               int stop_by_asm = 0;
+               mm_attrs_get_int_by_name(player->attrs, "sound_stop_when_unplugged", &stop_by_asm);
+               if (!stop_by_asm)
+                       goto DONE;
        }
-
-       if (player->audio_stream_cb)
+       else if (event_src == ASM_EVENT_SOURCE_RESOURCE_CONFLICT)
        {
+               /* can use video overlay simultaneously */
+               /* video resource conflict */
+               if(player->pipeline->videobin)
                {
-                       GstPad *pad = NULL;
+                       if (player->ini.multiple_codec_supported)
+                       {
+                               debug_log("video conflict but, can support multiple video");
+                               result = _mmplayer_pause((MMHandleType)player);
+                               cb_res = ASM_CB_RES_PAUSE;
+                       }
+                       else
+                       {
+                               debug_log("video conflict, can't support multiple video");
+                               result = _mmplayer_unrealize((MMHandleType)player);
+                               cb_res = ASM_CB_RES_STOP;
+                       }
+               }
+               else if (player->pipeline->audiobin)
+               {
+                       debug_log("audio resource conflict");
+                       result = _mmplayer_pause((MMHandleType)player);
+                       if (result != MM_ERROR_NONE)
+                       {
+                               debug_warning("fail to set pause by asm");
+                       }
+                       cb_res = ASM_CB_RES_PAUSE;
+               }
+               goto DONE;
+       }
+#if 0 // should remove
+       else if (event_src == ASM_EVENT_SOURCE_RESUMABLE_CANCELED)
+       {
+               debug_warning("Got msg from asm for resumable canceled.\n");
+               player->sm.antishock = TRUE;
+               player->sm.by_asm_cb = FALSE;
 
-                       pad = gst_element_get_static_pad (player->pipeline->audiobin[MMPLAYER_A_SINK].gst, "sink");
+               player->resumable_cancel_id = g_idle_add((GSourceFunc)_asm_postmsg, (gpointer)player);
+               cb_res = ASM_CB_RES_IGNORE;
+               goto DONE;
+       }
+#endif
+       /* then, check command */
+       switch(command)
+       {
+               case ASM_COMMAND_PLAY:
+                       debug_warning ("Got unexpected asm command (%d)", command);
+                       break;
 
-                       if ( !pad )
+               case ASM_COMMAND_STOP: // notification case
                        {
-                               debug_error("failed to get sink pad from audiosink to probe data\n");
-                               return FALSE;
+                               GstFormat format = GST_FORMAT_TIME;
+                               debug_warning("Got msg from asm to stop");
+
+                               if (!gst_element_query_position(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, &format, &player->last_position)) {
+                                       debug_error("failed to get position");
+                                       player->last_position = 0;
+                               }
+
+                               debug_log ("pos_msec = %"GST_TIME_FORMAT"", GST_TIME_ARGS(player->last_position));
+
+                               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 = FALSE; // reset because no message any more from asm
+                               player->sm.keep_last_pos = TRUE;
                        }
+                       break;
 
-                       player->audio_cb_probe_id = gst_pad_add_buffer_probe (pad,
-                               G_CALLBACK (__mmplayer_audio_stream_probe), player);
+               case ASM_COMMAND_PAUSE:
+                       {
+                               debug_warning("Got msg from asm to Pause");
+                               if(event_src == ASM_EVENT_SOURCE_CALL_START ||
+                                       event_src == ASM_EVENT_SOURCE_NOTIFY_START ||
+                                       event_src == ASM_EVENT_SOURCE_ALARM_START)
+                               {
+                                       if(__mmplayer_ignore_current_external_display_mode(player) == MM_ERROR_NONE)
+                                               debug_log("screen will not display to external display");
+                               }
+                               if(event_src == ASM_EVENT_SOURCE_CALL_START ||
+                                       event_src == ASM_EVENT_SOURCE_ALARM_START ||
+                                       event_src == ASM_EVENT_SOURCE_MEDIA)
+                               {
+                                       if ( ! MMPLAYER_IS_RTSP_STREAMING(player) ) {
+                                               //hold 0.7 second to excute "fadedown mute" effect
+                                               debug_warning ("do fade down->pause->undo fade down");
 
-                       gst_object_unref (pad);
+                                               __mmplayer_do_sound_fadedown(player, MM_PLAYER_FADEOUT_TIME_DEFAULT);
 
-                       pad = NULL;
-              }
+                                               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 {
+                                               /* rtsp should connect again in specific network becasue tcp session can't be kept any more */
+                                               _mmplayer_unrealize((MMHandleType)player);
+                                       }
+                               }
+#ifdef USE_LAZY_PAUSE // if enabled, should consider event id and context when removed
+                               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_warning ("set lazy pause timer (id=[%d], timeout=[%d ms])", player->lazy_pause_event_id, LAZY_PAUSE_TIMEOUT_MSEC);
+                               }
+#endif
+                               else
+                               {
+                                       debug_warning ("pause immediately");
+                                       result = _mmplayer_pause((MMHandleType)player);
+                               }
+                               cb_res = ASM_CB_RES_PAUSE;
+                       }
+                       break;
+
+               case ASM_COMMAND_RESUME:
+                       {
+                               debug_warning("Got msg from asm to Resume. So, application can resume. code (%d) \n", event_src);
+                               player->sm.antishock = TRUE;
+                               player->sm.by_asm_cb = FALSE;
+
+                               //ASM server is single thread daemon. So use g_idle_add() to post resume msg
+                               player->resume_event_id = g_idle_add((GSourceFunc)_asm_postmsg, (gpointer)player);
+                               cb_res = ASM_CB_RES_IGNORE;
+                               goto DONE;
+                       }
+                       break;
+
+               default:
+                       break;
        }
-       else
+
+DONE:
+       if ( !lazy_pause )
        {
-               debug_error("There is no audio callback to configure.\n");
-               return FALSE;
+               player->sm.by_asm_cb = FALSE;
        }
+       player->sm.cb_pending = FALSE;
+       MMPLAYER_CMD_UNLOCK( player );
 
-       debug_fleave(); 
-
-       return TRUE;
+EXIT:
+       debug_warning("dispatched");
+       return cb_res;
 }
 
-static void
-__mmplayer_init_factories(mm_player_t* player) // @
+int
+_mmplayer_create_player(MMHandleType handle) // @
 {
-       debug_fenter();
+       mm_player_t* player = MM_PLAYER_CAST(handle);
 
-       return_if_fail ( player );
+       MMPLAYER_FENTER();
 
-       player->factories = gst_registry_feature_filter(gst_registry_get_default(),
-                                        (GstPluginFeatureFilter)__mmplayer_feature_filter, FALSE, NULL);
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
 
-       player->factories = g_list_sort(player->factories, (GCompareFunc)util_factory_rank_compare);
+       /* 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;
 
-       debug_fleave(); 
-}
+       /* check current state */
+       MMPLAYER_CHECK_STATE_RETURN_IF_FAIL ( player, MMPLAYER_COMMAND_CREATE );
 
-static void
-__mmplayer_release_factories(mm_player_t* player) // @
-{
-       debug_fenter();
+       /* construct attributes */
+       player->attrs = _mmplayer_construct_attribute(handle);
 
-       return_if_fail ( player );
+       if ( !player->attrs )
+       {
+               debug_error("Failed to construct attributes\n");
+               goto ERROR;
+       }
 
-       if (player->factories)
+       /* initialize gstreamer with configured parameter */
+       if ( ! __mmplayer_init_gstreamer(player) )
        {
-               gst_plugin_feature_list_free (player->factories);
-               player->factories = NULL;
+               debug_error("Initializing gstreamer failed\n");
+               goto ERROR;
        }
 
-       debug_fleave();
-}
+       /* initialize factories if not using decodebin */
+       if( player->factories == NULL )
+           __mmplayer_init_factories(player);
 
-static void
-__mmplayer_release_misc(mm_player_t* player)
-{
-       debug_fenter();
+       /* create lock. note that g_tread_init() has already called in gst_init() */
+       player->fsink_lock = g_mutex_new();
+       if ( ! player->fsink_lock )
+       {
+               debug_error("Cannot create mutex for command lock\n");
+               goto ERROR;
+       }
 
-       return_if_fail ( player );
+       /* create repeat mutex */
+       player->repeat_thread_mutex = g_mutex_new();
+       if ( ! player->repeat_thread_mutex )
+       {
+               debug_error("Cannot create repeat mutex\n");
+               goto ERROR;
+       }
 
-       /* free memory related to sound effect */
-       if(player->audio_filter_info.custom_ext_level_for_plugin)
+       /* create repeat cond */
+       player->repeat_thread_cond = g_cond_new();
+       if ( ! player->repeat_thread_cond )
        {
-               free(player->audio_filter_info.custom_ext_level_for_plugin);
+               debug_error("Cannot create repeat cond\n");
+               goto ERROR;
        }
 
-       debug_fleave();
-}
+       /* create repeat thread */
+       player->repeat_thread =
+               g_thread_create (__mmplayer_repeat_thread, (gpointer)player, TRUE, NULL);
+       if ( ! player->repeat_thread )
+       {
+               debug_error("failed to create repeat thread");
+               goto ERROR;
+       }
 
-static GstElement *__mmplayer_element_create_and_link(mm_player_t *player, GstPad* pad, const char* name)
-{
-       GstElement *element = NULL;
-       GstPad *sinkpad;
+       /* create next play mutex */
+       player->next_play_thread_mutex = g_mutex_new();
+       if ( ! player->next_play_thread_mutex )
+       {
+               debug_error("Cannot create next_play mutex\n");
+               goto ERROR;
+       }
 
-       debug_log("creating %s to plug\n", name);
-       
-       element = gst_element_factory_make(name, NULL);
-       if ( ! element )
+       /* create next play cond */
+       player->next_play_thread_cond = g_cond_new();
+       if ( ! player->next_play_thread_cond )
        {
-               debug_error("failed to create queue\n");
-               return NULL;
+               debug_error("Cannot create next_play cond\n");
+               goto ERROR;
        }
 
-       if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state(element, GST_STATE_READY) )
+       /* create next play thread */
+       player->next_play_thread =
+               g_thread_create (__mmplayer_next_play_thread, (gpointer)player, TRUE, NULL);
+       if ( ! player->next_play_thread )
        {
-               debug_error("failed to set state READY to %s\n", name);
-               return NULL;
+               debug_error("failed to create next play thread");
+               goto ERROR;
        }
 
-       if ( ! gst_bin_add(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, element) )
+       if ( MM_ERROR_NONE != _mmplayer_initialize_video_capture(player))
        {
-               debug_error("failed to add %s\n", name);
-               return NULL;
+               debug_error("failed to initialize video capture\n");
+               goto ERROR;
        }
 
-       sinkpad = gst_element_get_static_pad(element, "sink");
+       /* 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 ( GST_PAD_LINK_OK != gst_pad_link(pad, sinkpad) )
+       /* to add active device callback */
+       if ( MM_ERROR_NONE != mm_sound_add_device_information_changed_callback(MM_SOUND_DEVICE_STATE_ACTIVATED_FLAG, __mmplayer_sound_device_info_changed_cb_func, (void*)player))
        {
-               debug_error("failed to link %s\n", name);
-               gst_object_unref (sinkpad);
-               
-               return NULL;
+               debug_error("failed mm_sound_add_device_information_changed_callback \n");
        }
 
-       debug_log("linked %s to pipeline successfully\n", name);
+       if (MMPLAYER_IS_HTTP_PD(player))
+       {
+               player->pd_downloader = NULL;
+               player->pd_file_save_path = NULL;
+       }
 
-       gst_object_unref (sinkpad);
+       player->streaming_type = STREAMING_SERVICE_NONE;
 
-       return element; 
-}
+       /* give default value of audio effect setting */
+       player->sound.volume = MM_VOLUME_FACTOR_DEFAULT;
+       player->playback_rate = DEFAULT_PLAYBACK_RATE;
 
-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;
+       player->play_subtitle = FALSE;
+       player->use_textoverlay = FALSE;
+       player->play_count = 0;
+       player->use_decodebin = TRUE;
+       player->ignore_asyncdone = FALSE;
+       player->use_deinterleave = FALSE;
+       player->pp_rebuilding = FALSE;
+       player->max_audio_channels = 0;
+       player->video_share_api_delta = 0;
+       player->video_share_clock_delta = 0;
+       player->has_closed_caption = FALSE;
 
-       debug_fenter();
+       __mmplayer_post_proc_reset(player);
 
-       return_val_if_fail ( player && 
-               player->pipeline && 
-               player->pipeline->mainbin, 
-               FALSE );
+       if (player->ini.dump_element_keyword[0][0] == '\0')
+       {
+               player->ini.set_dump_element_flag= FALSE;
+       }
+       else
+       {
+               player->ini.set_dump_element_flag = TRUE;
+       }
 
-       mainbin = player->pipeline->mainbin;
+       /* 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_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);
+       return MM_ERROR_NONE;
 
+ERROR:
+       /* free lock */
+       if ( player->fsink_lock )
+               g_mutex_free( player->fsink_lock );
+       player->fsink_lock = NULL;
 
-       factory = gst_element_get_factory(sinkelement);
-       klass = gst_element_factory_get_klass(factory);
+       /* 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 );
 
-       /* check if player can do start continually */
-       MMPLAYER_CHECK_CMD_IF_EXIT(player);
+               g_thread_join( player->repeat_thread );
+               player->repeat_thread = NULL;
 
-       if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state(sinkelement, warmup) )
-       {
-               if (isvideo_decoder)
-                       player->keep_detecting_vcodec = TRUE;
+               g_mutex_free ( player->repeat_thread_mutex );
+               player->repeat_thread_mutex = NULL;
 
-               debug_error("failed to set %d state to %s\n", warmup, GST_ELEMENT_NAME( sinkelement ));
-               goto ERROR;
+               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 );
 
-       /* add to pipeline */
-       if ( ! gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), sinkelement) )
+       if ( player->repeat_thread_cond )
+               g_cond_free ( player->repeat_thread_cond );
+
+       /* free next play thread */
+       if ( player->next_play_thread_cond &&
+                player->next_play_thread_mutex &&
+                player->next_play_thread )
        {
-               debug_error("failed to add %s to mainbin\n", GST_ELEMENT_NAME( sinkelement ));
-               goto ERROR;
-       }
+               player->next_play_thread_exit = TRUE;
+               g_cond_signal( player->next_play_thread_cond );
 
-       debug_log("element klass : %s\n", klass);
+               g_thread_join( player->next_play_thread );
+               player->next_play_thread = NULL;
 
-       /* 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;
+               g_mutex_free ( player->next_play_thread_mutex );
+               player->next_play_thread_mutex = 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;
+               g_cond_free ( player->next_play_thread_cond );
+               player->next_play_thread_cond = NULL;
+       }
+       /* clear next play thread mutex/cond if still alive
+        * this can happen if only thread creating has failed
+        */
+       if ( player->next_play_thread_mutex )
+               g_mutex_free ( player->next_play_thread_mutex );
 
-                       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 ( player->next_play_thread_cond )
+               g_cond_free ( player->next_play_thread_cond );
 
-                       if (parser_name)
-                       {
-                               parser = __mmplayer_element_create_and_link(player, srcpad, parser_name);
+       /* release attributes */
+       _mmplayer_deconstruct_attribute(handle);
 
-                               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);
+       MMPLAYER_FLEAVE();
 
-               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;
-               }
+       return MM_ERROR_PLAYER_INTERNAL;
+}
 
-               /* update srcpad to link with decoder */
-               qsrcpad = gst_element_get_static_pad(queue, "src");
-               srcpad = qsrcpad;
+static gboolean
+__mmplayer_init_gstreamer(mm_player_t* player) // @
+{
+       static gboolean initialized = FALSE;
+       static const int max_argc = 50;
+       gint* argc = NULL;
+       gchar** argv = NULL;
+       gchar** argv2 = NULL;
+       GError *err = NULL;
+       int i = 0;
+       int arg_count = 0;
 
-               if (MMPLAYER_IS_HTTP_LIVE_STREAMING(player))
-                       q_max_size_time = GST_QUEUE_HLS_TIME;
-               else
-                       q_max_size_time = GST_QUEUE_DEFAULT_TIME;
+       if ( initialized )
+       {
+               debug_log("gstreamer already initialized.\n");
+               return TRUE;
+       }
 
-               /* 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;
+       /* alloc */
+       argc = malloc( sizeof(int) );
+       argv = malloc( sizeof(gchar*) * max_argc );
+       argv2 = malloc( sizeof(gchar*) * max_argc );
 
-                       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;
+       if ( !argc || !argv || !argv2)
+               goto ERROR;
 
-                       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);
-               }
+       memset( argv, 0, sizeof(gchar*) * max_argc );
+       memset( argv2, 0, sizeof(gchar*) * max_argc );
 
-               pad = gst_element_get_static_pad(sinkelement, padname);
+       /* add initial */
+       *argc = 1;
+       argv[0] = g_strdup( "mmplayer" );
 
-               if ( ! pad )
+       /* 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 )
                {
-                       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;
-                       }
+                       argv[*argc] = g_strdup( player->ini.gst_param[i] );
+                       (*argc)++;
                }
+       }
 
-               /*  to check the video/audio type set the proper flag*/
-               {
-                       srccaps = gst_pad_get_caps( srcpad );
-                       if ( !srccaps )
-                               goto ERROR;
+       /* we would not do fork for scanning plugins */
+       argv[*argc] = g_strdup("--gst-disable-registry-fork");
+       (*argc)++;
 
-                       str = gst_caps_get_structure( srccaps, 0 );
-                       if ( ! str )
-                               goto ERROR;
+       /* check disable registry scan */
+       if ( player->ini.skip_rescan )
+       {
+               argv[*argc] = g_strdup("--gst-disable-registry-update");
+               (*argc)++;
+       }
 
-                       name = gst_structure_get_name(str);
-                       if ( ! name )
-                               goto ERROR;
-               }
+       /* check disable segtrap */
+       if ( player->ini.disable_segtrap )
+       {
+               argv[*argc] = g_strdup("--gst-disable-segtrap");
+               (*argc)++;
+       }
 
-               /* 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 );
+       debug_log("initializing gstreamer with following parameter\n");
+       debug_log("argc : %d\n", *argc);
+       arg_count = *argc;
 
-                       /* reconstitute supportable codec */
-                       {
-                               if (strstr(name, "video"))
-                               {
-                                       player->can_support_codec ^= FOUND_PLUGIN_VIDEO;
-                               }
+       for ( i = 0; i < arg_count; i++ )
+       {
+               argv2[i] = argv[i];
+               debug_log("argv[%d] : %s\n", i, argv2[i]);
+       }
 
-                               if (strstr(name, "audio"))
-                               {
-                                       player->can_support_codec ^= FOUND_PLUGIN_AUDIO;
-                               }
-                       }
-                       goto ERROR;
+
+       /* initializing gstreamer */
+       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);
                }
 
-               gst_object_unref(GST_OBJECT(pad));
+               goto ERROR;
+       }
+       /* release */
+       for ( i = 0; i < arg_count; i++ )
+       {
+               //debug_log("release - argv[%d] : %s\n", i, argv2[i]);
+               MMPLAYER_FREEIF( argv2[i] );
+       }
 
-               {
-                       if (strstr(name, "video"))
-                       {
-                               player->videodec_linked = 1;
-                               debug_msg("player->videodec_linked set to 1\n");
+       MMPLAYER_FREEIF( argv );
+       MMPLAYER_FREEIF( argv2 );
+       MMPLAYER_FREEIF( argc );
 
-                       }
-                       if (strstr(name, "audio"))
-                       {
-                               player->audiodec_linked = 1;
-                               debug_msg("player->auddiodec_linked set to 1\n");
-                       }
+       /* done */
+       initialized = TRUE;
 
-                       gst_caps_unref(GST_CAPS(srccaps));
-                       srccaps = NULL;
-               }
-       }
+       return TRUE;
 
-       if ( !MMPLAYER_IS_HTTP_PD(player) )
+ERROR:
+
+       /* release */
+       for ( i = 0; i < arg_count; i++ )
        {
-               if( (g_strrstr(klass, "Demux") && !g_strrstr(klass, "Metadata")) || (g_strrstr(klass, "Parser") ) )
-               {
-                       if (MMPLAYER_IS_HTTP_STREAMING(player) || MMPLAYER_IS_HTTP_LIVE_STREAMING(player))
-                       {
-                               GstFormat fmt  = GST_FORMAT_BYTES;
-                               gint64 dur_bytes = 0L;
-                               gchar *file_buffering_path = NULL;
-                               gboolean use_file_buffer = FALSE;
+               debug_log("free[%d] : %s\n", i, argv2[i]);
+               MMPLAYER_FREEIF( argv2[i] );
+       }
 
-                               if ( !mainbin[MMPLAYER_M_S_BUFFER].gst)
-                               {
-                                       debug_log("creating http streaming buffering queue\n");
+       MMPLAYER_FREEIF( argv );
+       MMPLAYER_FREEIF( argv2 );
+       MMPLAYER_FREEIF( argc );
 
-                                       queue = gst_element_factory_make("queue2", "http_streaming_buffer");
-                                       if ( ! queue )
-                                       {
-                                               debug_critical ( "failed to create buffering queue element\n" );
-                                               goto ERROR;
-                                       }
+       return FALSE;
+}
 
-                                       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;
-                                       }
+int
+__mmplayer_destroy_streaming_ext(mm_player_t* player)
+{
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
 
-                                       if ( !gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), queue) )
-                                       {
-                                               debug_error("failed to add buffering queue\n");
-                                               goto ERROR;
-                                       }
+       if (player->pd_downloader)
+       {
+               _mmplayer_unrealize_pd_downloader((MMHandleType)player);
+               MMPLAYER_FREEIF(player->pd_downloader);
+       }
 
-                                       qsinkpad = gst_element_get_static_pad(queue, "sink");
-                                       qsrcpad = gst_element_get_static_pad(queue, "src");
+       if (MMPLAYER_IS_HTTP_PD(player))
+       {
+               _mmplayer_destroy_pd_downloader((MMHandleType)player);
+               MMPLAYER_FREEIF(player->pd_file_save_path);
+       }
 
-                                       if ( GST_PAD_LINK_OK != gst_pad_link(srcpad, qsinkpad) )
-                                       {
-                                               debug_error("failed to link buffering queue\n");
-                                               goto ERROR;
-                                       }
-                                       srcpad = qsrcpad;
+       return MM_ERROR_NONE;
+}
 
+int
+_mmplayer_destroy(MMHandleType handle) // @
+{
+       mm_player_t* player = MM_PLAYER_CAST(handle);
 
-                                       mainbin[MMPLAYER_M_S_BUFFER].id = MMPLAYER_M_S_BUFFER;
-                                       mainbin[MMPLAYER_M_S_BUFFER].gst = queue;
+       MMPLAYER_FENTER();
 
-                                       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");
+       /* check player handle */
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
 
-                                               if (dur_bytes>0)
-                                               {
-                                                       use_file_buffer = MMPLAYER_USE_FILE_FOR_BUFFERING(player);
-                                                       file_buffering_path = g_strdup(PLAYER_INI()->http_file_buffer_path);
-                                               }
-                                       }
+       /* destroy can called at anytime */
+       MMPLAYER_CHECK_STATE_RETURN_IF_FAIL ( player, MMPLAYER_COMMAND_DESTROY );
 
-                                       __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_destroy_streaming_ext(player);
 
-                                       MMPLAYER_FREEIF(file_buffering_path);
-                               }
-                       }
-               }
+       /* 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 it is not decoder or */
-       /* in decoder case any of the video/audio still need to link*/
-       if(!g_strrstr(klass, "Decoder"))
+
+       /* release next play thread */
+       if ( player->next_play_thread_cond &&
+                player->next_play_thread_mutex &&
+                player->next_play_thread )
        {
+               player->next_play_thread_exit = TRUE;
+               g_cond_signal( player->next_play_thread_cond );
 
-               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) );
+               debug_log("waitting for next play thread exit\n");
+               g_thread_join ( player->next_play_thread );
+               g_mutex_free ( player->next_play_thread_mutex );
+               g_cond_free ( player->next_play_thread_cond );
+               debug_log("next play thread released\n");
+       }
 
-                       pad = gst_element_get_static_pad(sinkelement, "sink");
+       _mmplayer_release_video_capture(player);
 
-                       if ( ! pad )
-                       {
-                               debug_error("failed to get pad(sink) from %s. \n",
-                                       GST_ELEMENT_NAME(sinkelement) );
-                               goto ERROR;
-                       }
-               }
+       /* flush any pending asm_cb */
+       if (player->sm.cb_pending)
+       {
+               /* set a flag for make sure asm_cb to be returned immediately */
+               debug_warning("asm cb has pending state");
+               player->sm.exit_cb = TRUE;
 
-               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;
-               }
+               /* make sure to release any pending asm_cb which locked by cmd_lock */
+               MMPLAYER_CMD_UNLOCK(player);
+               sched_yield();
+               MMPLAYER_CMD_LOCK(player);
+       }
 
-               gst_object_unref(GST_OBJECT(pad));
+       /* withdraw asm */
+       if ( MM_ERROR_NONE != _mmplayer_asm_unregister(&player->sm) )
+       {
+               debug_error("failed to deregister asm server\n");
        }
 
-       for(;templlist != NULL; templlist = templlist->next)
+#ifdef USE_LAZY_PAUSE
+       if (player->lazy_pause_event_id)
        {
-               padtemplate = templlist->data;
+               __mmplayer_remove_g_source_from_context(player->context.global_default, player->lazy_pause_event_id);
+               player->lazy_pause_event_id = 0;
+       }
+#endif
 
-               debug_log ("director = [%d], presence = [%d]\n", padtemplate->direction, padtemplate->presence);
+       if (player->resume_event_id)
+       {
+               g_source_remove (player->resume_event_id);
+               player->resume_event_id = 0;
+       }
 
-               if(     padtemplate->direction != GST_PAD_SRC ||
-                       padtemplate->presence == GST_PAD_REQUEST        )
-                       continue;
+       if (player->resumable_cancel_id)
+       {
+               g_source_remove (player->resumable_cancel_id);
+               player->resumable_cancel_id = 0;
+       }
 
-               switch(padtemplate->presence)
-               {
-                       case GST_PAD_ALWAYS:
-                       {
-                               GstPad *srcpad = gst_element_get_static_pad(sinkelement, "src");
-                               GstCaps *caps = gst_pad_get_caps(srcpad);
+       /* release pipeline */
+       if ( MM_ERROR_NONE != __mmplayer_gst_destroy_pipeline( player ) )
+       {
+               debug_error("failed to destory pipeline\n");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
 
-                               /* 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 (player->is_external_subtitle_present && player->subtitle_language_list)
+       {
+         g_list_free (player->subtitle_language_list);
+         player->subtitle_language_list = NULL;
+       }
 
-                               if ( ! __mmplayer_try_to_plug(player, srcpad, caps) )
-                               {
-                                       gst_object_unref(GST_OBJECT(srcpad));
-                                       gst_caps_unref(GST_CAPS(caps));
+       __mmplayer_release_dump_list (player->dump_list);
 
-                                       debug_error("failed to plug something after %s\n", GST_ELEMENT_NAME( sinkelement ));
-                                       goto ERROR;
-                               }
+       /* release miscellaneous information.
+          these info needs to be released after pipeline is destroyed. */
+       __mmplayer_release_misc_post( player );
 
-                               gst_caps_unref(GST_CAPS(caps));
-                               gst_object_unref(GST_OBJECT(srcpad));
+       /* release attributes */
+       _mmplayer_deconstruct_attribute( handle );
 
-                       }
-                       break;
+       /* release factories */
+       __mmplayer_release_factories( player );
 
+       /* release lock */
+       if ( player->fsink_lock )
+               g_mutex_free( player->fsink_lock );
 
-                       case GST_PAD_SOMETIMES:
-                               has_dynamic_pads = TRUE;
-                       break;
+       if ( player->msg_cb_lock )
+               g_mutex_free( player->msg_cb_lock );
 
-                       default:
-                               break;
-               }
-       }
+       MMPLAYER_FLEAVE();
 
-       /* check if player can do start continually */
-       MMPLAYER_CHECK_CMD_IF_EXIT(player);
+       return MM_ERROR_NONE;
+}
 
-       if( has_dynamic_pads )
+int
+__mmplayer_realize_streaming_ext(mm_player_t* player)
+{
+       int ret = MM_ERROR_NONE;
+
+       MMPLAYER_FENTER();
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       if (MMPLAYER_IS_HTTP_PD(player))
        {
-               player->have_dynamic_pad = TRUE;
-               MMPLAYER_SIGNAL_CONNECT ( player, sinkelement, "pad-added",
-                       G_CALLBACK(__mmplayer_add_new_pad), player);
+               gboolean bret = FALSE;
 
-               /* 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 ) )
+               player->pd_downloader = _mmplayer_create_pd_downloader();
+               if ( !player->pd_downloader )
                {
-                       MMPLAYER_SIGNAL_CONNECT( player, sinkelement, "no-more-pads",
-                               G_CALLBACK(__mmplayer_pipeline_complete), player);
+                       debug_error ("Unable to create PD Downloader...");
+                       ret = MM_ERROR_PLAYER_NO_FREE_SPACE;
                }
-       }
 
-       if (has_many_types)
-       {
-               GstPad *pad = NULL;
+               bret = _mmplayer_realize_pd_downloader((MMHandleType)player, player->profile.uri, player->pd_file_save_path, player->pipeline->mainbin[MMPLAYER_M_SRC].gst);
 
-               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));
+               if (FALSE == bret)
+               {
+                       debug_error ("Unable to create PD Downloader...");
+                       ret = MM_ERROR_PLAYER_NOT_INITIALIZED;
+               }
        }
 
+       MMPLAYER_FLEAVE();
+       return ret;
+}
 
-       /* check if player can do start continually */
-       MMPLAYER_CHECK_CMD_IF_EXIT(player);
+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;
 
-       if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state(sinkelement, GST_STATE_PAUSED) )
+       MMPLAYER_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("failed to set state PAUSED to %s\n", GST_ELEMENT_NAME( sinkelement ));
-               goto ERROR;
+               debug_error("fail to get attributes.\n");
+               return MM_ERROR_PLAYER_INTERNAL;
        }
 
-       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;
-               }
+       mm_attrs_get_int_by_name(attrs, "sound_application_pid", &application_pid );
+       player->sm.pid = application_pid;
 
-               queue = NULL;
+       mm_attrs_get_string_by_name(attrs, "profile_uri", &uri);
+       mm_attrs_get_data_by_name(attrs, "profile_user_param", &param);
 
-               gst_object_unref (GST_OBJECT(qsrcpad));
-               qsrcpad = NULL;
-       }
+       ret = __mmfplayer_parse_profile((const char*)uri, param, &player->profile);
 
-       if ( parser )
+       if (ret != MM_ERROR_NONE)
        {
-               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;
-               }
+               debug_error("failed to parse profile\n");
+               return ret;
+       }
 
-               parser = NULL;
+       /* 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;
+       }
 
-               gst_object_unref (GST_OBJECT(pssrcpad));
-               pssrcpad = NULL;
+       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;
        }
 
-       debug_fleave();
+       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;
 
-       return TRUE;
+       player->needed_v_parser = FALSE;
+       player->smooth_streaming = FALSE;
+       player->videodec_linked  = 0;
+       player->videosink_linked = 0;
+       player->audiodec_linked  = 0;
+       player->audiosink_linked = 0;
+       player->textsink_linked = 0;
+       player->is_external_subtitle_present = FALSE;
+       /* set the subtitle ON default */
+       player->is_subtitle_off = FALSE;
 
-ERROR:
+       /* registry should be updated for downloadable codec */
+       mm_attrs_get_int_by_name(attrs, "profile_update_registry", &update_registry);
 
-       if ( queue )
+       if ( update_registry )
        {
-               gst_object_unref(GST_OBJECT(qsrcpad));
+               debug_log("updating registry...\n");
+               gst_update_registry();
 
-               /* 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.
-                */
+               /* then we have to rebuild factories */
+               __mmplayer_release_factories( player );
+               __mmplayer_init_factories(player);
+       }
 
-               gst_bin_remove (GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), queue);
-               //gst_object_unref( queue );
+       /* realize pipeline */
+       ret = __gst_realize( player );
+       if ( ret != MM_ERROR_NONE )
+       {
+               debug_error("fail to realize the player.\n");
+       }
+       else
+       {
+               ret = __mmplayer_realize_streaming_ext(player);
        }
 
-       if ( srccaps )
-               gst_caps_unref(GST_CAPS(srccaps));
+       MMPLAYER_FLEAVE();
 
-    return FALSE;
+       return ret;
 }
 
-static gboolean __mmplayer_feature_filter(GstPluginFeature *feature, gpointer data) // @
+int
+__mmplayer_unrealize_streaming_ext(mm_player_t *player)
 {
-       const gchar *klass;
-       //const gchar *name;
+       MMPLAYER_FENTER();
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
 
-       /* 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));
+       /* destroy can called at anytime */
+       if (player->pd_downloader && MMPLAYER_IS_HTTP_PD(player))
+       {
+               _mmplayer_unrealize_pd_downloader ((MMHandleType)player);
+               MMPLAYER_FREEIF(player->pd_downloader);
+       }
 
-       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;
+       MMPLAYER_FLEAVE();
+       return MM_ERROR_NONE;
 }
 
-
-static void    __mmplayer_add_new_caps(GstPad* pad, GParamSpec* unused, gpointer data)
+int
+_mmplayer_unrealize(MMHandleType hplayer)
 {
-       mm_player_t* player = (mm_player_t*) data;
-       GstCaps *caps = NULL;
-       GstStructure *str = NULL;
-       const char *name;
+       mm_player_t* player = (mm_player_t*)hplayer;
+       int ret = MM_ERROR_NONE;
 
-       debug_fenter();
+       MMPLAYER_FENTER();
 
-       return_if_fail ( pad )
-       return_if_fail ( unused )
-       return_if_fail ( data )
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED )
 
-       caps = gst_pad_get_caps(pad);
-       if ( !caps )
-               return;
-       
-       str = gst_caps_get_structure(caps, 0);
-       if ( !str )
-               return;
+       /* check current state */
+       MMPLAYER_CHECK_STATE_RETURN_IF_FAIL( player, MMPLAYER_COMMAND_UNREALIZE );
 
-       name = gst_structure_get_name(str);
-       if ( !name )
-               return;
-       debug_log("name=%s\n", name);
+       __mmplayer_unrealize_streaming_ext(player);
 
-       if ( ! __mmplayer_try_to_plug(player, pad, caps) )
+       /* unrealize pipeline */
+       ret = __gst_unrealize( player );
+
+       /* set asm stop if success */
+       if (MM_ERROR_NONE == ret)
        {
-               debug_error("failed to autoplug for type (%s)\n", name);
-               gst_caps_unref(caps);
-               return;
+               if (player->sm.state != ASM_STATE_STOP)
+               {
+                       /* NOTE : Stop asm after pipeline unrealize. Keep this sequence. */
+                       ret = _mmplayer_asm_set_state(hplayer, ASM_STATE_STOP, FALSE);
+                       if ( ret )
+                       {
+                               debug_error("failed to set asm state to STOP");
+                               return ret;
+                       }
+               }
+       }
+       else
+       {
+               debug_error("failed and don't change asm state to stop");
        }
 
-       gst_caps_unref(caps);
-
-       __mmplayer_pipeline_complete( NULL, (gpointer)player );
-
-       debug_fleave(); 
+       MMPLAYER_FLEAVE();
 
-       return;
+       return ret;
 }
 
-static void __mmplayer_set_unlinked_mime_type(mm_player_t* player, GstCaps *caps)
+int
+_mmplayer_set_message_callback(MMHandleType hplayer, MMMessageCallback callback, gpointer user_param) // @
 {
-       GstStructure *str;
-       gint version = 0;
-       const char *stream_type;
-       gchar *version_field = NULL;
-
-       debug_fenter();
+       mm_player_t* player = (mm_player_t*)hplayer;
 
-       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;
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
+       return __gst_set_message_callback(player, callback, user_param);
+}
 
-       /* 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;
-               }
+int
+_mmplayer_get_state(MMHandleType hplayer, int* state) // @
+{
+       mm_player_t *player = (mm_player_t*)hplayer;
 
-               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;
-               }
+       return_val_if_fail(state, MM_ERROR_INVALID_ARGUMENT);
 
-               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);
-               }
-       }
+       *state = MMPLAYER_CURRENT_STATE(player);
 
-       debug_fleave();
+       return MM_ERROR_NONE;
 }
 
-static void __mmplayer_add_new_pad(GstElement *element, GstPad *pad, gpointer data)
+
+int
+_mmplayer_set_volume(MMHandleType hplayer, MMPlayerVolumeType volume) // @
 {
-       mm_player_t* player = (mm_player_t*) data;
-       GstCaps *caps = NULL;
-       GstStructure *str = NULL;
-       const char *name;
+       mm_player_t* player = (mm_player_t*) hplayer;
+       GstElement* vol_element = NULL;
+       int i = 0;
 
-       debug_fenter();
+       MMPLAYER_FENTER();
 
-       return_if_fail ( player );
-       return_if_fail ( pad );
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
 
-       GST_OBJECT_LOCK (pad);
-       if ((caps = GST_PAD_CAPS(pad)))
-               gst_caps_ref(caps);
-       GST_OBJECT_UNLOCK (pad);
+       debug_log("volume [L]=%f:[R]=%f\n",
+               volume.level[MM_VOLUME_CHANNEL_LEFT], volume.level[MM_VOLUME_CHANNEL_RIGHT]);
 
-       if ( NULL == caps )
+       /* invalid factor range or not */
+       for ( i = 0; i < MM_VOLUME_CHANNEL_NUM; i++ )
        {
-               caps = gst_pad_get_caps(pad);
-               if ( !caps ) return;
+               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;
+               }
        }
 
-       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;
+       /* not support to set other value into each channel */
+       if ((volume.level[MM_VOLUME_CHANNEL_LEFT] != volume.level[MM_VOLUME_CHANNEL_RIGHT]))
+               return MM_ERROR_INVALID_ARGUMENT;
 
-       player->num_dynamic_pad++;
-       debug_log("stream count inc : %d\n", player->num_dynamic_pad);
+       /* Save volume to handle. Currently the first array element will be saved. */
+       player->sound.volume = volume.level[MM_VOLUME_CHANNEL_LEFT];
 
-       if (__mmplayer_is_amr_type(name))
-       {
-               /* store type string */
-               MMPLAYER_FREEIF(player->type);
-               player->type = gst_caps_to_string(caps);
-               player->bypass_sound_effect = FALSE;
-               if ( (PLAYER_INI()->use_audio_filter_preset || PLAYER_INI()->use_audio_filter_custom) )
-               {
-                       if ( player->audio_filter_info.filter_type == MM_AUDIO_FILTER_TYPE_PRESET )
-                       {
-                               if (!_mmplayer_sound_filter_preset_apply(player, player->audio_filter_info.preset))
-                               {
-                                       debug_msg("apply sound effect(preset:%d) setting success\n",player->audio_filter_info.preset);
-                               }
-                       }
-                       else if ( player->audio_filter_info.filter_type == MM_AUDIO_FILTER_TYPE_CUSTOM )
-                       {
-                               if (!_mmplayer_sound_filter_custom_apply(player))
-                               {
-                                       debug_msg("apply sound effect(custom) setting success\n");
-                               }
-                       }
-               }
-       }
-       /* 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.
-         */
-       else 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\n");
-               }
-               else
-               {
-                       /* Otherwise, we assume that this stream is subtile. */
-                       debug_log(" application mime type pad is closed. \n");
-                       return;
-               }
-       }
-       else if (g_strrstr(name, "video"))
+       /* check pipeline handle */
+       if ( ! player->pipeline || ! player->pipeline->audiobin )
        {
-               int 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\n");
-                       return;
-               }
+               debug_log("audiobin is not created yet\n");
+               debug_log("but, current stored volume will be set when it's created.\n");
 
-               player->v_stream_caps = gst_caps_copy(caps); //if needed, video caps is required when videobin is created
+               /* 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;
        }
 
-       if ( ! __mmplayer_try_to_plug(player, pad, caps) )
+       /* setting volume to volume element */
+       vol_element = player->pipeline->audiobin[MMPLAYER_A_VOL].gst;
+
+       if ( vol_element )
        {
-               debug_error("failed to autoplug for type (%s)\n", name);
-               
-               __mmplayer_set_unlinked_mime_type(player, caps);                
+               debug_log("volume is set [%f]\n", player->sound.volume);
+               g_object_set(vol_element, "volume", player->sound.volume, NULL);
        }
 
-       gst_caps_unref(caps);
-
-       debug_fleave();
+       MMPLAYER_FLEAVE();
 
-       return;
+       return MM_ERROR_NONE;
 }
 
-/* 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)
+_mmplayer_get_volume(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;
+       int i = 0;
 
-       debug_fenter();
+       MMPLAYER_FENTER();
 
-       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
-       return_val_if_fail( player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED )
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail( volume, MM_ERROR_INVALID_ARGUMENT );
 
-       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]);
+       /* returning stored volume */
+       for (i = 0; i < MM_VOLUME_CHANNEL_NUM; i++)
+               volume->level[i] = player->sound.volume;
 
-       isMidi = ( player->profile.play_mode == MM_PLAYER_MODE_MIDI ) ? TRUE : FALSE;
+       MMPLAYER_FLEAVE();
 
-       if ( isMidi )
-               vol_max = 1000;
-       else
-               vol_max = 100;
+       return MM_ERROR_NONE;
+}
 
-       /* is it proper volume level? */
-       for (i = 0; i < MM_VOLUME_CHANNEL_NUM; ++i)
+
+
+int
+_mmplayer_set_mute(MMHandleType hplayer, int mute) // @
+{
+       mm_player_t* player = (mm_player_t*) hplayer;
+       GstElement* vol_element = NULL;
+
+       MMPLAYER_FENTER();
+
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       /* mute value shoud 0 or 1 */
+       if ( mute != 0 && mute != 1 )
        {
-               if (volume.level[i] < 0 || volume.level[i] > vol_max) {
-                       debug_log("Invalid Volume level!!!! \n");
-                       return MM_ERROR_INVALID_ARGUMENT;
-               }
+               debug_error("bad mute value\n");
+
+               /* FIXIT : definitly, we need _BAD_PARAM error code */
+               return MM_ERROR_INVALID_ARGUMENT;
        }
 
-       if ( isMidi )
+       player->sound.mute = mute;
+
+       /* just hold mute value if pipeline is not ready */
+       if ( !player->pipeline || !player->pipeline->audiobin )
        {
-               if ( player->pipeline->mainbin )
-               {
-                       GstElement *midi_element = player->pipeline->mainbin[MMPLAYER_M_DEMUX].gst;
+               debug_log("pipeline is not ready. holding mute value\n");
+               return MM_ERROR_NONE;
+       }
 
-                       if ( midi_element && ( strstr(GST_ELEMENT_NAME(midi_element), "midiparse")) )
-                       {
-                               debug_log("setting volume (%d) level to midi plugin\n", volume.level[0]);
+       vol_element = player->pipeline->audiobin[MMPLAYER_A_SINK].gst;
 
-                               g_object_set(midi_element, "volume", volume.level[0], NULL);
-                       }
-               }
+       /* NOTE : volume will only created when the bt is enabled */
+       if ( vol_element )
+       {
+               debug_log("mute : %d\n", mute);
+               g_object_set(vol_element, "mute", mute, NULL);
        }
        else
        {
-               if ( player->pipeline->audiobin )
-               {
-                       GstElement *sink_element = player->pipeline->audiobin[MMPLAYER_A_SINK].gst;
+               debug_log("volume elemnet is not created. using volume in audiosink\n");
+       }
 
-                       /* Set to Avsysaudiosink element */
-                       if ( sink_element )
-                       {
-                               gint vol_value = 0;
-                               gboolean mute = FALSE;
-                               vol_value = volume.level[0];
+       MMPLAYER_FLEAVE();
 
-                               g_object_set(G_OBJECT(sink_element), "tuningvolume", vol_value, NULL);
+       return MM_ERROR_NONE;
+}
 
-                               mute = (vol_value == 0)? TRUE:FALSE;
+int
+_mmplayer_get_mute(MMHandleType hplayer, int* pmute) // @
+{
+       mm_player_t* player = (mm_player_t*) hplayer;
 
-                               g_object_set(G_OBJECT(sink_element), "mute", mute, NULL);
-                       }
+       MMPLAYER_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;
        }
 
-       debug_fleave();
+       *pmute = player->sound.mute;
 
-       return error;
+       MMPLAYER_FLEAVE();
+
+       return MM_ERROR_NONE;
 }
 
-gboolean
-__mmplayer_dump_pipeline_state( mm_player_t* player )
+int
+_mmplayer_set_videostream_cb(MMHandleType hplayer, mm_player_video_stream_callback callback, void *user_param) // @
 {
-       GstIterator*iter = NULL;
-       gboolean done = FALSE;
+       mm_player_t* player = (mm_player_t*) hplayer;
 
-       GstElement *item = NULL;
-       GstElementFactory *factory = NULL;
+       MMPLAYER_FENTER();
 
-       GstState state = GST_STATE_VOID_PENDING;
-       GstState pending = GST_STATE_VOID_PENDING;
-       GstClockTime time = 200*GST_MSECOND;
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
 
-       debug_fenter();
+       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);
 
-       return_val_if_fail ( player &&
-               player->pipeline &&
-               player->pipeline->mainbin,
-               FALSE );
+       MMPLAYER_FLEAVE();
 
+       return MM_ERROR_NONE;
+}
 
-       iter = gst_bin_iterate_recurse(GST_BIN(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst) );
+int
+_mmplayer_set_audiostream_cb(MMHandleType hplayer, mm_player_audio_stream_callback callback, void *user_param) // @
+{
+       mm_player_t* player = (mm_player_t*) hplayer;
 
-       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);
+       MMPLAYER_FENTER();
 
-                               factory = gst_element_get_factory (item) ;
-                                debug_log("%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));
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
 
+       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);
 
-                                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;
-                        }
-               }
-       }
+       MMPLAYER_FLEAVE();
 
-       item = GST_ELEMENT(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst);
+       return MM_ERROR_NONE;
+}
 
-       gst_element_get_state(GST_ELEMENT (item),&state, &pending,time);
+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;
 
-       factory = gst_element_get_factory (item) ;
+       MMPLAYER_FENTER();
+
+       return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail(callback, MM_ERROR_INVALID_ARGUMENT);
 
-       debug_log("%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) );
+       player->need_data_cb = callback;
+       player->buffer_cb_user_param = user_param;
 
-       if ( iter )
-               gst_iterator_free (iter);
+       debug_log("buffer need dataHandle value is %p : %p\n", player, player->need_data_cb);
 
-       debug_fleave();
+       MMPLAYER_FLEAVE();
 
-       return FALSE;
+       return MM_ERROR_NONE;
 }
 
-
-gboolean
-__mmplayer_check_subtitle( mm_player_t* player )
+int
+_mmplayer_set_buffer_enough_data_cb(MMHandleType hplayer, mm_player_buffer_enough_data_callback callback, void *user_param) // @
 {
-       MMHandleType attrs = 0;
-       char *subtitle_uri = NULL;
-
-       debug_fenter();
+       mm_player_t* player = (mm_player_t*) hplayer;
 
-       return_val_if_fail( player, FALSE );
+       MMPLAYER_FENTER();
 
-       /* get subtitle attribute */
-       attrs = MMPLAYER_GET_ATTRS(player);
-       if ( !attrs )
-               return FALSE;
+       return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail(callback, MM_ERROR_INVALID_ARGUMENT);
 
-       mm_attrs_get_string_by_name(attrs, "subtitle_uri", &subtitle_uri);
-       if ( !subtitle_uri || !strlen(subtitle_uri))
-               return FALSE;
+       player->enough_data_cb = callback;
+       player->buffer_cb_user_param = user_param;
 
-       debug_log ("subtite uri is %s[%d]\n", subtitle_uri, strlen(subtitle_uri));
+       debug_log("buffer enough data cb Handle value is %p : %p\n", player, player->enough_data_cb);
 
-       debug_fleave();
+       MMPLAYER_FLEAVE();
 
-       return TRUE;
+       return MM_ERROR_NONE;
 }
 
-static gboolean
-__mmplayer_can_extract_pcm( mm_player_t* player )
+int
+_mmplayer_set_buffer_seek_data_cb(MMHandleType hplayer, mm_player_buffer_seek_data_callback callback, void *user_param) // @
 {
-       MMHandleType attrs = 0;
-       gboolean is_drm = FALSE;
-       gboolean sound_extraction = FALSE;
+       mm_player_t* player = (mm_player_t*) hplayer;
 
-       debug_fenter();
+       MMPLAYER_FENTER();
 
-       return_val_if_fail ( player, FALSE );
+       return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail(callback, MM_ERROR_INVALID_ARGUMENT);
 
-       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);
+       player->seek_data_cb = callback;
+       player->buffer_cb_user_param = user_param;
 
-       /* get sound_extraction property */
-       mm_attrs_get_int_by_name(attrs, "pcm_extraction", &sound_extraction);
+       debug_log("buffer seek data cb Handle value is %p : %p\n", player, player->seek_data_cb);
 
-       if ( ! sound_extraction || is_drm )
+       MMPLAYER_FLEAVE();
+
+       return MM_ERROR_NONE;
+}
+
+int
+__mmplayer_start_streaming_ext(mm_player_t *player)
+{
+       gint ret = MM_ERROR_NONE;
+
+       MMPLAYER_FENTER();
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       if (MMPLAYER_IS_HTTP_PD(player))
        {
-               debug_log("pcm extraction param.. is drm = %d, extraction mode = %d", is_drm, sound_extraction);
-               return FALSE;
-       }
+               if ( !player->pd_downloader )
+               {
+                       ret = __mmplayer_realize_streaming_ext(player);
 
-       debug_fleave();
+                       if ( ret != MM_ERROR_NONE)
+                       {
+                               debug_error ("failed to realize streaming ext\n");
+                               return ret;
+                       }
+               }
 
-       return TRUE;
+               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;
+               }
+       }
+
+       MMPLAYER_FLEAVE();
+       return ret;
 }
 
-static gboolean
-__mmplayer_handle_gst_error ( mm_player_t* player, GstMessage * message, GError* error )
+int
+_mmplayer_start(MMHandleType hplayer) // @
 {
-       MMMessageParamType msg_param;
-       gchar *msg_src_element;
-
-       debug_fenter();
+       mm_player_t* player = (mm_player_t*) hplayer;
+       gint ret = MM_ERROR_NONE;
 
-       return_val_if_fail( player, FALSE );
-       return_val_if_fail( error, FALSE );
+       MMPLAYER_FENTER();
 
-       /* NOTE : do somthing necessary inside of __gst_handle_XXX_error. not here */
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
 
-       memset (&msg_param, 0, sizeof(MMMessageParamType));
+       /* check current state */
+       MMPLAYER_CHECK_STATE_RETURN_IF_FAIL( player, MMPLAYER_COMMAND_START );
 
-       if ( error->domain == GST_CORE_ERROR )
+       ret = _mmplayer_asm_set_state(hplayer, ASM_STATE_PLAYING, TRUE);
+       if ( ret != MM_ERROR_NONE )
        {
-               msg_param.code = __gst_handle_core_error( player, error->code );
+               debug_error("failed to set asm state to PLAYING\n");
+               return ret;
        }
-       else if ( error->domain == GST_LIBRARY_ERROR )
+
+       /* NOTE : we should check and create pipeline again if not created as we destroy
+        * whole pipeline when stopping in streamming playback
+        */
+       if ( ! player->pipeline )
        {
-               msg_param.code = __gst_handle_library_error( player, error->code );
-       }
-       else if ( error->domain == GST_RESOURCE_ERROR )
+               ret = __gst_realize( player );
+               if ( MM_ERROR_NONE != ret )
+               {
+                       debug_error("failed to realize before starting. only in streamming\n");
+                       /* unlock */
+                       return ret;
+               }
+       }
+
+       ret = __mmplayer_start_streaming_ext(player);
+       if ( ret != MM_ERROR_NONE )
        {
-               msg_param.code = __gst_handle_resource_error( player, error->code );
+               debug_error("failed to start streaming ext \n");
        }
-       else if ( error->domain == GST_STREAM_ERROR )
+
+       /* start pipeline */
+       ret = __gst_start( player );
+       if ( ret != MM_ERROR_NONE )
        {
-               msg_param.code = __gst_handle_stream_error( player, error, message );
+               debug_error("failed to start player.\n");
        }
-       else
+
+       MMPLAYER_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_handle_missed_plugin(mm_player_t* player)
+{
+       MMMessageParamType msg_param;
+       memset (&msg_param, 0, sizeof(MMMessageParamType));
+       gboolean post_msg_direct = FALSE;
+
+       MMPLAYER_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 )
        {
-               debug_warning("This error domain is not defined.\n");
+               msg_param.code = MM_ERROR_PLAYER_CODEC_NOT_FOUND;
+               msg_param.data = g_strdup_printf("%s", player->unlinked_demuxer_mime);
 
-               /* we treat system error as an internal error */
-               msg_param.code = MM_ERROR_PLAYER_INVALID_STREAM;
+               MMPLAYER_POST_MSG( player, MM_MESSAGE_ERROR, &msg_param );
+               MMPLAYER_FREEIF(msg_param.data);
+
+               return MM_ERROR_NONE;
        }
 
-       if ( message->src )
+       if (player->not_supported_codec)
        {
-               msg_src_element = GST_ELEMENT_NAME( GST_ELEMENT_CAST( message->src ) );
+               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;
+               }
 
-               msg_param.data = (void *) error->message;
+               if ( post_msg_direct )
+               {
+                       MMMessageParamType msg_param;
+                       memset (&msg_param, 0, sizeof(MMMessageParamType));
 
-               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);
+                       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);
+               }
        }
 
-       if (MMPLAYER_IS_HTTP_LIVE_STREAMING(player))
+       MMPLAYER_FLEAVE();
+
+       return MM_ERROR_NONE;
+}
+
+static void __mmplayer_check_pipeline(mm_player_t* player)
+{
+       GstState element_state = GST_STATE_VOID_PENDING;
+       GstState element_pending_state = GST_STATE_VOID_PENDING;
+       gint timeout = 0;
+       int ret = MM_ERROR_NONE;
+
+       if (player->pp_rebuilding)
        {
-               __mm_player_ahs_stop (player->ahs_player);
+               debug_warning("pipeline is under construction.\n");
+
+               MMPLAYER_PLAYBACK_LOCK(player);
+               MMPLAYER_PLAYBACK_UNLOCK(player);
+
+               timeout = MMPLAYER_STATE_CHANGE_TIMEOUT ( player );
+
+               /* wait for state transition */
+               ret = gst_element_get_state( player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, &element_state, &element_pending_state, timeout * GST_SECOND );
+
+               if ( ret == GST_STATE_CHANGE_FAILURE )
+               {
+                       debug_error("failed to change pipeline state within %d sec\n", timeout );
+               }
        }
+}
 
-       /* post error to application */
-       if ( ! player->posted_msg )
+/* 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;
+
+       MMPLAYER_FENTER();
+
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       /* check current state */
+       MMPLAYER_CHECK_STATE_RETURN_IF_FAIL( player, MMPLAYER_COMMAND_STOP );
+
+       /* check pipline building state */
+       __mmplayer_check_pipeline(player);
+
+       /* NOTE : application should not wait for EOS after calling STOP */
+       __mmplayer_cancel_eos_timer( player );
+
+       __mmplayer_unrealize_streaming_ext(player);
+
+       /* reset */
+       player->doing_seek = FALSE;
+
+       /* stop pipeline */
+       ret = __gst_stop( player );
+
+       if ( ret != MM_ERROR_NONE )
+       {
+               debug_error("failed to stop player.\n");
+       }
+
+       MMPLAYER_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;
+
+       MMPLAYER_FENTER();
+
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       /* check current state */
+       MMPLAYER_CHECK_STATE_RETURN_IF_FAIL( player, MMPLAYER_COMMAND_PAUSE );
+
+       /* check pipline building state */
+       __mmplayer_check_pipeline(player);
+
+       switch (MMPLAYER_CURRENT_STATE(player))
        {
-               if (msg_param.code == MM_MESSAGE_DRM_NOT_AUTHORIZED)
+               case MM_PLAYER_STATE_READY:
                {
-                       MMPLAYER_POST_MSG( player, MM_MESSAGE_DRM_NOT_AUTHORIZED, NULL );
+                       /* 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 working mode : %s", (async ? "async" : "sync"));
                }
-               else
+               break;
+
+               case MM_PLAYER_STATE_PLAYING:
                {
-                       MMPLAYER_POST_MSG( player, MM_MESSAGE_ERROR, &msg_param );
-               }
+                       /* NOTE : store current point to overcome some bad operation
+                       * ( returning zero when getting current position in paused state) of some
+                       * elements
+                       */
+                       if ( !gst_element_query_position(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, &fmt, &pos_msec))
+                               debug_warning("getting current position failed in paused\n");
 
-               /* don't post more if one was sent already */
-               player->posted_msg = TRUE;
+                       player->last_position = pos_msec;
+               }
+               break;
        }
-       else
+
+       /* pause pipeline */
+       ret = __gst_pause( player, async );
+
+       if ( ret != MM_ERROR_NONE )
        {
-               debug_log("skip error post because it's sent already.\n");
+               debug_error("failed to pause player. ret : 0x%x\n", ret);
        }
 
-       debug_fleave();
+       MMPLAYER_FLEAVE();
 
-       return TRUE;
+       return ret;
 }
 
-static gboolean
-__mmplayer_handle_streaming_error  ( mm_player_t* player, GstMessage * message )
+int
+_mmplayer_resume(MMHandleType hplayer)
 {
-       debug_log("\n");
-       MMMessageParamType msg_param;
-       gchar *msg_src_element = NULL;
-       GstStructure *s = NULL;
-       guint error_id = 0;
-       gchar *error_string = NULL;
+       mm_player_t* player = (mm_player_t*)hplayer;
+       int ret = MM_ERROR_NONE;
+       gboolean async = FALSE;
 
-       debug_fenter();
+       MMPLAYER_FENTER();
 
-       return_val_if_fail ( player, FALSE );
-       return_val_if_fail ( message, FALSE );
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
 
-       s = malloc( sizeof(GstStructure) );
-       memcpy ( s, gst_message_get_structure ( message ), sizeof(GstStructure));
+       ret = _mmplayer_asm_set_state(hplayer, ASM_STATE_PLAYING, TRUE);
+       if ( ret )
+       {
+               debug_error("failed to set asm state to PLAYING\n");
+               return ret;
+       }
 
-       if ( !gst_structure_get_uint (s, "error_id", &error_id) )
-               error_id = MMPLAYER_STREAMING_ERROR_NONE;
+       /* check current state */
+       MMPLAYER_CHECK_STATE_RETURN_IF_FAIL( player, MMPLAYER_COMMAND_RESUME );
 
-       switch ( error_id )
+       /* resume pipeline */
+       ret = __gst_resume( player, async );
+
+       if ( ret != MM_ERROR_NONE )
        {
-               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;
+               debug_error("failed to resume player.\n");
+       }
+
+       MMPLAYER_FLEAVE();
+
+       return ret;
+}
+
+int
+__mmplayer_set_play_count(mm_player_t* player, gint count)
+{
+       MMHandleType attrs = 0;
+
+       MMPLAYER_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");
+
+       MMPLAYER_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;
+
+       MMPLAYER_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,
+                                       player->playback_rate,
+                                       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);
+
+       MMPLAYER_FLEAVE();
+
+       return  MM_ERROR_NONE;
+}
+
+static int
+__mmplayer_set_pcm_extraction(mm_player_t* player)
+{
+       gint64 start_nsec = 0;
+       gint64 end_nsec = 0;
+       gint64 dur_nsec = 0;
+       gint64 dur_msec = 0;
+       GstFormat fmt = GST_FORMAT_TIME;
+       int required_start = 0;
+       int required_end = 0;
+       int ret = 0;
+
+       MMPLAYER_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);
+
+       MMPLAYER_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;
+
+       MMPLAYER_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;
+       }
+
+       MMPLAYER_FENTER();
+
+       return MM_ERROR_NONE;
+}
+
+int
+_mmplayer_set_playspeed(MMHandleType hplayer, float 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;
+       MMPLAYER_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 %0.1f\n", rate);
+
+       MMPLAYER_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;
+
+       MMPLAYER_FENTER();
+
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       ret = __gst_set_position ( player, format, (unsigned long)position, FALSE );
+
+       MMPLAYER_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;
+
+       MMPLAYER_FENTER();
+
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       ret = __gst_adjust_subtitle_position(player, format, position);
+
+       MMPLAYER_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;
+       }
+
+       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;
+}
+
+/* try to use ALP decoder first instead of selected decoder */
+static gboolean
+__mmplayer_is_omx_decoder_type (mm_player_t* player)
+{
+#define MIN_THRESHOLD_SIZE  320 * 1024 // 320K
+       gboolean ret = FALSE;
+       gchar* path = NULL;
+       guint64 data_size = 0;
+       struct stat sb;
+
+       return_val_if_fail (player, FALSE);
+
+       /* consider mp3 audio only */
+       if ((!MMPLAYER_IS_STREAMING(player)) &&
+               (__mmplayer_is_only_mp3_type(player->type)))
+       {
+               mm_attrs_get_string_by_name(player->attrs, "profile_uri", &path);
+
+               if (stat(path, &sb) == 0)
+               {
+                       data_size = (guint64)sb.st_size;
+
+                       if (data_size > MIN_THRESHOLD_SIZE)
+                       {
+                               ret = TRUE;
+                       }
+               }
+       }
+
+       debug_log ("need to select omx_decoder ? [%s]\n", (ret)?"YES":"NO");
+       return ret;
+}
+
+static void
+__mmplayer_set_audio_attrs (mm_player_t* player, GstCaps* caps)
+{
+       GstStructure* caps_structure = NULL;
+       gint samplerate = 0;
+       gint channels = 0;
+
+       MMPLAYER_FENTER();
+       return_if_fail (player && caps);
+
+       caps_structure = gst_caps_get_structure(caps, 0);
+
+       /* set stream information */
+       gst_structure_get_int (caps_structure, "rate", &samplerate);
+       mm_attrs_set_int_by_name (player->attrs, "content_audio_samplerate", samplerate);
+
+       gst_structure_get_int (caps_structure, "channels", &channels);
+       mm_attrs_set_int_by_name (player->attrs, "content_audio_channels", channels);
+
+       debug_log ("audio samplerate : %d       channels : %d\n", samplerate, channels);
+}
+
+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;
+
+       MMPLAYER_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));
+
+       if ( (!MMPLAYER_IS_WFD_STREAMING( player )) &&
+                (!MMPLAYER_IS_RTSP_STREAMING( player )) &&
+                (g_strrstr(player->type, "audio/x-raw-int")))
+       {
+               debug_error("not support media format\n");
+
+               if (player->msg_posted == FALSE)
+               {
+                       MMMessageParamType msg_param;
+                       memset (&msg_param, 0, sizeof(MMMessageParamType));
+
+                       msg_param.code = MM_ERROR_PLAYER_NOT_SUPPORTED_FORMAT;
+                       MMPLAYER_POST_MSG( player, MM_MESSAGE_ERROR, &msg_param );
+
+                       /* don't post more if one was sent already */
+                       player->msg_posted = TRUE;
+               }
+               return;
+       }
+
+       /* 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;
+               player->bypass_audio_effect = TRUE;
+       }
+       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;
+       }
+       else if ( g_strrstr(player->type, "application/dash+xml"))
+       {
+               player->profile.uri_type = MM_PLAYER_URI_TYPE_DASH;
+       }
+
+       pad = gst_element_get_static_pad(tf, "src");
+       if ( !pad )
+       {
+               debug_error("fail to get typefind src pad.\n");
+               return;
+       }
+
+       if (player->use_decodebin)
+       {
+               if(!__mmplayer_try_to_plug_decodebin( player, pad, caps ))
+               {
+                       gboolean async = FALSE;
+                       debug_error("failed to autoplug %s\n", player->type);
+
+                       mm_attrs_get_int_by_name(player->attrs, "profile_prepare_async", &async);
+
+                       if ( async && player->msg_posted == FALSE )
+                       {
+                               __mmplayer_handle_missed_plugin( player );
+                       }
+
+                       goto DONE;
+               }
+       }
+       else
+       {
+               /* try to plug */
+               if ( ! __mmplayer_try_to_plug( player, pad, caps ) )
+               {
+                       gboolean async = FALSE;
+                       debug_error("failed to autoplug %s\n", player->type);
+
+                       mm_attrs_get_int_by_name(player->attrs, "profile_prepare_async", &async);
+
+                       if ( async && player->msg_posted == FALSE )
+                       {
+                               __mmplayer_handle_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) );
+
+       MMPLAYER_FLEAVE();
+
+       return;
+}
+
+#ifdef _MM_PLAYER_ALP_PARSER
+void check_name (void *data, void *user_data)
+{
+       mm_player_t* player = user_data;
+
+       if (g_strrstr((gchar*)data, "mpegaudioparse"))
+       {
+               debug_log("mpegaudioparse - set alp-mp3dec\n");
+               g_object_set(player->pipeline->mainbin[MMPLAYER_M_DEMUX].gst, "alp-mp3dec", TRUE, NULL);
+       }
+}
+#endif
+
+static GstElement *
+__mmplayer_create_decodebin (mm_player_t* player)
+{
+       GstElement *decodebin = NULL;
+
+       MMPLAYER_FENTER();
+
+       /* create decodebin */
+       decodebin = gst_element_factory_make("decodebin2", "decodebin2");
+
+       if (!decodebin)
+       {
+               debug_error("fail to create decodebin\n");
+               goto ERROR;
+       }
+
+       /* raw pad handling signal */
+       MMPLAYER_SIGNAL_CONNECT( player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-added",
+                                               G_CALLBACK(__mmplayer_gst_decode_pad_added), player);
+
+       /* no-more-pad pad handling signal */
+       MMPLAYER_SIGNAL_CONNECT( player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "no-more-pads",
+                                               G_CALLBACK(__mmplayer_gst_decode_no_more_pads), player);
+
+       MMPLAYER_SIGNAL_CONNECT( player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-removed",
+                                               G_CALLBACK(__mmplayer_gst_decode_pad_removed), player);
+
+       /* This signal is emitted when a pad for which there is no further possible
+          decoding is added to the decodebin.*/
+       MMPLAYER_SIGNAL_CONNECT( player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "unknown-type",
+                                               G_CALLBACK(__mmplayer_gst_decode_unknown_type), player );
+
+       /* This signal is emitted whenever decodebin2 finds a new stream. It is emitted
+          before looking for any elements that can handle that stream.*/
+       MMPLAYER_SIGNAL_CONNECT( player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "autoplug-continue",
+                                               G_CALLBACK(__mmplayer_gst_decode_autoplug_continue), player);
+
+       /* This signal is emitted whenever decodebin2 finds a new stream. It is emitted
+          before looking for any elements that can handle that stream.*/
+       MMPLAYER_SIGNAL_CONNECT( player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "autoplug-select",
+                                               G_CALLBACK(__mmplayer_gst_decode_autoplug_select), player);
+
+       /* Once decodebin2 has found the possible GstElementFactory objects to try for
+          caps on pad, this signal is emited. The purpose of the signal is for the
+          application to perform additional sorting or filtering on the element factory
+          array.*/
+       MMPLAYER_SIGNAL_CONNECT( player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "autoplug-sort",
+                                               G_CALLBACK(__mmplayer_gst_decode_autoplug_sort), player);
+
+       /* This signal is emitted once decodebin2 has finished decoding all the data.*/
+       MMPLAYER_SIGNAL_CONNECT( player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "drained",
+                                               G_CALLBACK(__mmplayer_gst_decode_drained), player);
+
+       /* This signal is emitted when a element is added to the bin.*/
+       MMPLAYER_SIGNAL_CONNECT( player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "element-added",
+                                               G_CALLBACK(__mmplayer_gst_element_added), player);
+
+ERROR:
+       return decodebin;
+}
+
+static void
+__mmplayer_gst_id3_pad_added(GstElement *element, GstPad *pad, gpointer data)
+{
+       mm_player_t* player = (mm_player_t*)data;
+       GstCaps *caps = NULL;
+       gchar *caps_str = NULL;
+
+       MMPLAYER_FENTER();
+       return_if_fail (player && pad);
+
+       caps = gst_pad_get_caps(pad);
+       caps_str = gst_caps_to_string(caps);
+
+       debug_log("pad %s:%s, caps %s", GST_DEBUG_PAD_NAME(pad), caps_str);
+       __mmplayer_try_to_plug_decodebin(player, pad, caps);
+
+       MMPLAYER_FREEIF( caps_str );
+       gst_caps_unref(caps);
+
+       MMPLAYER_FLEAVE();
+}
+
+static gboolean
+__mmplayer_try_to_plug_decodebin(mm_player_t* player, GstPad *srcpad, const GstCaps *caps)
+{
+       MMPlayerGstElement* mainbin = NULL;
+       GstElement* decodebin2 = NULL;
+       GstElement* queue2 = NULL;
+       GstElement* id3demux = NULL;
+
+       GstPad* sinkpad = NULL;
+       GstPad* qsrcpad= NULL;
+       gchar *caps_str = NULL;
+
+       GstFormat fmt  = GST_FORMAT_BYTES;
+       gint64 dur_bytes = 0L;
+       gchar* file_buffering_path = NULL;
+       gboolean use_file_buffer = FALSE;
+
+       guint max_buffer_size_bytes = 0;
+       gdouble init_buffering_time = (gdouble)player->streamer->buffering_req.initial_second;
+
+       MMPLAYER_FENTER();
+       return_val_if_fail (player && player->pipeline && player->pipeline->mainbin, FALSE);
+
+       mainbin = player->pipeline->mainbin;
+
+       if ((!MMPLAYER_IS_HTTP_PD(player)) &&
+               (MMPLAYER_IS_HTTP_STREAMING(player)))
+       {
+               debug_log ("creating http streaming buffering queue (queue2)\n");
+
+               if (mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst)
+               {
+                       debug_error ("MMPLAYER_M_MUXED_S_BUFFER is not null\n");
+               }
+               else
+           {
+                       if (!mainbin[MMPLAYER_M_ID3DEMUX].gst)
+                       {
+                               caps_str = gst_caps_to_string(caps);
+                               if (g_strrstr(caps_str, "application/x-id3"))
+                               {
+                                       debug_log("create id3demux in front of queue2 \n");
+
+                                       id3demux = gst_element_factory_make ("id3demux", NULL);
+                                       if (!id3demux)
+                                       {
+                                               debug_error ("failed to create buffering id3demux element\n");
+                                               goto ERROR;
+                                       }
+
+                                       MMPLAYER_SIGNAL_CONNECT( player, G_OBJECT(id3demux), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-added",
+                                                                               G_CALLBACK(__mmplayer_gst_id3_pad_added), player);
+
+                                       if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), id3demux))
+                                       {
+                                               debug_error("failed to add id3demux\n");
+                                               goto ERROR;
+                                       }
+
+                                       sinkpad = gst_element_get_static_pad(id3demux, "sink");
+
+                                       if (GST_PAD_LINK_OK != gst_pad_link(srcpad, sinkpad))
+                                       {
+                                               debug_error("failed to link buffering queue\n");
+                                               goto ERROR;
+                                       }
+
+                                       if (GST_STATE_CHANGE_FAILURE == gst_element_sync_state_with_parent (id3demux))
+                                       {
+                                               debug_error("failed to sync id3demux state with parent\n");
+                                               goto ERROR;
+                                       }
+
+                                       mainbin[MMPLAYER_M_ID3DEMUX].id = MMPLAYER_M_ID3DEMUX;
+                                       mainbin[MMPLAYER_M_ID3DEMUX].gst = id3demux;
+
+                                       gst_object_unref(GST_OBJECT(sinkpad));
+                                       MMPLAYER_FREEIF( caps_str );
+
+                                       MMPLAYER_FLEAVE();
+                                       return TRUE;
+                               }
+
+                               MMPLAYER_FREEIF( caps_str );
+                       }
+
+                       queue2 = gst_element_factory_make ("queue2", "queue2");
+                       if (!queue2)
+                       {
+                               debug_error ("failed to create buffering queue element\n");
+                               goto ERROR;
+                       }
+
+                       if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), queue2))
+                       {
+                               debug_error("failed to add buffering queue\n");
+                               goto ERROR;
+                       }
+
+                       sinkpad = gst_element_get_static_pad(queue2, "sink");
+                       qsrcpad = gst_element_get_static_pad(queue2, "src");
+
+                       if (GST_PAD_LINK_OK != gst_pad_link(srcpad, sinkpad))
+                       {
+                               debug_error("failed to link buffering queue\n");
+                               goto ERROR;
+                       }
+
+                       // 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");
+
+                               debug_log("dur_bytes = %lld\n", dur_bytes);
+
+                               if (dur_bytes > 0)
+                               {
+                                       use_file_buffer = MMPLAYER_USE_FILE_FOR_BUFFERING(player);
+                                       file_buffering_path = g_strdup(player->ini.http_file_buffer_path);
+                               }
+                               else
+                               {
+                                       dur_bytes = 0;
+                               }
+                       }
+
+                       /* NOTE : we cannot get any duration info from ts container in case of streaming */
+                       // if(!g_strrstr(GST_ELEMENT_NAME(sinkelement), "mpegtsdemux"))
+                       if(!g_strrstr(player->type, "video/mpegts"))
+                       {
+                               max_buffer_size_bytes = (use_file_buffer)?(player->ini.http_max_size_bytes):(5*1024*1024);
+                               debug_log("max_buffer_size_bytes = %d\n", max_buffer_size_bytes);
+
+                               __mm_player_streaming_set_queue2(player->streamer,
+                                                                                               queue2,
+                                                                                               FALSE,
+                                                                                               max_buffer_size_bytes,
+                                                                                               player->ini.http_buffering_time,
+                                                                                               1.0,                                                            // no meaning
+                                                                                               player->ini.http_buffering_limit,       // no meaning
+                                                                                               use_file_buffer,
+                                                                                               file_buffering_path,
+                                                                                               (guint64)dur_bytes);
+                       }
+
+                       MMPLAYER_FREEIF(file_buffering_path);
+                       if (GST_STATE_CHANGE_FAILURE == gst_element_sync_state_with_parent (queue2))
+                       {
+                               debug_error("failed to sync queue2 state with parent\n");
+                               goto ERROR;
+                       }
+
+                       srcpad = qsrcpad;
+
+                       gst_object_unref(GST_OBJECT(sinkpad));
+
+                       mainbin[MMPLAYER_M_MUXED_S_BUFFER].id = MMPLAYER_M_MUXED_S_BUFFER;
+                       mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst = queue2;
+               }
+       }
+
+       /* create decodebin */
+       decodebin2 = __mmplayer_create_decodebin(player);
+
+       if (!decodebin2)
+       {
+               debug_error("can not create autoplug element\n");
+               goto ERROR;
+       }
+
+       if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), decodebin2))
+       {
+               debug_error("failed to add decodebin2\n");
+               goto ERROR;
+       }
+
+       /* to force caps on the decodebin element and avoid reparsing stuff by
+       * typefind. It also avoids a deadlock in the way typefind activates pads in
+       * the state change */
+       g_object_set (decodebin2, "sink-caps", caps, NULL);
+
+       sinkpad = gst_element_get_static_pad(decodebin2, "sink");
+
+       if (GST_PAD_LINK_OK != gst_pad_link(srcpad, sinkpad))
+       {
+               debug_error("failed to link decodebin2\n");
+               goto ERROR;
+       }
+
+       gst_object_unref(GST_OBJECT(sinkpad));
+
+       mainbin[MMPLAYER_M_AUTOPLUG].id = MMPLAYER_M_AUTOPLUG;
+       mainbin[MMPLAYER_M_AUTOPLUG].gst = decodebin2;
+
+       if ( ((!MMPLAYER_IS_HTTP_PD(player)) &&
+           (MMPLAYER_IS_HTTP_STREAMING(player))) || MMPLAYER_IS_DASH_STREAMING (player))
+       {
+               init_buffering_time = (init_buffering_time != 0)?(init_buffering_time):(player->ini.http_buffering_time);
+
+               g_object_set (G_OBJECT(decodebin2), "use-buffering", TRUE,
+                                                                                       "high-percent", (gint)player->ini.http_buffering_limit,
+                                                                                       "low-percent", 1,   // 1%
+                                                                                       "max-size-bytes", MAX_DECODEBIN_BUFFER_BYTES,
+                                                                                       "max-size-time", (guint64)(MAX_DECODEBIN_BUFFER_TIME * GST_SECOND),
+                                                                                       "max-size-buffers", 0, NULL);  // disable or automatic
+       }
+
+       if (GST_STATE_CHANGE_FAILURE == gst_element_sync_state_with_parent(decodebin2))
+       {
+               debug_error("failed to sync decodebin2 state with parent\n");
+               goto ERROR;
+       }
+
+       MMPLAYER_FLEAVE();
+
+       return TRUE;
+
+ERROR:
+
+       MMPLAYER_FREEIF( caps_str );
+
+       if (sinkpad)
+               gst_object_unref(GST_OBJECT(sinkpad));
+
+       if (queue2)
+       {
+               /* 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(queue2, 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), queue2);
+               gst_object_unref (queue2);
+               queue2 = NULL;
+       }
+
+       if (id3demux)
+       {
+               /* NOTE : Trying to dispose element id3demux, 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(id3demux, 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), id3demux);
+               gst_object_unref (id3demux);
+               id3demux = NULL;
+       }
+
+       if (decodebin2)
+       {
+               /* 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(decodebin2, 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), decodebin2);
+               gst_object_unref (decodebin2);
+               decodebin2 = NULL;
+       }
+
+       return FALSE;
+}
+
+/* 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;
+
+       MMPLAYER_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, 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 ( MMPLAYER_IS_RTSP_STREAMING(player) && g_strrstr(GST_PLUGIN_FEATURE_NAME (factory), "omx_mpeg4dec"))
+               {
+                       // omx decoder can not support mpeg4video data partitioned
+                       // rtsp streaming didn't know mpeg4video data partitioned format
+                       // so, if rtsp playback, player will skip omx_mpeg4dec.
+                       debug_warning("skipping [%s] when rtsp streaming \n",
+                                       GST_PLUGIN_FEATURE_NAME (factory));
+
+                       skip = TRUE;
+               }
+
+               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("skipping [%s] by not required\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);
+
+                               /* check ALP Codec can be used or not */
+                               if ((g_strrstr(klass, "Codec/Decoder/Audio")))
+                               {
+                                       /* consider mp3 audio only */
+                                       if ( !MMPLAYER_IS_STREAMING(player) && __mmplayer_is_only_mp3_type(player->type) )
+                                       {
+                                               /* try to use ALP decoder first instead of selected decoder */
+                                               GstElement *element = NULL;
+                                               GstElementFactory * element_facory;
+                                               gchar *path = NULL;
+                                               guint64 data_size = 0;
+                                               #define MIN_THRESHOLD_SIZE  320 * 1024 // 320K
+                                               struct stat sb;
+
+                                               mm_attrs_get_string_by_name(player->attrs, "profile_uri", &path);
+
+                                               if (stat(path, &sb) == 0)
+                                               {
+                                                       data_size = (guint64)sb.st_size;
+                                               }
+                                               debug_log("file size : %u", data_size);
+
+                                               if (data_size > MIN_THRESHOLD_SIZE)
+                                               {
+                                                       debug_log("checking if ALP can be used or not");
+                                                       element = gst_element_factory_make("omx_mp3dec", "omx mp3 decoder");
+                                                       if ( element )
+                                                       {
+                                                               /* check availability because multi-instance is not supported */
+                                                               GstStateChangeReturn ret = gst_element_set_state(element, GST_STATE_READY);
+
+                                                               if (ret != GST_STATE_CHANGE_SUCCESS) // use just selected decoder
+                                                               {
+                                                                       gst_object_unref (element);
+                                                               }
+                                                               else if (ret == GST_STATE_CHANGE_SUCCESS) // replace facotry to use omx
+                                                               {
+                                                                       /* clean  */
+                                                                       gst_element_set_state(element, GST_STATE_NULL);
+                                                                       gst_object_unref (element);
+
+                                                                       element_facory = gst_element_factory_find("omx_mp3dec");
+                                                                       /* replace, otherwise use selected thing instead */
+                                                                       if (element_facory)
+                                                                       {
+                                                                               factory = element_facory;
+                                                                               name_to_plug = GST_PLUGIN_FEATURE_NAME(factory);
+                                                                       }
+
+                                                                       /* make parser alp mode */
+                                                                       #ifdef _MM_PLAYER_ALP_PARSER
+                                                                       g_list_foreach (player->parsers, check_name, player);
+                                                                       #endif
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               }
+                               else if ((g_strrstr(klass, "Codec/Decoder/Video")))
+                               {
+                                       if ( g_strrstr(GST_PLUGIN_FEATURE_NAME(factory), "omx_") )
+                                       {
+                                               char *env = getenv ("MM_PLAYER_HW_CODEC_DISABLE");
+                                               if (env != NULL)
+                                               {
+                                                       if (strncasecmp(env, "yes", 3) == 0)
+                                                       {
+                                                               debug_log("skipping [%s] by disabled\n", name_to_plug);
+                                                               MMPLAYER_FREEIF(name_template);
+                                                               continue;
+                                                       }
+                                               }
+                                       }
+                               }
+
+                               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)
+                                       {
+                                               MMPLAYER_FREEIF(name_template);
+                                               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;
+
+                                       /*Added for multi audio support */
+                                       if(g_strrstr(klass, "Demux"))
+                                       {
+                                               mainbin[MMPLAYER_M_DEMUX_EX].id = MMPLAYER_M_DEMUX_EX;
+                                               mainbin[MMPLAYER_M_DEMUX_EX].gst = new_element;
+
+                                               /* NOTE : workaround for bug in mpegtsdemux since doesn't emit
+                                               no-more-pad signal. this may cause wrong content attributes at PAUSED state
+                                               this code should be removed after mpegtsdemux is fixed */
+                                               if ( g_strrstr(GST_PLUGIN_FEATURE_NAME(factory), "mpegtsdemux") )
+                                               {
+                                                       debug_warning("force no-more-pad to TRUE since mpegtsdemux os not giving no-more-pad signal. content attributes may wrong");
+                                                       player->no_more_pad = TRUE;
+                                               }
+                                       }
+                                       if (g_strrstr(name_to_plug, "asfdemux")) // to support trust-zone only
+                                       {
+                                               g_object_set(mainbin[MMPLAYER_M_DEMUX_EX].gst, "file-location", player->profile.uri,NULL);
+                                       }
+                               }
+                               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_str = 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_str = gst_caps_to_string(caps);
+
+                                               /* clean */
+                                               MMPLAYER_FREEIF( caps_str );
+                                               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)) )
+                               {
+                                       MMPLAYER_FREEIF(name_template);
+                                       if (player->keep_detecting_vcodec)
+                                       continue;
+
+                                       /* Link is failed even though a supportable codec is found. */
+                                       __mmplayer_check_not_supported_codec(player, klass, mime);
+
+                                       debug_error("failed to call _close_link\n");
+                                       return FALSE;
+                               }
+
+                               MMPLAYER_FREEIF(name_template);
+                               return TRUE;
+                       }
+
+                       gst_caps_unref(res);
+                       break;
+               }
+       }
+
+       /* There is no available codec. */
+       __mmplayer_check_not_supported_codec(player, klass, mime);
+
+       MMPLAYER_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, const gchar* factory_class, const gchar* mime)
+{
+       MMPLAYER_FENTER();
+
+       return_val_if_fail(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       return_val_if_fail ( mime, MM_ERROR_INVALID_ARGUMENT );
+
+       debug_log("class : %s, mime : %s \n", factory_class, 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_strrstr(factory_class, "Demuxer"))
+       {
+               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:
+       MMPLAYER_FLEAVE();
+
+       return MM_ERROR_NONE;
+}
+
+
+static void
+__mmplayer_pipeline_complete(GstElement *decodebin,  gpointer data)
+{
+    mm_player_t* player = (mm_player_t*)data;
+
+       MMPLAYER_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");
+
+       if ( ( player->ini.async_start ) &&
+               ( player->msg_posted == FALSE ) &&
+               ( player->cmd >= MMPLAYER_COMMAND_START ))
+       {
+               __mmplayer_handle_missed_plugin( player );
+       }
+
+       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-complete" );
+}
+
+static gboolean
+__mmplayer_verify_next_play_path(mm_player_t *player)
+{
+       MMHandleType attrs = 0;
+       MMPlayerParseProfile profile;
+       gint uri_idx = 0, check_cnt = 0;
+       char *uri = NULL;
+       gint mode = MM_PLAYER_PD_MODE_NONE;
+       gint count = 0;
+       guint num_of_list = 0;
+
+       MMPLAYER_FENTER();
+
+       debug_log("checking for next play");
+
+       if (player->pipeline->textbin)
+       {
+               debug_error("subtitle path is enabled. next play is not supported.\n");
+               goto ERROR;
+       }
+
+       attrs = MMPLAYER_GET_ATTRS(player);
+       if ( !attrs )
+       {
+               debug_error("fail to get attributes.\n");
+               goto ERROR;
+       }
+
+       /* seamless playback is supported in case of audio only */
+       mm_attrs_get_int_by_name(attrs, "content_video_found", &mode);
+       if (mode)
+       {
+               debug_log("video found");
+               goto ERROR;
+       }
+
+       if (mm_attrs_get_int_by_name (attrs, "pd_mode", &mode) == MM_ERROR_NONE)
+       {
+               if (mode == TRUE)
+               {
+                       debug_warning("pd mode\n");
+                       goto ERROR;
+               }
+       }
+
+       if (mm_attrs_get_int_by_name(attrs, "profile_play_count", &count) != MM_ERROR_NONE)
+       {
+               debug_error("can not get play count\n");
+       }
+
+       num_of_list = g_list_length(player->uri_info.uri_list);
+
+       debug_log("repeat count = %d, num_of_list = %d\n", count, num_of_list);
+
+       if ( num_of_list == 0 )
+       {
+               if (mm_attrs_get_string_by_name(player->attrs, "profile_uri", &uri) != MM_ERROR_NONE)
+               {
+                       debug_error("can not get profile_uri\n");
+                       goto ERROR;
+               }
+
+               if (!uri)
+               {
+                       debug_error("uri list is empty.\n");
+                       goto ERROR;
+               }
+
+               player->uri_info.uri_list = g_list_append(player->uri_info.uri_list, g_strdup(uri));
+               debug_log("add original path : %s ", uri);
+
+               num_of_list = 1;
+               uri= NULL;
+       }
+
+       uri_idx = player->uri_info.uri_idx;
+
+       while(TRUE)
+       {
+               check_cnt++;
+
+               if (check_cnt > num_of_list)
+               {
+                       debug_error("there is no valid uri.");
+                       goto ERROR;
+               }
+
+               debug_log("uri idx : %d / %d\n", uri_idx, num_of_list);
+
+               if ( uri_idx < num_of_list-1 )
+               {
+                       uri_idx++;
+               }
+               else
+               {
+                       if ((count <= 1) && (count != -1))
+                       {
+                               debug_log("no repeat.");
+                               goto ERROR;
+                       }
+                       else if ( count > 1 )   /* decrease play count */
+                       {
+                               /* 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");
+                               }
+                       }
+
+                       /* count < 0 : repeat continually */
+                       uri_idx = 0;
+               }
+
+               uri = g_list_nth_data(player->uri_info.uri_list, uri_idx);
+               debug_log("uri idx : %d, uri = %s\n", uri_idx, uri);
+
+               if (uri == NULL)
+               {
+                       debug_warning("next uri does not exist\n");
+                       continue;
+               }
+
+               if (__mmfplayer_parse_profile((const char*)uri, NULL, &profile) != MM_ERROR_NONE)
+               {
+                       debug_error("failed to parse profile\n");
+                       continue;
+               }
+
+               if ((profile.uri_type != MM_PLAYER_URI_TYPE_FILE) &&
+                       (profile.uri_type != MM_PLAYER_URI_TYPE_URL_HTTP))
+               {
+                       debug_warning("uri type is not supported (%d).", profile.uri_type);
+                       continue;
+               }
+
+               break;
+       }
+
+       player->uri_info.uri_idx = uri_idx;
+       mm_attrs_set_string_by_name(player->attrs, "profile_uri", uri);
+
+
+       if (mmf_attrs_commit(player->attrs))
+       {
+               debug_error("failed to commit.\n");
+               goto ERROR;
+       }
+
+       debug_log("next uri %s (%d)\n", uri, uri_idx);
+
+       return TRUE;
+
+ERROR:
+
+       debug_error("unable to play next path. EOS will be posted soon.\n");
+       return FALSE;
+}
+
+static void
+__mmplayer_initialize_next_play(mm_player_t *player)
+{
+       int i;
+
+       MMPLAYER_FENTER();
+
+       player->needed_v_parser = FALSE;
+       player->smooth_streaming = FALSE;
+       player->videodec_linked = 0;
+       player->audiodec_linked = 0;
+       player->videosink_linked = 0;
+       player->audiosink_linked = 0;
+       player->textsink_linked = 0;
+       player->is_external_subtitle_present = FALSE;
+       player->not_supported_codec = MISSING_PLUGIN_NONE;
+       player->can_support_codec = FOUND_PLUGIN_NONE;
+       player->pending_seek.is_pending = FALSE;
+       player->pending_seek.format = MM_PLAYER_POS_FORMAT_TIME;
+       player->pending_seek.pos = 0;
+       player->msg_posted = FALSE;
+       player->has_many_types = FALSE;
+       player->no_more_pad = FALSE;
+       player->is_drm_file = FALSE;
+       player->not_found_demuxer = 0;
+       player->doing_seek = FALSE;
+       player->max_audio_channels = 0;
+       player->is_subtitle_force_drop = FALSE;
+       player->play_subtitle = FALSE;
+       player->use_textoverlay = FALSE;
+       player->adjust_subtitle_pos = 0;
+
+       player->updated_bitrate_count = 0;
+       player->total_bitrate = 0;
+       player->updated_maximum_bitrate_count = 0;
+       player->total_maximum_bitrate = 0;
+
+       for (i = 0; i < MM_PLAYER_STREAM_COUNT_MAX; i++)
+       {
+               player->bitrate[i] = 0;
+               player->maximum_bitrate[i] = 0;
+       }
+
+       if (player->v_stream_caps)
+       {
+               gst_caps_unref(player->v_stream_caps);
+               player->v_stream_caps = NULL;
+       }
+
+       mm_attrs_set_int_by_name(player->attrs, "content_video_found", 0);
+       mm_attrs_set_int_by_name(player->attrs, "content_audio_found", 0);
+
+       /* clean found parsers */
+       if (player->parsers)
+       {
+               GList *parsers = player->parsers;
+               for ( ;parsers ; parsers = g_list_next(parsers))
+               {
+                       gchar *name = parsers->data;
+                       MMPLAYER_FREEIF(name);
+               }
+               g_list_free(player->parsers);
+               player->parsers = NULL;
+       }
+
+       /* clean found audio decoders */
+       if (player->audio_decoders)
+       {
+               GList *a_dec = player->audio_decoders;
+               for ( ;a_dec ; a_dec = g_list_next(a_dec))
+               {
+                       gchar *name = a_dec->data;
+                       MMPLAYER_FREEIF(name);
+               }
+               g_list_free(player->audio_decoders);
+               player->audio_decoders = NULL;
+       }
+
+       MMPLAYER_FLEAVE();
+}
+
+static void
+__mmplayer_activate_next_source(mm_player_t *player, GstState target)
+{
+       MMPlayerGstElement *mainbin = NULL;
+       MMMessageParamType msg_param = {0,};
+       GstElement *element = NULL;
+       MMHandleType attrs = 0;
+       char *uri = NULL;
+       enum MainElementID elemId = MMPLAYER_M_NUM;
+
+       MMPLAYER_FENTER();
+
+       if ((player->pipeline == NULL) ||
+               (player->pipeline->mainbin == NULL))
+       {
+               debug_error("player is null.\n");
+               goto ERROR;
+       }
+
+       mainbin = player->pipeline->mainbin;
+       msg_param.code = MM_ERROR_PLAYER_INTERNAL;
+
+       attrs = MMPLAYER_GET_ATTRS(player);
+       if ( !attrs )
+       {
+               debug_error("fail to get attributes.\n");
+               goto ERROR;
+       }
+
+       /* Initialize Player values */
+       __mmplayer_initialize_next_play(player);
+
+       mm_attrs_get_string_by_name(attrs, "profile_uri", &uri);
+
+       if (__mmfplayer_parse_profile((const char*)uri, NULL, &player->profile) != MM_ERROR_NONE)
+       {
+               debug_error("failed to parse profile\n");
+               msg_param.code = MM_ERROR_PLAYER_INVALID_URI;
+               goto ERROR;
+       }
+
+       if ((MMPLAYER_URL_HAS_DASH_SUFFIX(player)) ||
+               (MMPLAYER_URL_HAS_HLS_SUFFIX(player)))
+       {
+               debug_error("it's dash or hls. not support.");
+               msg_param.code = MM_ERROR_PLAYER_INVALID_URI;
+               goto ERROR;
+       }
+
+       /* setup source */
+       switch ( player->profile.uri_type )
+       {
+               /* file source */
+               case MM_PLAYER_URI_TYPE_FILE:
+               {
+
+#ifdef ENABLE_DRMSRC
+
+                       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_error("failed to create %s\n", drmsrc);
+                               break;
+                       }
+#else
+                       debug_log("using filesrc for 'file://' handler.\n");
+
+                       element = gst_element_factory_make("filesrc", "source");
+
+                       if ( !element )
+                       {
+                               debug_error("failed to create filesrc\n");
+                               break;
+                       }
+#endif
+                       g_object_set(G_OBJECT(element), "location", (player->profile.uri)+7, NULL);     /* uri+7 -> remove "file:// */
+                       break;
+               }
+               case MM_PLAYER_URI_TYPE_URL_HTTP:
+               {
+                       gchar *user_agent, *proxy, *cookies, **cookie_list;
+                       gint http_timeout = DEFAULT_HTTP_TIMEOUT;
+                       user_agent = proxy = cookies = NULL;
+                       cookie_list = NULL;
+
+                       element = gst_element_factory_make(player->ini.name_of_httpsrc, "http_streaming_source");
+                       if ( !element )
+                       {
+                               debug_error("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 );
+                       mm_attrs_get_int_by_name ( attrs, "streaming_timeout", &http_timeout );
+
+                       if ((http_timeout == DEFAULT_HTTP_TIMEOUT) &&
+                               (player->ini.http_timeout != DEFAULT_HTTP_TIMEOUT))
+                       {
+                               debug_log("get timeout from ini\n");
+                               http_timeout = player->ini.http_timeout;
+                       }
+
+                       /* get attribute */
+                       secure_debug_log("location : %s\n", player->profile.uri);
+                       secure_debug_log("cookies : %s\n", cookies);
+                       secure_debug_log("proxy : %s\n", proxy);
+                       secure_debug_log("user_agent :  %s\n", user_agent);
+                       debug_log("timeout : %d\n", http_timeout);
+
+                       /* setting property to streaming source */
+                       g_object_set(G_OBJECT(element), "location", player->profile.uri, NULL);
+                       g_object_set(G_OBJECT(element), "timeout", http_timeout, NULL);
+                       g_object_set(G_OBJECT(element), "blocksize", (unsigned long)(64*1024), 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);
+                       break;
+               }
+               default:
+                       debug_error("not support uri type %d\n", player->profile.uri_type);
+                       break;
+       }
+
+       if ( !element )
+       {
+               debug_error("no source element was created.\n");
+               goto ERROR;
+       }
+
+       if (gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), element) == FALSE)
+       {
+               debug_error("failed to add source element to pipeline\n");
+               gst_object_unref(GST_OBJECT(element));
+               element = NULL;
+               goto ERROR;
+       }
+
+       /* take source element */
+       mainbin[MMPLAYER_M_SRC].id = MMPLAYER_M_SRC;
+       mainbin[MMPLAYER_M_SRC].gst = element;
+
+       element = NULL;
+
+       if (MMPLAYER_IS_HTTP_STREAMING(player))
+       {
+               if (player->streamer == NULL)
+               {
+                       player->streamer = __mm_player_streaming_create();
+
+                       if(player->streamer == NULL)
+                       goto ERROR;
+
+                       __mm_player_streaming_initialize(player->streamer);
+               }
+
+               elemId = MMPLAYER_M_TYPEFIND;
+               element = gst_element_factory_make("typefind", "typefinder");
+               MMPLAYER_SIGNAL_CONNECT( player, element, MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "have-type",
+                       G_CALLBACK(__mmplayer_typefind_have_type), (gpointer)player );
+       }
+       else
+       {
+               elemId = MMPLAYER_M_AUTOPLUG;
+               element = __mmplayer_create_decodebin(player);
+       }
+
+       /* check autoplug element is OK */
+       if ( ! element )
+       {
+               debug_error("can not create element (%d)\n", elemId);
+               goto ERROR;
+       }
+
+       if (gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), element) == FALSE)
+       {
+               debug_error("failed to add sinkbin to pipeline\n");
+               gst_object_unref(GST_OBJECT(element));
+               element = NULL;
+               goto ERROR;
+       }
+
+       mainbin[elemId].id = elemId;
+       mainbin[elemId].gst = element;
+
+       if ( gst_element_link (mainbin[MMPLAYER_M_SRC].gst, mainbin[elemId].gst) == FALSE )
+       {
+               debug_error("Failed to link src - autoplug (or typefind)\n");
+               goto ERROR;
+       }
+
+       if (gst_element_set_state (mainbin[MMPLAYER_M_SRC].gst, target) == GST_STATE_CHANGE_FAILURE)
+       {
+               debug_error("Failed to change state of src element\n");
+               goto ERROR;
+       }
+
+       if (!MMPLAYER_IS_HTTP_STREAMING(player))
+       {
+               if (gst_element_set_state (mainbin[MMPLAYER_M_AUTOPLUG].gst, target) == GST_STATE_CHANGE_FAILURE)
+               {
+                       debug_error("Failed to change state of decodebin2\n");
+                       goto ERROR;
+               }
+       }
+       else
+       {
+               if (gst_element_set_state (mainbin[MMPLAYER_M_TYPEFIND].gst, target) == GST_STATE_CHANGE_FAILURE)
+               {
+                       debug_error("Failed to change state of src element\n");
+                       goto ERROR;
+               }
+       }
+
+       player->src_changed = TRUE;
+       MMPLAYER_FLEAVE();
+       return;
+
+ERROR:
+
+       MMPLAYER_PLAYBACK_UNLOCK(player);
+
+       if (!player->msg_posted)
+       {
+               MMPLAYER_POST_MSG(player, MM_MESSAGE_ERROR, &msg_param);
+               player->msg_posted = TRUE;
+       }
+       return;
+}
+
+static gboolean
+__mmplayer_deactivate_selector(mm_player_t *player, MMPlayerTrackType type)
+{
+       mm_player_selector_t *selector = &player->selector[type];
+       MMPlayerGstElement *sinkbin = NULL;
+       enum MainElementID selectorId = MMPLAYER_M_NUM;
+       enum MainElementID sinkId = MMPLAYER_M_NUM;
+       GstPad *srcpad = NULL;
+       GstPad *sinkpad = NULL;
+
+       MMPLAYER_FENTER();
+       return_val_if_fail (player, FALSE);
+
+       debug_log("type %d", type);
+
+       switch (type)
+       {
+               case MM_PLAYER_TRACK_TYPE_VIDEO:
+                       selectorId = MMPLAYER_M_V_INPUT_SELECTOR;
+                       sinkId = MMPLAYER_V_BIN;
+                       sinkbin = player->pipeline->videobin;
+               break;
+               case MM_PLAYER_TRACK_TYPE_AUDIO:
+                       selectorId = MMPLAYER_M_A_INPUT_SELECTOR;
+                       sinkId = MMPLAYER_A_BIN;
+                       sinkbin = player->pipeline->audiobin;
+               break;
+               case MM_PLAYER_TRACK_TYPE_TEXT:
+                       selectorId = MMPLAYER_M_T_INPUT_SELECTOR;
+                       sinkId = MMPLAYER_T_BIN;
+                       sinkbin = player->pipeline->textbin;
+               break;
+               default:
+                       debug_error("requested type is not supportable");
+                       return FALSE;
+               break;
+       }
+
+       if (player->pipeline->mainbin[selectorId].gst)
+       {
+               gint n;
+
+               srcpad = gst_element_get_static_pad(player->pipeline->mainbin[selectorId].gst, "src");
+
+               if ((sinkbin) && (sinkbin[sinkId].gst))
+               {
+                       sinkpad = gst_element_get_static_pad(sinkbin[sinkId].gst, "sink");
+
+                       if (srcpad && sinkpad)
+                       {
+                               /* after getting drained signal there is no data flows, so no need to do pad_block */
+                               debug_log("unlink %s:%s, %s:%s", GST_DEBUG_PAD_NAME(srcpad), GST_DEBUG_PAD_NAME(sinkpad));
+                               gst_pad_unlink (srcpad, sinkpad);
+                       }
+
+                       gst_object_unref (sinkpad);
+                       sinkpad = NULL;
+               }
+               gst_object_unref (srcpad);
+               srcpad = NULL;
+
+               debug_log("selector release");
+               if(selector->channels)
+               {
+                       debug_log("release and unref request pads");
+
+                       /* release and unref requests pad from the selector */
+                       for (n = 0; n < selector->channels->len; n++)
+                       {
+                               GstPad *sinkpad = g_ptr_array_index (selector->channels, n);
+                               gst_element_release_request_pad ((player->pipeline->mainbin[selectorId].gst), sinkpad);
+                       }
+                       g_ptr_array_set_size (selector->channels, 0);
+               }
+               gst_element_set_state (player->pipeline->mainbin[selectorId].gst, GST_STATE_NULL);
+               gst_bin_remove (GST_BIN_CAST (player->pipeline->mainbin[MMPLAYER_M_PIPE].gst), player->pipeline->mainbin[selectorId].gst);
+
+               player->pipeline->mainbin[selectorId].gst = NULL;
+               selector = NULL;
+       }
+
+       return TRUE;
+}
+
+static void
+__mmplayer_deactivate_old_path(mm_player_t *player)
+{
+       MMPLAYER_FENTER();
+       return_if_fail ( player );
+
+       g_object_set(G_OBJECT(player->pipeline->mainbin[MMPLAYER_M_DEC1].gst), "remove-buffer-signal", TRUE, NULL);
+
+       if ((!__mmplayer_deactivate_selector(player, MM_PLAYER_TRACK_TYPE_VIDEO)) ||
+               (!__mmplayer_deactivate_selector(player, MM_PLAYER_TRACK_TYPE_AUDIO)) ||
+               (!__mmplayer_deactivate_selector(player, MM_PLAYER_TRACK_TYPE_TEXT)))
+       {
+               debug_error("deactivate selector error");
+               goto ERROR;
+       }
+
+       __mmplayer_release_signal_connection( player, MM_PLAYER_SIGNAL_TYPE_AUTOPLUG );
+
+       if (player->streamer)
+       {
+               __mm_player_streaming_deinitialize (player->streamer);
+               __mm_player_streaming_destroy(player->streamer);
+               player->streamer = NULL;
+       }
+
+       MMPLAYER_PLAYBACK_LOCK(player);
+       g_cond_signal( player->next_play_thread_cond );
+
+       MMPLAYER_FLEAVE();
+       return;
+
+ERROR:
+
+       if (!player->msg_posted)
+       {
+               MMMessageParamType msg = {0,};
+
+               /*post error*/
+               msg.code = MM_ERROR_PLAYER_INTERNAL;
+               debug_error("next_uri_play> deactivate error");
+
+               MMPLAYER_POST_MSG(player, MM_MESSAGE_ERROR, &msg);
+               player->msg_posted = TRUE;
+       }
+       return;
+}
+
+int _mmplayer_set_uri(MMHandleType hplayer, const char* uri)
+{
+       int result = MM_ERROR_NONE;
+       mm_player_t* player = (mm_player_t*) hplayer;
+       MMPLAYER_FENTER();
+
+       return_val_if_fail (player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       mm_attrs_set_string_by_name(player->attrs, "profile_uri", uri);
+       if (mmf_attrs_commit(player->attrs))
+       {
+               debug_error("failed to commit the original uri.\n");
+               result = MM_ERROR_PLAYER_INTERNAL;
+       }
+       else
+       {
+               if (_mmplayer_set_next_uri(hplayer, uri, TRUE) != MM_ERROR_NONE)
+               {
+                       debug_error("failed to add the original uri in the uri list.\n");
+               }
+       }
+
+       MMPLAYER_FLEAVE();
+       return result;
+}
+
+int _mmplayer_set_next_uri(MMHandleType hplayer, const char* uri, bool is_first_path)
+{
+       mm_player_t* player = (mm_player_t*) hplayer;
+       guint num_of_list = 0;
+
+       MMPLAYER_FENTER();
+
+       return_val_if_fail (player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       return_val_if_fail (uri, MM_ERROR_INVALID_ARGUMENT);
+
+       if (player->pipeline && player->pipeline->textbin)
+       {
+               debug_error("subtitle path is enabled.\n");
+               return MM_ERROR_PLAYER_INVALID_STATE;
+       }
+
+       num_of_list = g_list_length(player->uri_info.uri_list);
+
+       if (is_first_path == TRUE)
+       {
+               if (num_of_list == 0)
+               {
+                       player->uri_info.uri_list = g_list_append(player->uri_info.uri_list, g_strdup(uri));
+                       debug_log("add original path : %s", uri);
+               }
+               else
+               {
+                       player->uri_info.uri_list = g_list_delete_link(player->uri_info.uri_list, g_list_nth(player->uri_info.uri_list, 0));
+                       player->uri_info.uri_list = g_list_insert(player->uri_info.uri_list, g_strdup(uri), 0);
+
+                       debug_log("change original path : %s", uri);
+               }
+       }
+       else
+       {
+               if (num_of_list == 0)
+               {
+                       MMHandleType attrs = 0;
+                       char *original_uri = NULL;
+
+                       attrs = MMPLAYER_GET_ATTRS(player);
+                       if ( attrs )
+                       {
+                               mm_attrs_get_string_by_name(attrs, "profile_uri", &original_uri);
+
+                               if (!original_uri)
+                               {
+                                       debug_error("there is no original uri.");
+                                       return MM_ERROR_PLAYER_INVALID_STATE;
+                               }
+
+                               player->uri_info.uri_list = g_list_append(player->uri_info.uri_list, g_strdup(original_uri));
+                               player->uri_info.uri_idx = 0;
+
+                               debug_log("add original path at first : %s (%d)", original_uri);
+                       }
+               }
+
+               player->uri_info.uri_list = g_list_append(player->uri_info.uri_list, g_strdup(uri));
+               debug_log("add new path : %s (total num of list = %d)", uri, g_list_length(player->uri_info.uri_list));
+       }
+
+       MMPLAYER_FLEAVE();
+       return MM_ERROR_NONE;
+}
+
+int _mmplayer_get_next_uri(MMHandleType hplayer, char** uri)
+{
+       mm_player_t* player = (mm_player_t*) hplayer;
+       char *next_uri = NULL;
+       guint num_of_list = 0;
+
+       MMPLAYER_FENTER();
+       return_val_if_fail (player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       num_of_list = g_list_length(player->uri_info.uri_list);
+
+       if (num_of_list > 0)
+       {
+               gint uri_idx = player->uri_info.uri_idx;
+
+               if ( uri_idx < num_of_list-1 )
+                       uri_idx++;
+               else
+                       uri_idx = 0;
+
+               next_uri = g_list_nth_data(player->uri_info.uri_list, uri_idx);
+               debug_error("next uri idx : %d, uri = %s\n", uri_idx, next_uri);
+
+               *uri = g_strdup(next_uri);
+       }
+
+       MMPLAYER_FLEAVE();
+       return MM_ERROR_NONE;
+}
+
+static void
+__mmplayer_gst_decode_unknown_type(GstElement *elem,  GstPad* pad,
+GstCaps *caps, gpointer data)
+{
+       mm_player_t* player = (mm_player_t*)data;
+       const gchar* klass = NULL;
+       const gchar* mime = NULL;
+       gchar* caps_str = NULL;
+
+       klass = gst_element_factory_get_klass (gst_element_get_factory(elem));
+       mime = gst_structure_get_name (gst_caps_get_structure(caps, 0));
+       caps_str = gst_caps_to_string(caps);
+
+       debug_warning("unknown type of caps : %s from %s",
+                                       caps_str, GST_ELEMENT_NAME (elem));
+
+       MMPLAYER_FREEIF(caps_str);
+
+       /* There is no available codec. */
+       __mmplayer_check_not_supported_codec (player, klass, mime);
+}
+
+static gboolean
+__mmplayer_gst_decode_autoplug_continue(GstElement *bin,  GstPad* pad,
+GstCaps * caps,  gpointer data)
+{
+       mm_player_t* player = (mm_player_t*)data;
+       const char* mime = NULL;
+       gboolean ret = TRUE;
+
+       MMPLAYER_LOG_GST_CAPS_TYPE(caps);
+       mime = gst_structure_get_name (gst_caps_get_structure(caps, 0));
+
+       if (g_str_has_prefix(mime, "audio")) {
+               GstStructure* caps_structure = NULL;
+               gint samplerate = 0;
+               gint channels = 0;
+               gchar *caps_str = NULL;
+
+               caps_structure = gst_caps_get_structure(caps, 0);
+               gst_structure_get_int (caps_structure, "rate", &samplerate);
+               gst_structure_get_int (caps_structure, "channels", &channels);
+
+               if ( (channels > 0 && samplerate == 0)) {
+                       debug_log("exclude audio...");
+                       ret = FALSE;
+               }
+
+               caps_str = gst_caps_to_string(caps);
+               /* set it directly because not sent by TAG */
+               if (g_strrstr(caps_str, "mobile-xmf")) {
+                       mm_attrs_set_string_by_name(player->attrs, "content_audio_codec", "mobile-xmf");
+               }
+               MMPLAYER_FREEIF (caps_str);
+       } else if (g_str_has_prefix(mime, "video") && player->videodec_linked) {
+               debug_log("already video linked");
+               ret = FALSE;
+       } else {
+               debug_log("found new stream");
+       }
+
+       return ret;
+}
+
+static gint
+__mmplayer_gst_decode_autoplug_select(GstElement *bin,  GstPad* pad,
+GstCaps* caps, GstElementFactory* factory, gpointer data)
+{
+       /* NOTE : GstAutoplugSelectResult is defined in gstplay-enum.h but not exposed
+        We are defining our own and will be removed when it actually exposed */
+       typedef enum {
+               GST_AUTOPLUG_SELECT_TRY,
+               GST_AUTOPLUG_SELECT_EXPOSE,
+               GST_AUTOPLUG_SELECT_SKIP
+       } GstAutoplugSelectResult;
+
+       GstAutoplugSelectResult result = GST_AUTOPLUG_SELECT_TRY;
+       mm_player_t* player = (mm_player_t*)data;
+
+       gchar* factory_name = NULL;
+       gchar* caps_str = NULL;
+       const gchar* klass = NULL;
+       gint idx = 0;
+
+       factory_name = GST_PLUGIN_FEATURE_NAME (factory);
+       klass = gst_element_factory_get_klass(factory);
+       caps_str = gst_caps_to_string(caps);
+
+//     debug_log("found new element [%s] to link for caps [%s]", factory_name, caps_str);
+       debug_log("found new element [%s] to link", factory_name);
+
+       /* store type string */
+       if (player->type == NULL)
+       {
+               player->type = gst_caps_to_string(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;
+                       player->bypass_audio_effect = TRUE;
+               }
+               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;
+               }
+               else if (g_strrstr(player->type, "application/dash+xml"))
+               {
+                       player->profile.uri_type = MM_PLAYER_URI_TYPE_DASH;
+               }
+       }
+
+       /* filtering exclude keyword */
+       for ( idx = 0; player->ini.exclude_element_keyword[idx][0] != '\0'; idx++ )
+       {
+               if ( strstr(factory_name, player->ini.exclude_element_keyword[idx] ) )
+               {
+                       debug_warning("skipping [%s] by exculde keyword [%s]\n",
+                       factory_name, player->ini.exclude_element_keyword[idx] );
+
+                       // NOTE : does we need to check n_value against the number of item selected?
+                       result = GST_AUTOPLUG_SELECT_SKIP;
+                       goto DONE;
+               }
+       }
+
+       /* check factory class for filtering */
+       /* 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("skipping [%s] by not required\n", factory_name);
+               result = GST_AUTOPLUG_SELECT_SKIP;
+               goto DONE;
+       }
+
+       if (g_strrstr(factory_name, "mpegpsdemux"))
+       {
+               debug_log("skipping PS container - not support\n");
+               result = GST_AUTOPLUG_SELECT_SKIP;
+               goto DONE;
+       }
+
+       if (g_strrstr(factory_name, "mpegtsdemux") || g_strrstr(factory_name, "ssdemux"))
+       {
+               if (g_strrstr(factory_name, "ssdemux"))
+                       player->smooth_streaming = TRUE;
+
+               if (g_strrstr(caps_str, "video/x-h264"))
+               {
+                       player->needed_v_parser = TRUE;
+               }
+               else if (g_strrstr(caps_str, "video/mpeg"))
+               {
+                       player->needed_v_parser = TRUE;
+               }
+       }
+
+       /* check ALP Codec can be used or not */
+       if ((g_strrstr(klass, "Codec/Decoder/Audio")))
+       {
+               GstStructure* str = NULL;
+               gint channels = 0;
+
+               str = gst_caps_get_structure( caps, 0 );
+               if ( str )
+               {
+                       gst_structure_get_int (str, "channels", &channels);
+
+                       debug_log ("check audio ch : %d %d\n", player->max_audio_channels, channels);
+                       if (player->max_audio_channels < channels)
+                       {
+                               player->max_audio_channels = channels;
+                       }
+               }
+
+               if (!player->audiodec_linked)
+               {
+                       /* set stream information */
+                       __mmplayer_set_audio_attrs (player, caps);
+               }
+       }
+       else if ((g_strrstr(klass, "Codec/Decoder/Video")))
+       {
+               if (g_strrstr(factory_name, "omx_"))
+               {
+                       char *env = getenv ("MM_PLAYER_HW_CODEC_DISABLE");
+                       if (env != NULL)
+                       {
+                               if (strncasecmp(env, "yes", 3) == 0)
+                               {
+                                       debug_log ("skipping [%s] by disabled\n", factory_name);
+                                       result = GST_AUTOPLUG_SELECT_SKIP;
+                                       goto DONE;
+                               }
+                       }
+               }
+       }
+
+       if ((g_strrstr(klass, "Codec/Parser/Converter/Video")) ||
+               (g_strrstr(klass, "Codec/Decoder/Video")))
+       {
+               gint stype = 0;
+               gint width = 0;
+               GstStructure *str = NULL;
+               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 expose");
+                       if (player->set_mode.media_packet_video_stream == FALSE)
+                       {
+                               result = GST_AUTOPLUG_SELECT_EXPOSE;
+                               goto DONE;
+                       }
+               }
+
+               /* get w/h for omx state-tune */
+               str = gst_caps_get_structure (caps, 0);
+               gst_structure_get_int (str, "width", &width);
+
+               if (width != 0) {
+                       #define UHD_SIZE 3840*2160
+                       gint height = 0;
+                       gst_structure_get_int (str, "height", &height);
+
+                       if (player->v_stream_caps) {
+                               gst_caps_unref(player->v_stream_caps);
+                               player->v_stream_caps = NULL;
+                       }
+
+                       player->v_stream_caps = gst_caps_copy(caps);
+                       debug_log ("take caps for video state tune");
+                       MMPLAYER_LOG_GST_CAPS_TYPE(player->v_stream_caps);
+
+                       /* check video resolution */
+                       if (width*height == UHD_SIZE) {
+                               if ((util_is_miracast_connected()) && (player->msg_posted == FALSE)) {
+                                       MMMessageParamType msg = {0,};
+                                       /*post error*/
+                                       msg.code = MM_ERROR_PLAYER_RESOURCE_LIMIT;
+                                       debug_error("can't play in miracast");
+                                       MMPLAYER_POST_MSG(player, MM_MESSAGE_ERROR, &msg);
+                                       player->msg_posted = TRUE;
+                               }
+                       }
+               }
+       }
+    if ((g_strrstr(klass, "Codec/Parser/Audio")))
+    {
+               if (player->smooth_streaming && (g_strrstr(caps_str, "audio/mpeg")))
+               {
+                       debug_log ("ssdemux can't use audio parse");
+                       result = GST_AUTOPLUG_SELECT_SKIP;
+                       goto DONE;
+               }
+
+    }
+
+       if (g_strrstr(klass, "Decoder"))
+       {
+               const char* mime = NULL;
+               mime = gst_structure_get_name (gst_caps_get_structure(caps, 0));
+
+               if (g_str_has_prefix(mime, "video"))
+               {
+                       // __mmplayer_check_video_zero_cpoy(player, factory);
+
+                       player->not_supported_codec &= MISSING_PLUGIN_AUDIO;
+                       player->can_support_codec |= FOUND_PLUGIN_VIDEO;
+
+                       player->videodec_linked = 1;
+               }
+               else if(g_str_has_prefix(mime, "audio"))
+               {
+                       player->not_supported_codec &= MISSING_PLUGIN_VIDEO;
+                       player->can_support_codec |= FOUND_PLUGIN_AUDIO;
+
+                       player->audiodec_linked = 1;
+               }
+       }
+
+DONE:
+       MMPLAYER_FREEIF(caps_str);
+
+       return result;
+}
+
+
+#if 0
+static GValueArray*
+__mmplayer_gst_decode_autoplug_factories(GstElement *bin,  GstPad* pad,
+GstCaps * caps,  gpointer data)
+{
+       //mm_player_t* player = (mm_player_t*)data;
+
+       debug_log("decodebin is requesting factories for caps [%s] from element[%s]",
+               gst_caps_to_string(caps),
+               GST_ELEMENT_NAME(GST_PAD_PARENT(pad)));
+
+       return NULL;
+}
+#endif
+
+static GValueArray*
+__mmplayer_gst_decode_autoplug_sort(GstElement *bin,  GstPad* pad,
+GstCaps* caps, GValueArray* factories, gpointer data) // @
+{
+#define DEFAULT_IDX 0xFFFF
+
+       guint idx = 0;
+       guint a_omx_idx = DEFAULT_IDX;
+       guint a_dec_idx = DEFAULT_IDX;
+       guint v_dec_idx = DEFAULT_IDX;
+       guint v_parser_idx = DEFAULT_IDX;
+       guint new_pos = DEFAULT_IDX;
+       guint elem_idx = DEFAULT_IDX;
+
+       GValueArray* new_factories = NULL;
+       GValue val = { 0, };
+
+       GstElementFactory *factory = NULL;
+       const gchar* klass = NULL;
+       gchar* factory_name = NULL;
+       gchar* caps_str = NULL;
+
+       mm_player_t* player = (mm_player_t*)data;
+       caps_str = gst_caps_to_string(caps);
+
+       //debug_log("autoplug-sort signal [num: %d]\n", factories->n_values);
+       debug_log("requesting custom sorting for the factories for caps [%s]", caps_str);
+
+       MMPLAYER_FREEIF(caps_str);
+
+       for(idx=0; idx < factories->n_values;idx++)
+       {
+               factory =       g_value_get_object (g_value_array_get_nth (factories, idx));
+
+               klass = gst_element_factory_get_klass(factory);
+               factory_name = GST_PLUGIN_FEATURE_NAME (factory);
+
+               //debug_log("Klass [%s] Factory [%s]\n", klass, factory_name);
+
+               if (g_strrstr(klass, "Codec/Decoder/Audio"))
+               {
+                       if (a_dec_idx == DEFAULT_IDX)
+                               a_dec_idx = idx;
+
+                       /* check ALP Codec can be used or not */
+                       if ((a_omx_idx == DEFAULT_IDX) &&
+                               (g_strrstr(factory_name, "omx_mp3dec")) &&
+                               (__mmplayer_is_omx_decoder_type(player)))
+                       {
+                               debug_log("--> mp3_local : Priority of omx is higher than the others\n");
+                               a_omx_idx = idx;
+                               break;
+                       }
+               }
+               else if ((v_dec_idx == DEFAULT_IDX) && (g_strrstr(klass, "Codec/Decoder/Video")))
+               {
+                       v_dec_idx = idx;
+               }
+
+               if ((v_parser_idx == DEFAULT_IDX) &&
+                       (((player->smooth_streaming) &&
+                         (g_strrstr(factory_name, "legacyh264parse"))) ||
+                        // (g_strrstr(factory_name, "h264parse")) ||
+                        (g_strrstr(factory_name, "mpeg4videoparse"))))
+               {
+                       v_parser_idx = idx;
+               }
+       }
+
+       if (player->needed_v_parser || player->smooth_streaming)
+       {
+               debug_log("needed parser? %s, ss? %s\n",
+                                       (player->needed_v_parser)?"OO":"XX",
+                                       (player->smooth_streaming)?"OO":"XX");
+       }
+
+       new_pos = (a_dec_idx!=DEFAULT_IDX)?(a_dec_idx):((player->needed_v_parser)?(v_dec_idx):(v_parser_idx));
+       elem_idx = (a_omx_idx!=DEFAULT_IDX)?(a_omx_idx):((player->needed_v_parser)?(v_parser_idx):(v_dec_idx));
+
+       /* consider file mp3 audio only */
+       if ((elem_idx != DEFAULT_IDX) && (new_pos < elem_idx))
+       {
+               debug_log("[Re-arrange] factories sequence, new_pos : %d, elem_idx : %d\n", new_pos, elem_idx);
+
+               new_factories = g_value_array_copy (factories);
+
+               // insert omx decoder in front of other decoders
+               factory = g_value_get_object (g_value_array_get_nth (factories, elem_idx));
+
+               g_value_init (&val, G_TYPE_OBJECT);
+               g_value_set_object (&val, factory);
+               g_value_array_insert (new_factories, new_pos, &val);
+               g_value_unset (&val);
+
+               // remove duplicated omx element
+               g_value_array_remove(new_factories, elem_idx+1);
+
+               for(idx=0; idx < new_factories->n_values;idx++)
+               {
+                       factory = g_value_get_object (g_value_array_get_nth (new_factories, idx));
+
+                       debug_log("[Re-arranged] Klass [%s] Factory [%s]\n",
+                               gst_element_factory_get_klass(factory), GST_PLUGIN_FEATURE_NAME (factory));
+               }
+       }
+
+       /* returning NULL to keep current order */
+       return (new_factories)?(new_factories):(NULL);
+}
+
+static void
+__mmplayer_gst_decode_pad_removed(GstElement *elem,  GstPad* new_pad,
+gpointer data) // @
+{
+       //mm_player_t* player = (mm_player_t*)data;
+       GstCaps* caps = NULL;
+
+       debug_log("[Decodebin2] pad-removed signal\n");
+
+       caps = gst_pad_get_caps(new_pad);
+       if (caps)
+       {
+               gchar* caps_str = NULL;
+               caps_str = gst_caps_to_string(caps);
+
+               debug_log("pad removed caps : %s from %s", caps_str, GST_ELEMENT_NAME(elem) );
+
+               MMPLAYER_FREEIF(caps_str);
+       }
+}
+
+static void
+__mmplayer_gst_decode_drained(GstElement *bin, gpointer data)
+{
+       mm_player_t* player = (mm_player_t*)data;
+
+       MMPLAYER_FENTER();
+       return_if_fail ( player );
+
+       debug_log("__mmplayer_gst_decode_drained");
+
+       if (player->use_deinterleave == TRUE)
+       {
+               debug_log("group playing mode.");
+               return;
+       }
+
+       if ( !player->cmd_lock )
+       {
+               debug_warning("can't get cmd lock\n");
+               return;
+       }
+
+       if (!g_mutex_trylock(player->cmd_lock))
+       {
+               debug_warning("Fail to get cmd lock");
+               return;
+       }
+
+       if (!__mmplayer_verify_next_play_path(player))
+       {
+               debug_log("decoding is finished.");
+               g_mutex_unlock(player->cmd_lock);
+               return;
+       }
+
+       player->pp_rebuilding = TRUE;
+
+       /* deactivate pipeline except sinkbins to set up the new pipeline of next uri*/
+       __mmplayer_deactivate_old_path(player);
+
+       g_mutex_unlock(player->cmd_lock);
+
+       MMPLAYER_FLEAVE();
+}
+
+static void
+__mmplayer_gst_element_added (GstElement *bin, GstElement *element, gpointer data)
+{
+       mm_player_t* player = (mm_player_t*)data;
+       const gchar* klass = NULL;
+       gchar* factory_name = NULL;
+
+       klass = gst_element_factory_get_klass (gst_element_get_factory(element));
+       factory_name = GST_PLUGIN_FEATURE_NAME (gst_element_get_factory(element));
+
+       debug_log("new elem klass: %s, factory_name: %s, new elem name : %s\n", klass, factory_name, GST_ELEMENT_NAME(element));
+
+       if (__mmplayer_add_dump_buffer_probe(player, element))
+               debug_log("add buffer probe");
+
+       //<-
+       if (g_strrstr(klass, "Codec/Decoder/Audio"))
+       {
+               gchar* selected = NULL;
+               selected = g_strdup( GST_ELEMENT_NAME(element));
+               player->audio_decoders = g_list_append (player->audio_decoders, selected);
+       }
+       //-> temp code
+
+       if (g_strrstr(klass, "Parser"))
+       {
+               gchar* selected = NULL;
+
+               selected = g_strdup (factory_name);
+               player->parsers = g_list_append (player->parsers, selected);
+       }
+
+       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");
+               player->pipeline->mainbin[MMPLAYER_M_DEMUX].id = MMPLAYER_M_DEMUX;
+               player->pipeline->mainbin[MMPLAYER_M_DEMUX].gst = element;
+
+               /*Added for multi audio support */ // Q. del?
+               if (g_strrstr(klass, "Demux"))
+               {
+                       player->pipeline->mainbin[MMPLAYER_M_DEMUX_EX].id = MMPLAYER_M_DEMUX_EX;
+                       player->pipeline->mainbin[MMPLAYER_M_DEMUX_EX].gst = element;
+               }
+       }
+
+       if (g_strrstr(factory_name, "asfdemux") || g_strrstr(factory_name, "qtdemux") || g_strrstr(factory_name, "avidemux"))
+       {
+               int surface_type = 0;
+
+               mm_attrs_get_int_by_name (player->attrs, "display_surface_type", &surface_type);
+
+               /* playback protection if drm file */
+               if (player->use_video_stream || surface_type == MM_DISPLAY_SURFACE_EVAS || surface_type == MM_DISPLAY_SURFACE_X_EXT)
+               {
+                       debug_log("playback can be protected if playready drm");
+                       g_object_set (G_OBJECT(element), "playback-protection", TRUE, NULL);
+               }
+       }
+
+       // to support trust-zone only
+       if (g_strrstr(factory_name, "asfdemux"))
+       {
+               debug_log ("set file-location %s\n", player->profile.uri);
+               g_object_set (G_OBJECT(element), "file-location", player->profile.uri, NULL);
+
+               if (player->video_hub_download_mode == TRUE)
+               {
+                       g_object_set (G_OBJECT(element), "downloading-mode", player->video_hub_download_mode, NULL);
+               }
+       }
+       else if (g_strrstr(factory_name, "legacyh264parse"))    // ssdemux
+       {
+               debug_log ("[ssdemux] output-format to legacyh264parse\n");
+               g_object_set (G_OBJECT(element), "output-format", 1, NULL); /* NALU/Byte Stream format */
+       }
+       else if (g_strrstr(factory_name, "mpegaudioparse"))
+       {
+               if ((MMPLAYER_IS_HTTP_STREAMING(player)) &&
+                       (__mmplayer_is_only_mp3_type(player->type)))
+               {
+                       debug_log ("[mpegaudioparse] set streaming pull mode.");
+                       g_object_set(G_OBJECT(element), "http-pull-mp3dec", TRUE, NULL);
+               }
+       }
+       else if (g_strrstr(factory_name, "omx_"))
+       {
+               if (g_strrstr(klass, "Codec/Decoder/Video"))
+               {
+                       gboolean ret = FALSE;
+
+                       if (player->v_stream_caps != NULL)
+                       {
+                               GstPad *pad = gst_element_get_static_pad(element, "sink");
+
+                               if (pad)
+                               {
+                                       ret = gst_pad_set_caps(pad, player->v_stream_caps);
+                                       debug_log("found omx decoder, setting gst_pad_set_caps for omx (ret:%d)", ret);
+                                       MMPLAYER_LOG_GST_CAPS_TYPE(player->v_stream_caps);
+                                       gst_object_unref (pad);
+                               }
+                       }
+                       g_object_set (G_OBJECT(element), "state-tuning", TRUE, NULL);
+               }
+#ifdef _MM_PLAYER_ALP_PARSER
+               if (g_strrstr(factory_name, "omx_mp3dec"))
+               {
+                       g_list_foreach (player->parsers, check_name, player);
+               }
+#endif
+               player->pipeline->mainbin[MMPLAYER_M_DEC1].gst = element;
+       }
+
+       if (g_strrstr(GST_ELEMENT_NAME(element), "multiqueue"))
+       {
+               debug_log ("plugged element is multiqueue. take it\n");
+               player->pipeline->mainbin[MMPLAYER_M_DEMUXED_S_BUFFER].id = MMPLAYER_M_DEMUXED_S_BUFFER;
+               player->pipeline->mainbin[MMPLAYER_M_DEMUXED_S_BUFFER].gst = element;
+
+               if (MMPLAYER_IS_HTTP_STREAMING(player))
+               {
+                       __mm_player_streaming_set_multiqueue(player->streamer,
+                               element,
+                               TRUE,
+                               MAX_DECODEBIN_BUFFER_BYTES, // player->ini.http_max_size_bytes,
+                               player->ini.http_buffering_time,
+                               1.0,
+                               player->ini.http_buffering_limit);
+
+                       __mm_player_streaming_sync_property(player->streamer, player->pipeline->mainbin[MMPLAYER_M_AUTOPLUG].gst);
+               }
+       }
+
+       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-added" );
+       return;
+}
+
+static gboolean __mmplayer_configure_audio_callback(mm_player_t* player)
+{
+       MMPLAYER_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;
+       }
+
+       MMPLAYER_FLEAVE();
+
+       return TRUE;
+}
+
+static void
+__mmplayer_init_factories(mm_player_t* player) // @
+{
+       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);
+}
+
+static void
+__mmplayer_release_factories(mm_player_t* player) // @
+{
+       MMPLAYER_FENTER();
+       return_if_fail ( player );
+
+       if (player->factories)
+       {
+               gst_plugin_feature_list_free (player->factories);
+               player->factories = NULL;
+       }
+
+       MMPLAYER_FLEAVE();
+}
+
+static void
+__mmplayer_release_misc(mm_player_t* player)
+{
+       int i;
+       gboolean cur_mode = player->set_mode.rich_audio;
+       MMPLAYER_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->sent_bos = FALSE;
+       player->playback_rate = DEFAULT_PLAYBACK_RATE;
+
+       player->doing_seek = FALSE;
+
+       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->pending_seek.is_pending = FALSE;
+       player->pending_seek.format = MM_PLAYER_POS_FORMAT_TIME;
+       player->pending_seek.pos = 0;
+       player->msg_posted = FALSE;
+       player->has_many_types = FALSE;
+       player->is_drm_file = FALSE;
+       player->max_audio_channels = 0;
+       player->video_share_api_delta = 0;
+       player->video_share_clock_delta = 0;
+       player->sm.keep_last_pos = FALSE;
+       player->display_stat = MMPLAYER_DISPLAY_STATUS_NULL;
+       player->is_subtitle_force_drop = FALSE;
+       player->play_subtitle = FALSE;
+       player->use_textoverlay = FALSE;
+       player->adjust_subtitle_pos = 0;
+       player->last_multiwin_status = FALSE;
+       player->has_closed_caption = FALSE;
+       player->set_mode.media_packet_video_stream = FALSE;
+
+       memset(&player->set_mode, 0, sizeof(MMPlayerSetMode));
+       /* recover mode */
+       player->set_mode.rich_audio = cur_mode;
+
+       for (i = 0; i < MM_PLAYER_STREAM_COUNT_MAX; i++)
+       {
+               player->bitrate[i] = 0;
+               player->maximum_bitrate[i] = 0;
+       }
+
+       /* free memory related to audio effect */
+       MMPLAYER_FREEIF(player->audio_effect_info.custom_ext_level_for_plugin);
+
+       if (player->state_tune_caps)
+       {
+               gst_caps_unref(player->state_tune_caps);
+               player->state_tune_caps = NULL;
+       }
+
+       if (player->video_cb_probe_id)
+       {
+               GstPad *pad = NULL;
+
+               pad = gst_element_get_static_pad (player->video_fakesink, "sink");
+
+               if (pad) {
+                       debug_log("release video probe\n");
+
+                       /* release audio callback */
+                       gst_pad_remove_buffer_probe (pad, player->video_cb_probe_id);
+                       player->video_cb_probe_id = 0;
+                       player->video_stream_cb = NULL;
+                       player->video_stream_cb_user_param = NULL;
+               }
+       }
+
+       MMPLAYER_FLEAVE();
+}
+
+static void
+__mmplayer_release_misc_post(mm_player_t* player)
+{
+       char *original_uri = NULL;
+       MMPLAYER_FENTER();
+
+       /* player->pipeline is already released before. */
+
+       return_if_fail ( player );
+
+       mm_attrs_set_int_by_name(player->attrs, "content_video_found", 0);
+       mm_attrs_set_int_by_name(player->attrs, "content_audio_found", 0);
+
+       /* clean found parsers */
+       if (player->parsers)
+       {
+               GList *parsers = player->parsers;
+               for ( ;parsers ; parsers = g_list_next(parsers))
+               {
+                       gchar *name = parsers->data;
+                       MMPLAYER_FREEIF(name);
+               }
+               g_list_free(player->parsers);
+               player->parsers = NULL;
+       }
+
+       /* clean found audio decoders */
+       if (player->audio_decoders)
+       {
+               GList *a_dec = player->audio_decoders;
+               for ( ;a_dec ; a_dec = g_list_next(a_dec))
+               {
+                       gchar *name = a_dec->data;
+                       MMPLAYER_FREEIF(name);
+               }
+               g_list_free(player->audio_decoders);
+               player->audio_decoders = NULL;
+       }
+
+       /* clean the uri list except original uri */
+       if (player->uri_info.uri_list)
+       {
+               original_uri = g_list_nth_data(player->uri_info.uri_list, 0);
+
+               if (player->attrs)
+               {
+                       mm_attrs_set_string_by_name(player->attrs, "profile_uri", original_uri);
+                       debug_log("restore original uri = %s\n", original_uri);
+
+                       if (mmf_attrs_commit(player->attrs))
+                       {
+                               debug_error("failed to commit the original uri.\n");
+                       }
+               }
+
+               GList *uri_list = player->uri_info.uri_list;
+               for ( ;uri_list ; uri_list = g_list_next(uri_list))
+               {
+                       gchar *uri = uri_list->data;
+                       MMPLAYER_FREEIF(uri);
+               }
+               g_list_free(player->uri_info.uri_list);
+               player->uri_info.uri_list = NULL;
+       }
+
+       player->uri_info.uri_idx = 0;
+       player->src_changed = FALSE;
+
+       MMPLAYER_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);
+               gst_object_unref (element);
+               return NULL;
+       }
+
+       if ( ! gst_bin_add(GST_BIN(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst), element))
+       {
+               debug_error("failed to add %s\n", name);
+               gst_object_unref (element);
+               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);
+               gst_object_unref (element);
+               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 target_state = GST_STATE_READY;
+       gboolean isvideo_decoder = FALSE;
+       guint q_max_size_time = 0;
+
+       MMPLAYER_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);
+
+       /* need it to warm up omx before linking to pipeline */
+       if (g_strrstr(GST_ELEMENT_NAME( GST_PAD_PARENT ( srcpad ) ), "demux"))
+       {
+               debug_log("get demux caps.\n");
+               if (player->state_tune_caps)
+               {
+                       gst_caps_unref(player->state_tune_caps);
+                       player->state_tune_caps = NULL;
+               }
+               player->state_tune_caps = gst_caps_copy(GST_PAD_CAPS(srcpad));
+       }
+
+       /* NOTE : OMX Codec can check if resource is available or not at this state. */
+       if (g_strrstr(GST_ELEMENT_NAME(sinkelement), "omx"))
+       {
+               if (player->state_tune_caps != NULL)
+               {
+                       debug_log("set demux's caps to omx codec if resource is available");
+                       if (gst_pad_set_caps(gst_element_get_static_pad(sinkelement, "sink"), player->state_tune_caps))
+                       {
+                               target_state = GST_STATE_PAUSED;
+                               isvideo_decoder = TRUE;
+                               g_object_set(G_OBJECT(sinkelement), "state-tuning", TRUE, NULL);
+                       }
+                       else
+                       {
+                               debug_warning("failed to set caps for state tuning");
+                       }
+               }
+               gst_caps_unref(player->state_tune_caps);
+               player->state_tune_caps = NULL;
+       }
+
+       if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state(sinkelement, target_state) )
+       {
+               debug_error("failed to set %d state to %s\n", target_state, GST_ELEMENT_NAME( sinkelement ));
+               if (isvideo_decoder)
+               {
+                       gst_element_set_state(sinkelement, GST_STATE_NULL);
+                       gst_object_unref(G_OBJECT(sinkelement));
+                       player->keep_detecting_vcodec = TRUE;
+               }
+               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 = g_strdup(GST_ELEMENT_NAME( GST_PAD_PARENT ( srcpad )));
+
+               if (g_strrstr(name, "mpegtsdemux")|| g_strrstr(name, "ssdemux"))
+               {
+                       gchar *src_demux_caps_str = NULL;
+                       gchar *needed_parser = NULL;
+                       GstCaps *src_demux_caps = NULL;
+                       gboolean smooth_streaming = FALSE;
+
+                       src_demux_caps = gst_pad_get_caps(srcpad);
+                       src_demux_caps_str = gst_caps_to_string(src_demux_caps);
+
+                       gst_caps_unref(src_demux_caps);
+
+                       if (g_strrstr(src_demux_caps_str, "video/x-h264"))
+                       {
+                               if (g_strrstr(name, "ssdemux"))
+                               {
+                                       needed_parser = g_strdup("legacyh264parse");
+                                       smooth_streaming = TRUE;
+                               }
+                               else
+                               {
+                                       needed_parser = g_strdup("h264parse");
+                               }
+                       }
+                       else if (g_strrstr(src_demux_caps_str, "video/mpeg"))
+                       {
+                               needed_parser = g_strdup("mpeg4videoparse");
+                       }
+                       MMPLAYER_FREEIF(src_demux_caps_str);
+
+                       if (needed_parser)
+                       {
+                               parser = __mmplayer_element_create_and_link(player, srcpad, needed_parser);
+                               MMPLAYER_FREEIF(needed_parser);
+
+                               if ( !parser )
+                               {
+                                       debug_error("failed to create parser\n");
+                               }
+                               else
+                               {
+                                       if (smooth_streaming)
+                                       {
+                                               g_object_set (parser, "output-format", 1, NULL); /* NALU/Byte Stream format */
+                                       }
+
+                                       /* 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;
+
+                       if (player->profile.uri_type == MM_PLAYER_URI_TYPE_SS)
+                       {
+                               g_object_set (G_OBJECT (mainbin[MMPLAYER_M_Q1].gst), "max-size-time", 0 , NULL);
+                               g_object_set (G_OBJECT (mainbin[MMPLAYER_M_Q1].gst), "max-size-buffers", 2, NULL);
+                               g_object_set (G_OBJECT (mainbin[MMPLAYER_M_Q1].gst), "max-size-bytes", 0, NULL);
+                       }
+                       else
+                       {
+                               if (!MMPLAYER_IS_RTSP_STREAMING(player))
+                                       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;
+
+                       if (player->profile.uri_type == MM_PLAYER_URI_TYPE_SS)
+                       {
+                               g_object_set (G_OBJECT (mainbin[MMPLAYER_M_Q2].gst), "max-size-time", 0 , NULL);
+                               g_object_set (G_OBJECT (mainbin[MMPLAYER_M_Q2].gst), "max-size-buffers", 2, NULL);
+                               g_object_set (G_OBJECT (mainbin[MMPLAYER_M_Q2].gst), "max-size-bytes", 0, NULL);
+                       }
+                       else
+                       {
+                               if (!MMPLAYER_IS_RTSP_STREAMING(player))
+                                       g_object_set (G_OBJECT (mainbin[MMPLAYER_M_Q2].gst), "max-size-time", q_max_size_time * GST_SECOND, NULL);
+                       }
+               }
+               else
+               {
+                       debug_error("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*/
+               const gchar *mime_type = NULL;
+               {
+                       srccaps = gst_pad_get_caps( srcpad );
+                       if ( !srccaps )
+                               goto ERROR;
+
+                       str = gst_caps_get_structure( srccaps, 0 );
+                       if ( ! str )
+                               goto ERROR;
+
+                       mime_type = gst_structure_get_name(str);
+                       if ( ! mime_type )
+                               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(mime_type, "video"))
+                       {
+                               player->can_support_codec ^= FOUND_PLUGIN_VIDEO;
+                       }
+                       else if (strstr(mime_type, "audio"))
+                       {
+                               player->can_support_codec ^= FOUND_PLUGIN_AUDIO;
+                       }
+                       goto ERROR;
+               }
+
+               if (strstr(mime_type, "video"))
+               {
+                       player->videodec_linked = 1;
+                       debug_msg("player->videodec_linked set to 1\n");
+
+               }
+               else if (strstr(mime_type, "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_MUXED_S_BUFFER].gst)
+                               {
+                                       debug_log("creating http streaming buffering queue\n");
+
+                                       queue = gst_element_factory_make("queue2", "queue2");
+                                       if ( ! queue )
+                                       {
+                                               debug_error ( "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_MUXED_S_BUFFER].id = MMPLAYER_M_MUXED_S_BUFFER;
+                                       mainbin[MMPLAYER_M_MUXED_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);
+                                               }
+                                               else
+                                               {
+                                                       dur_bytes = 0;
+                                               }
+                                       }
+
+                                       /* NOTE : we cannot get any duration info from ts container in case of streaming */
+                                       if(!g_strrstr(GST_ELEMENT_NAME(sinkelement), "mpegtsdemux"))
+                                       {
+                                               __mm_player_streaming_set_queue2(player->streamer,
+                                                       queue,
+                                                       TRUE,
+                                                       player->ini.http_max_size_bytes,
+                                                       player->ini.http_buffering_time,
+                                                       1.0,
+                                                       player->ini.http_buffering_limit,
+                                                       use_file_buffer,
+                                                       file_buffering_path,
+                                                       (guint64)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 ("always pad but, caps has many types");
+                                       MMPLAYER_LOG_GST_CAPS_TYPE(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, MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "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, MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "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, MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "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;
+       }
+
+       MMPLAYER_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;
+
+       MMPLAYER_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 );
+
+       MMPLAYER_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;
+
+       MMPLAYER_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);
+               }
+       }
+
+       MMPLAYER_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;
+
+       MMPLAYER_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;
+
+               if (player->audiodec_linked)
+               {
+                       gst_caps_unref(caps);
+                       debug_log("multi tracks. skip to plug");
+                       return;
+               }
+
+               /* 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);
+       }
+       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);
+
+       MMPLAYER_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;
+
+       MMPLAYER_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);
+                       }
+
+               }
+       }
+
+       MMPLAYER_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;
+
+       MMPLAYER_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) ;
+                               if (factory)
+                               {
+                                        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) ;
+
+       if (factory)
+       {
+               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);
+
+       MMPLAYER_FLEAVE();
+
+       return FALSE;
+}
+
+
+gboolean
+__mmplayer_check_subtitle( mm_player_t* player )
+{
+       MMHandleType attrs = 0;
+       char *subtitle_uri = NULL;
+
+       MMPLAYER_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));
+       player->is_external_subtitle_present = TRUE;
+
+       MMPLAYER_FLEAVE();
+
+       return TRUE;
+}
+
+static gboolean
+__mmplayer_can_extract_pcm( mm_player_t* player )
+{
+       MMHandleType attrs = 0;
+       gboolean is_drm = FALSE;
+       gboolean sound_extraction = FALSE;
+
+       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 */
+       if (g_object_class_find_property(G_OBJECT_GET_CLASS(player->pipeline->mainbin[MMPLAYER_M_SRC].gst), "is-drm"))
+               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("checking pcm extraction mode : %d, drm : %d", sound_extraction, is_drm);
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+static gboolean
+__mmplayer_handle_gst_error ( mm_player_t* player, GstMessage * message, GError* error )
+{
+       MMMessageParamType msg_param;
+       gchar *msg_src_element;
+
+       MMPLAYER_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);
+       }
+
+       /* no error */
+       if (msg_param.code == MM_ERROR_NONE)
+               return TRUE;
+
+       /* post error to application */
+       if ( ! player->msg_posted )
+       {
+               MMPLAYER_POST_MSG( player, MM_MESSAGE_ERROR, &msg_param );
+               /* don't post more if one was sent already */
+               player->msg_posted = TRUE;
+       }
+       else
+       {
+               debug_log("skip error post because it's sent already.\n");
+       }
+
+       MMPLAYER_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;
+
+       MMPLAYER_FENTER();
+
+       return_val_if_fail ( player, FALSE );
+       return_val_if_fail ( message, FALSE );
+
+       s = malloc( sizeof(GstStructure) );
+       if ( s == NULL)
+       {
+               debug_error ("malloc fail");
+               return FALSE;
+       }
+       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;
@@ -9757,833 +14781,1756 @@ __mmplayer_handle_streaming_error  ( mm_player_t* player, GstMessage * message )
                        msg_param.code = MM_ERROR_PLAYER_STREAMING_OPTION_NOT_SUPPORTED;
                        break;
                default:
-                       return MM_ERROR_PLAYER_STREAMING_FAIL;
+                       {
+                               MMPLAYER_FREEIF(s);
+                               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->msg_posted )
+       {
+               MMPLAYER_POST_MSG( player, MM_MESSAGE_ERROR, &msg_param );
+
+               /* don't post more if one was sent already */
+               player->msg_posted = TRUE;
+       }
+       else
+       {
+               debug_log("skip error post because it's sent already.\n");
+       }
+
+       MMPLAYER_FREEIF(s);
+       MMPLAYER_FLEAVE();
+       g_free(error_string);
+
+       return TRUE;
+
+}
+
+static gint
+__gst_handle_core_error( mm_player_t* player, int code )
+{
+       gint trans_err = MM_ERROR_NONE;
+
+       MMPLAYER_FENTER();
+
+       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       switch ( code )
+       {
+               case GST_CORE_ERROR_MISSING_PLUGIN:
+                       return MM_ERROR_PLAYER_NOT_SUPPORTED_FORMAT;
+               case GST_CORE_ERROR_STATE_CHANGE:
+               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;
+       }
+
+       MMPLAYER_FLEAVE();
+
+       return trans_err;
+}
+
+static gint
+__gst_handle_library_error( mm_player_t* player, int code )
+{
+       gint trans_err = MM_ERROR_NONE;
+
+       MMPLAYER_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;
+       }
+
+       MMPLAYER_FLEAVE();
+
+       return trans_err;
+}
+
+
+static gint
+__gst_handle_resource_error( mm_player_t* player, int code )
+{
+       gint trans_err = MM_ERROR_NONE;
+
+       MMPLAYER_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 )
+                               || MMPLAYER_IS_RTSP_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 )
+                               || MMPLAYER_IS_RTSP_STREAMING(player))
+                       {
+                               trans_err = MM_ERROR_PLAYER_STREAMING_FAIL;
+                               break;
+                       }
+               case GST_RESOURCE_ERROR_WRITE:
+               case GST_RESOURCE_ERROR_FAILED:
+               case GST_RESOURCE_ERROR_SEEK:
+               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_SYNC:
+               case GST_RESOURCE_ERROR_SETTINGS:
+               default:
+                       trans_err = MM_ERROR_PLAYER_INTERNAL;
+               break;
+       }
+
+       MMPLAYER_FLEAVE();
+
+       return trans_err;
+}
+
+
+static gint
+__gst_handle_stream_error( mm_player_t* player, GError* error, GstMessage * message )
+{
+       gint trans_err = MM_ERROR_NONE;
+
+       MMPLAYER_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:
+               case GST_STREAM_ERROR_CODEC_NOT_FOUND:
+                        trans_err = __gst_transform_gsterror( player, message, error );
+               break;
+
+               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;
+       }
+
+       MMPLAYER_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;
+
+       MMPLAYER_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);
+
+       //<-
+       {
+               int msg_src_pos = 0;
+               gint active_pad_index = player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].active_pad_index;
+               debug_log ("current  active pad index  -%d", active_pad_index);
+
+               if  (src_element_name) {
+                       int idx = 0;
+
+                       if (player->audio_decoders) {
+                               GList *adec = player->audio_decoders;
+                               for ( ;adec ; adec = g_list_next(adec)) {
+                                       gchar *name = adec->data;
+
+                                       debug_log("found audio decoder name  = %s", name);
+                                       if (g_strrstr(name, src_element_name)) {
+                                               msg_src_pos = idx;
+                                               break;
+                                       }
+                                       idx++;
+                               }
+                       }
+                       debug_log("active pad = %d, error src index = %d", active_pad_index,  msg_src_pos);
+               }
+
+               if (active_pad_index != msg_src_pos) {
+                       debug_log("skip error because error is posted from no activated track");
+                       return MM_ERROR_NONE;
+               }
+       }
+       //-> temp code
+
+       switch ( error->code )
+       {
+               case GST_STREAM_ERROR_DECODE:
+               {
+                       /* 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_CODEC_NOT_FOUND:
+               case GST_STREAM_ERROR_TYPE_NOT_FOUND:
+               case GST_STREAM_ERROR_WRONG_TYPE:
+                       return MM_ERROR_PLAYER_NOT_SUPPORTED_FORMAT;
+
+               case GST_STREAM_ERROR_FAILED:
+               {
+                       /* Decoder Custom Message */
+                       if ( strstr(error->message, "ongoing") )
+                       {
+                               if ( strncasecmp(klass, "audio", 5) )
+                               {
+                                       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 ( strncasecmp(klass, "video", 5) )
+                               {
+                                       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_NOT_SUPPORTED_FORMAT;
+               }
+               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);
+
+                       if ( strstr(error->message, "rights expired") )
+                       {
+                               return MM_ERROR_PLAYER_DRM_EXPIRED;
+                       }
+                       else if ( strstr(error->message, "no rights") )
+                       {
+                               return MM_ERROR_PLAYER_DRM_NO_LICENSE;
+                       }
+                       else if ( strstr(error->message, "has future rights") )
+                       {
+                               return MM_ERROR_PLAYER_DRM_FUTURE_USE;
+                       }
+                       else if ( strstr(error->message, "opl violation") )
+                       {
+                               return MM_ERROR_PLAYER_DRM_OUTPUT_PROTECTION;
+                       }
+                       return MM_ERROR_PLAYER_DRM_NOT_AUTHORIZED;
+               }
+               break;
+
+               default:
+               break;
        }
 
-       error_string = g_strdup(gst_structure_get_string (s, "error_string"));
-       if ( error_string )
-               msg_param.data = (void *) error_string;
+       MMPLAYER_FLEAVE();
 
-       if ( message->src )
+       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_handle_eos_delay( mm_player_t* player, int delay_in_ms )
+{
+       return_if_fail( player );
+
+
+       /* post now if delay is zero */
+       if ( delay_in_ms == 0 || player->set_mode.pcm_extraction)
        {
-               msg_src_element = GST_ELEMENT_NAME( GST_ELEMENT_CAST( message->src ) );
+               debug_log("eos delay is zero. posting EOS now\n");
+               MMPLAYER_POST_MSG( player, MM_MESSAGE_END_OF_STREAM, NULL );
 
-               debug_error("-Msg src : [%s] Code : [%x] Error : [%s]  \n",
-                       msg_src_element, msg_param.code, (char*)msg_param.data );
+               if ( player->set_mode.pcm_extraction )
+                       __mmplayer_cancel_eos_timer(player);
+
+               return;
+       }
+
+       /* cancel if existing */
+       __mmplayer_cancel_eos_timer( player );
+
+       /* 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 );
+
+       player->context.global_default = g_main_context_default ();
+       debug_log("global default context = %p, eos timer id = %d", player->context.global_default, player->eos_timer);
+
+       /* 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 );
+       }
+}
+
+static void
+__mmplayer_cancel_eos_timer( mm_player_t* player )
+{
+       return_if_fail( player );
+
+       if ( player->eos_timer )
+       {
+               debug_log("cancel eos timer");
+               __mmplayer_remove_g_source_from_context(player->context.global_default, player->eos_timer);
+               player->eos_timer = 0;
+       }
+
+       return;
+}
+
+static gboolean
+__mmplayer_eos_timer_cb(gpointer u_data)
+{
+       mm_player_t* player = NULL;
+       player = (mm_player_t*) u_data;
+
+       return_val_if_fail( player, FALSE );
+
+       if ( player->play_count > 1 )
+       {
+               gint ret_value = 0;
+               ret_value = __gst_set_position( player, MM_PLAYER_POS_FORMAT_TIME, 0, TRUE);
+               if (ret_value == MM_ERROR_NONE)
+               {
+                       MMHandleType attrs = 0;
+                       attrs = MMPLAYER_GET_ATTRS(player);
+
+                       /* we successeded to rewind. update play count and then wait for next EOS */
+                       player->play_count--;
+
+                       mm_attrs_set_int_by_name(attrs, "profile_play_count", player->play_count);
+                       mmf_attrs_commit ( attrs );
+               }
+               else
+               {
+                       debug_error("seeking to 0 failed in repeat play");
+               }
+       }
+       else
+       {
+               /* posting eos */
+               MMPLAYER_POST_MSG( player, MM_MESSAGE_END_OF_STREAM, NULL );
+       }
+
+       /* 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;
+
+       MMPLAYER_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);
+
+               if (player->sm.antishock) {
+                       antishock = TRUE;
+                       player->sm.antishock = 0;
+               }
+
+               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);
+       }
+
+       MMPLAYER_FLEAVE();
+
+       return;
+}
+
+
+static gboolean
+__mmplayer_link_decoder( mm_player_t* player, GstPad *srcpad)
+{
+       const gchar* name = NULL;
+       GstStructure* str = NULL;
+       GstCaps* srccaps = NULL;
+
+       MMPLAYER_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 );
+
+       MMPLAYER_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;
+
+       MMPLAYER_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;
+               }
        }
-
-       /* post error to application */
-       if ( ! player->posted_msg )
+       if (strstr(name, "audio"))
        {
-               MMPLAYER_POST_MSG( player, MM_MESSAGE_ERROR, &msg_param );
-
-               /* don't post more if one was sent already */
-               player->posted_msg = TRUE;
+               if(player->audiosink_linked)
+               {
+                       debug_msg("Audio Sink already linked\n");
+                       return FALSE;
+               }
        }
-       else
+       if (strstr(name, "text"))
        {
-               debug_log("skip error post because it's sent already.\n");
+               if(player->textsink_linked)
+               {
+                       debug_msg("Text Sink already linked\n");
+                       return FALSE;
+               }
        }
 
-       debug_fleave();
+       gst_caps_unref( srccaps );
+
+       MMPLAYER_FLEAVE();
 
        return TRUE;
+       //return (!player->videosink_linked || !player->audiosink_linked);
+
+ERROR:
+       if ( srccaps )
+               gst_caps_unref( srccaps );
 
+       return FALSE;
 }
 
-static gint
-__gst_handle_core_error( mm_player_t* player, int code )
+
+/* sending event to one of sinkelements */
+static gboolean
+__gst_send_event_to_sink( mm_player_t* player, GstEvent* event )
 {
-       gint trans_err = MM_ERROR_NONE;
+       GstEvent * event2 = NULL;
+       GList *sinks = NULL;
+       gboolean res = FALSE;
+       GstPad *sinkpad = NULL;
+       MMPLAYER_FENTER();
 
-       debug_fenter();
+       return_val_if_fail( player, FALSE );
+       return_val_if_fail ( event, FALSE );
 
-       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       if ( player->play_subtitle && !player->use_textoverlay)
+               event2 = gst_event_copy((const GstEvent *)event);
 
-       switch ( code )
+       sinks = player->sink_elements;
+       while (sinks)
        {
-               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;
+               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);
        }
 
-       debug_fleave();
+#if 0
+       if (internal_sub)
+         request pad name = sink0;
+       else
+         request pad name = sink1; // external
+#endif
 
-       return trans_err;
+       /* 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 = NULL;
+         gchar *change_pad_name = NULL;
+
+         debug_log ("external subtitle active idx = %d", player->external_text_idx);
+
+         /* To get the new pad from the selector */
+         change_pad_name = g_strdup_printf ("sink%d", player->external_text_idx);
+         if (change_pad_name == NULL)
+         {
+           debug_warning ("Pad does not exists\n");
+           return FALSE;
+         }
+
+         g_object_get (player->pipeline->mainbin[MMPLAYER_M_T_INPUT_SELECTOR].gst, "active-pad", &sinkpad, NULL);
+         if (!strcmp (GST_PAD_NAME (sinkpad), change_pad_name))
+         {
+           debug_log ("active pad & change pad are same no need to change active pad");
+         }
+         else
+         {
+           sinkpad = gst_element_get_static_pad (player->pipeline->mainbin[MMPLAYER_M_T_INPUT_SELECTOR].gst, change_pad_name);
+           if (sinkpad == NULL)
+           {
+             debug_error ("failed to get static pad");;
+             return FALSE;
+           }
+
+           debug_log ("Set Active Pad - %s:%s\n", GST_DEBUG_PAD_NAME(sinkpad));
+           g_object_set (player->pipeline->mainbin[MMPLAYER_M_T_INPUT_SELECTOR].gst, "active-pad", sinkpad, NULL);
+         }
+
+         text_sink = GST_ELEMENT_CAST (player->pipeline->textbin[MMPLAYER_T_FAKE_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);
+         }
+         g_free(change_pad_name);
+       }
+
+       gst_event_unref (event);
+
+       MMPLAYER_FLEAVE();
+
+       return res;
 }
 
-static gint
-__gst_handle_library_error( mm_player_t* player, int code )
+static void
+__mmplayer_add_sink( mm_player_t* player, GstElement* sink )
 {
-       gint trans_err = MM_ERROR_NONE;
-
-       debug_fenter();
+       MMPLAYER_FENTER();
 
-       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_if_fail ( player );
+       return_if_fail ( sink );
 
-       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();
+       player->sink_elements =
+               g_list_append(player->sink_elements, sink);
 
-       return trans_err;
+       MMPLAYER_FLEAVE();
 }
 
+static void
+__mmplayer_del_sink( mm_player_t* player, GstElement* sink )
+{
+       MMPLAYER_FENTER();
 
-static gint
-__gst_handle_resource_error( mm_player_t* player, int code )
+       return_if_fail ( player );
+       return_if_fail ( sink );
+
+       player->sink_elements =
+                       g_list_remove(player->sink_elements, sink);
+
+       MMPLAYER_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 )
 {
-       gint trans_err = MM_ERROR_NONE;
+       GstEvent* event = NULL;
+       gboolean result = FALSE;
 
-       debug_fenter();
+       MMPLAYER_FENTER();
 
-       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail( player, FALSE );
 
-       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;
-       }
+       __mmplayer_drop_subtitle(player, FALSE);
 
-       debug_fleave();
+       event = gst_event_new_seek (rate, format, flags, cur_type,
+               cur, stop_type, stop);
 
-       return trans_err;
-}
+       result = __gst_send_event_to_sink( player, event );
 
+       MMPLAYER_FLEAVE();
 
-static gint
-__gst_handle_stream_error( mm_player_t* player, GError* error, GstMessage * message )
+       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, MMPlayerSignalType type)
 {
-       gint trans_err = MM_ERROR_NONE;
+       GList* sig_list = NULL;
+       MMPlayerSignalItem* item = NULL;
 
-       debug_fenter();
+       MMPLAYER_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 );
+       return_if_fail( player );
 
-       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:
-                        trans_err = __gst_transform_gsterror( player, message, error );
-               break;
+       debug_log("release signals type : %d", type);
 
-               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:
-               case GST_STREAM_ERROR_DECRYPT_NOKEY:
-               default:
-                       trans_err = MM_ERROR_PLAYER_INVALID_STREAM;
-               break;
+       if ((type < MM_PLAYER_SIGNAL_TYPE_AUTOPLUG) || (type >= MM_PLAYER_SIGNAL_TYPE_ALL))
+       {
+               __mmplayer_release_signal_connection (player, MM_PLAYER_SIGNAL_TYPE_AUTOPLUG);
+               __mmplayer_release_signal_connection (player, MM_PLAYER_SIGNAL_TYPE_VIDEOBIN);
+               __mmplayer_release_signal_connection (player, MM_PLAYER_SIGNAL_TYPE_AUDIOBIN);
+               __mmplayer_release_signal_connection (player, MM_PLAYER_SIGNAL_TYPE_TEXTBIN);
+               __mmplayer_release_signal_connection (player, MM_PLAYER_SIGNAL_TYPE_OTHERS);
+               return;
        }
 
-       debug_fleave();
+       sig_list = player->signals[type];
 
-       return trans_err;
-}
+       for ( ; sig_list; sig_list = sig_list->next )
+       {
+               item = sig_list->data;
 
+               if ( item && item->obj && GST_IS_ELEMENT(item->obj) )
+               {
+                       if ( g_signal_handler_is_connected ( item->obj, item->sig ) )
+                       {
+                               g_signal_handler_disconnect ( item->obj, item->sig );
+                       }
+               }
 
-/* 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();
+               MMPLAYER_FREEIF( item );
+       }
 
-       /* 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 );
+       g_list_free ( player->signals[type] );
+       player->signals[type] = NULL;
+
+       MMPLAYER_FLEAVE();
+
+       return;
+}
+
+int _mmplayer_change_videosink(MMHandleType handle, MMDisplaySurfaceType surface_type, void *display_overlay)
+{
+       mm_player_t* player = 0;
+       int prev_display_surface_type = 0;
+       void *prev_display_overlay = NULL;
+       const gchar *klass = NULL;
+       gchar *cur_videosink_name = NULL;
+       int ret = 0;
+       int i = 0;
+       int num_of_dec = 2; /* DEC1, DEC2 */
 
-       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;
+       MMPLAYER_FENTER();
 
-       factory = gst_element_get_factory(src_element);
-       if ( !factory )
-               goto INTERNAL_ERROR;
-       
-       klass = gst_element_factory_get_klass(factory);
-       if ( !klass )
-               goto INTERNAL_ERROR;
+       return_val_if_fail(handle, MM_ERROR_COMMON_INVALID_ARGUMENT);
+       return_val_if_fail(display_overlay, MM_ERROR_COMMON_INVALID_ARGUMENT);
 
-       debug_log("error code=%d, msg=%s, src element=%s, class=%s\n", 
-                       error->code, error->message, src_element_name, klass);
+       player = MM_PLAYER_CAST(handle);
 
+       if (surface_type < MM_DISPLAY_SURFACE_X && surface_type > MM_DISPLAY_SURFACE_EVAS)
+       {
+               debug_error("Not support this surface type(%d) for changing vidoesink", surface_type);
+               MMPLAYER_FLEAVE();
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
 
-       switch ( error->code )
+       /* load previous attributes */
+       if (player->attrs)
        {
-               case GST_STREAM_ERROR_DECODE:
+               mm_attrs_get_int_by_name (player->attrs, "display_surface_type", &prev_display_surface_type);
+               mm_attrs_get_data_by_name (player->attrs, "display_overlay", &prev_display_overlay);
+               debug_log("[0: X surface, 1: EVAS surface] previous surface type(%d), new surface type(%d)", prev_display_surface_type, surface_type);
+               if (prev_display_surface_type == surface_type)
                {
-                       /* 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;
+                       debug_log("incoming display surface type is same as previous one, do nothing..");
+                       MMPLAYER_FLEAVE();
+                       return MM_ERROR_NONE;
                }
-               break;
+       }
+       else
+       {
+               debug_error("failed to load attributes");
+               MMPLAYER_FLEAVE();
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
 
-               case GST_STREAM_ERROR_WRONG_TYPE:
+       /* check videosink element is created */
+       if (!player->pipeline || !player->pipeline->videobin ||
+               !player->pipeline->videobin[MMPLAYER_V_SINK].gst )
+       {
+               debug_log("videosink element is not yet ready");
+
+               /* videobin is not created yet, so we just set attributes related to display surface */
+               debug_log("store display attribute for given surface type(%d)", surface_type);
+               mm_attrs_set_int_by_name (player->attrs, "display_surface_type", surface_type);
+               mm_attrs_set_data_by_name (player->attrs, "display_overlay", display_overlay, sizeof(display_overlay));
+               if ( mmf_attrs_commit ( player->attrs ) )
                {
-                       return MM_ERROR_PLAYER_NOT_SUPPORTED_FORMAT;
+                       debug_error("failed to commit attribute");
+                       MMPLAYER_FLEAVE();
+                       return MM_ERROR_PLAYER_INTERNAL;
+               }
+               MMPLAYER_FLEAVE();
+               return MM_ERROR_NONE;
+       }
+       else
+       {
+               /* get player command status */
+               if ( !(player->cmd == MMPLAYER_COMMAND_START || player->cmd == MMPLAYER_COMMAND_RESUME || player->cmd == MMPLAYER_COMMAND_PAUSE) )
+               {
+                       debug_error("invalid player command status(%d), __mmplayer_do_change_videosink() is only available with START/RESUME/PAUSE command",player->cmd);
+                       MMPLAYER_FLEAVE();
+                       return MM_ERROR_PLAYER_INVALID_STATE;
                }
-               break;
 
-               case GST_STREAM_ERROR_FAILED:
+               /* get a current videosink name */
+               cur_videosink_name = GST_ELEMENT_NAME(player->pipeline->videobin[MMPLAYER_V_SINK].gst);
+
+               /* surface change */
+               for ( i = 0 ; i < num_of_dec ; i++)
                {
-                       /* Decoder Custom Message */
-                       if ( strstr(error->message, "ongoing") )
+                       if ( player->pipeline->mainbin &&
+                               player->pipeline->mainbin[MMPLAYER_M_DEC1+i].gst )
                        {
-                               if ( strcasestr(klass, "audio") )
+                               klass = gst_element_factory_get_klass( gst_element_get_factory(player->pipeline->mainbin[MMPLAYER_M_DEC1+i].gst) );
+                               if ((g_strrstr(klass, "Codec/Decoder/Video")))
                                {
-                                       if ( ( player->can_support_codec & FOUND_PLUGIN_VIDEO ) )
-                                       {
-                                               debug_log("Video can keep playing.\n");
-                                               return MM_ERROR_PLAYER_AUDIO_CODEC_NOT_FOUND;
-                                       }
-                                       else
+                                       if ( !strncmp(cur_videosink_name, "x", 1) && (surface_type == MM_DISPLAY_SURFACE_EVAS) )
                                        {
-                                               goto CODEC_NOT_FOUND;
+                                               ret = __mmplayer_do_change_videosink(player, MMPLAYER_M_DEC1+i, player->ini.videosink_element_evas, surface_type, display_overlay);
+                                               if (ret)
+                                               {
+                                                       goto ERROR_CASE;
+                                               }
+                                               else
+                                               {
+                                                       debug_warning("success to changing display surface(%d)",surface_type);
+                                                       MMPLAYER_FLEAVE();
+                                                       return MM_ERROR_NONE;
+                                               }
                                        }
-
-                               }
-                               else if ( strcasestr(klass, "video") )
-                               {
-                                       if ( ( player->can_support_codec & FOUND_PLUGIN_AUDIO ) )
+                                       else if (!strncmp(cur_videosink_name, "evas", 4) && (surface_type == MM_DISPLAY_SURFACE_X) )
                                        {
-                                               debug_log("Audio can keep playing.\n");
-                                               return MM_ERROR_PLAYER_VIDEO_CODEC_NOT_FOUND;
+                                               ret = __mmplayer_do_change_videosink(player, MMPLAYER_M_DEC1+i, player->ini.videosink_element_x, surface_type, display_overlay);
+                                               if (ret)
+                                               {
+                                                       goto ERROR_CASE;
+                                               }
+                                               else
+                                               {
+                                                       debug_warning("success to changing display surface(%d)",surface_type);
+                                                       MMPLAYER_FLEAVE();
+                                                       return MM_ERROR_NONE;
+                                               }
                                        }
                                        else
                                        {
-                                               goto CODEC_NOT_FOUND;
+                                               debug_error("invalid incoming surface type(%d) and current videosink_name(%s) for changing display surface",surface_type, cur_videosink_name);
+                                               ret = MM_ERROR_PLAYER_INTERNAL;
+                                               goto ERROR_CASE;
                                        }
                                }
                        }
-       return MM_ERROR_PLAYER_INVALID_STREAM;
-               }
-               break;
-
-               case GST_STREAM_ERROR_TYPE_NOT_FOUND:
-               {                               
-                       goto CODEC_NOT_FOUND;
-               }
-               break;
-
-               case GST_STREAM_ERROR_DECRYPT:
-               {                               
-                       debug_log("%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;
+ERROR_CASE:
+       /* rollback to previous attributes */
+       mm_attrs_set_int_by_name (player->attrs, "display_surface_type", prev_display_surface_type);
+       mm_attrs_set_data_by_name(player->attrs, "display_overlay", prev_display_overlay, sizeof(prev_display_overlay));
+       if ( mmf_attrs_commit ( player->attrs ) )
+       {
+               debug_error("failed to commit attributes to rollback");
+               MMPLAYER_FLEAVE();
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+       MMPLAYER_FLEAVE();
+       return ret;
 }
 
-static void
-__mmplayer_post_delayed_eos( mm_player_t* player, int delay_in_ms )
+/* NOTE : It does not support some use cases, eg using colorspace converter */
+int
+__mmplayer_do_change_videosink(mm_player_t* player, const int dec_index, const char *videosink_element, MMDisplaySurfaceType surface_type, void *display_overlay)
 {
-       debug_fenter();
+       GstPad *src_pad_dec = NULL;
+       GstPad *sink_pad_videosink = NULL;
+       GstPad *sink_pad_videobin = NULL;
+       GstClock *clock = NULL;
+       MMPlayerStateType previous_state = MM_PLAYER_STATE_NUM;
+       int ret = MM_ERROR_NONE;
+       gboolean is_audiobin_created = TRUE;
 
-       return_if_fail( player );
+       MMPLAYER_FENTER();
 
-       /* cancel if existing */
-       __mmplayer_cancel_delayed_eos( player );
+       return_val_if_fail(player, MM_ERROR_COMMON_INVALID_ARGUMENT);
+       return_val_if_fail(videosink_element, MM_ERROR_COMMON_INVALID_ARGUMENT);
+       return_val_if_fail(display_overlay, MM_ERROR_COMMON_INVALID_ARGUMENT);
 
+       debug_log("video dec is found(idx:%d), we are going to change videosink to %s", dec_index, videosink_element);
+       debug_log("surface type(%d), display overlay(%x)", surface_type, display_overlay);
 
-       /* post now if delay is zero */
-       if ( delay_in_ms == 0 || player->is_sound_extraction)
+       /* get information whether if audiobin is created */
+       if ( !player->pipeline->audiobin ||
+                    !player->pipeline->audiobin[MMPLAYER_A_SINK].gst )
        {
-               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;
+               debug_warning("audiobin is null, this video content may not have audio data");
+               is_audiobin_created = FALSE;
        }
 
-       /* 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 );
+       /* get current state of player */
+       previous_state = MMPLAYER_CURRENT_STATE(player);
+       debug_log("previous state(%d)", previous_state);
 
 
-       /* check timer is valid. if not, send EOS now */
-       if ( player->eos_timer == 0 )
+       /* get src pad of decoder and block it */
+       src_pad_dec = gst_element_get_static_pad (GST_ELEMENT(player->pipeline->mainbin[dec_index].gst), "src");
+       if (!src_pad_dec)
        {
-               debug_warning("creating timer for delayed EOS has failed. sending EOS now\n");
-               MMPLAYER_POST_MSG( player, MM_MESSAGE_END_OF_STREAM, NULL );
+               debug_error("failed to get src pad from decode in mainbin");
+               return MM_ERROR_PLAYER_INTERNAL;
        }
 
-       debug_fleave();
-}
-
-static void
-__mmplayer_cancel_delayed_eos( mm_player_t* player )
-{
-       debug_fenter();
-
-       return_if_fail( player );
-
-       if ( player->eos_timer )
+       if (!player->doing_seek && previous_state == MM_PLAYER_STATE_PLAYING)
        {
-               g_source_remove( player->eos_timer );
+               debug_warning("trying to block pad(video)");
+               if (!gst_pad_set_blocked (src_pad_dec, TRUE))
+               {
+                       debug_error("failed to set block pad(video)");
+                       return MM_ERROR_PLAYER_INTERNAL;
+               }
+               debug_warning("pad is blocked(video)");
+       }
+       else
+       {
+               /* no data flows, so no need to do pad_block */
+               if (player->doing_seek) {
+                       debug_warning("not completed seek(%d), do nothing", player->doing_seek);
+               }
+               debug_log("MM_PLAYER_STATE is not PLAYING now, skip pad-block(TRUE)");
        }
 
-       player->eos_timer = 0;
-
-       debug_fleave();
-
-       return;
-}
+       /* remove pad */
+       if (!gst_element_remove_pad(player->pipeline->videobin[MMPLAYER_V_BIN].gst,
+               GST_PAD_CAST(GST_GHOST_PAD(player->ghost_pad_for_videobin))))
+       {
+               debug_error("failed to remove previous ghost_pad for videobin");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
 
-static gboolean
-__mmplayer_eos_timer_cb(gpointer u_data)
-{
-       mm_player_t* player = NULL;
-       player = (mm_player_t*) u_data;
+       /* change state of videobin to NULL */
+       debug_log("setting [%s] state to : %d", GST_ELEMENT_NAME(player->pipeline->videobin[MMPLAYER_V_BIN].gst), GST_STATE_NULL);
+       ret = gst_element_set_state(player->pipeline->videobin[MMPLAYER_V_BIN].gst, GST_STATE_NULL);
+       if (ret != GST_STATE_CHANGE_SUCCESS)
+       {
+               debug_error("failed to change state of videobin to NULL");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
 
-       debug_fenter();
+       /* unlink between decoder and videobin and remove previous videosink from videobin */
+       GST_ELEMENT_UNLINK(GST_ELEMENT(player->pipeline->mainbin[dec_index].gst),GST_ELEMENT(player->pipeline->videobin[MMPLAYER_V_BIN].gst));
+       if ( !gst_bin_remove (GST_BIN(player->pipeline->videobin[MMPLAYER_V_BIN].gst), GST_ELEMENT(player->pipeline->videobin[MMPLAYER_V_SINK].gst)) )
+       {
+               debug_error("failed to remove former videosink from videobin");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
 
-       return_val_if_fail( player, FALSE );
+       __mmplayer_del_sink( player, player->pipeline->videobin[MMPLAYER_V_SINK].gst );
 
-       /* posting eos */
-       MMPLAYER_POST_MSG( player, MM_MESSAGE_END_OF_STREAM, NULL );
+       /* create a new videosink and add it to videobin */
+       player->pipeline->videobin[MMPLAYER_V_SINK].gst = gst_element_factory_make(videosink_element, videosink_element);
+       gst_bin_add (GST_BIN(player->pipeline->videobin[MMPLAYER_V_BIN].gst), GST_ELEMENT(player->pipeline->videobin[MMPLAYER_V_SINK].gst));
+       __mmplayer_add_sink( player, player->pipeline->videobin[MMPLAYER_V_SINK].gst );
+       g_object_set (G_OBJECT (player->pipeline->videobin[MMPLAYER_V_SINK].gst), "qos", TRUE, NULL);
 
-       /* cleare timer id */
-       player->eos_timer = 0;
+       /* save attributes */
+       if (player->attrs)
+       {
+               /* set a new display surface type */
+               mm_attrs_set_int_by_name (player->attrs, "display_surface_type", surface_type);
+               /* set a new diplay overlay */
+               switch (surface_type)
+               {
+                       case MM_DISPLAY_SURFACE_X:
+                               debug_log("save attributes related to display surface to X : xid = %d", *(int*)display_overlay);
+                               mm_attrs_set_data_by_name (player->attrs, "display_overlay", display_overlay, sizeof(display_overlay));
+                               break;
+                       case MM_DISPLAY_SURFACE_EVAS:
+                               debug_log("save attributes related to display surface to EVAS : evas image object = %x", display_overlay);
+                               mm_attrs_set_data_by_name (player->attrs, "display_overlay", display_overlay, sizeof(display_overlay));
+                               break;
+                       default:
+                               debug_error("invalid type(%d) for changing display surface",surface_type);
+                               MMPLAYER_FLEAVE();
+                               return MM_ERROR_INVALID_ARGUMENT;
+               }
+               if ( mmf_attrs_commit ( player->attrs ) )
+               {
+                       debug_error("failed to commit");
+                       MMPLAYER_FLEAVE();
+                       return MM_ERROR_PLAYER_INTERNAL;
+               }
+       }
+       else
+       {
+               debug_error("player->attrs is null, failed to save attributes");
+               MMPLAYER_FLEAVE();
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
 
-       debug_fleave();
+       /* update video param */
+       if ( MM_ERROR_NONE != _mmplayer_update_video_param( player ) )
+       {
+               debug_error("failed to update video param");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
 
-       /* we are returning FALSE as we need only one posting */
-       return FALSE;
-}
+       /* change state of videobin to READY */
+       debug_log("setting [%s] state to : %d", GST_ELEMENT_NAME(player->pipeline->videobin[MMPLAYER_V_BIN].gst), GST_STATE_READY);
+       ret = gst_element_set_state(player->pipeline->videobin[MMPLAYER_V_BIN].gst, GST_STATE_READY);
+       if (ret != GST_STATE_CHANGE_SUCCESS)
+       {
+               debug_error("failed to change state of videobin to READY");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
 
-static void __mmplayer_set_antishock( mm_player_t* player, gboolean disable_by_force)
-{
-       gint antishock = FALSE;
-       MMHandleType attrs = 0;
+       /* change ghostpad */
+       sink_pad_videosink = gst_element_get_static_pad(GST_ELEMENT(player->pipeline->videobin[MMPLAYER_V_SINK].gst), "sink");
+       if ( !sink_pad_videosink )
+       {
+               debug_error("failed to get sink pad from videosink element");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+       player->ghost_pad_for_videobin = gst_ghost_pad_new("sink", sink_pad_videosink);
+       if (!gst_pad_set_active(player->ghost_pad_for_videobin, TRUE))
+       {
+               debug_error("failed to set active to ghost_pad");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+       if ( FALSE == gst_element_add_pad(player->pipeline->videobin[MMPLAYER_V_BIN].gst, player->ghost_pad_for_videobin) )
+       {
+               debug_error("failed to change ghostpad for videobin");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+       gst_object_unref(sink_pad_videosink);
 
-       debug_fenter();
+       /* link decoder with videobin */
+       sink_pad_videobin = gst_element_get_static_pad( GST_ELEMENT(player->pipeline->videobin[MMPLAYER_V_BIN].gst), "sink");
+       if ( !sink_pad_videobin )
+       {
+               debug_error("failed to get sink pad from videobin");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+       if ( GST_PAD_LINK_OK != GST_PAD_LINK(src_pad_dec, sink_pad_videobin) )
+       {
+               debug_error("failed to link");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+       gst_object_unref(sink_pad_videobin);
 
-       return_if_fail ( player && player->pipeline );
+       /* clock setting for a new videosink plugin */
+       /* NOTE : Below operation is needed, because a new videosink plugin doesn't have clock for basesink,
+                       so we set it from audiosink plugin or pipeline(system clock) */
+       if (!is_audiobin_created)
+       {
+               debug_warning("audiobin is not created, get clock from pipeline..");
+               clock = GST_ELEMENT_CLOCK (player->pipeline->mainbin[MMPLAYER_M_PIPE].gst);
+       }
+       else
+       {
+               clock = GST_ELEMENT_CLOCK (player->pipeline->audiobin[MMPLAYER_A_SINK].gst);
+       }
+       if (clock)
+       {
+               GstClockTime now;
+               GstClockTime base_time;
+               debug_log("set the clock to videosink");
+               gst_element_set_clock (GST_ELEMENT_CAST(player->pipeline->videobin[MMPLAYER_V_SINK].gst), clock);
+               clock = GST_ELEMENT_CLOCK (player->pipeline->videobin[MMPLAYER_V_SINK].gst);
+               if (clock)
+               {
+                       debug_log("got clock of videosink");
+                       now = gst_clock_get_time ( clock );
+                       base_time = GST_ELEMENT_CAST (player->pipeline->videobin[MMPLAYER_V_SINK].gst)->base_time;
+                       debug_log ("at time %" GST_TIME_FORMAT ", base %"
+                                       GST_TIME_FORMAT, GST_TIME_ARGS (now), GST_TIME_ARGS (base_time));
+               }
+               else
+               {
+                       debug_error("failed to get clock of videosink after setting clock");
+                       return MM_ERROR_PLAYER_INTERNAL;
+               }
+       }
+       else
+       {
+               debug_warning("failed to get clock, maybe it is the time before first playing");
+       }
 
-       /* It should be passed for video only clip */
-       if ( ! player->pipeline->audiobin )
-               return;
+       if (!player->doing_seek && previous_state == MM_PLAYER_STATE_PLAYING)
+       {
+               /* change state of videobin to PAUSED */
+               debug_log("setting [%s] state to : %d", GST_ELEMENT_NAME(player->pipeline->videobin[MMPLAYER_V_BIN].gst), GST_STATE_PLAYING);
+               ret = gst_element_set_state(player->pipeline->videobin[MMPLAYER_V_BIN].gst, GST_STATE_PLAYING);
+               if (ret != GST_STATE_CHANGE_FAILURE)
+               {
+                       debug_warning("change state of videobin to PLAYING, ret(%d)", ret);
+               }
+               else
+               {
+                       debug_error("failed to change state of videobin to PLAYING");
+                       return MM_ERROR_PLAYER_INTERNAL;
+               }
 
-       if ( ( g_strrstr(PLAYER_INI()->name_of_audiosink, "avsysaudiosink")) )
+               /* release blocked and unref src pad of video decoder */
+               if (!gst_pad_set_blocked (src_pad_dec, FALSE))
+               {
+                       debug_error("failed to set pad blocked FALSE(video)");
+                       return MM_ERROR_PLAYER_INTERNAL;
+               }
+               debug_warning("pad is unblocked(video)");
+       }
+       else
        {
-               attrs = MMPLAYER_GET_ATTRS(player);
-               if ( ! attrs )
+               if (player->doing_seek) {
+                       debug_warning("not completed seek(%d)", player->doing_seek);
+               }
+               /* change state of videobin to PAUSED */
+               debug_log("setting [%s] state to : %d", GST_ELEMENT_NAME(player->pipeline->videobin[MMPLAYER_V_BIN].gst), GST_STATE_PAUSED);
+               ret = gst_element_set_state(player->pipeline->videobin[MMPLAYER_V_BIN].gst, GST_STATE_PAUSED);
+               if (ret != GST_STATE_CHANGE_FAILURE)
                {
-                       debug_error("fail to get attributes.\n");
-                       return;
+                       debug_warning("change state of videobin to PAUSED, ret(%d)", ret);
+               }
+               else
+               {
+                       debug_error("failed to change state of videobin to PLAYING");
+                       return MM_ERROR_PLAYER_INTERNAL;
                }
 
-               mm_attrs_get_int_by_name(attrs, "sound_fadeup", &antishock);
+               /* already skipped pad block */
+               debug_log("previous MM_PLAYER_STATE is not PLAYING, skip pad-block(FALSE)");
+       }
 
-               debug_log("setting antishock as (%d)\n", antishock);
+       /* do get/set position for new videosink plugin */
+       {
+               unsigned long position = 0;
+               gint64 pos_msec = 0;
 
-               if ( disable_by_force )
+               debug_log("do get/set position for new videosink plugin");
+               if (__gst_get_position(player, MM_PLAYER_POS_FORMAT_TIME, &position ))
                {
-                       debug_log("but, antishock is disabled by force when is seeked\n");
-
-                       antishock = FALSE;
+                       debug_error("failed to get position");
+                       return MM_ERROR_PLAYER_INTERNAL;
+               }
+#ifdef SINKCHANGE_WITH_ACCURATE_SEEK
+               /* accurate seek */
+               if (__gst_set_position(player, MM_PLAYER_POS_FORMAT_TIME, position, TRUE ))
+               {
+                       debug_error("failed to set position");
+                       return MM_ERROR_PLAYER_INTERNAL;
+               }
+#else
+               /* key unit seek */
+               pos_msec = 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_KEY_UNIT ),
+                                                       GST_SEEK_TYPE_SET, pos_msec,
+                                                       GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE );
+               if ( !ret  )
+               {
+                       debug_error("failed to set position");
+                       return MM_ERROR_PLAYER_INTERNAL;
                }
+#endif
+       }
 
-               g_object_set(G_OBJECT(player->pipeline->audiobin[MMPLAYER_A_SINK].gst), "fadeup", antishock, NULL);
+       if (src_pad_dec)
+       {
+               gst_object_unref (src_pad_dec);
        }
+       debug_log("success to change sink");
 
-       debug_fleave();
+       MMPLAYER_FLEAVE();
 
-       return;
+       return MM_ERROR_NONE;
 }
 
-
-static gboolean
-__mmplayer_link_decoder( mm_player_t* player, GstPad *srcpad)
+int _mmplayer_sync_subtitle_pipeline(mm_player_t* player)
 {
-       const gchar* name = NULL;
-       GstStructure* str = NULL;
-       GstCaps* srccaps = NULL;
-
-       debug_fenter();
+       MMPlayerGstElement* mainbin = NULL;
+       MMPlayerGstElement* textbin = NULL;
+       GstStateChangeReturn ret = GST_STATE_CHANGE_FAILURE;
+       GstState current_state = GST_STATE_VOID_PENDING;
+       GstState element_state = GST_STATE_VOID_PENDING;
+       GstState element_pending_state = GST_STATE_VOID_PENDING;
+       gint64 time = 0;
+       GstFormat format = GST_FORMAT_TIME;
+       GstEvent *event = NULL;
+       int result = MM_ERROR_NONE;
 
-       return_val_if_fail( player, FALSE );
-       return_val_if_fail ( srcpad, FALSE );
+       GstClock *curr_clock = NULL;
+       GstClockTime base_time, start_time, curr_time;
 
-       /* 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;
+       MMPLAYER_FENTER();
 
-       name = gst_structure_get_name(str);
-       if ( ! name )
-               goto ERROR;
+       /* check player handle */
+       return_val_if_fail ( player && player->pipeline , MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-       if (strstr(name, "video"))
-       {
-               if(player->videodec_linked)
-               {
-                   debug_msg("Video decoder already linked\n");
-                       return FALSE;
-               }
-       }
-       if (strstr(name, "audio"))
+       if (!(player->pipeline->mainbin) || !(player->pipeline->textbin))
        {
-               if(player->audiodec_linked)
-               {
-                   debug_msg("Audio decoder already linked\n");
-                       return FALSE;
-               }
+               debug_error("Pipeline is not in proper state\n");
+               result = MM_ERROR_PLAYER_NOT_INITIALIZED;
+               goto EXIT;
        }
 
-       gst_caps_unref( srccaps );
-
-       debug_fleave();
-
-       return TRUE;
+       mainbin = player->pipeline->mainbin;
+       textbin = player->pipeline->textbin;
 
-ERROR:
-       if ( srccaps )
-               gst_caps_unref( srccaps );
+       current_state = GST_STATE (mainbin[MMPLAYER_M_PIPE].gst);
 
-       return FALSE;
-}
+       // sync clock with current pipeline
+       curr_clock = GST_ELEMENT_CLOCK (player->pipeline->mainbin[MMPLAYER_M_PIPE].gst);
+       curr_time = gst_clock_get_time (curr_clock);
 
-static gboolean
-__mmplayer_link_sink( mm_player_t* player , GstPad *srcpad)
-{
-       const gchar* name = NULL;
-       GstStructure* str = NULL;
-       GstCaps* srccaps = NULL;
+       base_time = gst_element_get_base_time (GST_ELEMENT_CAST (player->pipeline->mainbin[MMPLAYER_M_PIPE].gst));
+       start_time = gst_element_get_start_time (GST_ELEMENT_CAST(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst));
 
-       debug_fenter();
+       debug_log ("base_time=%" GST_TIME_FORMAT " start_time=%" GST_TIME_FORMAT " curr_time=%" GST_TIME_FORMAT,
+               GST_TIME_ARGS (base_time), GST_TIME_ARGS (start_time), GST_TIME_ARGS (curr_time));
 
-       return_val_if_fail ( player, FALSE );
-       return_val_if_fail ( srcpad, FALSE );
+       if (current_state > GST_STATE_READY)
+       {
+               // sync state with current pipeline
+               gst_element_set_state(textbin[MMPLAYER_T_BIN].gst, GST_STATE_PAUSED);
+               gst_element_set_state(mainbin[MMPLAYER_M_T_INPUT_SELECTOR].gst, GST_STATE_PAUSED); // Naveen : enable if required only
+               gst_element_set_state(mainbin[MMPLAYER_M_T_SUBMUX_EXTERNAL].gst, GST_STATE_PAUSED);
+               gst_element_set_state(mainbin[MMPLAYER_M_SUBSRC].gst, GST_STATE_PAUSED);
 
-       /* to check any of the decoder (video/audio) need to be linked  to parser*/
-       srccaps = gst_pad_get_caps( srcpad );
-       if ( !srccaps )
-               goto ERROR;
+               ret = gst_element_get_state (mainbin[MMPLAYER_M_SUBSRC].gst, &element_state, &element_pending_state, 5 * GST_SECOND);
+               if ( GST_STATE_CHANGE_FAILURE == ret )
+               {
+                       debug_error("fail to state change.\n");
+               }
+       }
 
-       str = gst_caps_get_structure( srccaps, 0 );
-       if ( ! str )
-               goto ERROR;
+       gst_element_set_base_time (textbin[MMPLAYER_T_BIN].gst, base_time);
+       gst_element_set_start_time(textbin[MMPLAYER_T_BIN].gst, start_time);
 
-       name = gst_structure_get_name(str);
-       if ( ! name )
-               goto ERROR;
+       if (curr_clock)
+       {
+               gst_element_set_clock (textbin[MMPLAYER_T_BIN].gst, curr_clock);
+               gst_object_unref (curr_clock);
+       }
 
-       if (strstr(name, "video"))
+       // seek to current position
+       if (!gst_element_query_position (mainbin[MMPLAYER_M_PIPE].gst, &format, &time))
        {
-               if(player->videosink_linked)
-               {
-                       debug_msg("Video Sink already linked\n");
-                       return FALSE;
-               }
+               result = MM_ERROR_PLAYER_INVALID_STATE;
+               debug_error("gst_element_query_position failed, invalid state\n");
+               goto EXIT;
        }
-       if (strstr(name, "audio"))
+
+       debug_log("seek time = %lld\n", time);
+
+       event = gst_event_new_seek (1.0, GST_FORMAT_TIME, (GstSeekFlags) (GST_SEEK_FLAG_SEGMENT | GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_SKIP), GST_SEEK_TYPE_SET, time, GST_SEEK_TYPE_NONE, -1);
+       if (event)
        {
-               if(player->audiosink_linked)
-               {
-                       debug_msg("Audio Sink already linked\n");
-                       return FALSE;
-               }
+               __gst_send_event_to_sink(player, event);
        }
-       if (strstr(name, "text"))
+       else
        {
-               if(player->textsink_linked)
-               {
-                       debug_msg("Text Sink already linked\n");
-                       return FALSE;
-               }
+               result = MM_ERROR_PLAYER_INTERNAL;
+               debug_error("gst_event_new_seek failed\n");
+               goto EXIT;
        }
 
-       gst_caps_unref( srccaps );
-
-       debug_fleave();
+       // sync state with current pipeline
+       gst_element_sync_state_with_parent(textbin[MMPLAYER_T_BIN].gst);
+       gst_element_sync_state_with_parent(mainbin[MMPLAYER_M_T_INPUT_SELECTOR].gst);
+       gst_element_sync_state_with_parent(mainbin[MMPLAYER_M_T_SUBMUX_EXTERNAL].gst);
+       gst_element_sync_state_with_parent(mainbin[MMPLAYER_M_SUBSRC].gst);
 
-       return TRUE;
-       //return (!player->videosink_linked || !player->audiosink_linked);
+EXIT:
+       return result;
+}
 
-ERROR:
-       if ( srccaps )
-               gst_caps_unref( srccaps );
+static int
+__mmplayer_change_external_subtitle_language(mm_player_t* player, const char* filepath)
+{
+       GstStateChangeReturn ret = GST_STATE_CHANGE_FAILURE;
+       GstState current_state = GST_STATE_VOID_PENDING;
 
-       return FALSE;
-}
+       MMHandleType attrs = 0;
+       MMPlayerGstElement* mainbin = NULL;
+       MMPlayerGstElement* textbin = NULL;
 
+       gchar* subtitle_uri = NULL;
+       int result = MM_ERROR_NONE;
+       const gchar *charset = NULL;
 
-/* sending event to one of sinkelements */
-static gboolean
-__gst_send_event_to_sink( mm_player_t* player, GstEvent* event )
-{
-       GList *sinks = NULL;
-       gboolean res = FALSE;
+       MMPLAYER_FENTER();
 
-       debug_fenter();
-       
-       return_val_if_fail( player, FALSE );
-       return_val_if_fail ( event, FALSE );
+       /* check player handle */
+       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail( filepath, MM_ERROR_COMMON_INVALID_ARGUMENT );
 
-       sinks = player->sink_elements;
-       while (sinks)
+       if (!(player->pipeline) || !(player->pipeline->mainbin))
        {
-               GstElement *sink = GST_ELEMENT_CAST (sinks->data);
-
-               if ( sink )
-               {
-                       /* keep ref to the event */
-                       gst_event_ref (event);
+               result = MM_ERROR_PLAYER_INVALID_STATE;
+               debug_error("Pipeline is not in proper state\n");
+               goto EXIT;
+       }
 
-                       debug_log("sending event[%s] to sink element [%s]\n",
-                               GST_EVENT_TYPE_NAME(event), GST_ELEMENT_NAME(sink) );
+       mainbin = player->pipeline->mainbin;
+       textbin = player->pipeline->textbin;
 
-                       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;
-                       }
+       current_state = GST_STATE (mainbin[MMPLAYER_M_PIPE].gst);
+       if (current_state < GST_STATE_READY)
+       {
+               result = MM_ERROR_PLAYER_INVALID_STATE;
+               debug_error("Pipeline is not in proper state\n");
+               goto EXIT;
+       }
 
-                       debug_log("sending event[%s] to sink element [%s] failed. try with next one.\n",
-                               GST_EVENT_TYPE_NAME(event), GST_ELEMENT_NAME(sink) );
-               }
+       attrs = MMPLAYER_GET_ATTRS(player);
+       if (!attrs)
+       {
+               debug_error("cannot get content attribute\n");
+               result = MM_ERROR_PLAYER_INTERNAL;
+               goto EXIT;
+       }
 
-               sinks = g_list_next (sinks);
+       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");
+               result = MM_ERROR_PLAYER_INVALID_URI;
+               goto EXIT;
        }
 
-       /* Note : Textbin is not linked to the video or audio bin.
-        *              It needs to send the event to the text sink seperatelly.
-        */
-        if ( MMPLAYER_PLAY_SUBTITLE(player) )
-        {
-               GstElement *subtitle_sink = GST_ELEMENT_CAST (player->pipeline->subtitlebin[MMPLAYER_SUB_SINK].gst);
+       debug_log("old subtitle file path is [%s]\n", subtitle_uri);
+       debug_log("new subtitle file path is [%s]\n", filepath);
 
-               if ( (res != gst_element_send_event (subtitle_sink, event)) )
-               {
-                       debug_error("sending event[%s] to subtitle sink element [%s] failed!\n",
-                               GST_EVENT_TYPE_NAME(event), GST_ELEMENT_NAME(subtitle_sink) );
-               }
-               else
+       if (!strcmp (filepath, subtitle_uri))
+       {
+               debug_log("No need to swtich subtitle, as input filepath is same as current filepath\n");
+               goto EXIT;
+       }
+       else
+       {
+               mm_attrs_set_string_by_name(player->attrs, "subtitle_uri", filepath);
+               if (mmf_attrs_commit(player->attrs))
                {
-                       debug_log("sending event[%s] to subtitle sink element [%s] success!\n",
-                               GST_EVENT_TYPE_NAME(event), GST_ELEMENT_NAME(subtitle_sink) );
+                       debug_error("failed to commit.\n");
+                       goto EXIT;
                }
-        }
-
-       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);
+       //gst_pad_set_blocked_async(src-srcpad, TRUE)
 
-       debug_fleave();
-}
+       ret = gst_element_set_state(textbin[MMPLAYER_T_BIN].gst, GST_STATE_READY);
+       if (ret != GST_STATE_CHANGE_SUCCESS)
+       {
+               debug_error("failed to change state of textbin to READY");
+               result = MM_ERROR_PLAYER_INTERNAL;
+               goto EXIT;
+       }
 
-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;
+       ret = gst_element_set_state(mainbin[MMPLAYER_M_T_INPUT_SELECTOR].gst, GST_STATE_READY);
+       if (ret != GST_STATE_CHANGE_SUCCESS)
+       {
+               debug_error("failed to change state of input-selector to READY");
+               result = MM_ERROR_PLAYER_INTERNAL;
+               goto EXIT;
+       }
 
-       debug_fenter();
-       
-       return_val_if_fail( player, FALSE );
+       ret = gst_element_set_state(mainbin[MMPLAYER_M_T_SUBMUX_EXTERNAL].gst, GST_STATE_READY);
+       if (ret != GST_STATE_CHANGE_SUCCESS)
+       {
+               debug_error("failed to change state of subparse to READY");
+               result = MM_ERROR_PLAYER_INTERNAL;
+               goto EXIT;
+       }
 
-       event = gst_event_new_seek (rate, format, flags, cur_type,
-               cur, stop_type, stop);
+       ret = gst_element_set_state(mainbin[MMPLAYER_M_SUBSRC].gst, GST_STATE_READY);
+       if (ret != GST_STATE_CHANGE_SUCCESS)
+       {
+               debug_error("failed to change state of filesrc to READY");
+               result = MM_ERROR_PLAYER_INTERNAL;
+               goto EXIT;
+       }
 
-       result = __gst_send_event_to_sink( player, event );
+       g_object_set(G_OBJECT(mainbin[MMPLAYER_M_SUBSRC].gst), "location", filepath, NULL);
 
-       /* Note : After sending seek event, the sink elements receive flush event
-        * Not only buffering state but after seeking, state_lost needs to be set to TRUE.
-        */
-       if (  MMPLAYER_IS_RTSP_STREAMING ( player )  && result )
-               player->state_lost = TRUE;
+       charset = util_get_charset(filepath);
+       if (charset)
+       {
+               debug_log ("detected charset is %s\n", charset );
+               g_object_set (G_OBJECT (mainbin[MMPLAYER_M_T_SUBMUX_EXTERNAL].gst), "subtitle-encoding", charset, NULL);
+       }
 
-       debug_fleave();
+       result = _mmplayer_sync_subtitle_pipeline(player);
 
+EXIT:
+       MMPLAYER_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)
+/* API to switch between external subtitles */
+int _mmplayer_set_external_subtitle_path(MMHandleType hplayer, const char* filepath)
 {
-       GList* sig_list = player->signals;
-       MMPlayerSignalItem* item = NULL;
+       int result = MM_ERROR_NONE;
+       mm_player_t* player = (mm_player_t*)hplayer;
 
-       debug_fenter();
-       
-       return_if_fail( player );
+       MMPLAYER_FENTER();
+
+       /* check player handle */
+       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
 
-       for ( ; sig_list; sig_list = sig_list->next )
+       if (!player->pipeline)  // IDLE state
        {
-               item = sig_list->data;
-
-               if ( item && item->obj && GST_IS_ELEMENT(item->obj) )
+               mm_attrs_set_string_by_name(player->attrs, "subtitle_uri", filepath);
+               if (mmf_attrs_commit(player->attrs))
                {
-                       debug_log("checking signal connection : [%lud] from [%s]\n", item->sig, GST_OBJECT_NAME( item->obj ));
+                       debug_error("failed to commit.\n");
+                       result= MM_ERROR_PLAYER_INTERNAL;
+               }
+       }
+       else    // curr state <> IDLE (READY, PAUSE, PLAYING..)
+       {
+               if ( filepath == NULL )
+                       return MM_ERROR_COMMON_INVALID_ARGUMENT;
 
-                       if ( g_signal_handler_is_connected ( item->obj, item->sig ) )
+               if (!__mmplayer_check_subtitle(player))
+               {
+                       mm_attrs_set_string_by_name(player->attrs, "subtitle_uri", filepath);
+                       if (mmf_attrs_commit(player->attrs))
                        {
-                               debug_log("signal disconnecting : [%lud] from [%s]\n", item->sig, GST_OBJECT_NAME( item->obj ));
-                               g_signal_handler_disconnect ( item->obj, item->sig );
+                               debug_error("failed to commit.\n");
+                               result = MM_ERROR_PLAYER_INTERNAL;
                        }
-               }
 
-               MMPLAYER_FREEIF( item );
+                       if ( MM_ERROR_NONE != __mmplayer_gst_create_subtitle_src(player) )
+                               debug_error("fail to create subtitle src\n");
 
+                       result = _mmplayer_sync_subtitle_pipeline(player);
+               }
+               else
+               {
+                       result = __mmplayer_change_external_subtitle_language(player, filepath);
+               }
        }
-       g_list_free ( player->signals );
-       player->signals = NULL;
-
-       debug_fleave();
 
-       return;
+       MMPLAYER_FLEAVE();
+       return result;
 }
 
-
-/* Note : if silent is true, then subtitle would not be displayed. :*/
-int _mmplayer_set_subtitle_silent (MMHandleType hplayer, int silent)
+static int
+__mmplayer_change_selector_pad (mm_player_t* player, MMPlayerTrackType type, int index)
 {
-       mm_player_t* player = (mm_player_t*) hplayer;
+       int result = MM_ERROR_NONE;
+       gchar* change_pad_name = NULL;
+       GstPad* sinkpad = NULL;
+       MMPlayerGstElement* mainbin = NULL;
+       enum MainElementID elemId = MMPLAYER_M_NUM;
+       GstCaps* caps = NULL;
+       gint total_track_num = 0;
 
-       debug_fenter();
+       MMPLAYER_FENTER();
 
-       /* check player handle */
-       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED );
-       return_val_if_fail ( MMPLAYER_PLAY_SUBTITLE(player),    MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail (player && player->pipeline && player->pipeline->mainbin,
+                                                                                                       MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       debug_log ("Change Track(%d) to %d\n", type, index);
+
+       mainbin = player->pipeline->mainbin;
+
+       if (type == MM_PLAYER_TRACK_TYPE_AUDIO)
+       {
+               elemId = MMPLAYER_M_A_INPUT_SELECTOR;
+       }
+       else if (type == MM_PLAYER_TRACK_TYPE_TEXT)
+       {
+               elemId = MMPLAYER_M_T_INPUT_SELECTOR;
+       }
+       else
+       {
+               debug_error ("Track Type Error\n");
+               goto EXIT;
+       }
 
-       player->is_subtitle_off = silent;
+       if (mainbin[elemId].gst == NULL)
+       {
+               result = MM_ERROR_PLAYER_NO_OP;
+               debug_log ("Req track doesn't exist\n");
+               goto EXIT;
+       }
 
-       debug_log("subtitle is %s.\n", player->is_subtitle_off ? "ON" : "OFF");
+       total_track_num = player->selector[type].total_track_num;
+       if (total_track_num <= 0)
+       {
+               result = MM_ERROR_PLAYER_NO_OP;
+               debug_log ("Language list is not available \n");
+               goto EXIT;
+       }
 
-       debug_fleave();
+       if ((index < 0) || (index >= total_track_num))
+       {
+               result = MM_ERROR_INVALID_ARGUMENT;
+               debug_log ("Not a proper index : %d \n", index);
+               goto EXIT;
+       }
 
-       return MM_ERROR_NONE;
-}
+       /*To get the new pad from the selector*/
+       change_pad_name = g_strdup_printf ("sink%d", index);
+       if (change_pad_name == NULL)
+       {
+               result = MM_ERROR_PLAYER_INTERNAL;
+               debug_log ("Pad does not exists\n");
+               goto EXIT;
+       }
 
+       debug_log ("new active pad name: %s\n", change_pad_name);
 
-int _mmplayer_get_subtitle_silent (MMHandleType hplayer, int* silent)
-{
-       mm_player_t* player = (mm_player_t*) hplayer;
+       sinkpad = gst_element_get_static_pad (mainbin[elemId].gst, change_pad_name);
+       if (sinkpad == NULL)
+       {
+               result = MM_ERROR_PLAYER_INTERNAL;
+               goto EXIT;
+       }
 
-       debug_fenter();
+       debug_log ("Set Active Pad - %s:%s\n", GST_DEBUG_PAD_NAME(sinkpad));
+       g_object_set (mainbin[elemId].gst, "active-pad", sinkpad, NULL);
 
-       /* check player handle */
-       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED );
-       return_val_if_fail ( MMPLAYER_PLAY_SUBTITLE(player),    MM_ERROR_PLAYER_NOT_INITIALIZED );
+       caps = GST_PAD_CAPS(sinkpad);
+       MMPLAYER_LOG_GST_CAPS_TYPE(caps);
 
-       *silent = player->is_subtitle_off;
+       if (sinkpad)
+               gst_object_unref (sinkpad);
 
-       debug_log("subtitle is %s.\n", silent ? "ON" : "OFF");
+       if (type == MM_PLAYER_TRACK_TYPE_AUDIO)
+       {
+               __mmplayer_set_audio_attrs (player, caps);
+       }
 
-       debug_fleave();
+EXIT:
 
-       return MM_ERROR_NONE;
+       MMPLAYER_FREEIF(change_pad_name);
+       return result;
 }
 
-int _mmplayer_get_track_count(MMHandleType hplayer,  MMPlayerTrackType track_type, int *count)
+int _mmplayer_change_track_language (MMHandleType hplayer, MMPlayerTrackType type, int index)
 {
-       mm_player_t* player = (mm_player_t*) hplayer;
-       MMHandleType attrs = 0;
-       int ret = MM_ERROR_NONE;
+       int result = MM_ERROR_NONE;
+       mm_player_t* player = NULL;
+       MMPlayerGstElement* mainbin = NULL;
 
-       debug_fenter();
+       gint current_active_index = 0;
 
-       /* 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);
+       GstState current_state = GST_STATE_VOID_PENDING;
+       GstEvent* event = NULL;
+       GstFormat format = GST_FORMAT_TIME;
+       gint64 time = 0;
 
-       attrs = MMPLAYER_GET_ATTRS(player);
-       if ( !attrs )
+       MMPLAYER_FENTER();
+
+       player = (mm_player_t*)hplayer;
+       return_val_if_fail (player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       if (!player->pipeline)
        {
-               debug_error("cannot get content attribute");
-               return MM_ERROR_PLAYER_INTERNAL;
+               debug_error ("Track %d pre setting -> %d\n", type, index);
+
+               player->selector[type].active_pad_index = index;
+               goto EXIT;
        }
 
-       switch (track_type)
+       mainbin = player->pipeline->mainbin;
+
+       current_active_index = player->selector[type].active_pad_index;
+
+       /*If index is same as running index no need to change the pad*/
+       if (current_active_index == index)
        {
-               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;
+               goto EXIT;
+       }
+
+       if (!gst_element_query_position(mainbin[MMPLAYER_M_PIPE].gst, &format, &time))
+       {
+               result = MM_ERROR_PLAYER_INVALID_STATE;
+               goto EXIT;
        }
 
-       debug_log ("%d track num is %d\n", track_type, *count);
+       current_state = GST_STATE(mainbin[MMPLAYER_M_PIPE].gst);
+       if (current_state < GST_STATE_PAUSED)
+       {
+               result = MM_ERROR_PLAYER_INVALID_STATE;
+               debug_warning ("Pipeline not in porper state\n");
+               goto EXIT;
+       }
 
-       debug_fleave();
+       result = __mmplayer_change_selector_pad(player, type, index);
+       if (result != MM_ERROR_NONE)
+       {
+               debug_error ("change selector pad error\n");
+               goto EXIT;
+       }
 
-       return ret;
-}
+       player->selector[type].active_pad_index = index;
 
+       if (current_state == GST_STATE_PLAYING)
+       {
+               event = gst_event_new_seek (1.0, GST_FORMAT_TIME,(GstSeekFlags) (GST_SEEK_FLAG_SEGMENT | GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_SKIP),GST_SEEK_TYPE_SET, time, GST_SEEK_TYPE_NONE, -1);
+               if (event)
+               {
+                       __gst_send_event_to_sink (player, event);
+               }
+               else
+               {
+                       result = MM_ERROR_PLAYER_INTERNAL;
+                       goto EXIT;
+               }
+       }
 
+EXIT:
+       return result;
+}
 
-const gchar * 
+const gchar *
 __get_state_name ( int state )
 {
        switch ( state )
@@ -10602,6 +16549,7 @@ __get_state_name ( int state )
                        return "INVAID";
        }
 }
+
 gboolean
 __is_rtsp_streaming ( mm_player_t* player )
 {
@@ -10610,6 +16558,14 @@ __is_rtsp_streaming ( mm_player_t* player )
        return ( player->profile.uri_type == MM_PLAYER_URI_TYPE_URL_RTSP ) ? TRUE : FALSE;
 }
 
+gboolean
+__is_wfd_streaming ( mm_player_t* player )
+{
+  return_val_if_fail ( player, FALSE );
+
+  return ( player->profile.uri_type == MM_PLAYER_URI_TYPE_URL_WFD ) ? TRUE : FALSE;
+}
+
 static gboolean
 __is_http_streaming ( mm_player_t* player )
 {
@@ -10623,7 +16579,8 @@ __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;
+  return ( __is_rtsp_streaming ( player ) || __is_wfd_streaming ( player ) || __is_http_streaming ( player )
+          || __is_http_live_streaming ( player ) || __is_dash_streaming ( player ) || __is_smooth_streaming(player) ) ? TRUE : FALSE;
 }
 
 gboolean
@@ -10639,9 +16596,26 @@ __is_http_live_streaming( mm_player_t* player )
 {
        return_val_if_fail( player, FALSE );
 
-       return ( (player->ahs_player) && (player->profile.uri_type == MM_PLAYER_URI_TYPE_HLS) ) ? TRUE : FALSE;
+       return ( player->profile.uri_type == MM_PLAYER_URI_TYPE_HLS ) ? TRUE : FALSE;
+}
+
+static gboolean
+__is_dash_streaming ( mm_player_t* player )
+{
+       return_val_if_fail ( player, FALSE );
+
+       return ( player->profile.uri_type == MM_PLAYER_URI_TYPE_DASH ) ? TRUE : FALSE;
+}
+
+static gboolean
+__is_smooth_streaming ( mm_player_t* player )
+{
+       return_val_if_fail ( player, FALSE );
+
+       return ( player->profile.uri_type == MM_PLAYER_URI_TYPE_SS ) ? TRUE : FALSE;
 }
 
+
 static gboolean
 __is_http_progressive_down(mm_player_t* player)
 {
@@ -10649,3 +16623,233 @@ __is_http_progressive_down(mm_player_t* player)
 
        return ((player->pd_mode) ? TRUE:FALSE);
 }
+
+gboolean
+__has_suffix(mm_player_t* player, const gchar* suffix)
+{
+       return_val_if_fail( player, FALSE );
+       return_val_if_fail( suffix, FALSE );
+
+       gboolean ret = FALSE;
+       gchar* t_url = g_ascii_strdown(player->profile.uri, -1);
+       gchar* t_suffix = g_ascii_strdown(suffix, -1);
+
+       if ( g_str_has_suffix(player->profile.uri, suffix) )
+       {
+               ret = TRUE;
+       }
+
+       MMPLAYER_FREEIF(t_url);
+       MMPLAYER_FREEIF(t_suffix);
+
+       return ret;
+}
+
+int
+_mmplayer_set_display_zoom(MMHandleType hplayer, float level, int x, int y)
+{
+       mm_player_t* player = (mm_player_t*) hplayer;
+
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       MMPLAYER_VIDEO_SINK_CHECK(player);
+
+       debug_log("setting display zoom level = %f, offset = %d, %d", level, x, y);
+
+       g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "zoom", level, "zoom-pos-x", x, "zoom-pos-y", y, NULL);
+
+       return MM_ERROR_NONE;
+}
+int
+_mmplayer_get_display_zoom(MMHandleType hplayer, float *level, int *x, int *y)
+{
+
+       mm_player_t* player = (mm_player_t*) hplayer;
+       float _level = 0.0;
+       int _x = 0;
+       int _y = 0;
+
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       MMPLAYER_VIDEO_SINK_CHECK(player);
+
+       g_object_get(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "zoom", &_level, "zoom-pos-x", &_x, "zoom-pos-y", &_y, NULL);
+
+       debug_log("display zoom level = %f, start off x = %d, y = %d", _level, _x, _y);
+
+       *level = _level;
+       *x = _x;
+       *y = _y;
+
+       return MM_ERROR_NONE;
+}
+
+int
+_mmplayer_get_video_rotate_angle(MMHandleType hplayer, int *angle)
+{
+       mm_player_t* player = (mm_player_t*) hplayer;
+       int org_angle = 0;
+
+       MMPLAYER_FENTER();
+
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail ( angle, MM_ERROR_COMMON_INVALID_ARGUMENT );
+
+       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");
+               }
+       }
+
+       debug_log("orientation: %d", org_angle);
+       *angle = org_angle;
+
+       MMPLAYER_FLEAVE();
+       return MM_ERROR_NONE;
+}
+
+gboolean
+__mmplayer_is_streaming(mm_player_t* player)
+{
+       gboolean result = FALSE;
+
+       MMPLAYER_FENTER();
+
+       return_val_if_fail (player, FALSE);
+       result = __is_streaming (player) ;
+
+       MMPLAYER_FLEAVE();
+       return result;
+}
+
+static gboolean
+__mmplayer_add_dump_buffer_probe(mm_player_t *player, GstElement *element)
+{
+       return_val_if_fail (player, FALSE);
+       return_val_if_fail (element, FALSE);
+
+       gchar *factory_name = GST_PLUGIN_FEATURE_NAME (gst_element_get_factory(element));
+       gchar dump_file_name[PLAYER_INI_MAX_STRLEN*2];
+       int len = PLAYER_INI_MAX_STRLEN*2;
+
+       int idx = 0;
+
+       for ( idx = 0; player->ini.dump_element_keyword[idx][0] != '\0'; idx++ )
+       {
+               if (g_strrstr(factory_name, player->ini.dump_element_keyword[idx]))
+               {
+                       debug_log("dump [%s] sink pad", player->ini.dump_element_keyword[idx]);
+                       mm_player_dump_t *dump_s;
+                       dump_s = g_malloc (sizeof(mm_player_dump_t));
+
+                       if (dump_s == NULL)
+                       {
+                               debug_error ("malloc fail");
+                               return FALSE;
+                       }
+
+                       dump_s->dump_element_file = NULL;
+                       dump_s->dump_pad = NULL;
+                       dump_s->dump_pad = gst_element_get_static_pad (element, "sink");
+
+                       if (dump_s->dump_pad)
+                       {
+                               memset (dump_file_name, 0x00, PLAYER_INI_MAX_STRLEN*2);
+                               snprintf (dump_file_name, len, "%s/%s_sink_pad.dump", player->ini.dump_element_path, player->ini.dump_element_keyword[idx]);
+                               dump_s->dump_element_file = fopen(dump_file_name,"w+");
+                               dump_s->probe_handle_id = gst_pad_add_buffer_probe (dump_s->dump_pad, G_CALLBACK(__mmplayer_dump_buffer_probe_cb), dump_s->dump_element_file);
+                               /* add list for removed buffer probe and close FILE */
+                               player->dump_list = g_list_append (player->dump_list, dump_s);
+                               debug_log ("%s sink pad added buffer probe for dump", factory_name);
+                               return TRUE;
+                       }
+                       else
+                       {
+                               g_free(dump_s);
+                               dump_s = NULL;
+                               debug_error ("failed to get %s sink pad added", factory_name);
+                       }
+
+
+               }
+       }
+       return FALSE;
+}
+
+static gboolean
+__mmplayer_dump_buffer_probe_cb(GstPad *pad, GstBuffer *buffer, gpointer u_data)
+{
+       FILE *dump_data = (FILE *) u_data;
+//     int written = 0;
+
+       return_val_if_fail ( dump_data, FALSE );
+
+//     debug_log ("buffer timestamp = %" GST_TIME_FORMAT, GST_TIME_ARGS( GST_BUFFER_TIMESTAMP(buffer)));
+
+       fwrite ( GST_BUFFER_DATA(buffer), 1, GST_BUFFER_SIZE(buffer), dump_data);
+
+       return TRUE;
+}
+
+static void
+__mmplayer_release_dump_list (GList *dump_list)
+{
+       if (dump_list)
+       {
+               GList *d_list = dump_list;
+               for ( ;d_list ; d_list = g_list_next(d_list))
+               {
+                       mm_player_dump_t *dump_s = d_list->data;
+                       if (dump_s->dump_pad)
+                       {
+                               if (dump_s->probe_handle_id)
+                               {
+                                       gst_pad_remove_buffer_probe (dump_s->dump_pad, dump_s->probe_handle_id);
+                               }
+
+                       }
+                       if (dump_s->dump_element_file)
+                       {
+                               fclose(dump_s->dump_element_file);
+                               dump_s->dump_element_file = NULL;
+                       }
+                       MMPLAYER_FREEIF(dump_s);
+               }
+               g_list_free(dump_list);
+               dump_list = NULL;
+       }
+}
+
+static int
+__mmplayer_ignore_current_external_display_mode(mm_player_t* player)
+{
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       MMPLAYER_VIDEO_SINK_CHECK(player);
+
+       g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "keep-external-fullscreen-prev", TRUE, NULL);
+       debug_log("set keep-external-fullscreen-prev property to TRUE");
+
+       return MM_ERROR_NONE;
+}
+
+int
+_mmplayer_enable_media_packet_video_stream(MMHandleType hplayer, bool enable)
+{
+       mm_player_t* player = (mm_player_t*) hplayer;
+
+       MMPLAYER_FENTER();
+
+       return_val_if_fail (player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       return_val_if_fail (enable == TRUE || enable == FALSE, MM_ERROR_INVALID_ARGUMENT);
+
+       player->set_mode.media_packet_video_stream = enable;
+
+       MMPLAYER_FLEAVE();
+
+       return MM_ERROR_NONE;
+}
diff --git a/src/mm_player_sndeffect.c b/src/mm_player_sndeffect.c
deleted file mode 100755 (executable)
index 09bd66b..0000000
+++ /dev/null
@@ -1,884 +0,0 @@
-/*
- * 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_sndeffect.h"
-#include "mm_player_ini.h"
-#include "mm_player_priv.h"
-#include <mm_sound.h>
-
-
-int
-mm_player_get_foreach_present_supported_filter_type(MMHandleType player, MMAudioFilterType filter_type, mmplayer_supported_sound_filter_cb foreach_cb, void *user_data)
-{
-       debug_fenter();
-       int result = MM_ERROR_NONE;
-       gboolean is_earphone = NULL;
-       int i = 0;
-
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
-
-       /* get status if earphone is activated */
-       result = mm_sound_is_route_available(MM_SOUND_ROUTE_OUT_WIRED_ACCESSORY, &is_earphone);
-       if ( result ) {
-               debug_error("mm_sound_is_route_available() failed [%x]!!\n", result);
-               return result;
-       }
-
-       /* preset */
-       if (filter_type == MM_AUDIO_FILTER_TYPE_PRESET)
-       {
-               for ( i = 0; i < MM_AUDIO_FILTER_PRESET_NUM; i++ )
-               {
-                       if (is_earphone) {
-                               if (PLAYER_INI()->audio_filter_preset_list[i])
-                               {
-                                       if (!foreach_cb(filter_type, i, user_data))
-                                       {
-                                               goto CALLBACK_ERROR;
-                                       }
-                               }
-                       }
-                       else
-                       {
-                               if (PLAYER_INI()->audio_filter_preset_list[i] && !PLAYER_INI()->audio_filter_preset_earphone_only_list[i])
-                               {
-                                       if (!foreach_cb(filter_type, i, user_data))
-                                       {
-                                               goto CALLBACK_ERROR;
-                                       }
-                               }
-
-                       }
-               }
-       }
-       /* custom */
-       else if (filter_type == MM_AUDIO_FILTER_TYPE_CUSTOM)
-       {
-               for ( i = 0; i < MM_AUDIO_FILTER_CUSTOM_NUM; i++ )
-               {
-                       if (is_earphone)
-                       {
-                               if (PLAYER_INI()->audio_filter_custom_list[i])
-                               {
-                                       if (!foreach_cb(filter_type, i, user_data))
-                                       {
-                                               goto CALLBACK_ERROR;
-                                       }
-                               }
-                       }
-                       else
-                       {
-                               if (PLAYER_INI()->audio_filter_custom_list[i] && !PLAYER_INI()->audio_filter_custom_earphone_only_list[i])
-                               {
-                                       if (!foreach_cb(filter_type,i, user_data))
-                                       {
-                                               goto CALLBACK_ERROR;
-                                       }
-                               }
-                       }
-               }
-       }
-       else
-       {
-               debug_error("invalid filter type(%d)\n", filter_type);
-               result = MM_ERROR_INVALID_ARGUMENT;
-       }
-
-       return result;
-
-CALLBACK_ERROR:
-       debug_error("foreach cb returned error\n");
-       return MM_ERROR_PLAYER_INTERNAL;
-}
-
-
-int
-__mmplayer_set_harmony_filter(mm_player_t *player, GstElement *filter_element)
-{
-       debug_fenter();
-       gint *ext_filter_level_list = NULL;
-       int count = 1;          /* start from 1, because of excepting eq index */
-       int ext_level_index = 0;
-       int result = MM_ERROR_NONE;
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
-       return_val_if_fail ( filter_element, MM_ERROR_INVALID_ARGUMENT );
-
-       /* Custom EQ */
-       if( PLAYER_INI()->audio_filter_custom_eq_num )
-       {
-               debug_log("pass custom EQ level list to sound effect plugin\n");
-               /* set custom-equalizer level list */
-               g_object_set(filter_element, "custom-eq", player->audio_filter_info.custom_eq_level, NULL);
-       }
-       else
-       {
-               debug_warning("no custom EQ\n");
-       }
-
-       /* Custom Extension filters */
-       if( PLAYER_INI()->audio_filter_custom_ext_num )
-       {
-               debug_log("pass custom extension level list to sound effect plugin\n");
-               ext_filter_level_list = player->audio_filter_info.custom_ext_level_for_plugin;
-               if (!ext_filter_level_list) {
-                       ext_filter_level_list = (gint*) malloc (sizeof(gint)*PLAYER_INI()->audio_filter_custom_ext_num);
-                       if (!ext_filter_level_list)
-                       {
-                               debug_error("memory allocation for extension filter list failed\n");
-                               return MM_ERROR_OUT_OF_MEMORY;
-                       }
-                       else
-                       {
-                               memset (ext_filter_level_list, 0, PLAYER_INI()->audio_filter_custom_ext_num);
-                       }
-               }
-
-               while ( count < MM_AUDIO_FILTER_CUSTOM_NUM )
-               {
-                       if ( PLAYER_INI()->audio_filter_custom_list[count] )
-                       {
-                               ext_filter_level_list[ext_level_index] = player->audio_filter_info.custom_ext_level[count-1];
-                               ext_level_index++;
-                               if (ext_level_index == PLAYER_INI()->audio_filter_custom_ext_num)
-                               {
-                                       break;
-                               }
-                       }
-                       count++;
-               }
-
-               /* set custom-extension filters level list */
-               g_object_set(filter_element, "custom-ext", ext_filter_level_list, NULL);
-       }
-       else
-       {
-               debug_warning("no custom extension fliter\n");
-       }
-
-       /* order action to sound effect plugin */
-       g_object_set(filter_element, "filter-action", MM_AUDIO_FILTER_TYPE_CUSTOM, NULL);
-       debug_log("filter-action = %d\n", MM_AUDIO_FILTER_TYPE_CUSTOM);
-
-       debug_fleave();
-
-       return result;
-}
-
-
-gboolean
-__mmplayer_is_earphone_only_filter_type(mm_player_t *player, MMAudioFilterType filter_type, int filter)
-{
-       gboolean result = FALSE;
-       int i = 0;
-       debug_fenter();
-
-       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-
-       /* preset */
-       if (filter_type == MM_AUDIO_FILTER_TYPE_PRESET)
-       {
-               if (PLAYER_INI()->audio_filter_preset_earphone_only_list[filter])
-               {
-                       debug_msg("this preset filter(%d) is only available with earphone\n", filter);
-                       result = TRUE;
-               }
-       }
-       /* custom */
-       else if (filter_type == MM_AUDIO_FILTER_TYPE_CUSTOM)
-       {
-               for (i = 1; i < MM_AUDIO_FILTER_CUSTOM_NUM; i++) /* it starts from 1(except testing for EQ) */
-               {
-                       if (PLAYER_INI()->audio_filter_custom_earphone_only_list[i])
-                       {
-                               /* check if the earphone only custom filter was set */
-                               if (player->audio_filter_info.custom_ext_level[i-1])
-                               {
-                                       debug_msg("this custom filter(%d) is only available with earphone\n", i);
-                                       result = TRUE;
-                               }
-                       }
-               }
-       }
-       else
-       {
-               debug_error("invalid filter type(%d)\n", filter_type);
-       }
-
-       return result;
-}
-
-
-gboolean
-_mmplayer_is_supported_filter_type(MMAudioFilterType filter_type, int filter)
-{
-       gboolean result = TRUE;
-
-       debug_fenter();
-
-       /* preset */
-       if (filter_type == MM_AUDIO_FILTER_TYPE_PRESET)
-       {
-               if ( filter < MM_AUDIO_FILTER_PRESET_AUTO || filter >= MM_AUDIO_FILTER_PRESET_NUM )
-               {
-                       debug_error("out of range, preset filter(%d)\n", filter);
-                       result = FALSE;
-               }
-               if (!PLAYER_INI()->audio_filter_preset_list[filter])
-               {
-                       debug_error("this filter(%d) is not supported\n", filter);
-                       result = FALSE;
-               }
-       }
-       /* custom */
-       else if (filter_type == MM_AUDIO_FILTER_TYPE_CUSTOM)
-       {
-               if ( filter < MM_AUDIO_FILTER_CUSTOM_EQ || filter >= MM_AUDIO_FILTER_CUSTOM_NUM )
-               {
-                       debug_error("out of range, custom filter(%d)\n", filter);
-                       result = FALSE;
-               }
-               if (!PLAYER_INI()->audio_filter_custom_list[filter])
-               {
-                       debug_error("this custom filter(%d) is not supported\n", filter);
-                       result = FALSE;
-               }
-       }
-       else
-       {
-               debug_error("invalid filter type(%d)\n", filter_type);
-               result = FALSE;
-       }
-
-       return result;
-}
-
-
-int
-_mmplayer_sound_filter_preset_apply(mm_player_t *player, MMAudioFilterPresetType filter_type)
-{
-       GstElement *filter_element = NULL;
-       int result = MM_ERROR_NONE;
-       int output_type = 0;
-       bool is_earphone = FALSE;
-       debug_fenter();
-
-       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
-
-       /* Music Player can set sound effect value before Audiobin is created. */
-       if ( !player->pipeline || !player->pipeline->audiobin )
-       {
-               debug_warning("filter element is not created yet.\n");
-
-               player->bypass_sound_effect = FALSE;
-
-               /* store sound effect setting in order to apply it when audio filter is created */
-               player->audio_filter_info.filter_type = MM_AUDIO_FILTER_TYPE_PRESET;
-               player->audio_filter_info.preset = filter_type;
-       }
-       else
-       {
-               return_val_if_fail( player->pipeline->audiobin, MM_ERROR_PLAYER_NOT_INITIALIZED );
-
-               filter_element = player->pipeline->audiobin[MMPLAYER_A_FILTER].gst;
-
-               /* get status if earphone is activated */
-               result = mm_sound_is_route_available(MM_SOUND_ROUTE_OUT_WIRED_ACCESSORY, &is_earphone);
-               if ( result ) {
-                       debug_error("mm_sound_is_route_available() failed [%x]!!\n", result);
-                       return result;
-               }
-
-               if (is_earphone)
-               {
-                       output_type = MM_AUDIO_FILTER_OUTPUT_EAR;
-               }
-               else
-               {
-                       output_type = MM_AUDIO_FILTER_OUTPUT_SPK;
-                       if (__mmplayer_is_earphone_only_filter_type(player, MM_AUDIO_FILTER_TYPE_PRESET, filter_type))
-                       {
-                               debug_error("earphone is not equipped, this filter will not be applied\n");
-                               return MM_ERROR_PLAYER_SOUND_EFFECT_INVALID_STATUS;
-                       }
-               }
-
-               /* set filter output mode as SPEAKER or EARPHONE */
-               g_object_set(filter_element, "filter-output-mode", output_type, NULL);
-               debug_log("filter-output-mode = %d (0:spk,1:ear)\n", output_type);
-
-               if (filter_type == MM_AUDIO_FILTER_PRESET_AUTO) {
-                       /* TODO: Add codes about auto selecting preset mode according to ID3 tag */
-                       /* set filter preset mode */
-                       g_object_set(filter_element, "preset-mode", 0, NULL); /* forced set to 0(normal) temporarily */
-                       debug_log("preset-mode = %d\n", filter_type);
-
-               } else {
-                       /* set filter preset mode */
-                       g_object_set(filter_element, "preset-mode", filter_type-1, NULL); /* filter_type-1, because of _PRESET_AUTO in MSL/CAPI which does not exist in soundAlive plugin */
-                       debug_log("preset-mode = %d\n", filter_type);
-               }
-
-               /* order action to sound effect plugin */
-               g_object_set(filter_element, "filter-action", MM_AUDIO_FILTER_TYPE_PRESET, NULL);
-               debug_log("filter-action = %d\n", MM_AUDIO_FILTER_TYPE_PRESET);
-
-       }
-       debug_fleave();
-
-       return result;
-}
-
-
-int
-_mmplayer_sound_filter_custom_apply(mm_player_t *player)
-{
-       GstElement *filter_element = NULL;
-       int result = MM_ERROR_NONE;
-
-       debug_fenter();
-
-       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
-
-       /* Music Player can set sound effect value before Audiobin is created. */
-       if ( !player->pipeline || !player->pipeline->audiobin )
-       {
-               debug_warning("filter element is not created yet.\n");
-
-               player->bypass_sound_effect = FALSE;
-
-               /* store sound effect setting in order to apply it when audio filter is created */
-               player->audio_filter_info.filter_type = MM_AUDIO_FILTER_TYPE_CUSTOM;
-       }
-       else
-       {
-               int output_type;
-               bool is_earphone = FALSE;
-               return_val_if_fail( player->pipeline->audiobin, MM_ERROR_PLAYER_NOT_INITIALIZED );
-
-               filter_element = player->pipeline->audiobin[MMPLAYER_A_FILTER].gst;
-
-               /* get status if earphone is activated */
-               result = mm_sound_is_route_available(MM_SOUND_ROUTE_OUT_WIRED_ACCESSORY, &is_earphone);
-               if ( result ) {
-                       debug_error("mm_sound_is_route_available() failed [%x]!!\n", result);
-                       return result;
-               }
-
-               if (is_earphone)
-               {
-                       output_type = MM_AUDIO_FILTER_OUTPUT_EAR;
-               }
-               else
-               {
-                       output_type = MM_AUDIO_FILTER_OUTPUT_SPK;
-                       if (__mmplayer_is_earphone_only_filter_type(player, MM_AUDIO_FILTER_TYPE_CUSTOM, NULL))
-                       {
-                               debug_error("earphone is not equipped, some custom filter should operate with earphone(%x)\n", result);
-                               return MM_ERROR_PLAYER_SOUND_EFFECT_INVALID_STATUS;
-                       }
-               }
-
-               /* set filter output mode as SPEAKER or EARPHONE */
-               g_object_set(filter_element, "filter-output-mode", output_type, NULL);
-               debug_log("filter output mode = %d(0:spk,1:ear)\n", output_type);
-
-               result = __mmplayer_set_harmony_filter(player, filter_element);
-               if ( result )
-               {
-                       debug_error("_set_harmony_filter() failed(%x)\n", result);
-                       return result;
-               }
-       }
-       debug_fleave();
-
-       return result;
-}
-
-
-int
-mm_player_sound_filter_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 filter */
-       memset(player->audio_filter_info.custom_eq_level, MM_AUDIO_FILTER_CUSTOM_LEVEL_INIT, sizeof(int)*MM_AUDIO_FILTER_EQ_BAND_MAX);
-
-       debug_msg("All the EQ bands clearing success\n");
-
-       return result;
-}
-
-
-int
-mm_player_sound_filter_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 filters, except EQ */
-       for ( i = 0 ; i < MM_AUDIO_FILTER_CUSTOM_NUM - 1 ; i++ )
-       {
-               player->audio_filter_info.custom_ext_level[i] = MM_AUDIO_FILTER_CUSTOM_LEVEL_INIT;
-       }
-
-       debug_msg("All the extension filters clearing success\n");
-
-       return result;
-}
-
-
-int
-mm_player_is_supported_preset_filter_type(MMHandleType hplayer, MMAudioFilterPresetType filter)
-{
-       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_filter_type( MM_AUDIO_FILTER_TYPE_PRESET, filter ) )
-       {
-               result = MM_ERROR_PLAYER_SOUND_EFFECT_NOT_SUPPORTED_FILTER;
-       }
-
-       return result;
-}
-
-
-int
-mm_player_is_supported_custom_filter_type(MMHandleType hplayer, MMAudioFilterCustomType filter)
-{
-       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_filter_type( MM_AUDIO_FILTER_TYPE_CUSTOM, filter ) )
-       {
-               result = MM_ERROR_PLAYER_SOUND_EFFECT_NOT_SUPPORTED_FILTER;
-       }
-
-       return result;
-}
-
-
-int
-mm_player_sound_filter_preset_apply(MMHandleType hplayer, MMAudioFilterPresetType 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_filter_preset)
-       {
-               debug_error("sound filter(preset) is not suppported\n", type);
-               return MM_ERROR_NOT_SUPPORT_API;
-       }
-
-       if (type < MM_AUDIO_FILTER_PRESET_AUTO || type >= MM_AUDIO_FILTER_PRESET_NUM)
-       {
-               debug_error("out of range, type(%d)\n", type);
-               return MM_ERROR_INVALID_ARGUMENT;
-       }
-
-       /* check if this filter type is supported */
-       if ( !_mmplayer_is_supported_filter_type( MM_AUDIO_FILTER_TYPE_PRESET, type ) )
-       {
-               return MM_ERROR_PLAYER_SOUND_EFFECT_NOT_SUPPORTED_FILTER;
-       }
-
-       result = _mmplayer_sound_filter_preset_apply(player, type);
-
-       return result;
-}
-
-
-int
-mm_player_sound_filter_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_filter_custom)
-       {
-               debug_error("sound filter(custom) is not suppported\n");
-               return MM_ERROR_NOT_SUPPORT_API;
-       }
-
-       result = _mmplayer_sound_filter_custom_apply(player);
-
-       return result;
-}
-
-
-int
-mm_player_sound_filter_bypass (MMHandleType hplayer)
-{
-       mm_player_t* player = (mm_player_t*)hplayer;
-       int result = MM_ERROR_NONE;
-       GstElement *filter_element = NULL;
-       debug_fenter();
-
-       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-
-       if ( !PLAYER_INI()->use_audio_filter_preset && !PLAYER_INI()->use_audio_filter_custom )
-       {
-               debug_error("sound filter(preset/custom) is not suppported\n");
-               return MM_ERROR_NOT_SUPPORT_API;
-       }
-       if ( !player->pipeline || !player->pipeline->audiobin )
-       {
-               debug_warning("filter element is not created yet.\n");
-       }
-       else
-       {
-               return_val_if_fail( player->pipeline->audiobin, MM_ERROR_PLAYER_NOT_INITIALIZED );
-               filter_element = player->pipeline->audiobin[MMPLAYER_A_FILTER].gst;
-
-               /* order action to sound effect plugin */
-               g_object_set(filter_element, "filter-action", MM_AUDIO_FILTER_TYPE_NONE, NULL);
-               debug_log("filter-action = %d\n", MM_AUDIO_FILTER_TYPE_NONE);
-       }
-
-       debug_fleave();
-       return result;
-}
-
-
-int
-_mmplayer_sound_filter_custom_set_level_ext(mm_player_t *player, MMAudioFilterCustomType custom_filter_type, int level)
-{
-       int filter_level_max = 0;
-       int filter_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_filter_type( MM_AUDIO_FILTER_TYPE_CUSTOM, custom_filter_type ) )
-       {
-               return MM_ERROR_PLAYER_SOUND_EFFECT_NOT_SUPPORTED_FILTER;
-       }
-
-       while ( count < MM_AUDIO_FILTER_CUSTOM_NUM )
-       {
-               if ( PLAYER_INI()->audio_filter_custom_list[count] )
-               {
-                       if ( count == custom_filter_type )
-                       {
-                               filter_level_min = PLAYER_INI()->audio_filter_custom_min_level_list[ext_level_index];
-                               filter_level_max = PLAYER_INI()->audio_filter_custom_max_level_list[ext_level_index];
-                               debug_msg("level min value(%d), level max value(%d)\n", filter_level_min, filter_level_max);
-                               break;
-                       }
-                       ext_level_index++;
-                       if (ext_level_index == PLAYER_INI()->audio_filter_custom_ext_num + 1)
-                       {
-                               debug_error("could not find min, max value. maybe filter information in ini file is not proper for sound effect plugin\n");
-                               break;
-                       }
-               }
-               count++;
-       }
-
-       if ( level < filter_level_min || level > filter_level_max )
-       {
-               debug_error("out of range, level(%d)\n", level);
-               result = MM_ERROR_INVALID_ARGUMENT;
-       }
-       else
-       {
-               player->audio_filter_info.custom_ext_level[custom_filter_type-1] = level;
-               debug_msg("set ext[%d] = %d\n", custom_filter_type-1, level);
-       }
-
-       debug_fleave();
-       return result;
-}
-
-
-int
-_mmplayer_sound_filter_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_filter_type( MM_AUDIO_FILTER_TYPE_CUSTOM, MM_AUDIO_FILTER_CUSTOM_EQ ) )
-       {
-               return MM_ERROR_PLAYER_SOUND_EFFECT_NOT_SUPPORTED_FILTER;
-       }
-
-       if ( index < 0 || index > PLAYER_INI()->audio_filter_custom_eq_num - 1 )
-       {
-               debug_error("out of range, index(%d)\n", index);
-               result = MM_ERROR_INVALID_ARGUMENT;
-       }
-       else
-       {
-               eq_level_min = PLAYER_INI()->audio_filter_custom_min_level_list[MM_AUDIO_FILTER_CUSTOM_EQ];
-               eq_level_max = PLAYER_INI()->audio_filter_custom_max_level_list[MM_AUDIO_FILTER_CUSTOM_EQ];
-               debug_msg("EQ level min value(%d), EQ level max value(%d)\n", eq_level_min, eq_level_max);
-
-               if ( level < eq_level_min || level > eq_level_max )
-               {
-                       debug_error("out of range, EQ level(%d)\n", level);
-                       result =  MM_ERROR_INVALID_ARGUMENT;
-               }
-               else
-               {
-                       player->audio_filter_info.custom_eq_level[index] = level;
-                       debug_msg("set EQ[%d] = %d\n", index, level);
-               }
-       }
-       debug_fleave();
-
-       return result;
-}
-
-
-/* NOTE : parameter eq_index is only used for _set_eq_level() */
-int
-mm_player_sound_filter_custom_set_level(MMHandleType hplayer, MMAudioFilterCustomType filter_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 filter type is supported */
-       if ( !_mmplayer_is_supported_filter_type( MM_AUDIO_FILTER_TYPE_CUSTOM, filter_custom_type ) )
-       {
-               return MM_ERROR_PLAYER_SOUND_EFFECT_NOT_SUPPORTED_FILTER;
-       }
-
-       if (filter_custom_type == MM_AUDIO_FILTER_CUSTOM_EQ)
-       {
-               result = _mmplayer_sound_filter_custom_set_level_eq(player, eq_index, level);
-       }
-       else if (filter_custom_type > MM_AUDIO_FILTER_CUSTOM_EQ || filter_custom_type < MM_AUDIO_FILTER_CUSTOM_NUM)
-       {
-               result = _mmplayer_sound_filter_custom_set_level_ext(player, filter_custom_type, level);
-       }
-       else
-       {
-               debug_error("out of range, filter type(%d)\n", filter_custom_type);
-               result = MM_ERROR_INVALID_ARGUMENT;
-       }
-       return result;
-}
-
-
-int
-mm_player_sound_filter_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_filter_type( MM_AUDIO_FILTER_TYPE_CUSTOM, MM_AUDIO_FILTER_CUSTOM_EQ ) )
-       {
-               return MM_ERROR_PLAYER_SOUND_EFFECT_NOT_SUPPORTED_FILTER;
-       }
-
-       *bands = PLAYER_INI()->audio_filter_custom_eq_num;
-       debug_log("number of custom eq band = %d\n", *bands);
-
-       debug_fleave();
-
-       return result;
-}
-
-
-int
-mm_player_sound_filter_custom_get_level(MMHandleType hplayer, MMAudioFilterCustomType 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 filter type is supported */
-       if ( !_mmplayer_is_supported_filter_type( MM_AUDIO_FILTER_TYPE_CUSTOM, type ) )
-       {
-               return MM_ERROR_PLAYER_SOUND_EFFECT_NOT_SUPPORTED_FILTER;
-       }
-
-       if (type == MM_AUDIO_FILTER_CUSTOM_EQ)
-       {
-               if ( eq_index < 0 || eq_index > PLAYER_INI()->audio_filter_custom_eq_num - 1 )
-               {
-                       debug_error("out of range, eq index(%d)\n", eq_index);
-                       result = MM_ERROR_INVALID_ARGUMENT;
-               }
-               else
-               {
-                       *level = player->audio_filter_info.custom_eq_level[eq_index];
-                       debug_log("EQ index = %d, level = %d\n", eq_index, *level);
-               }
-       }
-       else if ( type > MM_AUDIO_FILTER_CUSTOM_EQ && type < MM_AUDIO_FILTER_CUSTOM_NUM )
-       {
-               *level = player->audio_filter_info.custom_ext_level[type-1];
-               debug_log("extention filter index = %d, level = %d\n", type, *level);
-       }
-       else
-       {
-               debug_error("out of range, type(%d)\n", type);
-               result = MM_ERROR_INVALID_ARGUMENT;
-       }
-
-       debug_fleave();
-
-       return result;
-}
-
-
-int
-mm_player_sound_filter_custom_get_level_range(MMHandleType hplayer, MMAudioFilterCustomType 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 filter type is supported */
-       if ( !_mmplayer_is_supported_filter_type( MM_AUDIO_FILTER_TYPE_CUSTOM, type ) )
-       {
-               return MM_ERROR_PLAYER_SOUND_EFFECT_NOT_SUPPORTED_FILTER;
-       }
-
-       if ( type == MM_AUDIO_FILTER_CUSTOM_EQ )
-       {
-               *min = PLAYER_INI()->audio_filter_custom_min_level_list[MM_AUDIO_FILTER_CUSTOM_EQ];
-               *max = PLAYER_INI()->audio_filter_custom_max_level_list[MM_AUDIO_FILTER_CUSTOM_EQ];
-               debug_log("EQ min level = %d, max level = %d\n", *min, *max);
-       }
-       else
-       {
-               while ( count < MM_AUDIO_FILTER_CUSTOM_NUM )
-               {
-                       if ( PLAYER_INI()->audio_filter_custom_list[count] )
-                       {
-                               if ( count == type )
-                               {
-                                       *min = PLAYER_INI()->audio_filter_custom_min_level_list[ext_level_index];
-                                       *max = PLAYER_INI()->audio_filter_custom_max_level_list[ext_level_index];
-                                       debug_msg("Extension filter(%d) min level = %d, max level = %d\n", count, *min, *max);
-                                       break;
-                               }
-                               ext_level_index++;
-                               if ( ext_level_index == PLAYER_INI()->audio_filter_custom_ext_num + 1 )
-                               {
-                                       debug_error("could not find min, max value. maybe filter information in ini file is not proper for sound effect plugin\n");
-                                       break;
-                               }
-                       }
-                       count++;
-               }
-       }
-
-       debug_fleave();
-
-       return result;
-}
-
-
-int
-mm_player_sound_filter_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_filter_type( MM_AUDIO_FILTER_TYPE_CUSTOM, MM_AUDIO_FILTER_CUSTOM_EQ ) )
-       {
-               return MM_ERROR_PLAYER_SOUND_EFFECT_NOT_SUPPORTED_FILTER;
-       }
-
-       if ( size != PLAYER_INI()->audio_filter_custom_eq_num )
-       {
-               debug_error("input size variable(%d) does not match with number of eq band(%d)\n", size, PLAYER_INI()->audio_filter_custom_eq_num);
-               result = MM_ERROR_INVALID_ARGUMENT;
-       }
-       else
-       {
-               eq_level_min = PLAYER_INI()->audio_filter_custom_min_level_list[MM_AUDIO_FILTER_CUSTOM_EQ];
-               eq_level_max = PLAYER_INI()->audio_filter_custom_max_level_list[MM_AUDIO_FILTER_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\n", i, level_list[i]);
-                               result = MM_ERROR_INVALID_ARGUMENT;
-                               break;
-                       }
-                       player->audio_filter_info.custom_eq_level[i] = level_list[i];
-               }
-       }
-       debug_fleave();
-
-       return result;
-}
index adcb763..0f5fc56 100755 (executable)
 
 #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);
-
+#define TO_THE_END 0
+
+typedef struct{
+       gint byte_in_rate;              // byte
+       gint byte_out_rate;             // byte
+       gdouble time_rate;              // second
+       guint buffer_criteria;  // byte
+}streaming_bitrate_info_t;
+
+typedef struct{
+       gint64 position;        // ns
+       gint64 duration;        // ns
+       guint64 content_size;   // bytes
+}streaming_content_info_t;
+
+typedef struct{
+       guint buffering_bytes;          // bytes
+       gdouble buffering_time;         // second
+       gdouble percent_byte;
+       gdouble percent_time;
+}streaming_buffer_info_t;
+
+static void streaming_check_buffer_percent(gdouble in_low, gdouble in_high, gdouble *out_low, gdouble *out_high);
+static void streaming_set_buffer_percent(mm_player_streaming_t* streamer, BufferType type, gdouble low_percent, gdouble high_percent_byte, gdouble high_percent_time);
+static void streaming_set_queue2_queue_type (mm_player_streaming_t* streamer, gboolean use_file, gchar * file_path, guint64 content_size);
+static void streaming_set_buffer_size(mm_player_streaming_t* streamer, BufferType type, guint buffering_bytes, gdouble buffering_time);
+static void streaming_update_buffering_status(mm_player_streaming_t* streamer, GstMessage *buffering_msg, gint64 position);
+static void streaming_get_current_bitrate_info(        mm_player_streaming_t* streamer,
+                                                                                               GstMessage *buffering_msg,
+                                                                                               streaming_content_info_t content_info,
+                                                                                               streaming_bitrate_info_t* bitrate_info);
+static void
+streaming_handle_fixed_buffering_mode( mm_player_streaming_t* streamer,
+                                                                               gint byte_out_rate,
+                                                                               gdouble fixed_buffering_time,
+                                                                               streaming_buffer_info_t* buffer_info);
+static void
+streaming_handle_adaptive_buffering_mode(      mm_player_streaming_t* streamer,
+                                                                                       streaming_content_info_t content_info,
+                                                                                       streaming_bitrate_info_t bitrate_info,
+                                                                                       streaming_buffer_info_t* buffer_info,
+                                                                                       gint expected_play_time);
+static void
+streaming_update_buffer_setting        (       mm_player_streaming_t* streamer,
+                                                                       GstMessage *buffering_msg,
+                                                                       guint64 content_size,
+                                                                       gint64 position,
+                                                                       gint64 duration);
 
 mm_player_streaming_t *
-__mm_player_streaming_create ()
+__mm_player_streaming_create (void)
 {
        mm_player_streaming_t *streamer = NULL;
 
-       debug_fenter();
+       MMPLAYER_FENTER();
 
        streamer = (mm_player_streaming_t *) malloc (sizeof (mm_player_streaming_t));
        if (!streamer)
@@ -45,392 +87,1034 @@ __mm_player_streaming_create ()
                return NULL;
        }
 
-       debug_fleave();
+       memset(streamer, 0, sizeof(mm_player_streaming_t));
+
+       MMPLAYER_FLEAVE();
 
        return streamer;
 }
 
+static void
+streaming_buffer_initialize (streaming_buffer_t* buffer_handle, gboolean buffer_init)
+{
+       if (buffer_init)
+               buffer_handle->buffer = NULL;
+
+       buffer_handle->buffering_bytes = DEFAULT_BUFFER_SIZE_BYTES;
+       buffer_handle->buffering_time = DEFAULT_BUFFERING_TIME;
+       buffer_handle->buffer_low_percent = DEFAULT_BUFFER_LOW_PERCENT;
+       buffer_handle->buffer_high_percent = DEFAULT_BUFFER_HIGH_PERCENT;
+       buffer_handle->is_live = FALSE;
+
+}
+
 void __mm_player_streaming_initialize (mm_player_streaming_t* streamer)
 {
-       debug_fenter();
+       MMPLAYER_FENTER();
+
+       streamer->streaming_buffer_type = BUFFER_TYPE_DEFAULT;  // multi-queue
+
+       streaming_buffer_initialize(&(streamer->buffer_handle[BUFFER_TYPE_MUXED]), TRUE);
+       streaming_buffer_initialize(&(streamer->buffer_handle[BUFFER_TYPE_DEMUXED]), TRUE);
+
+       streamer->buffering_req.mode = MM_PLAYER_BUFFERING_MODE_ADAPTIVE;
+       streamer->buffering_req.is_pre_buffering = FALSE;
+       streamer->buffering_req.initial_second = 0;
+       streamer->buffering_req.runtime_second = 0;
+
+       streamer->default_val.buffering_monitor = FALSE;
+       streamer->default_val.buffering_time = DEFAULT_BUFFERING_TIME;
 
-       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->need_sync = FALSE;
 
        streamer->is_buffering = FALSE;
+       streamer->is_buffering_done = FALSE;
        streamer->buffering_percent = -1;
-       streamer->buffering_time = DEFAULT_BUFFERING_TIME;
-
-       debug_fleave();
 
+       MMPLAYER_FLEAVE();
        return;
 }
 
 void __mm_player_streaming_deinitialize (mm_player_streaming_t* streamer)
 {
-       debug_fenter();
-
+       MMPLAYER_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->streaming_buffer_type = BUFFER_TYPE_DEFAULT;  // multi-queue
+
+       streaming_buffer_initialize(&(streamer->buffer_handle[BUFFER_TYPE_MUXED]), FALSE);
+       streaming_buffer_initialize(&(streamer->buffer_handle[BUFFER_TYPE_DEMUXED]), FALSE);
+
+       streamer->buffering_req.mode = MM_PLAYER_BUFFERING_MODE_ADAPTIVE;
+       streamer->buffering_req.is_pre_buffering = FALSE;
+       streamer->buffering_req.initial_second = 0;
+       streamer->buffering_req.runtime_second = 0;
+
+       streamer->default_val.buffering_monitor = FALSE;
+       streamer->default_val.buffering_time = DEFAULT_BUFFERING_TIME;
+
        streamer->buffer_avg_bitrate = 0;
        streamer->buffer_max_bitrate = 0;
        streamer->need_update = FALSE;
+       streamer->need_sync = FALSE;
 
        streamer->is_buffering = FALSE;
+       streamer->is_buffering_done = FALSE;
        streamer->buffering_percent = -1;
-       streamer->buffering_time = DEFAULT_BUFFERING_TIME;
-
-       debug_fleave();
 
+       MMPLAYER_FLEAVE();
        return;
 }
 
-
 void __mm_player_streaming_destroy (mm_player_streaming_t* streamer)
 {
-       debug_fenter();
+       MMPLAYER_FENTER();
 
        if(streamer)
        {
-               free (streamer);
+               g_free (streamer);
                streamer = NULL;
        }
 
-       debug_fleave();
+       MMPLAYER_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)
+void __mm_player_streaming_set_content_bitrate(mm_player_streaming_t* streamer, guint max_bitrate, guint avg_bitrate)
 {
-       debug_fenter();
+       MMPLAYER_FENTER();
 
        return_if_fail(streamer);
 
-       if (buffer)
+       /* 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)
        {
-               streamer->buffer = buffer;
-
-               debug_log("buffer element is %s.", GST_ELEMENT_NAME(buffer));
+               debug_log("set maximum bitrate(%dbps).\n", max_bitrate);
+               streamer->buffer_max_bitrate = max_bitrate;
+               if (streamer->buffering_req.is_pre_buffering == FALSE)
+               {
+                       streamer->need_update = TRUE;
+               }
+               else
+               {
+                       debug_log("pre-buffering...\n");
 
-               g_object_set ( G_OBJECT (streamer->buffer), "use-buffering", use_buffering, NULL );
+                       if (IS_MUXED_BUFFERING_MODE(streamer))
+                               streaming_update_buffer_setting(streamer, NULL, 0, 0, 0);
+               }
        }
 
-       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);
+       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;
 
-       debug_fleave();
+               if (streamer->buffering_req.is_pre_buffering == FALSE)
+               {
+                       streamer->need_update = TRUE;
+               }
+               else
+               {
+                       debug_log("pre-buffering...\n");
+
+                       if (IS_MUXED_BUFFERING_MODE(streamer))
+                               streaming_update_buffer_setting(streamer, NULL, 0, 0, 0);
+               }
+       }
 
+       MMPLAYER_FLEAVE();
        return;
 }
 
-
-void __mm_player_streaming_set_content_bitrate(mm_player_streaming_t* streamer, guint max_bitrate, guint avg_bitrate)
+static void
+streaming_check_buffer_percent(gdouble in_low, gdouble in_high, gdouble *out_low, gdouble *out_high)
 {
-       debug_fenter();
-
-       return_if_fail(streamer);
+       gdouble buffer_low_percent = DEFAULT_BUFFER_LOW_PERCENT;
+       gdouble buffer_high_percent = DEFAULT_BUFFER_HIGH_PERCENT;
 
-       /* 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;
+       MMPLAYER_FENTER();
 
-               streamer->need_update = TRUE;
-        }
+       return_if_fail(out_low && out_high);
 
-        if (avg_bitrate > 0 && streamer->buffer_avg_bitrate != avg_bitrate)
+       if (in_low <= MIN_BUFFER_PERCENT || in_low >= MAX_BUFFER_PERCENT)
+       {
+               debug_warning("buffer low percent is out of range. use defaut value.");
+       }
+       else
        {
-              debug_log("set averate bitrate(%dbps).\n", avg_bitrate);
-              streamer->buffer_avg_bitrate = avg_bitrate;
+               buffer_low_percent = in_low;
+       }
 
-               streamer->need_update = TRUE;
+       if (in_high  <=  MIN_BUFFER_PERCENT || in_high  >=  MAX_BUFFER_PERCENT)
+       {
+               debug_warning("buffer high percent is out of range. use defaut value.");
+       }
+       else
+       {
+               buffer_high_percent = in_high;
        }
 
-       debug_fleave();
+       if (buffer_high_percent <= buffer_low_percent)
+               buffer_high_percent =  buffer_low_percent + 1.0;
 
-       return;
+       debug_log("set buffer percent to %2.3f ~ %2.3f.",  buffer_low_percent, buffer_high_percent);
+
+       *out_low = buffer_low_percent;
+       *out_high = buffer_high_percent;
 }
 
 static void
-streaming_set_buffer_size(mm_player_streaming_t* streamer, guint buffer_size)
+streaming_set_buffer_percent(  mm_player_streaming_t* streamer,
+                                                               BufferType type,
+                                                               gdouble low_percent,
+                                                               gdouble high_percent_byte,
+                                                               gdouble high_percent_time)
 {
-       debug_fenter();
+       gdouble confirmed_low = DEFAULT_BUFFER_LOW_PERCENT;
+       gdouble confirmed_high = DEFAULT_BUFFER_HIGH_PERCENT;
+       gdouble high_percent = 0.0;
+
+       streaming_buffer_t* buffer_handle = NULL;
+       gchar* factory_name = NULL;
 
+       MMPLAYER_FENTER();
        return_if_fail(streamer);
-       return_if_fail(buffer_size>0);
+       return_if_fail(type < BUFFER_TYPE_MAX);
+
+       buffer_handle = &(streamer->buffer_handle[type]);
+       if (!(buffer_handle && buffer_handle->buffer))
+       {
+               debug_error("buffer_handle->buffer is NULL!");
+               return;
+       }
 
-       debug_log("set buffer size to %d.", buffer_size);
+       factory_name = GST_PLUGIN_FEATURE_NAME(gst_element_get_factory(buffer_handle->buffer));
 
-       streamer->buffer_size = buffer_size;
+       if (!factory_name)
+       {
+               debug_error("Fail to get factory name!");
+               return;
+       }
+
+       if (type == BUFFER_TYPE_MUXED)
+               high_percent = high_percent_byte;
+       else
+               high_percent = MAX(high_percent_time, high_percent_byte);
 
-       if (streamer->buffer)
-               g_object_set (G_OBJECT(streamer->buffer), "max-size-bytes", buffer_size, NULL);
+       streaming_check_buffer_percent(low_percent, high_percent, &confirmed_low, &confirmed_high);
 
-       debug_fleave();
+       // if use-buffering is disabled, this settings do not have any meaning.
+       debug_log("target buffer elem : %s (%2.3f ~ %2.3f)",
+               GST_ELEMENT_NAME(buffer_handle->buffer), confirmed_low, confirmed_high);
 
+       if ((confirmed_low == DEFAULT_BUFFER_LOW_PERCENT) ||
+               (buffer_handle->buffer_low_percent != confirmed_low))
+       {
+               if (g_strrstr(factory_name, "queue2"))
+                       g_object_set (G_OBJECT(buffer_handle->buffer), "low-percent", confirmed_low, NULL);
+               else
+                       g_object_set (G_OBJECT(buffer_handle->buffer), "low-percent", (gint)confirmed_low, NULL);
+       }
+
+       if ((confirmed_high == DEFAULT_BUFFER_HIGH_PERCENT) ||
+               (buffer_handle->buffer_high_percent != confirmed_high))
+       {
+               if (g_strrstr(factory_name, "queue2"))
+                       g_object_set (G_OBJECT(buffer_handle->buffer), "high-percent", confirmed_high, NULL);
+               else
+                       g_object_set (G_OBJECT(buffer_handle->buffer), "high-percent", (gint)confirmed_high, NULL);
+       }
+
+       buffer_handle->buffer_low_percent = confirmed_low;
+       buffer_handle->buffer_high_percent = confirmed_high;
+
+       MMPLAYER_FLEAVE();
        return;
 }
 
 static void
-streaming_set_buffer_percent(mm_player_streaming_t* streamer, gdouble low_percent, gdouble high_percent)
+streaming_set_queue2_queue_type (mm_player_streaming_t* streamer, gboolean use_file, gchar * file_path, guint64 content_size)
 {
-       gdouble buffer_low_percent = DEFAULT_BUFFER_LOW_PERCENT;
-       gdouble buffer_high_percent = DEFAULT_BUFFER_HIGH_PERCENT;
-
-       debug_fenter();
+       streaming_buffer_t* buffer_handle = NULL;
+       guint64 storage_available_size = 0L; //bytes
+       guint64 file_buffer_size = 0L;  //bytes
+       gchar file_buffer_name[MM_MAX_URL_LEN] = {0};
+       struct statfs buf = {0};
+       gchar* factory_name = NULL;
 
+       MMPLAYER_FENTER();
        return_if_fail(streamer);
+       return_if_fail(streamer->buffer_handle[BUFFER_TYPE_MUXED].buffer);
+
+       buffer_handle = &(streamer->buffer_handle[BUFFER_TYPE_MUXED]);
 
-       if (low_percent <= MIN_BUFFER_PERCENT || low_percent >= MAX_BUFFER_PERCENT)
+       if (!(buffer_handle && buffer_handle->buffer))
        {
-               debug_warning("buffer low percent is out of range. use defaut value.");
-               buffer_low_percent = DEFAULT_BUFFER_LOW_PERCENT;
+               debug_error("buffer_handle->buffer is NULL!");
+               return;
        }
-       else
+
+       factory_name = GST_PLUGIN_FEATURE_NAME(gst_element_get_factory(buffer_handle->buffer));
+
+       if (!factory_name)
        {
-               buffer_low_percent = low_percent;
+               debug_error("Fail to get factory name!");
+               return;
        }
 
-       if (high_percent  <=  MIN_BUFFER_PERCENT || high_percent  >=  MAX_BUFFER_PERCENT)
+       debug_log("target buffer elem : %s", GST_ELEMENT_NAME(buffer_handle->buffer));
+
+       if (!g_strrstr(factory_name, "queue2"))
        {
-               debug_warning("buffer high percent is out of range. use defaut value.");
-               buffer_high_percent = DEFAULT_BUFFER_HIGH_PERCENT;
+               debug_log("only queue2 can use file buffer. not decodebin2 or multiQ\n");
+               return;
        }
-       else
+
+       if ((!use_file) || (!g_strrstr(factory_name, "queue2")))
        {
-               buffer_high_percent = high_percent;
+               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;
        }
 
-       if (buffer_high_percent <= buffer_low_percent)
-               buffer_high_percent =  buffer_low_percent + 1.0;
+       debug_log("[Queue2] 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);
 
-       debug_log("set buffer percent to %2.3f ~ %2.3f.",  streamer->buffer_low_percent, streamer->buffer_high_percent);
+       g_snprintf(file_buffer_name, MM_MAX_URL_LEN, "%s/XXXXXX", file_path);
+       secure_debug_log("[Queue2] the buffering file name is %s.\n", file_buffer_name);
 
-       if (streamer->buffer)
+       if (statfs((const char *)file_path, &buf) < 0)
        {
-               if ( streamer->buffer_low_percent != buffer_low_percent )
-                       g_object_set (G_OBJECT(streamer->buffer), "low-percent", streamer->buffer_low_percent, NULL);
+               debug_warning ("[Queue2] 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 ("[Queue2] the number of available blocks : %"G_GUINT64_FORMAT
+                                       ", the block size is %"G_GUINT64_FORMAT".\n",
+                                       (guint64)buf.f_bavail, (guint64)buf.f_bsize);
 
-               if ( streamer->buffer_high_percent != buffer_high_percent )
-                       g_object_set (G_OBJECT(streamer->buffer), "high-percent", streamer->buffer_high_percent, NULL);
+               debug_log ("[Queue2] 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;
        }
 
-       streamer->buffer_low_percent = buffer_low_percent;
-       streamer->buffer_high_percent = buffer_high_percent;
+       if (file_buffer_size>0)
+               debug_log("[Queue2] use file ring buffer for buffering.");
 
-       debug_fleave();
+       g_object_set (G_OBJECT(buffer_handle->buffer), "temp-template", file_buffer_name, NULL);
+       g_object_set (G_OBJECT(buffer_handle->buffer), "file-buffer-max-size", file_buffer_size, NULL);
 
+       MMPLAYER_FLEAVE();
        return;
 }
 
 static void
-streaming_set_buffering_time(mm_player_streaming_t* streamer, gdouble buffering_time)
+streaming_set_buffer_size(mm_player_streaming_t* streamer, BufferType type, guint buffering_bytes, gdouble buffering_time)
 {
-       gdouble buffer_buffering_time = DEFAULT_BUFFERING_TIME;
+       streaming_buffer_t* buffer_handle = NULL;
 
-       debug_fenter();
+       MMPLAYER_FENTER();
 
        return_if_fail(streamer);
+       return_if_fail(buffering_bytes > 0);
+       return_if_fail(type < BUFFER_TYPE_MAX);
 
-       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;
+       buffer_handle = &(streamer->buffer_handle[type]);
 
-       if (streamer->buffering_time != buffer_buffering_time)
+       if (buffer_handle && buffer_handle->buffer)
        {
-               debug_log("set buffer buffering time from %2.1f to %2.1f.", streamer->buffering_time, buffer_buffering_time);
+               if (g_strrstr(GST_ELEMENT_NAME(buffer_handle->buffer), "multiqueue"))
+               {
+                       if (buffering_time <= 0)
+                               buffering_time = GET_CURRENT_BUFFERING_TIME(buffer_handle);
+
+                       g_object_set (G_OBJECT(buffer_handle->buffer),
+                                                       "max-size-bytes", MAX_DECODEBIN_BUFFER_BYTES,   // fixed
+                                                       "max-size-time", ((guint)ceil(buffering_time) * GST_SECOND),
+                                                       "max-size-buffers", 0, NULL);                                   // disable
+
+                       buffer_handle->buffering_time = buffering_time;
+                       buffer_handle->buffering_bytes = MAX_DECODEBIN_BUFFER_BYTES;
+
+                       debug_log("[New][MQ] max-size-time : %f", buffering_time);
+               }
+               else    // queue2
+               {
+                       if (buffer_handle->is_live)
+                       {
+                               g_object_set (G_OBJECT(buffer_handle->buffer),
+                                                               "max-size-bytes", buffering_bytes,
+                                                               "max-size-time", (guint64)(buffering_time*GST_SECOND),
+                                                               "max-size-buffers", 0,
+                                                               "use-rate-estimate", TRUE, NULL);
+                       }
+                       else
+                       {
+                               g_object_set (G_OBJECT(buffer_handle->buffer),
+                                                               "max-size-bytes", buffering_bytes,
+                                                               "max-size-time", (guint64)0,
+                                                               "max-size-buffers", 0,
+                                                               "use-rate-estimate", FALSE, NULL);
+                       }
+
+                       buffer_handle->buffering_bytes = buffering_bytes;
+                       buffer_handle->buffering_time = buffering_time;
+
+                       debug_log("[New][Q2] max-size-bytes : %d", buffering_bytes);
+               }
+       }
+
+       MMPLAYER_FLEAVE();
+       return;
+}
 
-               streamer->buffering_time = buffer_buffering_time;
+void __mm_player_streaming_set_queue2(         mm_player_streaming_t* streamer,
+                                                                               GstElement* buffer,
+                                                                               gboolean use_buffering,
+                                                                               guint buffering_bytes,
+                                                                               gdouble buffering_time,
+                                                                               gdouble low_percent,
+                                                                               gdouble high_percent,
+                                                                               gboolean use_file,
+                                                                               gchar* file_path,
+                                                                               guint64 content_size)
+{
+       MMPLAYER_FENTER();
+       return_if_fail(streamer);
+
+       if (buffer)
+       {
+               debug_log("USE-BUFFERING : %s", (use_buffering)?"OOO":"XXX");
+
+               streamer->buffer_handle[BUFFER_TYPE_MUXED].buffer = buffer;
+
+               if (use_buffering)
+               {
+                       streamer->streaming_buffer_type = BUFFER_TYPE_MUXED;
+
+                       if (content_size > 0)
+                       {
+                               if (streamer->buffering_req.initial_second > 0)
+                                       streamer->buffering_req.is_pre_buffering = TRUE;
+                               else
+                                       streamer->buffering_req.initial_second = (gint)ceil(buffering_time);
+                       }
+                       else
+                       {
+                               debug_log("live streaming without mq");
+
+                               streamer->buffer_handle[BUFFER_TYPE_MUXED].is_live = TRUE;
+                               streamer->buffering_req.initial_second = buffering_time = DEFAULT_BUFFERING_TIME;
+                       }
+               }
+
+               g_object_set ( G_OBJECT (streamer->buffer_handle[BUFFER_TYPE_MUXED].buffer), "use-buffering", use_buffering, NULL );
        }
 
-       debug_fleave();
+       streaming_set_buffer_size               (streamer, BUFFER_TYPE_MUXED, buffering_bytes, buffering_time);
+       streaming_set_buffer_percent    (streamer, BUFFER_TYPE_MUXED, low_percent, high_percent, 0);
+       streaming_set_queue2_queue_type (streamer, use_file, file_path, content_size);
 
+       MMPLAYER_FLEAVE();
        return;
 }
 
-static void
-streaming_set_buffer_type (mm_player_streaming_t* streamer, gboolean use_file, gchar * file_path, guint64 content_size)
+void __mm_player_streaming_sync_property(mm_player_streaming_t* streamer, GstElement* decodebin)
 {
-       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};
+       streaming_buffer_t* buffer_handle = NULL;
+
+       MMPLAYER_FENTER();
 
-       debug_fenter();
+       return_if_fail ( streamer && decodebin );
 
-       return_if_fail(streamer && streamer->buffer);
+       buffer_handle = &(streamer->buffer_handle[BUFFER_TYPE_DEMUXED]);
 
-       if (!use_file)
+       if ((streamer->need_sync) && (streamer->streaming_buffer_type == BUFFER_TYPE_DEMUXED))
        {
-               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;
+               g_object_set (G_OBJECT(decodebin),
+                                       "max-size-bytes", buffer_handle->buffering_bytes,
+                                       "max-size-time", (guint64)(ceil(buffer_handle->buffering_time) * GST_SECOND),
+                                       "low-percent", (gint)buffer_handle->buffer_low_percent,
+                                       "high-percent", (gint)buffer_handle->buffer_high_percent, NULL);
+
        }
 
-       debug_log("use file for buffering. streaming is played on pull-based. \n");
+       streamer->need_sync = FALSE;
+}
 
-       if (!file_path || strlen(file_path) <= 0)
-               file_path = g_strdup(DEFAULT_FILE_BUFFER_PATH);
+void __mm_player_streaming_set_multiqueue(     mm_player_streaming_t* streamer,
+                                                                               GstElement* buffer,
+                                                                               gboolean use_buffering,
+                                                                               guint buffering_bytes,
+                                                                               gdouble buffering_time,
+                                                                               gdouble low_percent,
+                                                                               gdouble high_percent)
+{
+       streaming_buffer_t* buffer_handle = NULL;
+       gdouble pre_buffering_time = 0.0;
 
-       sprintf( file_buffer_name, "%s/XXXXXX", file_path );
-       debug_log("the buffering file name is %s.\n", file_buffer_name);
+       MMPLAYER_FENTER();
+       return_if_fail(streamer);
 
-       if (statfs((const char *)file_path, &buf) < 0)
+       buffer_handle = &(streamer->buffer_handle[BUFFER_TYPE_DEMUXED]);
+       pre_buffering_time = (gdouble)streamer->buffering_req.initial_second;
+
+       if (buffer)
        {
-               debug_warning ("fail to get availabe storage capacity. just use file buffer.\n");
-               file_buffer_size = 0L;
+               debug_log("USE-BUFFERING : %s", (use_buffering)?"OOO":"XXX");
+
+               buffer_handle->buffer = buffer;
+
+               if (use_buffering)
+               {
+                       streamer->streaming_buffer_type = BUFFER_TYPE_DEMUXED;
+
+                       // during prebuffering by requirement, buffer setting should not be changed.
+                       if (pre_buffering_time > 0)
+                               streamer->buffering_req.is_pre_buffering = TRUE;
+               }
+
+               g_object_set ( G_OBJECT (buffer_handle->buffer), "use-buffering", use_buffering, NULL );
        }
-       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);
+       debug_log ("time req: %2.2f, default: %2.2f\n", pre_buffering_time, buffering_time);
 
-               if (content_size <= 0 || content_size >= storage_available_size)
-                       file_buffer_size = storage_available_size;
-               else
-                       file_buffer_size = 0L;
+       if (pre_buffering_time <= 0.0)
+       {
+               pre_buffering_time = DEFAULT_PLAYING_TIME;
+               streamer->buffering_req.initial_second = (gint)ceil(buffering_time);
        }
 
-       if (file_buffer_size>0)
-               debug_log("use file ring buffer for buffering.");
+       high_percent = (pre_buffering_time * 100) / MAX_DECODEBIN_BUFFER_TIME;
+       debug_log ("high_percent :  per %2.3f %%\n", high_percent);
 
-       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);
+       streaming_set_buffer_size (streamer, BUFFER_TYPE_DEMUXED, MAX_DECODEBIN_BUFFER_BYTES, MAX_DECODEBIN_BUFFER_TIME);
+       streaming_set_buffer_percent (streamer, BUFFER_TYPE_DEMUXED, low_percent, 0, high_percent);
 
-       debug_fleave();
+       streamer->need_sync = TRUE;
 
+       MMPLAYER_FLEAVE();
        return;
 }
 
-#define GET_BYTE_FROM_BIT(bit) (bit/8)
-void __mm_player_streaming_buffering(mm_player_streaming_t* streamer, GstMessage *buffering_msg)
+static void
+streaming_get_current_bitrate_info(    mm_player_streaming_t* streamer,
+                                                                       GstMessage *buffering_msg,
+                                                                       streaming_content_info_t content_info,
+                                                                       streaming_bitrate_info_t* bitrate_info)
 {
+
+       GstQuery *query = NULL;
        GstBufferingMode mode = GST_BUFFERING_STREAM;
-       gint byte_in_rate = 0;
-       gint byte_out_rate = 0;
+       gint in_rate = 0;
+       gint 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;
+       guint estimated_content_bitrate = 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 );
+       gdouble buffer_buffering_time = DEFAULT_BUFFERING_TIME;
 
-       /* update when buffering has started. */
-       if ( !streamer->is_buffering )
+       MMPLAYER_FENTER();
+
+       return_if_fail(streamer);
+       return_if_fail(bitrate_info);
+
+       if ((buffering_msg == NULL) ||
+               ((streamer->buffer_handle[BUFFER_TYPE_DEMUXED].buffer != NULL) &&
+               (streamer->buffer_handle[BUFFER_TYPE_MUXED].buffer != NULL) &&
+               (buffering_msg->src == (GstObject *)streamer->buffer_handle[BUFFER_TYPE_DEMUXED].buffer)))
        {
-               debug_log ( "buffering has started.\n" );
+               query = gst_query_new_buffering (GST_FORMAT_PERCENT);
 
-               streamer->is_buffering = TRUE;
-               streamer->buffering_percent = -1;
-               streamer->need_update = TRUE;
+               if (gst_element_query ((streamer->buffer_handle[BUFFER_TYPE_MUXED].buffer), query))
+               {
+                       gst_query_parse_buffering_stats (query, &mode, &in_rate, &out_rate, &buffering_left);
+               }
+
+               gst_query_unref (query);
+       }
+       else
+       {
+               gst_message_parse_buffering_stats (buffering_msg, &mode, &in_rate, &out_rate, &buffering_left);
        }
 
-       /* update buffer percent */
-       gst_message_parse_buffering ( buffering_msg, &buffer_percent );
+       debug_log ("Streaming Info : in %d, out %d, left %lld\n", in_rate, out_rate, buffering_left);
+
+       if ((content_info.content_size > 0) && (content_info.duration > 0) && ((content_info.duration/GST_SECOND) > 0))
+               estimated_content_bitrate = GET_BIT_FROM_BYTE((guint)(content_info.content_size / (content_info.duration/GST_SECOND)));
 
-       if ( streamer->buffering_percent < buffer_percent )
+       if (streamer->buffer_max_bitrate > 0)
        {
-               debug_log ( "buffering %d%%....\n", buffer_percent );
-               streamer->buffering_percent = buffer_percent;
+               streamer->buffer_max_bitrate = MAX(streamer->buffer_max_bitrate, streamer->buffer_avg_bitrate);
+               streamer->buffer_max_bitrate = MAX(streamer->buffer_max_bitrate, estimated_content_bitrate);
+
+               buffer_criteria = GET_BYTE_FROM_BIT(streamer->buffer_max_bitrate);
+
+               if (streamer->buffer_avg_bitrate > estimated_content_bitrate)
+                       out_rate = GET_BYTE_FROM_BIT(streamer->buffer_avg_bitrate);
+               else if (estimated_content_bitrate != 0)
+                       out_rate = GET_BYTE_FROM_BIT(estimated_content_bitrate);
+               else
+                       out_rate = GET_BYTE_FROM_BIT(streamer->buffer_max_bitrate/3);
+
+               debug_log ("(max)content_max_byte_rate %d, byte_out_rate %d\n", buffer_criteria, out_rate);
        }
+       else if (streamer->buffer_avg_bitrate > 0)
+       {
+               buffer_criteria = GET_BYTE_FROM_BIT(streamer->buffer_avg_bitrate * 3);
+               out_rate = GET_BYTE_FROM_BIT(MAX(streamer->buffer_avg_bitrate,estimated_content_bitrate));
 
-       if ( streamer->buffering_percent == MAX_BUFFER_PERCENT )
+               debug_log ("(avg)content_max_byte_rate %d, byte_out_rate %d\n", buffer_criteria, out_rate);
+       }
+       else
        {
-               debug_log ( "buffering had done.\n" );
-               streamer->is_buffering = FALSE;
+               debug_warning ("There is no content bitrate information\n");
        }
 
-       if (!streamer->need_update)
+       if ((in_rate > 0) && (out_rate > 0))
+               buffer_buffering_time =  (gdouble)out_rate / (gdouble)in_rate;
+       else if ((in_rate <= 0) && (out_rate > 0))
+               buffer_buffering_time = MAX_BUFFERING_TIME;
+       else
+               buffer_buffering_time = DEFAULT_BUFFERING_TIME;
+
+       (*bitrate_info).byte_in_rate = in_rate;
+       (*bitrate_info).byte_out_rate = out_rate;
+       (*bitrate_info).time_rate = buffer_buffering_time;
+       (*bitrate_info).buffer_criteria = buffer_criteria;
+}
+
+static void
+streaming_handle_fixed_buffering_mode( mm_player_streaming_t* streamer,
+                                                                               gint byte_out_rate,
+                                                                               gdouble fixed_buffering_time,
+                                                                               streaming_buffer_info_t* buffer_info)
+{
+       streaming_buffer_t* buffer_handle = NULL;
+
+       guint buffering_bytes = 0;
+       gdouble buffering_time = 0.0;
+       gdouble per_byte = 0.0;
+       gdouble per_time = 0.0;
+
+       return_if_fail(streamer);
+       return_if_fail(buffer_info);
+
+       buffer_handle = &(streamer->buffer_handle[streamer->streaming_buffer_type]);
+       buffering_time = fixed_buffering_time;
+
+       debug_log ("[IN] MM_PLAYER_BUFFERING_MODE_FIXED (%2.2f sec), out:%d\n", buffering_time, byte_out_rate);
+
+       if ((buffering_time > 0) && (byte_out_rate > 0))
        {
-               debug_log ( "don't need to update buffering stats during buffering.\n" );
+               buffering_bytes = GET_NEW_BUFFERING_BYTE(byte_out_rate * buffering_time);
+       }
+       else
+       {
+               if (buffering_time <= 0)
+                       buffering_time = GET_CURRENT_BUFFERING_TIME(buffer_handle);
+
+               debug_warning ("content bitrate is not updated yet.\n");
+               buffering_bytes = GET_CURRENT_BUFFERING_BYTE(buffer_handle);
+       }
+
+       GET_PERCENT(buffering_time, GET_CURRENT_BUFFERING_TIME(buffer_handle), buffer_handle->buffer_high_percent, per_time);
+       GET_PERCENT(buffering_bytes, GET_CURRENT_BUFFERING_BYTE(buffer_handle), buffer_handle->buffer_high_percent, per_byte);
+
+       debug_log ("[NEW] bytes %d, time %f, per_byte %f, per_time %f\n",
+                                                                               buffering_bytes, buffering_time, per_byte, per_time);
+
+       (*buffer_info).buffering_bytes = buffering_bytes;
+       (*buffer_info).buffering_time = buffering_time;
+       (*buffer_info).percent_byte = per_byte;
+       (*buffer_info).percent_time = per_time;
+}
+
+static void
+streaming_handle_adaptive_buffering_mode(      mm_player_streaming_t* streamer,
+                                                                               streaming_content_info_t content_info,
+                                                                               streaming_bitrate_info_t bitrate_info,
+                                                                               streaming_buffer_info_t* buffer_info,
+                                                                               gint expected_play_time)
+{
+       streaming_buffer_t* buffer_handle = NULL;
+
+       gint buffering_bytes = 0;
+       gint adj_buffering_bytes = 0;
+       gdouble buffer_buffering_time = 0.0;
+       gdouble per_byte = 0.0;
+       gdouble per_time = 0.0;
+       gdouble portion = 0.0;
+       gdouble default_buffering_time = 0.0;
+
+       return_if_fail(streamer);
+       return_if_fail(buffer_info);
+
+       debug_log ("[IN] MM_PLAYER_BUFFERING_MODE_SLINK (pos %lld, dur %lld, size %lld), in/out:%d/%d, buffer_criteria:%d, time_rate:%f, need:%d sec\n",
+                                                                               content_info.position, content_info.duration, content_info.content_size,
+                                                                               bitrate_info.byte_in_rate, bitrate_info.byte_out_rate,
+                                                                               bitrate_info.buffer_criteria, bitrate_info.time_rate, expected_play_time);
+
+       if (((expected_play_time == TO_THE_END) && (content_info.position <= 0)) ||
+               (content_info.duration <= 0) ||
+               (content_info.content_size <= 0))
+       {
+               debug_warning ("Impossible to update buffer setting!! keep previous setting!\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 ((bitrate_info.byte_out_rate <= 0) || (bitrate_info.buffer_criteria == 0))
+       {
+               debug_warning ("Don't need to change buffer setting(or impossible)!! keep previous setting!\n");
+               return;
+       }
 
-       if (streamer->buffer_max_bitrate > 0)
+       buffer_handle = &(streamer->buffer_handle[streamer->streaming_buffer_type]);
+
+       if (bitrate_info.byte_in_rate < bitrate_info.byte_out_rate)
        {
-               buffer_criteria = GET_BYTE_FROM_BIT(streamer->buffer_max_bitrate);
-               byte_out_rate = GET_BYTE_FROM_BIT(streamer->buffer_max_bitrate /3);
+               if (expected_play_time != TO_THE_END)
+                       portion = (double)(expected_play_time * GST_SECOND) / (double)content_info.duration;
+               else
+                       portion = (1 - (double)content_info.position/(double)content_info.duration);
+
+               buffering_bytes = GET_NEW_BUFFERING_BYTE(((double)content_info.content_size * portion)  \
+                                                                                                                       * (1 - (double)bitrate_info.byte_in_rate/(double)bitrate_info.byte_out_rate));
        }
-       else if (streamer->buffer_avg_bitrate > 0)
+       else
        {
-               buffer_criteria = GET_BYTE_FROM_BIT(streamer->buffer_avg_bitrate * 3);
-               byte_out_rate = GET_BYTE_FROM_BIT(streamer->buffer_avg_bitrate);
+               // buffering_bytes will be set as streamer->default_val.buffering_time
+               debug_warning ("*Warning : receiving rate(%d) > avg content bitrate(%d)!\n", bitrate_info.byte_in_rate, bitrate_info.byte_out_rate);
+               debug_warning ("*Warning : There is no reason to buffering.!\n");
+               debug_warning ("*Warning : in-rate or content bitrate has reported wrong value.!\n");
+       }
+
+       if (buffering_bytes > 0)
+               buffer_buffering_time = (gdouble)buffering_bytes / (gdouble)bitrate_info.byte_out_rate;
+
+       if (content_info.position <= 0)
+       {
+               /* if the buffer is filled under 50%, MSL use the original default buffering time.
+                  if not, MSL use just 2 sec as a default buffering time. (to reduce initial buffering time) */
+               default_buffering_time = streamer->default_val.buffering_time - (streamer->buffering_percent/50);
+       }
+       else
+       {
+               default_buffering_time = streamer->default_val.buffering_time;
        }
 
-       debug_log ( "in rate is %d, out rate is %d (bytes/sec).\n", byte_in_rate, byte_out_rate );
+       if (buffer_buffering_time < default_buffering_time)
+       {
+               debug_log ("[NEW- adj] buffering time : %2.2f --> %2.2f\n", buffer_buffering_time, default_buffering_time);
+               debug_log ("[NEW- adj] buffering bytes : %d or %d or %d\n",
+                       buffering_bytes,
+                       (gint)(bitrate_info.byte_out_rate * buffer_buffering_time),
+                       (gint)(bitrate_info.buffer_criteria * buffer_buffering_time));
+
+               if (content_info.position > 0)
+               {
+                       // start monitoring the abmormal state
+                       streamer->default_val.buffering_monitor = TRUE;
+               }
+
+               buffer_buffering_time = default_buffering_time;
+               adj_buffering_bytes = GET_NEW_BUFFERING_BYTE(bitrate_info.byte_out_rate * (gint)ceil(buffer_buffering_time));
+               buffering_bytes = MAX(buffering_bytes, adj_buffering_bytes);
+       }
+
+       GET_PERCENT(buffering_bytes, GET_CURRENT_BUFFERING_BYTE(buffer_handle), buffer_handle->buffer_high_percent, per_byte);
+       GET_PERCENT(buffer_buffering_time, GET_CURRENT_BUFFERING_TIME(buffer_handle), buffer_handle->buffer_high_percent, per_time);
+
+       debug_log ("[NEW- last][buffering_monitor == %s] bytes %d, time %f, per_byte %f, per_time %f\n",
+                                                                               (streamer->default_val.buffering_monitor)?"OO":"XX",
+                                                                               buffering_bytes, buffer_buffering_time, per_byte, per_time);
+
+       (*buffer_info).buffering_bytes = buffering_bytes;
+       (*buffer_info).buffering_time = buffer_buffering_time;
+       (*buffer_info).percent_byte = per_byte;
+       (*buffer_info).percent_time = per_time;
+
+}
+
+static void
+streaming_update_buffer_setting        (       mm_player_streaming_t* streamer,
+                                                                       GstMessage *buffering_msg,      // can be null
+                                                                       guint64 content_size,
+                                                                       gint64 position,
+                                                                       gint64 duration)
+{
+       streaming_buffer_t* buffer_handle = NULL;
+       MMPlayerBufferingMode buffering_mode = MM_PLAYER_BUFFERING_MODE_ADAPTIVE;
+
+       streaming_buffer_info_t buffer_info;
+       streaming_content_info_t content_info;
+       streaming_bitrate_info_t bitrate_info;
+
+       gdouble low_percent = 0.0;
+
+       MMPLAYER_FENTER();
+
+       return_if_fail ( streamer );
+
+       memset(&buffer_info, 0x00, sizeof(streaming_buffer_info_t));
+       memset(&content_info, 0x00, sizeof(streaming_content_info_t));
+       memset(&bitrate_info, 0x00, sizeof(streaming_bitrate_info_t));
 
-       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;
+       buffer_handle = &(streamer->buffer_handle[streamer->streaming_buffer_type]);
+
+       if (streamer->buffering_req.is_pre_buffering == TRUE)
+               buffering_mode = MM_PLAYER_BUFFERING_MODE_FIXED;
        else
-               buffering_time = DEFAULT_BUFFERING_TIME;
+               buffering_mode = streamer->buffering_req.mode;
+
+       buffer_info.buffering_bytes = buffer_handle->buffering_bytes;
+       buffer_info.buffering_time = buffer_handle->buffering_time;
+       buffer_info.percent_byte = buffer_handle->buffer_high_percent;
+       buffer_info.percent_time = buffer_handle->buffer_high_percent;
+
+       content_info.position = position;
+       content_info.duration = duration;
+       content_info.content_size = content_size;
 
-       streaming_set_buffering_time(streamer, buffering_time);
+       streaming_get_current_bitrate_info(streamer, buffering_msg, content_info, &bitrate_info);
+
+       debug_log ("buffering mode %d, new info in_r:%d, out_r:%d, cb:%d, bt:%f\n",
+                                       buffering_mode, bitrate_info.byte_in_rate, bitrate_info.byte_out_rate,
+                                       bitrate_info.buffer_criteria, bitrate_info.time_rate);
 
        /* calculate buffer low/high percent */
        low_percent = DEFAULT_BUFFER_LOW_PERCENT;
 
-       if ( buffer_criteria > 0 )
+       /********************
+        * (1) fixed mode   *
+        ********************/
+
+       if (buffering_mode == MM_PLAYER_BUFFERING_MODE_FIXED)
+       {
+               gdouble buffering_time = 0.0;
+
+               if (streamer->buffering_req.is_pre_buffering == TRUE)
+                       buffering_time = (gdouble)streamer->buffering_req.initial_second;
+               else
+                       buffering_time = (gdouble)streamer->buffering_req.runtime_second;
+
+               streaming_handle_fixed_buffering_mode(streamer, bitrate_info.byte_out_rate, buffering_time, &buffer_info);
+       }
+
+       /***********************************
+        * (2) once mode for samsung link  *
+        ***********************************/
+       else if (buffering_mode == MM_PLAYER_BUFFERING_MODE_SLINK)
        {
-               high_percent_byte = buffer_criteria * streamer->buffering_time;
-               high_percent = ( (gdouble)high_percent_byte * 100.0 )  / (gdouble)streamer->buffer_size;
+               streaming_handle_adaptive_buffering_mode(streamer, content_info, bitrate_info, &buffer_info, TO_THE_END);
        }
+
+       /*********************************
+        * (3) adaptive mode (default)   *
+        *********************************/
        else
        {
-               high_percent_byte = streamer->buffer_high_percent * streamer->buffer_size / 100;
-               high_percent= streamer->buffer_high_percent;
+               gint expected_play_time = DEFAULT_PLAYING_TIME;
+
+               if (streamer->buffering_req.runtime_second > 0)
+               {
+                       expected_play_time = streamer->buffering_req.runtime_second;
+               }
+               else if ((position == 0) && (streamer->is_buffering))
+               {
+                       expected_play_time = streamer->buffering_req.initial_second;
+               }
+
+               if (expected_play_time <= 0)
+                       expected_play_time = DEFAULT_PLAYING_TIME;
+
+               streaming_handle_adaptive_buffering_mode(streamer, content_info, bitrate_info, &buffer_info, expected_play_time);
+
+               if (IS_MUXED_BUFFERING_MODE(streamer))  // even if new byte size is smaller than the previous one, time need to be updated.
+                       buffer_handle->buffering_time = buffer_info.buffering_time;
        }
 
-       if ( streamer->buffer_size < high_percent_byte )
+       debug_log ("new buffer size [%d -> %d bytes] / [%2.2f -> %2.2f sec] / %s \n",
+                                       GET_CURRENT_BUFFERING_BYTE(buffer_handle), buffer_info.buffering_bytes,
+                                       GET_CURRENT_BUFFERING_TIME(buffer_handle), buffer_info.buffering_time,
+                                       (IS_MUXED_BUFFERING_MODE(streamer))?"MUXED":((IS_DEMUXED_BUFFERING_MODE(streamer))?"DEMUXED":"----"));
+
+       // queue2 : bytes, multiqueue : time
+       if (((GET_CURRENT_BUFFERING_BYTE(buffer_handle) < buffer_info.buffering_bytes) && IS_MUXED_BUFFERING_MODE(streamer)) ||
+               ((GET_CURRENT_BUFFERING_TIME(buffer_handle) < buffer_info.buffering_time) && IS_DEMUXED_BUFFERING_MODE(streamer)))
        {
-               debug_log ( "buffer size[%d bytes] is smaller than high threshold[%d bytes]. update it. \n",
-                       streamer->buffer_size, high_percent_byte );
+               if (duration > 0 && position > 0)
+               {
+                       gdouble buffering_time_limit = (gdouble)(duration - position)/GST_SECOND;
 
-               streaming_set_buffer_size(streamer, high_percent_byte * 1.1);
+                       if (buffer_info.buffering_time > buffering_time_limit)
+                               buffer_info.buffering_time = buffering_time_limit;
+               }
+
+               streaming_set_buffer_size(streamer, streamer->streaming_buffer_type, buffer_info.buffering_bytes, buffer_info.buffering_time);
        }
 
-       streaming_set_buffer_percent(streamer, low_percent, high_percent);
+       streaming_set_buffer_percent(streamer, streamer->streaming_buffer_type, low_percent, buffer_info.percent_byte, buffer_info.percent_time);
 
-       streamer->need_update = FALSE;
+       debug_log("[FINAL] buffer setting : size %d, time %f, per %f\n",
+                                                       GET_CURRENT_BUFFERING_BYTE(buffer_handle),
+                                                       GET_CURRENT_BUFFERING_TIME(buffer_handle),
+                                                       buffer_handle->buffer_high_percent);
+
+       streamer->need_sync = TRUE;
+}
+
+static void
+streaming_adjust_min_threshold(mm_player_streaming_t* streamer, gint64 position)
+{
+#define DEFAULT_TIME_PAD 1     // sec
+       gint playing_time = 0;
+
+       MMPLAYER_FENTER();
+
+       return_if_fail(streamer);
+
+       playing_time = (gint)((position - streamer->default_val.prev_pos) / GST_SECOND);
+
+       debug_log ("[GRACE_NEW] buffering monitor = %s\n", (streamer->default_val.buffering_monitor)?"ON":"OFF");
+       debug_log ("[GRACE_NEW] playing_time ( %d sec) = %lld - %lld \n", playing_time, position, streamer->default_val.prev_pos);
+       debug_log ("[GRACE_NEW] default time : %2.3f, prev buffering t : %2.3f\n",
+                                       streamer->default_val.buffering_time, streamer->buffer_handle[streamer->streaming_buffer_type].buffering_time);
+
+       if ((streamer->default_val.buffering_monitor) && (playing_time <= (gint)streamer->default_val.buffering_time))
+       {
+               gint time_gap = 0;
+               time_gap = (gint)(streamer->default_val.buffering_time - DEFAULT_BUFFERING_TIME);
+               if (time_gap <= 0)
+                       time_gap = DEFAULT_TIME_PAD;
+
+               streamer->default_val.buffering_time += time_gap*2;
+               streamer->default_val.buffering_time = MIN(streamer->default_val.buffering_time, MAX_BUFFERING_TIME);
+       }
+       else
+       {
+               streamer->default_val.buffering_time = DEFAULT_BUFFERING_TIME;
+       }
+
+       debug_log ("[GRACE_NEW] new default min value %2.3f \n", streamer->default_val.buffering_time);
+
+       streamer->default_val.buffering_monitor = FALSE;
+       streamer->default_val.prev_pos = position;
+}
+
+static void
+streaming_update_buffering_status(mm_player_streaming_t* streamer, GstMessage *buffering_msg, gint64 position)
+{
+       gint buffer_percent = 0;
+       gboolean increased_per = TRUE;
+
+       MMPLAYER_FENTER();
+
+       return_if_fail(streamer);
+       return_if_fail(buffering_msg);
+
+       /* update when buffering has started. */
+       if ( !streamer->is_buffering )
+       {
+               debug_log ("buffering has started.\n");
+               streamer->is_buffering = TRUE;
+               streamer->is_buffering_done = FALSE;
+               streamer->buffering_percent = -1;
+
+               if (!streamer->buffering_req.is_pre_buffering)
+               {
+                       streamer->need_update = TRUE;
+                       streaming_adjust_min_threshold(streamer, position);
+               }
+       }
+
+       /* update buffer percent */
+       gst_message_parse_buffering (buffering_msg, &buffer_percent);
+
+       if (streamer->buffering_percent < buffer_percent)
+       {
+               debug_log ("[%s] buffering %d%%....\n", GST_OBJECT_NAME(GST_MESSAGE_SRC(buffering_msg)), buffer_percent);
+               streamer->buffering_percent = buffer_percent;
+       }
+       else
+       {
+               increased_per = FALSE;
+       }
+
+       if ((streamer->buffering_percent == MAX_BUFFER_PERCENT) || (streamer->is_buffering_done == TRUE))
+       {
+               debug_log ("buffering had done. finished!!\n");
+               streamer->is_buffering = FALSE;
+               streamer->buffering_req.is_pre_buffering = FALSE;
+               if (streamer->buffering_percent == MAX_BUFFER_PERCENT)
+                       streamer->is_buffering_done = FALSE;
+               else
+                       streamer->buffering_percent = MAX_BUFFER_PERCENT;
+       }
+       else
+       {
+               // need to update periodically in case of slink mode
+               if ((increased_per == TRUE) &&
+                       (buffer_percent%10 == 0) &&
+                       (streamer->buffering_req.mode == MM_PLAYER_BUFFERING_MODE_SLINK) &&
+                       (streamer->buffering_req.is_pre_buffering == FALSE))
+               {
+                       debug_log ("Update buffer setting to reflect data receiving rate (slink mode)\n");
+                       streamer->need_update = TRUE;
+               }
+       }
+}
+
+void __mm_player_streaming_buffering( mm_player_streaming_t* streamer,
+                                                                         GstMessage *buffering_msg,
+                                                                         guint64 content_size,
+                                                                         gint64 position,
+                                                                         gint64 duration)
+{
+       MMPLAYER_FENTER();
+
+       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) );
+
+       if (buffering_msg)
+       {
+               if (position > (gint64)(streamer->buffering_req.initial_second * GST_SECOND))
+                       streamer->buffering_req.is_pre_buffering = FALSE;
+
+               streaming_update_buffering_status(streamer, buffering_msg, position);
+
+               if (!streamer->need_update)
+               {
+                       //debug_log ("don't need to update buffering stats during buffering.\n");
+                       return;
+               }
+
+               streamer->need_update = FALSE;
+       }
+
+       streaming_update_buffer_setting (streamer, buffering_msg, content_size, position, duration);
 
        return;
 }
index 6ededf3..e32006e 100755 (executable)
 #include <string.h>
 #include <unistd.h>
 #include <sys/stat.h>
+#include <fcntl.h>
 #include <sys/socket.h>
+#include <sys/time.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)
+/* for getting status of connecting external display */
+#include <vconf.h>
+#include <vconf-internal-sysman-keys.h>
+#include <vconf-internal-wifi-keys.h>
+
+#define READ_MAX_BUFFER_SIZE 1024
+
+int util_exist_file_path(const char *file_path)
 {
-       debug_log("\n");
+       int fd = 0;
+       struct stat stat_results = {0, };
 
        if (!file_path || !strlen(file_path))
-               return FALSE;
+               return MM_ERROR_PLAYER_FILE_NOT_FOUND;
 
-       int res = access(file_path, R_OK);
-       if (res)
-               return FALSE;
+       fd = open (file_path, O_RDONLY);
 
-       return TRUE;
+       if (fd < 0)
+       {
+               char str_error[READ_MAX_BUFFER_SIZE];
+               debug_error("failed to open file by %s (%d)", strerror_r(errno, str_error, sizeof(str_error)), errno);
+
+               if (EACCES == errno)
+                       return MM_ERROR_PLAYER_PERMISSION_DENIED;
+
+               return MM_ERROR_PLAYER_FILE_NOT_FOUND;
+       }
+
+       if (fstat(fd, &stat_results) < 0)
+       {
+               debug_error("failed to get file status");
+       }
+       else if (stat_results.st_size == 0)
+       {
+               debug_error("file size is zero");
+               close(fd);
+               return MM_ERROR_PLAYER_FILE_NOT_FOUND;
+       }
+       else
+       {
+               debug_warning("file size : %lld bytes", (long long)stat_results.st_size);
+       }
+
+       close(fd);
+
+       return MM_ERROR_NONE;
 }
 
 bool util_write_file_backup(const char *backup_path, char *data_ptr, int data_size)
 {
-       debug_log("\n");
-
        FILE *fp = NULL;
        int wsize = 0;
 
@@ -71,48 +107,42 @@ bool util_write_file_backup(const char *backup_path, char *data_ptr, int data_si
        return TRUE;
 }
 
-#if 1 //tskim:MidiModuleRequires:+: for Midi player
 bool util_remove_file_backup(const char *backup_path)
 {
-       debug_log("\n");
-
        if (!backup_path || !strlen(backup_path))
                return FALSE;
 
-/*
-     Prevent defect patch. CID:22389 Checker:TOTCU
        int res = access(backup_path, R_OK);
        if (!res)
-*/
-               remove(backup_path);
+       {
+               if (remove(backup_path) == -1)
+                       return FALSE;
+       }
 
        return TRUE;
 }
-#endif
 
 #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; //FALSE;         // sbs:+:080903
+               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; // TRUE;// sbs:+:080903
+               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;//TRUE;// sbs:+:080903
+               return MM_AUDIO_CODEC_MIDI;
        }
-       /* mxmf file detection */ // sbs:+:080903
+       /* 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;
@@ -123,23 +153,21 @@ int util_is_midi_type_by_mem(void *mem, int size)
                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;//TRUE;// sbs:+:080903
+               return MM_AUDIO_CODEC_WAVE;
        }
-       /* i-melody file detection */ // sbs:+:080903
+       /* 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;//FALSE; // sbs:+:080903
+       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,};
@@ -148,7 +176,6 @@ int util_is_midi_type_by_file(const char *file_path)
        if (!file_path)
                return FALSE;
 
-       /* Prevent defect patch. CID: 22388 Checker: TOCTOU */
        fp = fopen(file_path, "r");
 
        if (!fp)
@@ -169,7 +196,7 @@ int util_is_midi_type_by_file(const char *file_path)
                fclose(fp);
                return FALSE;
        }
-       
+
        size = fread(prefix, sizeof(char), DETECTION_PREFIX_SIZE, fp);
 
        fclose(fp);
@@ -177,51 +204,57 @@ int util_is_midi_type_by_file(const char *file_path)
        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. 
+/* messages are treated as warnings bcz those code should not be checked in.
+ * and no error handling will supported for same manner.
  */
-gboolean 
+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));
-       
+       if(parent == NULL)
+       {
+               debug_error("parent is null\n");
+               return false;
+       }
+
+       debug_log("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)));
+               debug_log("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));
+               debug_log("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));
+               debug_log("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)));
+               MMPLAYER_LOG_GST_CAPS_TYPE(GST_BUFFER_CAPS(buffer));
        }
 
        /* drop buffer if flag is on */
        if ( flag & MM_PROBE_DROP_BUFFER )
        {
-               debug_warning("dropping\n");
+               debug_log("dropping\n");
                ret = FALSE;
        }
-               
+
        /* show clock time */
        if ( flag & MM_PROBE_CLOCK_TIME )
        {
@@ -233,7 +266,7 @@ __util_gst_pad_probe(GstPad *pad, GstBuffer *buffer, gpointer u_data)
                if ( clock )
                {
                        now = gst_clock_get_time( clock );
-                       debug_warning("clock time : %" GST_TIME_FORMAT "\n", GST_TIME_ARGS( now ));
+                       debug_log("clock time : %" GST_TIME_FORMAT "\n", GST_TIME_ARGS( now ));
                }
        }
 
@@ -243,7 +276,7 @@ __util_gst_pad_probe(GstPad *pad, GstBuffer *buffer, gpointer u_data)
        return ret;
 }
 
-char** 
+char**
 util_get_cookie_list ( const char *cookies )
 {
        char **cookie_list = NULL;
@@ -253,7 +286,7 @@ util_get_cookie_list ( const char *cookies )
        if ( !cookies || !strlen(cookies) )
                return NULL;
 
-       debug_log("cookies : %d[bytes] - %s \n", strlen(cookies), cookies);
+       secure_debug_log("cookies : %d[bytes] - %s \n", strlen(cookies), cookies);
 
        temp = g_strdup(cookies);
 
@@ -268,7 +301,7 @@ util_get_cookie_list ( const char *cookies )
                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]);
+                       secure_debug_log("cookie_list[%d] : %d[bytes] - %s \n", i, strlen(cookie_list[i]), cookie_list[i]);
                }
                else
                {
@@ -287,32 +320,37 @@ 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 )
+       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 
+bool
 util_is_sdp_file ( const char *path )
 {
        gboolean ret = FALSE;
        gchar* uri = NULL;
-       
-       debug_fenter();
-       
+
+       MMPLAYER_FENTER();
+
        return_val_if_fail ( path, FALSE );
 
        uri = g_ascii_strdown ( path, -1 );
 
+       if ( uri == NULL)
+       {
+               return FALSE;
+       }
+
        /* trimming */
        g_strstrip( uri );
 
@@ -330,17 +368,15 @@ util_is_sdp_file ( const char *path )
        if ( ! ret )
        {
                /* FIXIT : do it soon */
-               debug_warning("determining whether it's sdp or not with it's content is not implemented yet. ;)\n");
        }
 
-       if ( uri )
-               g_free( uri); 
+       g_free( uri);
        uri = NULL;
 
        return ret;
 }
 
-int64_t 
+int64_t
 util_get_time ( void )
 {
        struct timeval tv;
@@ -348,16 +384,16 @@ util_get_time ( void )
        return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
 }
 
-int 
+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") ) 
+       if ( g_strrstr(factory_class,"Dsp") )
                ret = rank_pri_inc;
-       else if ( g_strrstr(factory_class,"HW") ) 
+       else if ( g_strrstr(factory_class,"HW") )
                ret = rank_pri_inc;
        else if ( g_strrstr(factory_class,"Arm") )
                ret = rank_sec_inc;
@@ -365,7 +401,7 @@ util_get_rank_increase ( const char *factory_class )
        return ret;
 }
 
-int 
+int
 util_factory_rank_compare(GstPluginFeature *f1, GstPluginFeature *f2) // @
 {
        const gchar *klass;
@@ -379,3 +415,195 @@ util_factory_rank_compare(GstPluginFeature *f1, GstPluginFeature *f2) // @
 
        return (gst_plugin_feature_get_rank(f2)+f2_rank_inc) - (gst_plugin_feature_get_rank(f1)+f1_rank_inc );
 }
+
+const 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 =0;
+       size_t n_size = 0;
+
+       fin = fopen(file_path, "r");
+       if (!fin)
+       {
+               secure_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");
+               goto done;
+       }
+
+       ucsdet_enableInputFilter( ucsd, TRUE );
+
+       buf = g_malloc(READ_MAX_BUFFER_SIZE*READ_MAX_BUFFER_SIZE);
+       if (!buf)
+       {
+               debug_error("fail to alloc\n");
+               goto done;
+       }
+
+       n_size = fread( buf, 1, READ_MAX_BUFFER_SIZE*READ_MAX_BUFFER_SIZE, fin );
+       buf[READ_MAX_BUFFER_SIZE*READ_MAX_BUFFER_SIZE] = '\0';
+       if (!n_size)
+               goto done;
+
+       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:
+       if(fin)
+               fclose(fin);
+
+       if(ucsd)
+               ucsdet_close( ucsd );
+
+       if (buf)
+               g_free(buf);
+
+       return charset;
+}
+
+int
+util_get_is_connected_external_display(void)
+{
+  int is_connected_hdmi = -1;
+  int is_connected_mirroring = -1;
+
+       if (vconf_get_int(VCONFKEY_SYSMAN_HDMI, &is_connected_hdmi))
+               debug_error("[hdmi]vconf_set_int FAIL");
+       if (vconf_get_int(VCONFKEY_SCREEN_MIRRORING_STATE, &is_connected_mirroring))
+               debug_error("[mirroring]vconf_set_int FAIL");
+
+       /* if conneted with external display */
+       if (is_connected_mirroring == VCONFKEY_SCREEN_MIRRORING_CONNECTED) {
+               debug_warning ("connected with mirroring display");
+               return MMPLAYER_DISPLAY_MIRRORING_ACTIVE;
+       }
+       if (is_connected_hdmi == VCONFKEY_SYSMAN_HDMI_CONNECTED) {
+               debug_warning ("connected with external display");
+               return MMPLAYER_DISPLAY_HDMI_ACTIVE;
+       }
+       if ((is_connected_mirroring == VCONFKEY_SCREEN_MIRRORING_ACTIVATED || is_connected_mirroring == VCONFKEY_SCREEN_MIRRORING_DEACTIVATED) && is_connected_hdmi == VCONFKEY_SYSMAN_HDMI_DISCONNECTED) {
+               debug_warning ("non-connected status");
+               return MMPLAYER_DISPLAY_NULL;
+       }
+
+       debug_error ("it is not registered (%d, %d)", is_connected_mirroring, is_connected_hdmi);
+       return -1;
+}
+
+gboolean util_is_miracast_connected(void)
+{
+       int is_connected = 0;
+
+       if (vconf_get_bool(VCONFKEY_MIRACAST_WFD_SOURCE_STATUS, &is_connected) ) {
+               debug_error("failed to get miracast status key");
+               return FALSE;
+       }
+
+       if (VCONFKEY_MIRACAST_WFD_SOURCE_ON == is_connected) {
+               debug_warning("miracast connected");
+               return TRUE;
+       }
+
+       return FALSE;
+}
+
+int util_get_pixtype(unsigned int fourcc)
+{
+       int pixtype = MM_PIXEL_FORMAT_INVALID;
+
+    /*
+       char *pfourcc = (char*)&fourcc;
+
+       debug_log("fourcc(%c%c%c%c)",
+                        pfourcc[0], pfourcc[1], pfourcc[2], pfourcc[3]);
+    */
+
+
+       switch (fourcc) {
+       case GST_MAKE_FOURCC ('S', 'N', '1', '2'):
+       case GST_MAKE_FOURCC ('N', 'V', '1', '2'):
+               pixtype = MM_PIXEL_FORMAT_NV12;
+               break;
+       case GST_MAKE_FOURCC ('S', 'N', '2', '1'):
+       case GST_MAKE_FOURCC ('N', 'V', '2', '1'):
+               pixtype = MM_PIXEL_FORMAT_NV21;
+               break;
+       case GST_MAKE_FOURCC ('S', 'U', 'Y', 'V'):
+       case GST_MAKE_FOURCC ('Y', 'U', 'Y', 'V'):
+       case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
+               pixtype = MM_PIXEL_FORMAT_YUYV;
+               break;
+       case GST_MAKE_FOURCC ('S', 'Y', 'V', 'Y'):
+       case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
+               pixtype = MM_PIXEL_FORMAT_UYVY;
+               break;
+       case GST_MAKE_FOURCC ('S', '4', '2', '0'):
+       case GST_MAKE_FOURCC ('I', '4', '2', '0'):
+               pixtype = MM_PIXEL_FORMAT_I420;
+               break;
+       case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
+               pixtype = MM_PIXEL_FORMAT_YV12;
+               break;
+       case GST_MAKE_FOURCC ('4', '2', '2', 'P'):
+               pixtype = MM_PIXEL_FORMAT_422P;
+               break;
+       case GST_MAKE_FOURCC ('R', 'G', 'B', 'P'):
+               pixtype = MM_PIXEL_FORMAT_RGB565;
+               break;
+       case GST_MAKE_FOURCC ('R', 'G', 'B', '3'):
+               pixtype = MM_PIXEL_FORMAT_RGB888;
+               break;
+       case GST_MAKE_FOURCC ('A', 'R', 'G', 'B'):
+       case GST_MAKE_FOURCC ('x', 'R', 'G', 'B'):
+               pixtype = MM_PIXEL_FORMAT_ARGB;
+               break;
+       case GST_MAKE_FOURCC ('B', 'G', 'R', 'A'):
+       case GST_MAKE_FOURCC ('B', 'G', 'R', 'x'):
+       case GST_MAKE_FOURCC ('S', 'R', '3', '2'):
+               pixtype = MM_PIXEL_FORMAT_RGBA;
+               break;
+       case GST_MAKE_FOURCC ('J', 'P', 'E', 'G'):
+       case GST_MAKE_FOURCC ('P', 'N', 'G', ' '):
+               pixtype = MM_PIXEL_FORMAT_ENCODED;
+               break;
+       /*FIXME - ITLV */
+       case GST_MAKE_FOURCC ('I', 'T', 'L', 'V'):
+               pixtype = MM_PIXEL_FORMAT_ITLV_JPEG_UYVY;
+               break;
+       case GST_MAKE_FOURCC ('S', 'T', '1', '2'):
+               pixtype = MM_PIXEL_FORMAT_NV12T;
+               break;
+       default:
+               debug_error("Not supported fourcc type(%c%c%c%c)",
+                              fourcc, fourcc>>8, fourcc>>16, fourcc>>24);
+               pixtype = MM_PIXEL_FORMAT_INVALID;
+               break;
+       }
+
+       return pixtype;
+}