[libmm-streamrecorder] initial code for new feature of streamrecorder 48/53948/7 accepted/tizen/mobile/20160108.065506 accepted/tizen/tv/20160108.065615 accepted/tizen/wearable/20160108.065806 submit/tizen/20160108.040923
authorHyuntae, Kim <ht1211.kim@samsung.com>
Thu, 10 Dec 2015 09:37:40 +0000 (18:37 +0900)
committerHyuntae, Kim <ht1211.kim@samsung.com>
Thu, 7 Jan 2016 06:45:43 +0000 (15:45 +0900)
Change-Id: I1e25fb02ca03ce19b96ce512fea55ea835d3543a

37 files changed:
AUTHORS [new file with mode: 0644]
LICENSE.APLv2 [new file with mode: 0644]
Makefile.am [new file with mode: 0644]
NOTICE [new file with mode: 0644]
autogen.sh [new file with mode: 0755]
configure.ac [new file with mode: 0644]
libmm-streamrecorder.manifest [new file with mode: 0644]
m4/lt~obsolete.m4 [new file with mode: 0644]
mm-streamrecorder.pc.in [new file with mode: 0644]
packaging/libmm-streamrecorder.spec [new file with mode: 0644]
src/Makefile.am [new file with mode: 0644]
src/include/mm_streamrecorder.h [new file with mode: 0644]
src/include/mm_streamrecorder_attribute.h [new file with mode: 0644]
src/include/mm_streamrecorder_audio.h [new file with mode: 0644]
src/include/mm_streamrecorder_buffer_manager.h [new file with mode: 0644]
src/include/mm_streamrecorder_fileinfo.h [new file with mode: 0644]
src/include/mm_streamrecorder_gstcommon.h [new file with mode: 0644]
src/include/mm_streamrecorder_gstdispatch.h [new file with mode: 0644]
src/include/mm_streamrecorder_ini.h [new file with mode: 0644]
src/include/mm_streamrecorder_internal.h [new file with mode: 0644]
src/include/mm_streamrecorder_recorder.h [new file with mode: 0644]
src/include/mm_streamrecorder_util.h [new file with mode: 0644]
src/include/mm_streamrecorder_video.h [new file with mode: 0644]
src/mm_streamrecorder.c [new file with mode: 0644]
src/mm_streamrecorder_attribute.c [new file with mode: 0644]
src/mm_streamrecorder_audio.c [new file with mode: 0644]
src/mm_streamrecorder_buffer_manager.c [new file with mode: 0644]
src/mm_streamrecorder_fileinfo.c [new file with mode: 0644]
src/mm_streamrecorder_gstcommon.c [new file with mode: 0644]
src/mm_streamrecorder_gstdispatch.c [new file with mode: 0644]
src/mm_streamrecorder_ini.c [new file with mode: 0644]
src/mm_streamrecorder_internal.c [new file with mode: 0644]
src/mm_streamrecorder_recorder.c [new file with mode: 0644]
src/mm_streamrecorder_util.c [new file with mode: 0644]
src/mm_streamrecorder_video.c [new file with mode: 0644]
test/Makefile.am [new file with mode: 0644]
test/mm_streamrecorder_testsuite.c [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..3e37b5d
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,3 @@
+Jeongmo Yang <jm80.yang at samsung dot com>
+Hyuntae Kim <ht1211.kim at samsung dot com>
+Heechul Jeon <heechul.jeon at samsung dot com>
diff --git a/LICENSE.APLv2 b/LICENSE.APLv2
new file mode 100644 (file)
index 0000000..bbe9d02
--- /dev/null
@@ -0,0 +1,206 @@
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
+\r
+                                 Apache License\r
+                           Version 2.0, January 2004\r
+                        http://www.apache.org/licenses/\r
+\r
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\r
+\r
+   1. Definitions.\r
+\r
+      "License" shall mean the terms and conditions for use, reproduction,\r
+      and distribution as defined by Sections 1 through 9 of this document.\r
+\r
+      "Licensor" shall mean the copyright owner or entity authorized by\r
+      the copyright owner that is granting the License.\r
+\r
+      "Legal Entity" shall mean the union of the acting entity and all\r
+      other entities that control, are controlled by, or are under common\r
+      control with that entity. For the purposes of this definition,\r
+      "control" means (i) the power, direct or indirect, to cause the\r
+      direction or management of such entity, whether by contract or\r
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the\r
+      outstanding shares, or (iii) beneficial ownership of such entity.\r
+\r
+      "You" (or "Your") shall mean an individual or Legal Entity\r
+      exercising permissions granted by this License.\r
+\r
+      "Source" form shall mean the preferred form for making modifications,\r
+      including but not limited to software source code, documentation\r
+      source, and configuration files.\r
+\r
+      "Object" form shall mean any form resulting from mechanical\r
+      transformation or translation of a Source form, including but\r
+      not limited to compiled object code, generated documentation,\r
+      and conversions to other media types.\r
+\r
+      "Work" shall mean the work of authorship, whether in Source or\r
+      Object form, made available under the License, as indicated by a\r
+      copyright notice that is included in or attached to the work\r
+      (an example is provided in the Appendix below).\r
+\r
+      "Derivative Works" shall mean any work, whether in Source or Object\r
+      form, that is based on (or derived from) the Work and for which the\r
+      editorial revisions, annotations, elaborations, or other modifications\r
+      represent, as a whole, an original work of authorship. For the purposes\r
+      of this License, Derivative Works shall not include works that remain\r
+      separable from, or merely link (or bind by name) to the interfaces of,\r
+      the Work and Derivative Works thereof.\r
+\r
+      "Contribution" shall mean any work of authorship, including\r
+      the original version of the Work and any modifications or additions\r
+      to that Work or Derivative Works thereof, that is intentionally\r
+      submitted to Licensor for inclusion in the Work by the copyright owner\r
+      or by an individual or Legal Entity authorized to submit on behalf of\r
+      the copyright owner. For the purposes of this definition, "submitted"\r
+      means any form of electronic, verbal, or written communication sent\r
+      to the Licensor or its representatives, including but not limited to\r
+      communication on electronic mailing lists, source code control systems,\r
+      and issue tracking systems that are managed by, or on behalf of, the\r
+      Licensor for the purpose of discussing and improving the Work, but\r
+      excluding communication that is conspicuously marked or otherwise\r
+      designated in writing by the copyright owner as "Not a Contribution."\r
+\r
+      "Contributor" shall mean Licensor and any individual or Legal Entity\r
+      on behalf of whom a Contribution has been received by Licensor and\r
+      subsequently incorporated within the Work.\r
+\r
+   2. Grant of Copyright License. Subject to the terms and conditions of\r
+      this License, each Contributor hereby grants to You a perpetual,\r
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r
+      copyright license to reproduce, prepare Derivative Works of,\r
+      publicly display, publicly perform, sublicense, and distribute the\r
+      Work and such Derivative Works in Source or Object form.\r
+\r
+   3. Grant of Patent License. Subject to the terms and conditions of\r
+      this License, each Contributor hereby grants to You a perpetual,\r
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r
+      (except as stated in this section) patent license to make, have made,\r
+      use, offer to sell, sell, import, and otherwise transfer the Work,\r
+      where such license applies only to those patent claims licensable\r
+      by such Contributor that are necessarily infringed by their\r
+      Contribution(s) alone or by combination of their Contribution(s)\r
+      with the Work to which such Contribution(s) was submitted. If You\r
+      institute patent litigation against any entity (including a\r
+      cross-claim or counterclaim in a lawsuit) alleging that the Work\r
+      or a Contribution incorporated within the Work constitutes direct\r
+      or contributory patent infringement, then any patent licenses\r
+      granted to You under this License for that Work shall terminate\r
+      as of the date such litigation is filed.\r
+\r
+   4. Redistribution. You may reproduce and distribute copies of the\r
+      Work or Derivative Works thereof in any medium, with or without\r
+      modifications, and in Source or Object form, provided that You\r
+      meet the following conditions:\r
+\r
+      (a) You must give any other recipients of the Work or\r
+          Derivative Works a copy of this License; and\r
+\r
+      (b) You must cause any modified files to carry prominent notices\r
+          stating that You changed the files; and\r
+\r
+      (c) You must retain, in the Source form of any Derivative Works\r
+          that You distribute, all copyright, patent, trademark, and\r
+          attribution notices from the Source form of the Work,\r
+          excluding those notices that do not pertain to any part of\r
+          the Derivative Works; and\r
+\r
+      (d) If the Work includes a "NOTICE" text file as part of its\r
+          distribution, then any Derivative Works that You distribute must\r
+          include a readable copy of the attribution notices contained\r
+          within such NOTICE file, excluding those notices that do not\r
+          pertain to any part of the Derivative Works, in at least one\r
+          of the following places: within a NOTICE text file distributed\r
+          as part of the Derivative Works; within the Source form or\r
+          documentation, if provided along with the Derivative Works; or,\r
+          within a display generated by the Derivative Works, if and\r
+          wherever such third-party notices normally appear. The contents\r
+          of the NOTICE file are for informational purposes only and\r
+          do not modify the License. You may add Your own attribution\r
+          notices within Derivative Works that You distribute, alongside\r
+          or as an addendum to the NOTICE text from the Work, provided\r
+          that such additional attribution notices cannot be construed\r
+          as modifying the License.\r
+\r
+      You may add Your own copyright statement to Your modifications and\r
+      may provide additional or different license terms and conditions\r
+      for use, reproduction, or distribution of Your modifications, or\r
+      for any such Derivative Works as a whole, provided Your use,\r
+      reproduction, and distribution of the Work otherwise complies with\r
+      the conditions stated in this License.\r
+\r
+   5. Submission of Contributions. Unless You explicitly state otherwise,\r
+      any Contribution intentionally submitted for inclusion in the Work\r
+      by You to the Licensor shall be under the terms and conditions of\r
+      this License, without any additional terms or conditions.\r
+      Notwithstanding the above, nothing herein shall supersede or modify\r
+      the terms of any separate license agreement you may have executed\r
+      with Licensor regarding such Contributions.\r
+\r
+   6. Trademarks. This License does not grant permission to use the trade\r
+      names, trademarks, service marks, or product names of the Licensor,\r
+      except as required for reasonable and customary use in describing the\r
+      origin of the Work and reproducing the content of the NOTICE file.\r
+\r
+   7. Disclaimer of Warranty. Unless required by applicable law or\r
+      agreed to in writing, Licensor provides the Work (and each\r
+      Contributor provides its Contributions) on an "AS IS" BASIS,\r
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\r
+      implied, including, without limitation, any warranties or conditions\r
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\r
+      PARTICULAR PURPOSE. You are solely responsible for determining the\r
+      appropriateness of using or redistributing the Work and assume any\r
+      risks associated with Your exercise of permissions under this License.\r
+\r
+   8. Limitation of Liability. In no event and under no legal theory,\r
+      whether in tort (including negligence), contract, or otherwise,\r
+      unless required by applicable law (such as deliberate and grossly\r
+      negligent acts) or agreed to in writing, shall any Contributor be\r
+      liable to You for damages, including any direct, indirect, special,\r
+      incidental, or consequential damages of any character arising as a\r
+      result of this License or out of the use or inability to use the\r
+      Work (including but not limited to damages for loss of goodwill,\r
+      work stoppage, computer failure or malfunction, or any and all\r
+      other commercial damages or losses), even if such Contributor\r
+      has been advised of the possibility of such damages.\r
+\r
+   9. Accepting Warranty or Additional Liability. While redistributing\r
+      the Work or Derivative Works thereof, You may choose to offer,\r
+      and charge a fee for, acceptance of support, warranty, indemnity,\r
+      or other liability obligations and/or rights consistent with this\r
+      License. However, in accepting such obligations, You may act only\r
+      on Your own behalf and on Your sole responsibility, not on behalf\r
+      of any other Contributor, and only if You agree to indemnify,\r
+      defend, and hold each Contributor harmless for any liability\r
+      incurred by, or claims asserted against, such Contributor by reason\r
+      of your accepting any such warranty or additional liability.\r
+\r
+   END OF TERMS AND CONDITIONS\r
+\r
+   APPENDIX: How to apply the Apache License to your work.\r
+\r
+      To apply the Apache License to your work, attach the following\r
+      boilerplate notice, with the fields enclosed by brackets "[]"\r
+      replaced with your own identifying information. (Don't include\r
+      the brackets!)  The text should be enclosed in the appropriate\r
+      comment syntax for the file format. We also recommend that a\r
+      file or class name and description of purpose be included on the\r
+      same "printed page" as the copyright notice for easier\r
+      identification within third-party archives.\r
+\r
+   Copyright [yyyy] [name of copyright owner]\r
+\r
+   Licensed under the Apache License, Version 2.0 (the "License");\r
+   you may not use this file except in compliance with the License.\r
+   You may obtain a copy of the License at\r
+\r
+       http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+\r
+\r
+\r
diff --git a/Makefile.am b/Makefile.am
new file mode 100644 (file)
index 0000000..3839fb0
--- /dev/null
@@ -0,0 +1,8 @@
+ACLOCAL_AMFLAGS='-I m4'
+
+SUBDIRS = src test
+
+pcfiles = mm-streamrecorder.pc
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = $(pcfiles)
+EXTRA_DIST = $(pcfiles)
diff --git a/NOTICE b/NOTICE
new file mode 100644 (file)
index 0000000..0e0f016
--- /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.APLv2 file for Apache License terms and conditions.
diff --git a/autogen.sh b/autogen.sh
new file mode 100755 (executable)
index 0000000..d5ce106
--- /dev/null
@@ -0,0 +1,7 @@
+#! /bin/sh
+
+libtoolize --copy --force
+aclocal -I m4
+autoheader
+autoconf
+automake -a -c
diff --git a/configure.ac b/configure.ac
new file mode 100644 (file)
index 0000000..91eadff
--- /dev/null
@@ -0,0 +1,82 @@
+AC_PREREQ(2.52)
+
+AC_INIT([libmm-streamrecorder], [1.0])
+AM_INIT_AUTOMAKE([-Wall -Werror foreign])
+AC_CONFIG_HEADERS([config.h:config.hin])
+AC_CONFIG_MACRO_DIR([m4])
+
+m4_pattern_allow([AM_PROG_AR])
+AM_PROG_AR
+
+# Checks for programs.
+AC_PROG_CC
+AC_C_CONST
+dnl AC_FUNC_MALLOC
+AC_FUNC_MMAP
+AC_FUNC_REALLOC
+AC_FUNC_SELECT_ARGTYPES
+AC_FUNC_STAT
+AC_FUNC_VPRINTF
+AC_HEADER_STDBOOL
+AC_HEADER_STDC
+AC_HEADER_TIME
+AC_PROG_GCC_TRADITIONAL
+AC_PROG_LIBTOOL
+
+# Checks for libraries.
+PKG_CHECK_MODULES(GST, gstreamer-1.0 >= 1.2.0)
+AC_SUBST(GST_CFLAGS)
+AC_SUBST(GST_LIBS)
+
+PKG_CHECK_MODULES(GST_PLUGIN_BASE, gstreamer-base-1.0 >= 1.2.0)
+AC_SUBST(GST_PLUGIN_BASE_CFLAGS)
+AC_SUBST(GST_PLUGIN_BASE_LIBS)
+
+PKG_CHECK_MODULES(GST_VIDEO, gstreamer-video-1.0 >= 1.2.0)
+AC_SUBST(GST_VIDEO_CFLAGS)
+AC_SUBST(GST_VIDEO_LIBS)
+
+PKG_CHECK_MODULES(MM_COMMON, mm-common)
+AC_SUBST(MM_COMMON_CFLAGS)
+AC_SUBST(MM_COMMON_LIBS)
+
+PKG_CHECK_MODULES(MM_LOG, mm-log)
+AC_SUBST(MM_LOG_CFLAGS)
+AC_SUBST(MM_LOG_LIBS)
+
+PKG_CHECK_MODULES(GLIB, glib-2.0)
+AC_SUBST(GLIB_CFLAGS)
+AC_SUBST(GLIB_LIBS)
+
+PKG_CHECK_MODULES(GST_APP, gstreamer-app-1.0 >= 1.2.0)
+AC_SUBST(GST_APP_CFLAGS)
+AC_SUBST(GST_APP_LIBS)
+
+PKG_CHECK_MODULES(INIPARSER, iniparser)
+AC_SUBST(INIPARSER_CFLAGS)
+AC_SUBST(INIPARSER_LIBS)
+
+# Checks for header files.
+AC_HEADER_STDC
+AC_CHECK_HEADERS([fcntl.h memory.h stdlib.h string.h sys/time.h unistd.h])
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_TYPE_PID_T
+AC_TYPE_SIZE_T
+
+# Checks for library functions.
+AC_FUNC_ALLOCA
+AC_FUNC_FORK
+AC_FUNC_MALLOC
+AC_FUNC_MEMCMP
+AC_FUNC_SELECT_ARGTYPES
+AC_TYPE_SIGNAL
+AC_CHECK_FUNCS([memset select])
+AC_CONFIG_FILES([
+Makefile
+src/Makefile
+test/Makefile
+mm-streamrecorder.pc
+])
+AC_OUTPUT
diff --git a/libmm-streamrecorder.manifest b/libmm-streamrecorder.manifest
new file mode 100644 (file)
index 0000000..8ea72a2
--- /dev/null
@@ -0,0 +1,8 @@
+<manifest>
+       <request>
+               <domain name="_" />
+       </request>
+       <assign>
+               <filesystem path="/usr/bin/mm_streamrecorder_testsuite" label="_" exec_label="none" />
+       </assign>
+</manifest>
diff --git a/m4/lt~obsolete.m4 b/m4/lt~obsolete.m4
new file mode 100644 (file)
index 0000000..637bb20
--- /dev/null
@@ -0,0 +1,92 @@
+# lt~obsolete.m4 -- aclocal satisfying obsolete definitions.    -*-Autoconf-*-
+#
+#   Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
+#   Written by Scott James Remnant, 2004.
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 4 lt~obsolete.m4
+
+# These exist entirely to fool aclocal when bootstrapping libtool.
+#
+# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN)
+# which have later been changed to m4_define as they aren't part of the
+# exported API, or moved to Autoconf or Automake where they belong.
+#
+# The trouble is, aclocal is a bit thick.  It'll see the old AC_DEFUN
+# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
+# using a macro with the same name in our local m4/libtool.m4 it'll
+# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
+# and doesn't know about Autoconf macros at all.)
+#
+# So we provide this file, which has a silly filename so it's always
+# included after everything else.  This provides aclocal with the
+# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
+# because those macros already exist, or will be overwritten later.
+# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. 
+#
+# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
+# Yes, that means every name once taken will need to remain here until
+# we give up compatibility with versions before 1.7, at which point
+# we need to keep only those names which we still refer to.
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
+
+m4_ifndef([AC_LIBTOOL_LINKER_OPTION],  [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
+m4_ifndef([AC_PROG_EGREP],             [AC_DEFUN([AC_PROG_EGREP])])
+m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH],        [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_AC_SHELL_INIT],         [AC_DEFUN([_LT_AC_SHELL_INIT])])
+m4_ifndef([_LT_AC_SYS_LIBPATH_AIX],    [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
+m4_ifndef([_LT_PROG_LTMAIN],           [AC_DEFUN([_LT_PROG_LTMAIN])])
+m4_ifndef([_LT_AC_TAGVAR],             [AC_DEFUN([_LT_AC_TAGVAR])])
+m4_ifndef([AC_LTDL_ENABLE_INSTALL],    [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
+m4_ifndef([AC_LTDL_PREOPEN],           [AC_DEFUN([AC_LTDL_PREOPEN])])
+m4_ifndef([_LT_AC_SYS_COMPILER],       [AC_DEFUN([_LT_AC_SYS_COMPILER])])
+m4_ifndef([_LT_AC_LOCK],               [AC_DEFUN([_LT_AC_LOCK])])
+m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE],        [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
+m4_ifndef([_LT_AC_TRY_DLOPEN_SELF],    [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
+m4_ifndef([AC_LIBTOOL_PROG_CC_C_O],    [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
+m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
+m4_ifndef([AC_LIBTOOL_OBJDIR],         [AC_DEFUN([AC_LIBTOOL_OBJDIR])])
+m4_ifndef([AC_LTDL_OBJDIR],            [AC_DEFUN([AC_LTDL_OBJDIR])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
+m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP],  [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
+m4_ifndef([AC_PATH_MAGIC],             [AC_DEFUN([AC_PATH_MAGIC])])
+m4_ifndef([AC_PROG_LD_GNU],            [AC_DEFUN([AC_PROG_LD_GNU])])
+m4_ifndef([AC_PROG_LD_RELOAD_FLAG],    [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
+m4_ifndef([AC_DEPLIBS_CHECK_METHOD],   [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
+m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
+m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
+m4_ifndef([LT_AC_PROG_EGREP],          [AC_DEFUN([LT_AC_PROG_EGREP])])
+m4_ifndef([LT_AC_PROG_SED],            [AC_DEFUN([LT_AC_PROG_SED])])
+m4_ifndef([_LT_CC_BASENAME],           [AC_DEFUN([_LT_CC_BASENAME])])
+m4_ifndef([_LT_COMPILER_BOILERPLATE],  [AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
+m4_ifndef([_LT_LINKER_BOILERPLATE],    [AC_DEFUN([_LT_LINKER_BOILERPLATE])])
+m4_ifndef([_AC_PROG_LIBTOOL],          [AC_DEFUN([_AC_PROG_LIBTOOL])])
+m4_ifndef([AC_LIBTOOL_SETUP],          [AC_DEFUN([AC_LIBTOOL_SETUP])])
+m4_ifndef([_LT_AC_CHECK_DLFCN],                [AC_DEFUN([_LT_AC_CHECK_DLFCN])])
+m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER],     [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
+m4_ifndef([_LT_AC_TAGCONFIG],          [AC_DEFUN([_LT_AC_TAGCONFIG])])
+m4_ifndef([AC_DISABLE_FAST_INSTALL],   [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
+m4_ifndef([_LT_AC_LANG_CXX],           [AC_DEFUN([_LT_AC_LANG_CXX])])
+m4_ifndef([_LT_AC_LANG_F77],           [AC_DEFUN([_LT_AC_LANG_F77])])
+m4_ifndef([_LT_AC_LANG_GCJ],           [AC_DEFUN([_LT_AC_LANG_GCJ])])
+m4_ifndef([AC_LIBTOOL_RC],             [AC_DEFUN([AC_LIBTOOL_RC])])
+m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG],  [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
+m4_ifndef([_LT_AC_LANG_C_CONFIG],      [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG],        [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
+m4_ifndef([_LT_AC_LANG_CXX_CONFIG],    [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG],        [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
+m4_ifndef([_LT_AC_LANG_F77_CONFIG],    [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG],        [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
+m4_ifndef([_LT_AC_LANG_GCJ_CONFIG],    [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
+m4_ifndef([_LT_AC_LANG_RC_CONFIG],     [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
+m4_ifndef([AC_LIBTOOL_CONFIG],         [AC_DEFUN([AC_LIBTOOL_CONFIG])])
+m4_ifndef([_LT_AC_FILE_LTDLL_C],       [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
diff --git a/mm-streamrecorder.pc.in b/mm-streamrecorder.pc.in
new file mode 100644 (file)
index 0000000..799aca2
--- /dev/null
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: mm-streamrecorder
+Description: Multimedia Framework Stream Recorder Library
+Requires: gstreamer-1.0 gstreamer-base-1.0 mm-common mm-log
+Version: $VERSION
+Libs: -L${libdir} -lmmfstreamrecorder
+Cflags: -I${includedir}/ -I${includedir}/mmf
diff --git a/packaging/libmm-streamrecorder.spec b/packaging/libmm-streamrecorder.spec
new file mode 100644 (file)
index 0000000..1a1897f
--- /dev/null
@@ -0,0 +1,68 @@
+Name:       libmm-streamrecorder
+Summary:    Media Stream Recorder library
+Version:    0.0.1
+Release:    0
+Group:      Multimedia/Other
+License:    Apache-2.0
+Source0:    %{name}-%{version}.tar.gz
+Requires(post): /sbin/ldconfig
+Requires(postun): /sbin/ldconfig
+BuildRequires:  pkgconfig(mm-common)
+BuildRequires:  pkgconfig(mm-log)
+BuildRequires:  pkgconfig(gstreamer-base-1.0)
+BuildRequires:  pkgconfig(gstreamer-video-1.0)
+BuildRequires:  pkgconfig(gstreamer-app-1.0)
+BuildRequires:  pkgconfig(iniparser)
+
+%description
+This library is for making video/audio files with gstreamer
+
+
+%package devel
+Summary:    Common recorder development library
+Group:      libdevel
+Version:    %{version}
+Requires:   %{name} = %{version}-%{release}
+
+%description devel
+Media Stream Recorder development library
+
+
+%prep
+%setup -q
+
+
+%build
+#export CFLAGS+=" -DGST_EXT_TIME_ANALYSIS"
+export CFLAGS+=" -Wall -Wextra -Wno-array-bounds -Wno-empty-body -Wno-ignored-qualifiers -Wno-unused-parameter -Wshadow -Wwrite-strings -Wswitch-default -Wno-unused-but-set-parameter -Wno-unused-but-set-variable"
+./autogen.sh
+%configure --disable-static
+make %{?jobs:-j%jobs}
+
+%install
+rm -rf %{buildroot}
+mkdir -p %{buildroot}/usr/share/license
+cp LICENSE.APLv2 %{buildroot}/usr/share/license/%{name}
+%make_install
+
+%clean
+rm -rf %{buildroot}
+
+%post
+/sbin/ldconfig
+
+%postun -p /sbin/ldconfig
+
+%files
+%manifest libmm-streamrecorder.manifest
+%defattr(-,root,root,-)
+%{_bindir}/*
+%{_libdir}/*.so.*
+%{_datadir}/license/%{name}
+
+
+%files devel
+%defattr(-,root,root,-)
+%{_includedir}/mmf/mm_streamrecorder.h
+%{_libdir}/pkgconfig/mm-streamrecorder.pc
+%{_libdir}/*.so
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644 (file)
index 0000000..13d6b6c
--- /dev/null
@@ -0,0 +1,57 @@
+ACLOCAL_AMFLAGS='-I m4'
+
+lib_LTLIBRARIES = libmmfstreamrecorder.la
+
+includelibmmfstreamrecorderdir = $(includedir)/mmf
+
+includelibmmfstreamrecorder_HEADERS = include/mm_streamrecorder.h
+
+noinst_HEADERS = include/mm_streamrecorder.h \
+                include/mm_streamrecorder_internal.h   \
+                include/mm_streamrecorder_fileinfo.h   \
+                include/mm_streamrecorder_util.h \
+                include/mm_streamrecorder_gstdispatch.h \
+                include/mm_streamrecorder_attribute.h \
+                include/mm_streamrecorder_video.h \
+                include/mm_streamrecorder_gstcommon.h \
+                include/mm_streamrecorder_recorder.h \
+                include/mm_streamrecorder_audio.h \
+                include/mm_streamrecorder_buffer_manager.h\
+                include/mm_streamrecorder_ini.h
+
+libmmfstreamrecorder_la_SOURCES = mm_streamrecorder.c \
+                            mm_streamrecorder_internal.c       \
+                            mm_streamrecorder_fileinfo.c       \
+                            mm_streamrecorder_util.c \
+                            mm_streamrecorder_gstdispatch.c \
+                            mm_streamrecorder_attribute.c \
+                            mm_streamrecorder_video.c \
+                            mm_streamrecorder_gstcommon.c \
+                            mm_streamrecorder_recorder.c \
+                            mm_streamrecorder_audio.c \
+                            mm_streamrecorder_buffer_manager.c\
+                            mm_streamrecorder_ini.c
+
+libmmfstreamrecorder_la_CFLAGS = -I$(srcdir)/include \
+                            $(GST_CFLAGS) \
+                            $(GST_PLUGIN_BASE_CFLAGS) \
+                            $(GST_VIDEO_CFLAGS) \
+                            $(GST_INTERFACES_CFLAGS) \
+                            $(MM_LOG_CFLAGS) \
+                            $(MM_COMMON_CFLAGS) \
+                            $(GST_APP_CFLAGS)
+
+libmmfstreamrecorder_la_LIBADD = \
+                           $(GST_LIBS) \
+                           $(GST_PLUGIN_BASE_LIBS) \
+                           $(GST_VIDEO_LIBS) \
+                           $(GST_INTERFACES_LIBS) \
+                           $(MM_COMMON_LIBS) \
+                           $(MM_LOG_LIBS) \
+                           $(VCONF_LIBS) \
+                           $(GST_APP_LIBS) \
+                           $(INIPARSER_LIBS)
+
+libmmfstreamrecorder_la_CFLAGS += $(MMLOGSVR_CFLAGS) -DMMF_LOG_OWNER=0x00400000 -DMMF_DEBUG_PREFIX=\"MMF-STREAMRECORDER\"
+libmmfstreamrecorder_la_LIBADD += $(MMLOGSVR_LIBS)
+
diff --git a/src/include/mm_streamrecorder.h b/src/include/mm_streamrecorder.h
new file mode 100644 (file)
index 0000000..6414668
--- /dev/null
@@ -0,0 +1,640 @@
+/*
+ * libmm-streamrecorder
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Hyuntae Kim <ht1211.kim@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_STREAMRECORDER_H__
+#define __MM_STREAMRECORDER_H__
+
+/*=======================================================================================
+| INCLUDE FILES                                                                                |
+========================================================================================*/
+#include <glib.h>
+
+#include <mm_types.h>
+#include <mm_error.h>
+#include <mm_message.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*=======================================================================================
+| GLOBAL DEFINITIONS AND DECLARATIONS FOR STREAMRECORDER                                       |
+========================================================================================*/
+
+/*=======================================================================================
+| MACRO DEFINITIONS                                                                    |
+========================================================================================*/
+
+/* Attributes Macros */
+
+#define MMSTR_VIDEO_ENABLE                     "video-enable"
+
+#define MMSTR_VIDEO_BUFFER_TYPE                "videobuffer-type"
+
+#define MMSTR_VIDEO_SOURCE_FORMAT              "videosource-format"
+
+#define MMSTR_VIDEO_FRAMERATE                  "video-framerate"
+
+#define MMSTR_VIDEO_BITRATE                    "video-bitrate"
+
+#define MMSTR_VIDEO_RESOLUTION_WIDTH           "video-resolution-width"
+
+#define MMSTR_VIDEO_RESOLUTION_HEIGHT          "video-resolution-height"
+
+/**
+ * Disable Audio stream when record.
+ */
+#define MMSTR_AUDIO_ENABLE                     "audio-enable"
+
+#define MMSTR_AUDIO_SOURCE_FORMAT              "audio-source-format"
+
+#define MMSTR_AUDIO_BITRATE                    "audio-bitrate"
+
+#define MMSTR_AUDIO_SAMPLERATE                 "audio-samplerate"
+
+#define MMSTR_VIDEO_ENCODER                    "video-encoder"
+
+#define MMSTR_AUDIO_ENCODER                    "audio-encoder"
+
+#define MMSTR_AUDIO_CHANNEL                    "audio-channel-count"
+
+#define MMSTR_FILE_FORMAT                      "file-format"
+
+#define MMSTR_FILENAME                         "filename"
+
+#define MMSTR_RECORDER_MODE                    "recorder-mode"
+
+#define MMSTR_TARGET_MAX_SIZE                  "target-max-size"
+
+#define MMSTR_TARGET_TIME_LIMIT                "target-time-limit"
+
+/*=======================================================================================
+| ENUM DEFINITIONS                                                                     |
+========================================================================================*/
+/**
+ * An enumeration for streamrecorder states.
+ */
+typedef enum {
+       MM_STREAMRECORDER_STATE_NONE,           /**< Streamrecorder is not created yet */
+       MM_STREAMRECORDER_STATE_CREATED,        /**< Streamrecorder is created, but not initialized yet */
+       MM_STREAMRECORDER_STATE_PREPARED,       /**< Streamrecorder is prepared to record */
+       MM_STREAMRECORDER_STATE_RECORDING,      /**< Streamrecorder is now recording */
+       MM_STREAMRECORDER_STATE_PAUSED,         /**< Streamrecorder is paused while recording */
+       MM_STREAMRECORDER_STATE_NUM,            /**< Number of streamrecorder states */
+} MMStreamRecorderStateType;
+
+/**
+ * An enumeration of Audio Format.
+ */
+typedef enum {
+       MM_STREAMRECORDER_AUDIO_FORMAT_PCM_U8 = 0,      /**< unsigned 8bit audio */
+       MM_STREAMRECORDER_AUDIO_FORMAT_PCM_S16_LE = 2,  /**< signed 16bit audio. Little endian. */
+} MMStreamRecorderAudioFormat;
+
+/**********************************
+*          Stream data            *
+**********************************/
+
+typedef enum {
+       MM_STREAM_TYPE_NONE,
+       MM_STREAM_TYPE_VIDEO,
+       MM_STREAM_TYPE_AUDIO,
+} MMStreamRecorderStreamType;
+
+/*=======================================================================================
+| STRUCTURE DEFINITIONS                                                                        |
+========================================================================================*/
+
+/* General Structure */
+/**
+ * An enumeration for streamrecorder mode.
+ */
+
+typedef enum {
+       MM_STREAMRECORDER_MODE_MEDIABUFFER = 0,    /**< Recording with mediabuffer */
+       MM_STREAMRECORDER_MODE_SCREENRECORD,       /**< Recording with screenrecord */
+} MMStreamRecorderModeType;
+
+typedef enum {
+       MM_STREAMRECORDER_VIDEO_TYPE_TBM_BO,         /**< TBM BO type */
+       MM_STREAMRECORDER_VIDEO_TYPE_NORMAL_BUFFER,  /**< Normal Raw data buffer */
+} MMStreamRecorderVideoBufType;
+
+typedef enum {
+       MM_STREAMRECORDER_INPUT_FORMAT_INVALID = -1,/**< Invalid pixel format */
+       MM_STREAMRECORDER_INPUT_FORMAT_NV12,       /**< NV12 pixel format */
+       MM_STREAMRECORDER_INPUT_FORMAT_NV21,       /**< NV21 pixel format */
+       MM_STREAMRECORDER_INPUT_FORMAT_I420,       /**< I420 pixel format */
+       MM_STREAMRECORDER_INPUT_FORMAT_UYVY,       /**< UYVY pixel format */
+       MM_STREAMRECORDER_INPUT_FORMAT_YUYV,       /**< YUYV pixel format */
+       MM_STREAMRECORDER_INPUT_FORMAT_BGRA8888,   /**< BGRA8888 pixel format */
+       MM_STREAMRECORDER_INPUT_FORMAT_NUM         /**< Number of the pixel format */
+} MMStreamRecorderVideoSourceFormat;
+
+/**********************************
+*          Attribute info         *
+**********************************/
+
+/**
+ * Report structure of recording file
+ */
+typedef struct {
+       char *recording_filename;       /**< File name of stored recording file. Please free after using. */
+} MMStreamRecordingReport; /**< report structure definition of recording file */
+
+/**
+* An enumeration for attribute values types.
+*/
+typedef enum {
+   MM_STR_REC_ATTRS_TYPE_INVALID = -1, /**< Type is invalid */
+   MM_STR_REC_ATTRS_TYPE_INT,     /**< Integer type attribute */
+   MM_STR_REC_ATTRS_TYPE_DOUBLE,   /**< Double type attribute */
+   MM_STR_REC_ATTRS_TYPE_STRING,   /**< UTF-8 String type attribute */
+   MM_STR_REC_ATTRS_TYPE_DATA,    /**< Pointer type attribute */
+} MMStreamRecorderAttrsType;
+
+/**
+* An enumeration for attribute validation type.
+*/
+typedef enum {
+   MM_STR_REC_ATTRS_VALID_TYPE_INVALID = -1,   /**< Invalid validation type */
+   MM_STR_REC_ATTRS_VALID_TYPE_NONE,            /**< Do not check validity */
+   MM_STR_REC_ATTRS_VALID_TYPE_INT_ARRAY,       /**< validity checking type of integer array */
+   MM_STR_REC_ATTRS_VALID_TYPE_INT_RANGE,       /**< validity checking type of integer range */
+   MM_STR_REC_ATTRS_VALID_TYPE_DOUBLE_ARRAY,    /**< validity checking type of double array */
+   MM_STR_REC_ATTRS_VALID_TYPE_DOUBLE_RANGE,    /**< validity checking type of double range */
+} MMStreamRecorderAttrsValidType;
+
+/**
+* An enumeration for attribute access flag.
+*/
+typedef enum {
+   MM_STR_REC_ATTRS_FLAG_DISABLED = 0, /**< None flag is set. This means the attribute is not allowed to use.  */
+   MM_STR_REC_ATTRS_FLAG_READABLE = 1 << 0,/**< Readable */
+   MM_STR_REC_ATTRS_FLAG_WRITABLE = 1 << 1,/**< Writable */
+   MM_STR_REC_ATTRS_FLAG_MODIFIED = 1 << 2,/**< Modified */
+   MM_STR_REC_ATTRS_FLAG_RW = MM_STR_REC_ATTRS_FLAG_READABLE | MM_STR_REC_ATTRS_FLAG_WRITABLE,
+                                                                                                                                                                                  /**< Readable and Writable */
+} MMStreamRecorderAttrsFlag;
+
+/**
+* A structure for attribute information
+*/
+typedef struct {
+   MMStreamRecorderAttrsType type;
+   MMStreamRecorderAttrsFlag flag;
+   MMStreamRecorderAttrsValidType validity_type;
+
+/**
+* A union that describes validity of the attribute.
+*/
+   union {
+   /**
+       * Validity structure for integer array.
+       */
+          struct {
+                  int *array; /**< a pointer of array */
+                  int count;  /**< size of array */
+                  int def;    /**< default value. Real value not index of array */
+          } int_array;
+
+   /**
+       * Validity structure for integer range.
+       */
+          struct {
+                  int min;    /**< minimum range */
+                  int max;    /**< maximum range */
+                  int def;    /**< default value */
+          } int_range;
+
+   /**
+       * Validity structure for double array.
+       */
+          struct {
+                  double *array;  /**< a pointer of array */
+                  int count;  /**< size of array */
+                  double def; /**< default value. Real value not index of array */
+          } double_array;
+
+   /**
+       * Validity structure for double range.
+       */
+          struct {
+                  double min; /**< minimum range */
+                  double max; /**< maximum range */
+                  double def; /**< default value */
+          } double_range;
+   };
+} MMStreamRecorderAttrsInfo;
+
+
+/*=======================================================================================
+| TYPE DEFINITIONS                                                                     |
+========================================================================================*/
+/*=======================================================================================
+| GLOBAL FUNCTION PROTOTYPES                                                           |
+========================================================================================*/
+/**
+ *    mm_streamrecorder_create:\n
+ *  Create streamrecorder object. This is the function that an user who wants to use mm_streamrecorder calls first.
+ *  This function creates handle structure and initialize mutex, attributes, gstreamer.
+ *  When this function success, it will return  a handle of newly created object.
+ *  A user have to put the handle when he calls every function of mm_streamrecorder. \n
+ *
+ *     @param[out]     streamrecorder  A handle of streamrecorder.
+ *     @param[in]      info            Information for devices
+ *     @return         This function returns zero(MM_ERROR_NONE) on success, or negative value with error code.\n
+ *                     Please refer 'mm_error.h' to know the exact meaning of the error.
+ *     @see            mm_streamrecorder_destroy
+ *     @pre            None
+ *     @post           Next state of mm-streamrecorder will be MM_STREAMRECORDER_STATE_CREATED
+ *     @remarks        You can create multiple handles on a context at the same time. However,
+ *                     streamrecordercorder cannot guarantee proper operation because of limitation of resources.
+ *     @par example
+ *     @code
+
+#include <mm_streamrecorder.h>
+
+gboolean initialize_streamrecorder()
+{
+       int err;
+
+       err = mm_streamrecorder_create(&hstream);
+
+       if (err != MM_ERROR_NONE) {
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+ *     @endcode
+ */
+
+//INITIAL GSTREAMER
+int mm_streamrecorder_create(MMHandleType *streamrecorder);
+
+/**
+ *    mm_streamrecorder_destroy:\n
+ *  Destroy streamrecorder object. Release handle and all of the resources that were created in mm_streamrecorder_create().\n
+ *  This is the finalizing function of mm_streamrecorder. If this function is not called or fails to call, the handle isn't released fully.
+ *  This function releases attributes, mutexes, sessions, and handle itself. This function also removes all of remaining messages.
+ *  So if your application should wait a certain message of mm_streamrecorder, please wait to call this function till getting the message.
+ *
+ *
+ *     @param[in]      streamrecorder  A handle of streamrecorder.
+ *     @return         This function returns zero(MM_ERROR_NONE) on success, or negative value with error code.\n
+ *                     Please refer 'mm_error.h' to know the exact meaning of the error.
+ *     @see            mm_streamrecorder_create
+ *     @pre            Previous state of mm-streamrecorder should be MM_STREAMRECORDER_STATE_CREATED
+ *     @post           Because the handle is not valid, you can't check the state.
+ *     @remarks        None
+ *     @par example
+ *     @code
+
+#include <mm_streamrecorder.h>
+
+gboolean destroy_streamrecorder()
+{
+       int err;
+
+       //Destroy streamrecorder handle
+       err = mm_streamrecorder_destroy(hstreamrecorder);
+       if (err < 0) {
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+ *     @endcode
+ */
+
+// DESTROY GSTREAMER
+int mm_streamrecorder_destroy(MMHandleType streamrecorder);
+
+/**
+ *    mm_streamrecorder_realize:\n
+ *  Allocate resources for streamrecorder and initialize it.
+ *  This also creates streamer pipeline. So you have to set attributes that are pivotal to create
+ *  the pipeline before calling this function. This function also takes a roll to manage confliction
+ *  between different applications which use streamrecorder. For example, if you try to use streamrecorder when
+ *  other application that is more important such as call application, this function will return
+ *  'MM_ERROR_POLICY_BLOCKED'. On the contrary, if your application that uses streamrecorder starts to launch
+ *  while another application that uses speaker and has lower priority, your application will kick
+ *  another application.
+ *
+ *     @param[in]      streamrecorder  A handle of streamrecorder.
+ *     @return         This function returns zero(MM_ERROR_NONE) on success, or negative value with error code.\n
+ *                     Please refer 'mm_error.h' to know the exact meaning of the error.
+ *     @see            mm_streamrecorder_unrealize
+ *     @pre            Previous state of mm-streamrecorder should be MM_STREAMRECORDER_STATE_CREATED
+ *     @post           Next state of mm-streamrecorder will be MM_STREAMRECORDER_STATE_READY
+ *     @remarks        None
+ */
+
+// CONSTRUCT PIPLINE
+int mm_streamrecorder_realize(MMHandleType streamrecorder);
+
+/**
+ *    mm_streamrecorder_unrealize:\n
+ *  Uninitialize streamrecoder resources and free allocated memory.
+ *  Most important resource that is released here is gstreamer pipeline of mm_streamrecorder.
+ *  Because most of resources are operating on the gstreamer pipeline,
+ *  this function should be called to release its resources.
+ *  Moreover, mm_streamrecorder is controlled by audio session manager. If an user doesn't call this function when he want to release mm_streamrecorder,
+ *  other multimedia frameworks may face session problem. For more detail information, please refer mm_session module.
+ *
+ *     @param[in]      streamrecorder  A handle of streamrecorder.
+ *     @return         This function returns zero(MM_ERROR_NONE) on success, or negative value with error code.\n
+ *                     Please refer 'mm_error.h' to know the exact meaning of the error.
+ *     @see            mm_streamrecorder_realize
+ *     @pre            Previous state of mm-streamrecorder should be MM_STREAMRECORDER_STATE_READY
+ *     @post           Next state of mm-streamrecorder will be MM_STREAMRECORDER_STATE_CREATED
+ *     @remarks        None
+ */
+
+// DESTROY PIPELINE
+int mm_streamrecorder_unrealize(MMHandleType streamrecorder);
+
+/**
+ *     mm_streamrecorder_start:\n
+ *   Start previewing. (Image/Video mode)
+ *
+ *     @param[in]      streamrecorder  A handle of streamrecorder.
+ *     @return         This function returns zero(MM_ERROR_NONE) on success, or negative value with error code.\n
+ *                     Please refer 'mm_error.h' to know the exact meaning of the error.
+ *     @see            mm_streamrecorder_stop
+ *     @pre            Previous state of mm-streamrecorder should be MM_STREAMRECORDER_STATE_READY
+ *     @post           Next state of mm-streamrecorder will be MM_STREAMRECORDER_STATE_PREPARED
+ *     @remarks        None
+ */
+
+// START ENCODE
+int mm_streamrecorder_record(MMHandleType streamrecorder);
+
+/**
+ *    mm_streamrecorder_pause:\n
+ *  Pause A/V recording or Audio recording. (Audio/Video mode only)
+ *
+ *  @param[in]  streamrecorder   A handle of streamrecorder.
+ *  @return     This function returns zero(MM_ERROR_NONE) on success, or negative value with error code.\n
+ *          Please refer 'mm_error.h' to know the exact meaning of the error.
+ *  @see        mm_streamrecorder_record
+ *  @pre        Previous state of mm-streamrecorder should be MM_STREAMRECORDER_STATE_RECORDING
+ *  @post       Next state of mm-streamrecorder will be MM_STREAMRECORDER_STATE_PAUSED
+ *  @remarks    Even though this function is for pausing recording, small amount of buffers could be recorded after pause().
+ *          Because the buffers which are existed in the queue were created before pause(), the buffers should be recorded.
+ */
+int mm_streamrecorder_pause(MMHandleType streamrecorder);
+
+/**
+ *    mm_streamrecorder_stop:\n
+ *  Stop previewing. (Image/Video mode)
+ *  This function will change the status of pipeline.
+ *
+ *     @param[in]      streamrecorder  A handle of streamrecorder.
+ *     @return         This function returns zero(MM_ERROR_NONE) on success, or negative value with error code.\n
+ *                     Please refer 'mm_error.h' to know the exact meaning of the error.
+ *     @see            mm_streamrecorder_start
+ *     @pre            Previous state of mm-streamrecorder should be MM_STREAMRECORDER_STATE_PREPARED
+ *     @post           Next state of mm-streamrecorder will be MM_STREAMRECORDER_STATE_READY
+ *     @remarks        None
+ *     @par example
+ *     @code
+
+#include <mm_streamrecorder.h>
+
+gboolean stop_streamrecorder()
+{
+       int err;
+
+       //Stop preview
+       err =  mm_streamrecorder_stop(hstreamrecorder);
+       if (err < 0) {
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+ *     @endcode
+ */
+int mm_streamrecorder_commit(MMHandleType streamrecorder);
+
+int mm_streamrecorder_cancel(MMHandleType streamrecorder);
+
+int mm_streamrecorder_push_stream_buffer(MMHandleType streamrecorder, MMStreamRecorderStreamType streamtype, unsigned long timestamp, void *buffer, int size);
+
+/**
+ *    mm_streamrecorder_commit:\n
+ *  Stop recording and save results.  (Audio/Video mode only)\n
+ *  After starting recording, encoded data frame will be stored in the location specified in MMSTR_FILENAME.
+ *  Some encoder or muxer require a certain type of finalizing such as adding some information to header.
+ *  This function takes that roll. So if you don't call this function after recording, the result file may not be playable.\n
+ *  Because this is the function for saving the recording result, the operation is available
+ *
+ *     @param[in]      streamrecorder  A handle of streamrecorder.
+ *     @return         This function returns zero(MM_ERROR_NONE) on success, or negative value with error code.\n
+ *                     Please refer 'mm_error.h' to know the exact meaning of the error.
+ *     @see            mm_streamrecorder_cancel
+ *     @pre            Previous state of mm-streamrecorder should be MM_STREAMRECORDER_STATE_RECORDING
+ *     @post           Next state of mm-streamrecorder will be MM_STREAMRECORDER_STATE_PREPARED
+ *     @remarks        This function can take a few second when recording time is long.
+ *                     and if there are only quite few input buffer from video src or audio src,
+ *                     committing could be failed.
+ *     @par example
+ *     @code
+
+#include <mm_streamrecorder.h>
+
+gboolean record_and_save_video_file()
+{
+       int err;
+
+       // Start recording
+       err =  mm_streamrecorder_record(hstreamrecorder);
+       if (err < 0) {
+               return FALSE;
+       }
+
+       // Wait while recording for test...
+       // In normal case, mm_streamrecorder_record() and mm_streamrecorder_commit() aren't called in the same function.
+
+       // Save file
+       err =  mm_streamrecorder_commit(hstreamrecorder);
+       if (err < 0) {
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+ *     @endcode
+ */
+int mm_streamrecorder_commit(MMHandleType streamrecorder);
+
+/**
+ *     mm_streamrecorder_cancel:\n
+ *    Stop recording and discard the result. (Audio/Video mode only)
+ *     When a user want to finish recording without saving the result file, this function can be used.
+ *     Like mm_streamrecorder_commit(), this function also stops recording, release related resources(like codec) ,and goes back to preview status.
+ *     However, instead of saving file, this function unlinks(delete) the result.\n
+ *     Because this is the function for canceling recording, the operation is available
+ *
+ *     @param[in]      streamrecorder  A handle of streamrecorder.
+ *     @return         This function returns zero(MM_ERROR_NONE) on success, or negative value with error code.\n
+ *                     Please refer 'mm_error.h' to know the exact meaning of the error.
+ *     @see            mm_streamrecorder_commit
+ *     @pre            Previous state of mm-streamrecorder should be MM_STREAMRECORDER_STATE_RECORDING
+ *     @post           Next state of mm-streamrecorder will be MM_STREAMRECORDER_STATE_PREPARED
+ *     @remarks        None
+ *     @par example
+ *     @code
+
+#include <mm_streamrecorder.h>
+
+gboolean record_and_cancel_video_file()
+{
+       int err;
+
+       // Start recording
+       err =  mm_streamrecorder_record(hstreamrecorder);
+       if (err < 0) {
+               return FALSE;
+       }
+
+       // Wait while recording...
+
+       // Cancel recording
+       err =  mm_streamrecorder_cancel(hstreamrecorder);
+       if (err < 0) {
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+ *     @endcode
+ */
+int mm_streamrecorder_cancel(MMHandleType streamrecorder);
+
+/**
+ *    mm_streamrecorder_set_message_callback:\n
+ *  Set callback for receiving messages from streamrecorder. Through this callback function, streamrecorder
+ *  sends various message including status changes, asynchronous error, capturing, and limitations.
+ *  One thing you have to know is that message callback is working on the main loop of application.
+ *  So until releasing the main loop, message callback will not be called.
+ *
+ *     @param[in]      streamrecorder  A handle of streamrecorder.
+ *     @param[in]      callback        Function pointer of callback function. Please refer 'MMMessageCallback'.
+ *     @param[in]      user_data       User parameter for passing to callback function.
+ *     @return         This function returns zero(MM_ERROR_NONE) on success, or negative value with error code.\n
+ *                     Please refer 'mm_error.h' to know the exact meaning of the error.
+ *     @see            MMMessageCallback
+ *     @pre            None
+ *     @post           None
+ *     @remarks        registered 'callback' is called on main loop of the application. So until the main loop is released, 'callback' will not be called.
+ *     @par example
+ *     @code
+
+#include <mm_streamrecorder.h>
+
+gboolean setting_msg_callback()
+{
+       //set callback
+       mm_streamrecorder_set_message_callback(hstreamrecorder,(MMMessageCallback)msg_callback, (void*)hstreamrecorder);
+
+       return TRUE;
+}
+
+ *     @endcode
+ */
+int mm_streamrecorder_set_message_callback(MMHandleType streamrecorder, MMMessageCallback callback, void *user_data);
+
+/**
+ *    mm_streamrecorder_get_attributes:\n
+ *  Get attributes of streamrecorder with given attribute names. This function can get multiple attributes
+ *  simultaneously. If one of attribute fails, this function will stop at the point.
+ *  'err_attr_name' let you know the name of the attribute.
+ *
+ *     @param[in]      streamrecorder  Specifies the streamrecorder  handle.
+ *     @param[out]     err_attr_name   Specifies the name of attributes that made an error. If the function doesn't make an error, this will be null. @n
+ *                                     Free this variable after using.
+ *     @param[in]      attribute_name  attribute name that user want to get.
+ *     @return         This function returns zero(MM_ERROR_NONE) on success, or negative value with error code.\n
+ *                     Please refer 'mm_error.h' to know the exact meaning of the error.
+ *     @pre            None
+ *     @post           None
+ *     @remarks        You can retrieve multiple attributes at the same time.  @n
+ *                     This function must finish with 'NULL' argument.  @n
+ *                     ex) mm_streamrecorder_get_attributes(....... , NULL);
+ *     @see            mm_streamrecorder_set_attributes
+ */
+int mm_streamrecorder_get_attributes(MMHandleType streamrecorder, char **err_attr_name, const char *attribute_name, ...) G_GNUC_NULL_TERMINATED;
+
+/**
+ *    mm_streamrecorder_set_attributes:\n
+ *  Set attributes of streamrecorder with given attribute names. This function can set multiple attributes
+ *  simultaneously. If one of attribute fails, this function will stop at the point.
+ *  'err_attr_name' let you know the name of the attribute.
+ *
+ *     @param[in]      streamrecorder  Specifies the streamrecorder  handle.
+ *     @param[out]     err_attr_name   Specifies the name of attributes that made an error. If the function doesn't make an error, this will be null. @n
+ *                                     Free this variable after using.
+ *     @param[in]      attribute_name  attribute name that user want to set.
+ *     @return         This function returns zero(MM_ERROR_NONE) on success, or negative value with error code.\n
+ *                     Please refer 'mm_error.h' to know the exact meaning of the error.
+ *     @pre            None
+ *     @post           None
+ *     @remarks        You can put multiple attributes to streamrecorder at the same time.  @n
+ *                     This function must finish with 'NULL' argument.  @n
+ *                     ex) mm_streamrecorder_set_attributes(....... , NULL);
+ *     @see            mm_streamrecorder_get_attributes
+ */
+int mm_streamrecorder_set_attributes(MMHandleType streamrecorder, char **err_attr_name, const char *attribute_name, ...) G_GNUC_NULL_TERMINATED;
+
+/**
+ *    mm_streamrecorder_get_state:\n
+ *  Get the current state of streamreccorder.
+ *  mm_streamrecorderr is working on the base of its state. An user should check the state of mm_streamrecorder before calling its functions.
+ *  If the handle is avaiable, user can retrieve the value.
+ *
+ *  @param[in]  streamrecorder   A handle of streamrecorder.
+ *  @param[out] state       On return, it contains current state of streamrecorder.
+ *  @return     This function returns zero(MM_ERROR_NONE) on success, or negative value with error code.\n
+ *          Please refer 'mm_error.h' to know the exact meaning of the error.
+ *  @see        MMStreamRecorderStateType
+ *  @pre        None
+ *  @post       None
+ *  @remarks    None
+ */
+int mm_streamrecorder_get_state(MMHandleType streamrecorder, MMStreamRecorderStateType *status);
+
+/**
+       @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MM_STREAMRECORDER_H__ */
diff --git a/src/include/mm_streamrecorder_attribute.h b/src/include/mm_streamrecorder_attribute.h
new file mode 100644 (file)
index 0000000..4438ae3
--- /dev/null
@@ -0,0 +1,254 @@
+/*
+ * libmm-streamrecorder
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Hyuntae Kim <ht1211.kim@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_STREAMRECORDER_ATTRIBUTE_H__
+#define __MM_STREAMRECORDER_ATTRIBUTE_H__
+
+/*=======================================================================================
+| INCLUDE FILES                                                                                |
+========================================================================================*/
+#include <mm_types.h>
+#include <mm_attrs.h>
+#include <mm_attrs_private.h>
+#include <stdarg.h>
+#include "mm_streamrecorder_internal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*=======================================================================================
+| GLOBAL DEFINITIONS AND DECLARATIONS FOR STREAMRECORDER                                       |
+========================================================================================*/
+/* Disabled
+#define GET_AND_STORE_ATTRS_AFTER_SCENE_MODE
+*/
+
+/*=======================================================================================
+| MACRO DEFINITIONS                                                                    |
+========================================================================================*/
+/**
+ * Caster of attributes handle
+ */
+#define MMF_STREAMRECORDER_ATTRS(h) (((mmf_streamrecorder_t *)(h))->attributes)
+
+/*=======================================================================================
+| ENUM DEFINITIONS                                                                     |
+========================================================================================*/
+/**
+ * Enumerations for streamrecorder attribute ID.
+ */
+typedef enum {
+       MM_STR_VIDEO_BUFFER_TYPE,       /* 0 */
+       MM_STR_VIDEO_FORMAT,
+       MM_STR_VIDEO_FRAMERATE,
+       MM_STR_VIDEO_ENCODER_BITRATE,
+       MM_STR_VIDEO_RESOLUTION_WIDTH,
+       MM_STR_VIDEO_RESOLUTION_HEIGHT,
+       MM_STR_AUDIO_FORMAT,
+       MM_STR_AUDIO_ENCODER_BITRATE,
+       MM_STR_AUDIO_SAMPLERATE,
+       MM_STR_VIDEO_ENCODER,
+       MM_STR_AUDIO_ENCODER,   /* 10 */
+       MM_STR_AUDIO_CHENNEL_COUNT,
+       MM_STR_FILE_FORMAT,
+       MM_STR_TARGET_FILE_NAME,
+       MM_STR_VIDEO_ENABLE,
+       MM_STR_AUDIO_ENABLE,
+       MM_STR_MODE,
+       MM_STR_TARGET_MAX_SIZE,
+       MM_STR_TARGET_TIME_LIMIT,
+       MM_STR_NUM
+} MMStreamRecorderAttrsID;
+
+
+/*=======================================================================================
+| TYPE DEFINITIONS                                                                     |
+========================================================================================*/
+typedef bool(*mmf_streamrecorder_commit_func_t) (MMHandleType handle, int attr_idx, const mmf_value_t *value);
+
+/*=======================================================================================
+| STRUCTURE DEFINITIONS                                                                        |
+========================================================================================*/
+typedef struct {
+       MMStreamRecorderAttrsID attrid;
+       const char *name;
+       int value_type;
+       int flags;
+       union {
+               void *value_void;
+               char *value_string;
+               int value_int;
+               double value_double;
+       } default_value;                /* default value */
+       MMStreamRecorderAttrsValidType validity_type;
+       int validity_value1;    /* can be int min, int *array, double *array, or cast to double min. */
+       int validity_value2;    /* can be int max, int count, int count, or cast to double max. */
+       mmf_streamrecorder_commit_func_t attr_commit;
+} mm_streamrecorder_attr_construct_info;
+
+/*=======================================================================================
+| CONSTANT DEFINITIONS                                                                 |
+========================================================================================*/
+
+/*=======================================================================================
+| STATIC VARIABLES                                                                     |
+========================================================================================*/
+
+/*=======================================================================================
+| EXTERN GLOBAL VARIABLE                                                               |
+========================================================================================*/
+
+/*=======================================================================================
+| GLOBAL FUNCTION PROTOTYPES                                                           |
+========================================================================================*/
+/**
+ * This function allocates structure of attributes and sets initial values.
+ *
+ * @param[in]  handle          Handle of streamrecorder.
+ * @param[in]  info            Preset information of streamrecorder.
+ * @return     This function returns allocated structure of attributes.
+ * @remarks
+ * @see                _mmstreamrecorder_dealloc_attribute()
+ *
+ */
+MMHandleType _mmstreamrecorder_alloc_attribute(MMHandleType handle);
+
+/**
+ * This function release structure of attributes.
+ *
+ * @param[in]  attrs           Handle of streamrecorder attribute.
+ * @return     void
+ * @remarks
+ * @see                _mmstreamrecorder_alloc_attribute()
+ *
+ */
+void _mmstreamrecorder_dealloc_attribute(MMHandleType attrs);
+
+/**
+ * This is a meta  function to get attributes of streamrecorder with given attribute names.
+ *
+ * @param[in]  handle          Handle of streamrecorder.
+ * @param[out] err_attr_name   Specifies the name of attributes that made an error. If the function doesn't make an error, this will be null.
+ * @param[in]  attribute_name  attribute name that user want to get.
+ * @param[in]  var_args        Specifies variable arguments.
+ * @return     This function returns MM_ERROR_NONE on Success, minus on Failure.
+ * @remarks    You can retrieve multiple attributes at the same time.  @n
+ * @see                _mmstreamrecorder_set_attributes
+ */
+int _mmstreamrecorder_get_attributes(MMHandleType handle, char **err_attr_name, const char *attribute_name, va_list var_args);
+
+/**
+ * This is a meta  function to set attributes of steamrecorder with given attribute names.
+ *
+ * @param[in]  handle          Handle of streamrecorder.
+ * @param[out] err_attr_name   Specifies the name of attributes that made an error. If the function doesn't make an error, this will be null.
+ * @param[in]  attribute_name  attribute name that user want to set.
+ * @param[in]  var_args        Specifies variable arguments.
+ * @return     This function returns MM_ERROR_NONE on Success, minus on Failure.
+ * @remarks    You can put multiple attributes to streamrecorder at the same time.  @n
+ * @see                _mmstreamrecorder_get_attributes
+ */
+int _mmstreamrecorder_set_attributes(MMHandleType handle, char **err_attr_name, const char *attribute_name, va_list var_args);
+
+/**
+ * This is a meta  function to get detail information of the attribute.
+ *
+ * @param[in]  handle          Handle of streamrecorder.
+ * @param[in]  attr_name       attribute name that user want to get information.
+ * @param[out] info            a structure that holds information related with the attribute.
+ * @return     This function returns MM_ERROR_NONE on Success, minus on Failure.
+ * @remarks    If the function succeeds, 'info' holds detail information about the attribute, such as type, flag, validity_type, validity_values  @n
+ * @see                _mmstreamrecorder_get_attributes, _mmstreamrecorder_set_attributes
+ */
+int _mmstreamrecorder_get_attribute_info(MMHandleType handle, const char *attr_name, MMStreamRecorderAttrsInfo * info);
+
+/*=======================================================================================
+| STREAMRECORDER INTERNAL LOCAL                                                                |
+========================================================================================*/
+/**
+ * A commit function to set streamrecorder attributes
+ * If the attribute needs actual setting, this function handles that activity.
+ * When application sets an attribute, setting function in MSL common calls this function.
+ * If this function fails, original value will not change.
+ *
+ * @param[in]  attr_idx        Attribute index of subcategory.
+ * @param[in]  attr_name       Attribute name.
+ * @param[in]  value           Handle of streamrecorder.
+ * @param[in]  commit_param    Allocation type of streamrecorder context.
+ * @return     This function returns TRUE on success, or FALSE on failure
+ * @remarks
+ * @see
+ *
+ */
+bool _mmstreamrecorder_commit_streamrecorder_attrs(int attr_idx, const char *attr_name, const mmf_value_t *value, void *commit_param);
+
+bool _mmstreamrecorder_commit_video_enable(MMHandleType handle, int attr_idx, const mmf_value_t *value);
+
+bool _mmstreamrecorder_commit_video_encoder(MMHandleType handle, int attr_idx, const mmf_value_t *value);
+
+bool _mmstreamrecorder_commit_audio_enable(MMHandleType handle, int attr_idx, const mmf_value_t *value);
+
+bool _mmstreamrecorder_commit_audio_encoder(MMHandleType handle, int attr_idx, const mmf_value_t *value);
+
+bool _mmstreamrecorder_commit_audio_samplingrate(MMHandleType handle, int attr_idx, const mmf_value_t *value);
+
+bool _mmstreamrecorder_commit_audio_bitformat(MMHandleType handle, int attr_idx, const mmf_value_t *value);
+
+bool _mmstreamrecorder_commit_audio_channel(MMHandleType handle, int attr_idx, const mmf_value_t *value);
+
+bool _mmstreamrecorder_commit_audio_bitrate(MMHandleType handle, int attr_idx, const mmf_value_t *value);
+
+/**
+ * check whether supported or not
+ *
+ * @param[in]  handle          Handle of streamrecorder.
+ * @param[in]  attr_index      index of attribute to check.
+ * @return     bool            TRUE if supported or FALSE
+ */
+bool _mmstreamrecorder_check_supported_attribute(MMHandleType handle, int attr_index);
+
+/**
+ *    mm_streamrecorder_get_attribute_info:\n
+ *  Get detail information of the attribute. To manager attributes, an user may want to know the exact character of the attribute,
+ *  such as type, flag, and validity. This is the function to provide such information.
+ *  Depending on the 'validity_type', validity union would be different. To know about the type of union, please refer 'MMStreamRecorderAttrsInfo'.
+ *
+ *     @param[in]      streamrecorder  Specifies the streamrecorder  handle.
+ *     @param[in]      attribute_name  attribute name that user want to get information.
+ *     @param[out]     info            a structure that holds information related with the attribute.
+ *     @return         This function returns zero(MM_ERROR_NONE) on success, or negative value with error code.\n
+ *                     Please refer 'mm_error.h' to know the exact meaning of the error.
+ *     @pre            None
+ *     @post           None
+ *     @remarks        If the function succeeds, 'info' holds detail information about the attribute, such as type,
+ *                     flag, validity_type, validity_values, and default values.
+ *     @see            mm_streamrecorder_get_attributes, mm_streamrecorder_set_attributes
+ */
+
+int mm_streamrecorder_get_attribute_info(MMHandleType streamrecorder, const char *attribute_name, MMStreamRecorderAttrsInfo *info);
+
+bool _mmstreamrecorder_commit_video_bitrate(MMHandleType handle, int attr_idx, const mmf_value_t *value);
+
+#ifdef __cplusplus
+}
+#endif
+#endif                                                 /* __MM_STREAMRECORDER_ATTRIBUTE_H__ */
diff --git a/src/include/mm_streamrecorder_audio.h b/src/include/mm_streamrecorder_audio.h
new file mode 100644 (file)
index 0000000..0899880
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * libmm-streamrecorder
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Hyuntae Kim <ht1211.kim@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_STREAMRECORDER_AUDIO_H__
+#define __MM_STREAMRECORDER_AUDIO_H__
+
+/*=======================================================================================
+| INCLUDE FILES                                                                                |
+========================================================================================*/
+#include <glib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*=======================================================================================
+| STRUCTURE DEFINITIONS                                                                        |
+========================================================================================*/
+/**
+ * MMStreamRecorder information for audio mode
+ */
+typedef struct {
+       int iAudioEncoder;          /**<Encoder */
+       int iSamplingRate;          /**< Sampling rate */
+       int iBitDepth;              /**< Bit depth */
+       int iBitrate;               /**< audio bitrate */
+       int iChannels;              /**< audio channels */
+       gboolean b_commiting;       /**< Is it commiting now? */
+       gboolean bMuxing;           /**< whether muxing */
+       guint64 filesize;           /**< current recorded file size */
+       guint64 max_size;           /**< max recording size */
+       guint64 max_time;           /**< max recording time */
+       int audio_encode_depth;     /**< audio depth */
+       guint64 audio_frame_count;  /**< current audio frame */
+} _MMStreamRecorderAudioInfo;
+
+/**
+* Enumerations for AMR bitrate
+*/
+typedef enum _MMStreamRecorderAMRBitRate {
+       MM_STREAMRECORDER_MR475,    /**< MR475 : 4.75 kbit/s */
+       MM_STREAMRECORDER_MR515,    /**< MR515 : 5.15 kbit/s */
+       MM_STREAMRECORDER_MR59,     /**< MR59 : 5.90 kbit/s */
+       MM_STREAMRECORDER_MR67,     /**< MR67 : 6.70 kbit/s */
+       MM_STREAMRECORDER_MR74,     /**< MR74 : 7.40 kbit/s */
+       MM_STREAMRECORDER_MR795,    /**< MR795 : 7.95 kbit/s */
+       MM_STREAMRECORDER_MR102,    /**< MR102 : 10.20 kbit/s */
+       MM_STREAMRECORDER_MR122,    /**< MR122 : 12.20 kbit/s */
+       MM_STREAMRECORDER_MRDTX     /**< MRDTX */
+} MMStreamRecorderAMRBitRate;
+
+/*=======================================================================================
+| GLOBAL FUNCTION PROTOTYPES                                                           |
+========================================================================================*/
+
+int _mmstreamrecorder_check_audiocodec_fileformat_compatibility(unsigned int audio_codec, unsigned int file_format);
+
+int _mmstreamrecorder_get_amrnb_bitrate_mode(int bitrate);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __MM_STREAMRECORDER_AUDIO_H__ */
diff --git a/src/include/mm_streamrecorder_buffer_manager.h b/src/include/mm_streamrecorder_buffer_manager.h
new file mode 100644 (file)
index 0000000..cf1a019
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * libmm-streamrecorder
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Hyuntae Kim <ht1211.kim@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_STREAMRECORDER_BUFFER_MANAGER_H__
+#define __MM_STREAMRECORDER_BUFFER_MANAGER_H__
+
+/*=======================================================================================
+| INCLUDE FILES                                                                                |
+========================================================================================*/
+#include <glib.h>
+#include <gst/gst.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*=======================================================================================
+| GLOBAL DEFINITIONS AND DECLARATIONS FOR STREAMRECORDER                                       |
+========================================================================================*/
+
+/*=======================================================================================
+| ENUM DEFINITIONS                                                                     |
+========================================================================================*/
+
+/*=======================================================================================
+| STRUCTURE DEFINITIONS                                                                        |
+========================================================================================*/
+
+typedef struct _GstStreamRecorderBuffer GstStreamRecorderBuffer;
+
+struct _GstStreamRecorderBuffer {
+       GstBuffer *buffer;
+       MMHandleType str_handle;
+       void *user_buffer;
+};
+
+/*=======================================================================================
+| CONSTANT DEFINITIONS                                                                 |
+========================================================================================*/
+
+/*=======================================================================================
+| STATIC VARIABLES                                                                     |
+========================================================================================*/
+
+/*=======================================================================================
+| EXTERN GLOBAL VARIABLE                                                               |
+========================================================================================*/
+
+/*=======================================================================================
+| GLOBAL FUNCTION PROTOTYPES                                                           |
+========================================================================================*/
+void _mmstreamrecorder_buffer_destroy(gpointer stream_buffer);
+
+#ifdef __cplusplus
+}
+#endif
+#endif                                                 /* __MM_STREAMRECORDER_BUFFER_MANAGER_H__ */
diff --git a/src/include/mm_streamrecorder_fileinfo.h b/src/include/mm_streamrecorder_fileinfo.h
new file mode 100644 (file)
index 0000000..c40a841
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * libmm-streamrecorder
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Hyuntae Kim <ht1211.kim@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_STREAMRECORDER_FILEINFO_H__
+#define __MM_STREAMRECORDER_FILEINFO_H__
+
+/*=======================================================================================
+| INCLUDE FILES                                                                                |
+========================================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*=======================================================================================
+| GLOBAL DEFINITIONS AND DECLARATIONS FOR STREAMRECORDER                                       |
+========================================================================================*/
+
+/*=======================================================================================
+| MACRO DEFINITIONS                                                                    |
+========================================================================================*/
+
+#define MMSTREAMRECORDER_FOURCC(a,b,c,d)  (guint32)((a)|(b)<<8|(c)<<16|(d)<<24)
+#define MMSTREAMRECORDER_FOURCC_ARGS(fourcc) \
+        ((gchar)((fourcc)&0xff)), \
+        ((gchar)(((fourcc)>>8)&0xff)), \
+        ((gchar)(((fourcc)>>16)&0xff)), \
+        ((gchar)(((fourcc)>>24)&0xff))
+
+/*=======================================================================================
+| ENUM DEFINITIONS                                                                     |
+========================================================================================*/
+/**
+ *Type define of util.
+ */
+#define _OFFSET_COMPOSITION_MATRIX              40L
+
+/*=======================================================================================
+| STRUCTURE DEFINITIONS                                                                        |
+========================================================================================*/
+
+typedef struct {
+       char *filename;         /**< recorded filename */
+       guint64 filesize;       /**< current file size */
+       guint64 max_size;       /**< max recording size */
+       guint64 max_time;       /**< max recording time */
+       int fileformat;         /**< recording file format */
+} _MMStreamRecorderFileInfo;
+
+/**
+ * Structure of location info
+ */
+typedef struct {
+       gint32 longitude;
+       gint32 latitude;
+       gint32 altitude;
+} _MMStreamRecorderLocationInfo;
+
+enum MMStreamReorderTagVideoOrientation {
+       MM_STREAMRECORDER_TAG_VIDEO_ORT_NONE = 0, /**< No Orientation.*/
+       MM_STREAMRECORDER_TAG_VIDEO_ORT_90,       /**< 90 degree */
+       MM_STREAMRECORDER_TAG_VIDEO_ORT_180,      /**< 180 degree */
+       MM_STREAMRECORDER_TAG_VIDEO_ORT_270,      /**< 270 degree */
+};
+
+/*=======================================================================================
+| CONSTANT DEFINITIONS                                                                 |
+========================================================================================*/
+
+/**
+ *
+ */
+#define MMFILE_FOURCC(a,b,c,d)  (guint32)((a)|(b)<<8|(c)<<16|(d)<<24)
+#define MMFILE_FOURCC_ARGS(fourcc) \
+                       ((gchar)((fourcc)&0xff)), \
+                       ((gchar)(((fourcc)>>8)&0xff)), \
+                       ((gchar)(((fourcc)>>16)&0xff)), \
+                       ((gchar)(((fourcc)>>24)&0xff))
+
+/*=======================================================================================
+| GLOBAL FUNCTION PROTOTYPES                                                           |
+========================================================================================*/
+
+/* Recording */
+/* find top level tag only, do not use this function for finding sub level tags.
+   tag_fourcc is Four-character-code (FOURCC) */
+
+// READER
+gboolean _mmstreamrecorder_find_fourcc(FILE *f, guint32 tag_fourcc, gboolean do_rewind);
+gboolean _mmstreamrecorder_update_size(FILE *f, gint64 prev_pos, gint64 curr_pos);
+guint64 _mmstreamrecorder_get_container_size(const guchar *size);
+
+// WRITER
+// COMMON
+gboolean _mmstreamrecorder_write_udta(FILE *f, _MMStreamRecorderLocationInfo info);
+gboolean _mmstreamrecorder_update_size(FILE *f, gint64 prev_pos, gint64 curr_pos);
+
+// VIDEO FOURCC
+gboolean _mmstreamrecorder_write_udta(FILE *f, _MMStreamRecorderLocationInfo info);
+
+// AUDIO FOURCC
+gboolean _mmstreamrecorder_write_udta_m4a(FILE *f);
+gboolean _mmstreamrecorder_audio_add_metadata_info_m4a(MMHandleType handle);
+
+#ifdef __cplusplus
+}
+#endif
+#endif                                                 /* __MM_STREAMRECORDER_FILEINFO_H__ */
diff --git a/src/include/mm_streamrecorder_gstcommon.h b/src/include/mm_streamrecorder_gstcommon.h
new file mode 100644 (file)
index 0000000..2b832ea
--- /dev/null
@@ -0,0 +1,253 @@
+/*
+ * libmm-streamrecorder
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Hyuntae Kim <ht1211.kim@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_STREAMRECORDER_GSTCOMMON_H__
+#define __MM_STREAMRECORDER_GSTCOMMON_H__
+
+/*=======================================================================================
+| INCLUDE FILES                                                                                |
+========================================================================================*/
+#include <mm_types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*=======================================================================================
+| GLOBAL DEFINITIONS AND DECLARATIONS FOR STREAMRECORDER                                       |
+========================================================================================*/
+
+/*=======================================================================================
+| MACRO DEFINITIONS                                                                    |
+========================================================================================*/
+
+/* gstreamer element creation macro */
+#define _MMSTREAMRECORDER_PIPELINE_MAKE(sub_context, element, eid, name /*char* */, err) \
+       if (element[eid].gst != NULL) { \
+               _mmstreamrec_dbg_err("The element(Pipeline) is existed. element_id=[%d], name=[%s]", eid, name); \
+               gst_object_unref(element[eid].gst); \
+       } \
+       element[eid].id = eid; \
+       element[eid].gst = gst_pipeline_new(name); \
+       if (element[eid].gst == NULL) { \
+               _mmstreamrec_dbg_err("Pipeline creation fail. element_id=[%d], name=[%s]", eid, name); \
+               err = MM_ERROR_STREAMRECORDER_RESOURCE_CREATION; \
+               goto pipeline_creation_error; \
+       } else { \
+               g_object_weak_ref(G_OBJECT(element[eid].gst), (GWeakNotify)_mmstreamrecorder_element_release_noti/*NULL*/, sub_context); \
+       }
+
+#define _MMSTREAMRECORDER_BIN_MAKE(sub_context, element, eid, name /*char* */, err) \
+       if (element[eid].gst != NULL) { \
+               _mmstreamrec_dbg_err("The element(Bin) is existed. element_id=[%d], name=[%s]", eid, name); \
+               gst_object_unref(element[eid].gst); \
+       } \
+       element[eid].id = eid; \
+       element[eid].gst = gst_bin_new(name); \
+       if (element[eid].gst == NULL) { \
+               _mmstreamrec_dbg_err("Bin creation fail. element_id=[%d], name=[%s]\n", eid, name); \
+               err = MM_ERROR_STREAMRECORDER_RESOURCE_CREATION; \
+               goto pipeline_creation_error; \
+       } else { \
+               g_object_weak_ref(G_OBJECT(element[eid].gst), (GWeakNotify)_mmstreamrecorder_element_release_noti/*NULL*/, sub_context); \
+       }
+
+#define _MMSTREAMRECORDER_ELEMENT_MAKE(sub_context, element, eid, name /*char* */, nickname /*char* */, elist, err) \
+       if (element[eid].gst != NULL) { \
+               _mmstreamrec_dbg_err("The element is existed. element_id=[%d], name=[%s]", eid, name); \
+               gst_object_unref(element[eid].gst); \
+       } \
+       element[eid].gst = gst_element_factory_make(name, nickname); \
+       if (element[eid].gst == NULL) { \
+               _mmstreamrec_dbg_err("Element creation fail. element_id=[%d], name=[%s]", eid, name); \
+               err = MM_ERROR_STREAMRECORDER_RESOURCE_CREATION; \
+               goto pipeline_creation_error; \
+       } else { \
+               _mmstreamrec_dbg_err("Element creation done. element_id=[%d], name=[%s]", eid, name); \
+               element[eid].id = eid; \
+               g_object_weak_ref(G_OBJECT(element[eid].gst), (GWeakNotify)_mmstreamrecorder_element_release_noti/*NULL*/, sub_context); \
+               err = MM_ERROR_NONE; \
+       } \
+       elist = g_list_append(elist, &(element[eid]));
+
+#define _MMSTREAMRECORDER_ELEMENT_MAKE_IGNORE_ERROR(sub_context, element, eid, name /*char* */, nickname /*char* */, elist) \
+       if (element[eid].gst != NULL) { \
+               _mmstreamrec_dbg_err("The element is existed. element_id=[%d], name=[%s]", eid, name); \
+               gst_object_unref(element[eid].gst); \
+       } \
+       element[eid].gst = gst_element_factory_make(name, nickname); \
+       if (element[eid].gst == NULL) { \
+               _mmstreamrec_dbg_err("Element creation fail. element_id=[%d], name=[%s], but keep going...", eid, name); \
+       } else { \
+               _mmstreamrec_dbg_err("Element creation done. element_id=[%d], name=[%s]", eid, name); \
+               element[eid].id = eid; \
+               g_object_weak_ref(G_OBJECT(element[eid].gst), (GWeakNotify)_mmstreamrecorder_element_release_noti/*NULL*/, sub_context); \
+               elist = g_list_append(elist, &(element[eid])); \
+       }
+
+#define _MMSTREAMRECORDER_ENCODEBIN_ELMGET(sub_context, eid, name /*char* */, err) \
+       if (sub_context->encode_element[eid].gst != NULL) { \
+               _mmstreamrec_dbg_err("The element is existed. element_id=[%d], name=[%s]", eid, name); \
+               gst_object_unref(sub_context->encode_element[eid].gst); \
+       } \
+       sub_context->encode_element[eid].id = eid; \
+       g_object_get(G_OBJECT(sub_context->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst), name, &(sub_context->encode_element[eid].gst), NULL); \
+       if (sub_context->encode_element[eid].gst == NULL) { \
+               _mmstreamrec_dbg_err("Encode Element get fail. element_id=[%d], name=[%s]", eid, name); \
+               err = MM_ERROR_STREAMRECORDER_RESOURCE_CREATION; \
+               goto pipeline_creation_error; \
+       } else{ \
+               gst_object_unref(sub_context->encode_element[eid].gst); \
+               g_object_weak_ref(G_OBJECT(sub_context->encode_element[eid].gst), (GWeakNotify)_mmstreamrecorder_element_release_noti/*NULL*/, sub_context); \
+       }
+
+/* GStreamer element remove macro */
+#define _MMSTREAMRECORDER_ELEMENT_REMOVE(element, eid) \
+       if (element[eid].gst != NULL) { \
+               gst_object_unref(element[eid].gst); \
+       }
+
+#define _MM_GST_ELEMENT_LINK_MANY       gst_element_link_many
+#define _MM_GST_ELEMENT_LINK            gst_element_link
+#define _MM_GST_PAD_LINK                gst_pad_link
+
+#define _MM_GST_PAD_LINK_UNREF(srcpad, sinkpad, err, if_fail_goto)\
+{\
+       GstPadLinkReturn ret = _MM_GST_PAD_LINK(srcpad, sinkpad);\
+       if (ret != GST_PAD_LINK_OK) {\
+               GstObject *src_parent = gst_pad_get_parent(srcpad);\
+               GstObject *sink_parent = gst_pad_get_parent(sinkpad);\
+               char *src_name = NULL;\
+               char *sink_name = NULL;\
+               g_object_get((GObject *)src_parent, "name", &src_name, NULL);\
+               g_object_get((GObject *)sink_parent, "name", &sink_name, NULL);\
+               _mmstreamrec_dbg_err("src[%s] - sink[%s] link failed", src_name, sink_name);\
+               gst_object_unref(src_parent); src_parent = NULL;\
+               gst_object_unref(sink_parent); sink_parent = NULL;\
+               if (src_name) {\
+                       free(src_name); src_name = NULL;\
+               }\
+               if (sink_name) {\
+                       free(sink_name); sink_name = NULL;\
+               }\
+               gst_object_unref(srcpad); srcpad = NULL;\
+               gst_object_unref(sinkpad); sinkpad = NULL;\
+               err = MM_ERROR_STREAMRECORDER_GST_LINK;\
+               goto if_fail_goto;\
+       }\
+       gst_object_unref(srcpad); srcpad = NULL;\
+       gst_object_unref(sinkpad); sinkpad = NULL;\
+}
+
+#define _MM_GST_PAD_UNLINK_UNREF( srcpad, sinkpad) \
+       if (srcpad && sinkpad) { \
+               gst_pad_unlink(srcpad, sinkpad); \
+       } else { \
+               _mmstreamrec_dbg_warn("some pad(srcpad:%p,sinkpad:%p) is NULL", srcpad, sinkpad); \
+       } \
+       if (srcpad) { \
+               gst_object_unref(srcpad); srcpad = NULL; \
+       } \
+       if (sinkpad) { \
+               gst_object_unref(sinkpad); sinkpad = NULL; \
+       }
+
+/*=======================================================================================
+| ENUM DEFINITIONS                                                                     |
+========================================================================================*/
+
+/**
+* Encodebin profile
+*/
+typedef enum _MMStreamRecorderEncodebinProfile {
+       MM_STREAMRECORDER_ENCBIN_PROFILE_VIDEO = 0,      /**< Video recording profile */
+       MM_STREAMRECORDER_ENCBIN_PROFILE_AUDIO,          /**< Audio recording profile */
+       MM_STREAMRECORDER_ENCBIN_PROFILE_IMAGE,          /**< Image capture profile */
+       MM_STREAMRECORDER_ENCBIN_PROFILE_NUM
+} MMStreamRecorderEncodebinProfile;
+
+#define __MMSTREAMRECORDER_SET_GST_STATE_TIMEOUT     5
+
+/*=======================================================================================
+| STRUCTURE DEFINITIONS                                                                        |
+========================================================================================*/
+/**
+ * Element name table.
+ * @note if name is NULL, not supported.
+ */
+typedef struct {
+       unsigned int prof_id;   /**< id of mmstreamrecorder_profile_attrs_id */
+       unsigned int id;        /**< id of value id */
+       char *name;             /**< gstreamer element name*/
+} _MMStreamRecorderElementName;
+
+/**
+ * MMstreamrecorder Gstreamer Element
+ */
+typedef struct {
+       unsigned int id;        /**< Gstreamer piplinem element name */
+       GstElement *gst;        /**< Gstreamer element */
+} _MMStreamRecorderGstElement;
+
+/*=======================================================================================
+| CONSTANT DEFINITIONS                                                                 |
+========================================================================================*/
+
+/*=======================================================================================
+| STATIC VARIABLES                                                                     |
+========================================================================================*/
+
+/*=======================================================================================
+| EXTERN GLOBAL VARIABLE                                                               |
+========================================================================================*/
+
+/*=======================================================================================
+| GLOBAL FUNCTION PROTOTYPES                                                           |
+========================================================================================*/
+
+gboolean _mmstreamrecorder_gstreamer_init();
+
+/* etc */
+int _mmstreamrecorder_get_eos_message(MMHandleType handle);
+void _mmstreamrecorder_remove_element_handle(MMHandleType handle, void *element, int first_elem, int last_elem);
+gboolean _mmstreamrecorder_add_elements_to_bin(GstBin *bin, GList *element_list);
+gboolean _mmstreamrecorder_link_elements(GList *element_list);
+
+/**
+ * This function sets gstreamer element status.
+ * If the gstreamer fails to set status or returns asynchronous mode,
+ * this function waits for state changed until timeout expired.
+ *
+ * @param[in]  pipeline        Pointer of pipeline
+ * @param[in]  target_state    newly setting status
+ * @return     This function returns zero on success, or negative value with error code.
+ * @remarks
+ * @see
+ *
+ */
+int _mmstreamrecorder_gst_set_state(MMHandleType handle, GstElement *pipeline, GstState target_state);
+GstCaps *gst_set_videosrcpad_caps(gint srcfmt, gint width, gint height, gint rate, gint scale);
+GstCaps *gst_set_audiosrcpad_caps(gint samplerate, gint channel, gint depth, gint width, gint datatype);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __MM_STREAMRECORDER_GSTCOMMON_H__ */
diff --git a/src/include/mm_streamrecorder_gstdispatch.h b/src/include/mm_streamrecorder_gstdispatch.h
new file mode 100644 (file)
index 0000000..53a7ed9
--- /dev/null
@@ -0,0 +1,246 @@
+/*
+ * libmm-streamrecorder
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Hyuntae Kim <ht1211.kim@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_STREAMRECORDER_GSTDISPATCH_H__
+#define __MM_STREAMRECORDER_GSTDISPATCH_H__
+
+/*=======================================================================================
+| INCLUDE FILES                                                                                |
+========================================================================================*/
+#include "mm_streamrecorder_util.h"
+#include <gst/gst.h>
+#include <gst/gstutils.h>
+#include <gst/gstpad.h>
+#include <mm_types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*=======================================================================================
+| GLOBAL DEFINITIONS AND DECLARATIONS FOR STREAMRECORDER                                       |
+========================================================================================*/
+
+/*=======================================================================================
+| MACRO DEFINITIONS                                                                    |
+========================================================================================*/
+
+#define MMSTREAMRECORDER_ADD_BUFFER_PROBE(x_pad, x_category, x_callback, x_hstreamrecorder) \
+do { \
+       MMStreamRecorderHandlerItem *item = NULL; \
+       item = (MMStreamRecorderHandlerItem *)g_malloc(sizeof(MMStreamRecorderHandlerItem)); \
+       if (!item) {\
+               _mmstreamrec_dbg_err("Cannot connect buffer probe [malloc fail] \n"); \
+       } else if (x_category == 0 || !(x_category & _MMSTREAMRECORDER_HANDLER_CATEGORY_ALL)) { \
+               _mmstreamrec_dbg_err("Invalid handler category : %x \n", x_category); \
+       } else { \
+               item->object = G_OBJECT(x_pad); \
+               item->category = x_category; \
+               item->handler_id = gst_pad_add_probe(x_pad,GST_PAD_PROBE_TYPE_BUFFER,x_callback, x_hstreamrecorder,NULL); \
+               x_hstreamrecorder->buffer_probes = g_list_append(x_hstreamrecorder->buffer_probes, item); \
+               _mmstreamrec_dbg_log("Adding buffer probe on [%s:%s] - [ID : %lu], [Category : %x] ", GST_DEBUG_PAD_NAME(item->object), item->handler_id, item->category); \
+       } \
+} while (0);
+
+#define MMSTREAMRECORDER_ADD_EVENT_PROBE(x_pad, x_category, x_callback, x_hstreamrecorder) \
+do { \
+       MMStreamRecorderHandlerItem *item = NULL; \
+       item = (MMStreamRecorderHandlerItem *) g_malloc(sizeof(MMStreamRecorderHandlerItem)); \
+       if (!item) { \
+               _mmstreamrec_dbg_err("Cannot connect buffer probe [malloc fail] \n"); \
+       } \
+       else if (x_category == 0 || !(x_category & _MMSTREAMRECORDER_HANDLER_CATEGORY_ALL)) { \
+               _mmstreamrec_dbg_err("Invalid handler category : %x \n", x_category); \
+       } else { \
+               item->object =G_OBJECT(x_pad); \
+               item->category = x_category; \
+               item->handler_id = gst_pad_add_probe(x_pad,GST_PAD_PROBE_TYPE_EVENT_BOTH,x_callback, x_hstreamrecorder,NULL); \
+               x_hstreamrecorder->event_probes = g_list_append(x_hstreamrecorder->event_probes, item); \
+               _mmstreamrec_dbg_log("Adding event probe on [%s:%s] - [ID : %lu], [Category : %x] ", GST_DEBUG_PAD_NAME(item->object), item->handler_id, item->category); \
+       } \
+} while (0);
+
+#define MMSTREAMRECORDER_ADD_DATA_PROBE(x_pad, x_category, x_callback, x_hstreamrecorder) \
+do { \
+       MMStreamRecorderHandlerItem *item = NULL; \
+       item = (MMStreamRecorderHandlerItem *) g_malloc(sizeof(MMStreamRecorderHandlerItem)); \
+       if (!item) { \
+               _mmstreamrec_dbg_err("Cannot connect buffer probe [malloc fail] \n"); \
+       } else if (x_category == 0 || !(x_category & _MMSTREAMRECORDER_HANDLER_CATEGORY_ALL)) { \
+               _mmstreamrec_dbg_err("Invalid handler category : %x \n", x_category); \
+       } else { \
+               item->object =G_OBJECT(x_pad); \
+               item->category = x_category; \
+               item->handler_id = gst_pad_add_data_probe(x_pad, G_CALLBACK(x_callback), x_hstreamrecorder); \
+               x_hstreamrecorder->data_probes = g_list_append(x_hstreamrecorder->data_probes, item); \
+               _mmstreamrec_dbg_log("Adding data probe on [%s:%s] - [ID : %lu], [Category : %x] ", GST_DEBUG_PAD_NAME(item->object), item->handler_id, item->category); \
+       } \
+} while (0);
+
+#define MMSTREAMRECORDER_SIGNAL_CONNECT( x_object, x_category, x_signal, x_callback, x_hstreamrecorder) \
+do { \
+       MMStreamRecorderHandlerItem* item = NULL; \
+       item = (MMStreamRecorderHandlerItem *) g_malloc(sizeof(MMStreamRecorderHandlerItem)); \
+       if (!item) { \
+               _mmstreamrec_dbg_err("Cannot connect signal [%s]\n", x_signal ); \
+       } else if (x_category == 0 || !(x_category & _MMSTREAMRECORDER_HANDLER_CATEGORY_ALL)) { \
+               _mmstreamrec_dbg_err("Invalid handler category : %x \n", x_category); \
+       } else { \
+               item->object = G_OBJECT(x_object); \
+               item->category = x_category; \
+               item->handler_id = g_signal_connect(G_OBJECT(x_object), x_signal,\
+                                                   G_CALLBACK(x_callback), x_hstreamrecorder ); \
+               x_hstreamrecorder->signals = g_list_append(x_hstreamrecorder->signals, item); \
+               _mmstreamrec_dbg_log("Connecting signal on [%s] - [ID : %lu], [Category : %x] ", GST_OBJECT_NAME(item->object), item->handler_id, item->category); \
+       } \
+} while (0);
+
+#define MMSTREAMRECORDER_G_OBJECT_GET(obj, name, value) \
+do { \
+       if (obj) { \
+               if(g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(obj)), name)) { \
+                       g_object_get(G_OBJECT(obj), name, value, NULL); \
+               } else { \
+                       _mmstreamrec_dbg_warn ("The object doesn't have a property named(%s)", name); \
+               } \
+       } else { \
+               _mmstreamrec_dbg_err("Null object"); \
+       } \
+} while(0);
+
+#define MMSTREAMRECORDER_G_OBJECT_SET(obj, name, value) \
+do { \
+       if (obj) { \
+               if(g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(obj)), name)) { \
+                       g_object_set(G_OBJECT(obj), name, value, NULL); \
+               } else { \
+                       _mmstreamrec_dbg_warn ("The object doesn't have a property named(%s)", name); \
+               } \
+       } else { \
+               _mmstreamrec_dbg_err("Null object"); \
+       } \
+} while(0);
+
+#define MMSTREAMRECORDER_SEND_MESSAGE(handle, msg_id, msg_code) \
+{\
+       _MMStreamRecorderMsgItem msg;\
+       msg.id = msg_id;\
+       msg.param.code = msg_code;\
+       _mmstreamrec_dbg_log("msg id : %x, code : %x", msg_id, msg_code);\
+       _mmstreamrecorder_send_message((MMHandleType)handle, &msg);\
+}
+
+/*=======================================================================================
+| ENUM DEFINITIONS                                                                     |
+========================================================================================*/
+/**
+ *Type define of util.
+ */
+typedef enum {
+       _MMSTREAMRECORDER_HANDLER_VIDEOREC = (1 << 0),
+       _MMSTREAMRECORDER_HANDLER_AUDIOREC = (1 << 1),
+} _MMStreamRecorderHandlerCategory;
+
+/*=======================================================================================
+| STRUCTURE DEFINITIONS                                                                        |
+========================================================================================*/
+
+/**
+ * Structure of handler item
+ */
+typedef struct {
+       GObject *object;
+       _MMStreamRecorderHandlerCategory category;
+       gulong handler_id;
+} MMStreamRecorderHandlerItem;
+
+/**
+ * Structure of message item
+ */
+typedef struct {
+       MMHandleType handle;    /**< handle */
+       int id;                 /**< message id */
+       MMMessageParamType param;
+                                                       /**< message parameter */
+} _MMStreamRecorderMsgItem;
+
+/*=======================================================================================
+| CONSTANT DEFINITIONS                                                                 |
+========================================================================================*/
+#define _MMSTREAMRECORDER_HANDLER_CATEGORY_ALL \
+       (_MMSTREAMRECORDER_HANDLER_VIDEOREC | _MMSTREAMRECORDER_HANDLER_AUDIOREC)
+
+/*=======================================================================================
+| GLOBAL FUNCTION PROTOTYPES                                                           |
+========================================================================================*/
+/* GStreamer */
+void _mmstreamrecorder_remove_buffer_probe(MMHandleType handle, _MMStreamRecorderHandlerCategory category);
+void _mmstreamrecorder_remove_event_probe(MMHandleType handle, _MMStreamRecorderHandlerCategory category);
+void _mmstreamrecorder_remove_data_probe(MMHandleType handle, _MMStreamRecorderHandlerCategory category);
+void _mmstreamrecorder_disconnect_signal(MMHandleType handle, _MMStreamRecorderHandlerCategory category);
+void _mmstreamrecorder_element_release_noti(gpointer data, GObject *where_the_object_was);
+
+/* Message */
+gboolean _mmstreamrecorder_msg_callback(void *data);
+gboolean _mmstreamrecorder_send_message(MMHandleType handle, _MMStreamRecorderMsgItem *data);
+gboolean _mmstreamrecorder_remove_message_all(MMHandleType handle);
+
+gboolean _mmstreamrecorder_handle_gst_error(MMHandleType handle, GstMessage *message, GError *error);
+gint _mmstreamrecorder_gst_handle_stream_error(MMHandleType handle, int code, GstMessage *message);
+gint _mmstreamrecorder_gst_handle_resource_error(MMHandleType handle, int code, GstMessage *message);
+gint _mmstreamrecorder_gst_handle_library_error(MMHandleType handle, int code, GstMessage *message);
+gint _mmstreamrecorder_gst_handle_core_error(MMHandleType handle, int code, GstMessage *message);
+gboolean _mmstreamrecorder_handle_gst_warning(MMHandleType handle, GstMessage *message, GError *error);
+void _mmstreamrecorder_remove_all_handlers(MMHandleType handle, _MMStreamRecorderHandlerCategory category);
+
+/**
+ * This function is callback function of main pipeline.
+ * Once this function is registered with certain pipeline using gst_bus_add_watch(),
+ * this callback will be called every time when there is upcomming message from pipeline.
+ * Basically, this function is used as error handling function, now.
+ *
+ * @param[in]  bus             pointer of buf that called this function.
+ * @param[in]  message         callback message from pipeline.
+ * @param[in]  data            user data.
+ * @return     This function returns true on success, or false value with error
+ * @remarks
+ * @see                __mmstreamrecorder_create_preview_pipeline()
+ *
+ */
+gboolean _mmstreamrecorder_pipeline_cb_message(GstBus *bus, GstMessage *message, gpointer data);
+
+GstPadProbeReturn __mmstreamrecorder_eventprobe_monitor(GstPad *pad, GstPadProbeInfo *info, gpointer u_data);
+
+GstPadProbeReturn __mmstreamrecorder_video_dataprobe_audio_disable(GstPad *pad, GstPadProbeInfo *info, gpointer u_data);
+
+GstPadProbeReturn __mmstreamrecorder_video_dataprobe_record(GstPad *pad, GstPadProbeInfo *info, gpointer u_data);
+
+GstPadProbeReturn __mmstreamrecorder_audio_dataprobe_check(GstPad *pad, GstPadProbeInfo *info, gpointer u_data);
+
+GstPadProbeReturn __mmstreamrecorder_audioque_dataprobe(GstPad *pad, GstPadProbeInfo *info, gpointer u_data);
+
+GstPadProbeReturn __mmstreamrecorder_audio_dataprobe_record(GstPad *pad, GstPadProbeInfo *info, gpointer u_data);
+void __mmstreamrecorder_audiorec_pad_added_cb(GstElement *element, GstPad *pad, MMHandleType handle);
+
+#ifdef __cplusplus
+}
+#endif
+#endif                                                 /* __MM_STREAMRECORDER_GSTDISPATCH_H__ */
diff --git a/src/include/mm_streamrecorder_ini.h b/src/include/mm_streamrecorder_ini.h
new file mode 100644 (file)
index 0000000..7fbaca5
--- /dev/null
@@ -0,0 +1,217 @@
+/*
+ * libmm-streamrecorder
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Hyuntae Kim <ht1211.kim@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_STREAMRECORDER_INI_H__
+#define __MM_STREAMRECORDER_INI_H__
+
+#include <glib.h>
+#include "mm_debug.h"
+#include "mm_streamrecorder.h"
+#include "mm_streamrecorder_util.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MM_STREAMRECORDER_INI_DEFAULT_PATH     "/usr/etc/mmfw_streamrecorder.ini"
+
+#define STREAMRECORDER_INI_MAX_STRLEN  256
+#define STREAMRECORDER_INI_MAX_ELEMENT 10
+#define STREAMRECORDER_ATTRIBUTE_NUM_MAX 8
+
+enum keyword_type {
+       KEYWORD_VIDEO_WIDTH,
+       KEYWORD_VIDEO_HEIGHT,
+       KEYWORD_AUDIO_ENCODERS,
+       KEYWORD_VIDEO_ENCODERS,
+       KEYWORD_FILE_FORMATS,
+};
+
+typedef struct __mm_streamrecorder_ini {
+       /* general */
+       gboolean encsink_src_islive;
+       guint retrial_count;
+       guint minimum_frame;
+       guint convert_output_buffer_num;
+       guint reset_pause_time;
+       guint screen_record;
+
+       /*encodebin */
+       guint encsink_bin_profile;
+       gboolean encsink_bin_auto_audio_resample;
+       gboolean encsink_bin_auto_colorspace;
+       gboolean encsink_bin_auto_audio_convert;
+       gboolean encsink_bin_use_video_toggle;
+
+       /* pipeline */
+       gchar name_of_encsink_src[STREAMRECORDER_INI_MAX_STRLEN];
+       gchar name_of_audio_src[STREAMRECORDER_INI_MAX_STRLEN];
+       gchar h264_video_encoder[STREAMRECORDER_INI_MAX_STRLEN];
+       gchar h263_video_encoder[STREAMRECORDER_INI_MAX_STRLEN];
+       gchar mpeg4_video_encoder[STREAMRECORDER_INI_MAX_STRLEN];
+       gchar name_of_encsink_bin_audio_encoder[STREAMRECORDER_INI_MAX_STRLEN];
+       gchar name_of_encsink_bin_video_converter[STREAMRECORDER_INI_MAX_STRLEN];
+       gchar encsink_bin_use_parser[STREAMRECORDER_INI_MAX_STRLEN];
+       gchar name_of_encsink_bin_3GPMUXER[STREAMRECORDER_INI_MAX_STRLEN];
+       gchar name_of_encsink_bin_MP4MUXER[STREAMRECORDER_INI_MAX_STRLEN];
+       gchar name_of_encsink_sink[STREAMRECORDER_INI_MAX_STRLEN];
+
+       /* audio parameter */
+       guint audio_frame_minimum_space;
+       guint audio_frame_wait_time;
+
+       /* video parameter */
+       guint video_frame_wait_time;
+
+       /*list attributed*/
+       gint supported_video_width[STREAMRECORDER_ATTRIBUTE_NUM_MAX];
+       gint supported_video_height[STREAMRECORDER_ATTRIBUTE_NUM_MAX];
+       gchar supported_audio_encoders[STREAMRECORDER_ATTRIBUTE_NUM_MAX][STREAMRECORDER_INI_MAX_STRLEN];
+       gchar supported_video_encoders[STREAMRECORDER_ATTRIBUTE_NUM_MAX][STREAMRECORDER_INI_MAX_STRLEN];
+       gchar supported_file_formats[STREAMRECORDER_ATTRIBUTE_NUM_MAX][STREAMRECORDER_INI_MAX_STRLEN];
+
+} mm_streamrecorder_ini_t;
+
+/*Default sink ini values*/
+/* General*/
+#define DEFAULT_ENCSINK_SRC_IS_LIVE  FALSE
+#define DEFAULT_RETRIAL_COUNT 10
+#define DEFAULT_MINIMUM_FRAME  5
+#define DEFAULT_CONVERT_OUTPUT_BUFFER_NUM 6
+#define DEFAULT_RESET_PAUSE_TIME 0
+#define DEFAULT_SCREEN_RECORD 1
+
+/*encodebin*/
+#define DEFAULT_ENCSINK_BIN_PROFILE 0
+#define DEFAULT_ENCSINK_BIN_AUTO_AUDIO_RESAMPLE FALSE
+#define DEFAULT_ENCSINK_BIN_AUTO_COLORSPACE TRUE
+#define DEFAULT_ENCSINK_BIN_AUTO_CONVERT TRUE
+#define DEFAULT_ENCSINK_BIN_USE_VIDEO_TOGGLE FALSE
+
+/* Pipeline */
+#define DEFAULT_VIDEO_SOURCE "appsrc"
+#define DEFAULT_AUDIO_SRC "pulsesrc"
+#define DEFAULT_NAME_OF_H264_VIDEO_ENCODER "omx_h264enc"
+#define DEFAULT_NAME_OF_H263_VIDEO_ENCODER "avenc_h263p"
+#define DEFAULT_NAME_OF_MPEG4_VIDEO_ENCODER "avenc_mpeg4"
+#define DEFAULT_NAME_OF_AUDIO_ENCODER "avenc_aac"
+#define DEFAULT_USE_PARSER ""
+#define DEFAULT_NAME_OF_3GP_MUXER "avmux_3gp"
+#define DEFAULT_NAME_OF_MP4_MUXER "avmux_mp4"
+#define DEFAULT_NAME_OF_VIDEO_CONVERTER "videoconvet"
+#define DEFAULT_NAME_OF_BIN_SINK "filesink"
+
+/*audio param*/
+#define DEFAULT_AUDIO_FRAME_MINIMUM_SPACE 102400
+#define DEFAULT_AUDIO_FRAME_WAIT_TIME 20000
+
+/*video param*/
+#define DEFAULT_VIDEO_FRAME_WAIT_TIME  200000
+
+/*supported attribute*/
+#define DEFAULT_SUPPORTED_WIDTH ""
+#define DEFAULT_SUPPORTED_HEIGHT ""
+#define DEFAULT_SUPPORTED_AUDIO_ENCODERS ""
+#define DEFAULT_SUPPORTED_VIDEO_ENCODERS ""
+#define DEFAULT_SUPPORTED_FILE_FORMATS ""
+
+#define MM_STREAMRECORDER_DEFAULT_INI \
+" \
+[general]\n\
+\n\
+retrialcount =10\n\
+\n\
+minimum frame =5\n\
+\n\
+reset pause time = 0 \n\
+\n\
+screen record =0 \n\
+\n\
+convert output buffer num =6\n\
+\n\
+[encodebin]\n\
+\n\
+encsink bin profile = 0 \n\
+\n\
+encsink source auto audio resample = 0\n\
+\n\
+encsink source auto audio colorsapce = 0 \n\
+\n\
+encsink source auto audio convert =1\n\
+\n\
+encsink source use video toggle = 1\n\
+\n\
+[pipeline]\n\
+\n\
+encsink bin source = xvimagesrc\n\
+\n\
+name of audio src \n\
+\n\
+h264 encoder = omx_h264enc\n\
+\n\
+h263 encoder = omx_h263enc\n\
+\n\
+mpeg4 encoder = omx_mpeg4enc\n\
+\n\
+name of audio encoder =savsenc_aac\n\
+\n\
+name of 3GP muxer =ffmux_3gp\n\
+\n\
+use parser= \n\
+\n\
+name of MP4 muxer =ffmux_mp4\n\
+\n\
+name of video converter\n\
+\n\
+name of sink = filesink \n\
+\n\
+[video param]\n\
+\n\
+video frame wait time = 200000\n\
+\n\
+[audio param]\n\
+\n\
+audio frame minimum space = 102400\n\
+\n\
+audio frame wait time = 20000\n\
+\n\
+supported width = ""\n\
+\n\
+supported height = ""\n\
+\n\
+supported audio encoders = ""\n\
+\n\
+supported video encoders = ""\n\
+\n\
+supported file formats = ""\n\
+\n\
+"
+
+int
+ _mm_streamrecorder_ini_load(mm_streamrecorder_ini_t * ini);
+
+int
+ _mm_streamrecorder_ini_unload(mm_streamrecorder_ini_t * ini);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/include/mm_streamrecorder_internal.h b/src/include/mm_streamrecorder_internal.h
new file mode 100644 (file)
index 0000000..1e0e6ec
--- /dev/null
@@ -0,0 +1,483 @@
+/*
+ * libmm-streamrecorder
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Hyuntae Kim <ht1211.kim@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_STREAMRECORDER_INTERNAL_H__
+#define __MM_STREAMRECORDER_INTERNAL_H__
+
+/*=======================================================================================
+| INCLUDE FILES                                                                                |
+========================================================================================*/
+#include <malloc.h>
+#include <string.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <semaphore.h>
+
+#include <mm_types.h>
+#include <mm_attrs.h>
+#include <mm_attrs_private.h>
+#include <mm_message.h>
+
+#include "mm_streamrecorder.h"
+#include <gst/gst.h>
+
+/* streamrecorder sub module */
+#include "mm_streamrecorder_util.h"
+#include "mm_streamrecorder_video.h"
+#include "mm_streamrecorder_audio.h"
+#include "mm_streamrecorder_fileinfo.h"
+#include "mm_streamrecorder_gstcommon.h"
+#include "mm_streamrecorder_ini.h"
+#include "mm_streamrecorder_buffer_manager.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*=======================================================================================
+| MACRO DEFINITIONS                                                                    |
+========================================================================================*/
+
+#ifndef ARRAY_SIZE
+/**
+ *     Macro for getting array size
+ */
+#define ARRAY_SIZE(a) (sizeof((a)) / sizeof((a)[0]))
+#endif
+
+#define        _MMSTREAMRECORDER_STATE_SET_COUNT               3       /* checking interval */
+#define        _MMSTREAMRECORDER_STATE_CHECK_INTERVAL  1000    //5000      /* checking interval */
+
+/**
+ *     Functions related with LOCK and WAIT
+ */
+#define _MMSTREAMRECORDER_CAST_MTSAFE(handle)                          (((mmf_streamrecorder_t*)handle)->mtsafe)
+#define _MMSTREAMRECORDER_LOCK_FUNC(mutex)                             pthread_mutex_lock(&mutex)
+#define _MMSTREAMRECORDER_TRYLOCK_FUNC(mutex)                  (!pthread_mutex_trylock(&mutex))
+#define _MMSTREAMRECORDER_UNLOCK_FUNC(mutex)                           pthread_mutex_unlock(&mutex)
+
+#define _MMSTREAMRECORDER_GET_LOCK(handle)                                     (_MMSTREAMRECORDER_CAST_MTSAFE(handle).lock)
+#define _MMSTREAMRECORDER_LOCK(handle)                                         _MMSTREAMRECORDER_LOCK_FUNC(_MMSTREAMRECORDER_GET_LOCK(handle))
+#define _MMSTREAMRECORDER_TRYLOCK(handle)                                      _MMSTREAMRECORDER_TRYLOCK_FUNC(_MMSTREAMRECORDER_GET_LOCK(handle))
+#define _MMSTREAMRECORDER_UNLOCK(handle)                                       _MMSTREAMRECORDER_UNLOCK_FUNC(_MMSTREAMRECORDER_GET_LOCK(handle))
+
+#define _MMSTREAMRECORDER_GET_COND(handle)                                     (_MMSTREAMRECORDER_CAST_MTSAFE(handle).cond)
+#define _MMSTREAMRECORDER_WAIT(handle)                                         pthread_cond_wait(&_MMSTREAMRECORDER_GET_COND(handle), _MMSTREAMRECORDER_GET_LOCK(handle))
+#define _MMSTREAMRECORDER_TIMED_WAIT(handle, timeout)          pthread_cond_timedwait(&_MMSTREAMRECORDER_GET_COND(handle), _MMSTREAMRECORDER_GET_LOCK(handle),&timeout)
+
+/* for command */
+#define _MMSTREAMRECORDER_GET_CMD_LOCK(handle)                                 (_MMSTREAMRECORDER_CAST_MTSAFE(handle).cmd_lock)
+#define _MMSTREAMRECORDER_LOCK_CMD(handle)                                             _MMSTREAMRECORDER_LOCK_FUNC(_MMSTREAMRECORDER_GET_CMD_LOCK(handle))
+#define _MMSTREAMRECORDER_TRYLOCK_CMD(handle)                                  _MMSTREAMRECORDER_TRYLOCK_FUNC(_MMSTREAMRECORDER_GET_CMD_LOCK(handle))
+#define _MMSTREAMRECORDER_UNLOCK_CMD(handle)                                           _MMSTREAMRECORDER_UNLOCK_FUNC(_MMSTREAMRECORDER_GET_CMD_LOCK(handle))
+
+/* for state change */
+#define _MMSTREAMRECORDER_GET_STATE_LOCK(handle)                                       (_MMSTREAMRECORDER_CAST_MTSAFE(handle).state_lock)
+#define _MMSTREAMRECORDER_LOCK_STATE(handle)                                           _MMSTREAMRECORDER_LOCK_FUNC(_MMSTREAMRECORDER_GET_STATE_LOCK(handle))
+#define _MMSTREAMRECORDER_TRYLOCK_STATE(handle)                                        _MMSTREAMRECORDER_TRYLOCK_FUNC(_MMSTREAMRECORDER_GET_STATE_LOCK(handle))
+#define _MMSTREAMRECORDER_UNLOCK_STATE(handle)                                         _MMSTREAMRECORDER_UNLOCK_FUNC(_MMSTREAMRECORDER_GET_STATE_LOCK(handle))
+
+/* for gstreamer state change */
+#define _MMSTREAMRECORDER_GET_GST_STATE_LOCK(handle)                                   (_MMSTREAMRECORDER_CAST_MTSAFE(handle).gst_state_lock)
+#define _MMSTREAMRECORDER_LOCK_GST_STATE(handle)                                               _MMSTREAMRECORDER_LOCK_FUNC(_MMSTREAMRECORDER_GET_GST_STATE_LOCK(handle))
+#define _MMSTREAMRECORDER_TRYLOCK_GST_STATE(handle)                                    _MMSTREAMRECORDER_TRYLOCK_FUNC(_MMSTREAMRECORDER_GET_GST_STATE_LOCK(handle))
+#define _MMSTREAMRECORDER_UNLOCK_GST_STATE(handle)                                             _MMSTREAMRECORDER_UNLOCK_FUNC(_MMSTREAMRECORDER_GET_GST_STATE_LOCK(handle))
+
+/* for setting/calling callback */
+#define _MMSTREAMRECORDER_GET_MESSAGE_CALLBACK_LOCK(handle)      (_MMSTREAMRECORDER_CAST_MTSAFE(handle).message_cb_lock)
+#define _MMSTREAMRECORDER_LOCK_MESSAGE_CALLBACK(handle)          _MMSTREAMRECORDER_LOCK_FUNC(_MMSTREAMRECORDER_GET_MESSAGE_CALLBACK_LOCK(handle))
+#define _MMSTREAMRECORDER_TRYLOCK_MESSAGE_CALLBACK(handle)       _MMSTREAMRECORDER_TRYLOCK_FUNC(_MMSTREAMRECORDER_GET_MESSAGE_CALLBACK_LOCK(handle))
+#define _MMSTREAMRECORDER_UNLOCK_MESSAGE_CALLBACK(handle)        _MMSTREAMRECORDER_UNLOCK_FUNC(_MMSTREAMRECORDER_GET_MESSAGE_CALLBACK_LOCK(handle))
+
+/**
+ * Caster of main handle (streamrecorder)
+ */
+#define MMF_STREAMRECORDER(h) (mmf_streamrecorder_t *)(h)
+
+/**
+ * Caster of subcontext
+ */
+#define MMF_STREAMRECORDER_SUBCONTEXT(h) (((mmf_streamrecorder_t *)(h))->sub_context)
+
+/* LOCAL CONSTANT DEFINITIONS */
+
+/*=======================================================================================
+| ENUM DEFINITIONS                                                                     |
+========================================================================================*/
+
+/**
+ * streamrecorder Pipeline's Element name.
+ * @note index of element.
+ */
+typedef enum {
+       _MMSTREAMRECORDER_ENCODE_NONE = (-1),
+
+       /* Main Pipeline Element */
+       _MMSTREAMRECORDER_ENCODE_MAIN_PIPE = 0x00,
+
+       /* Pipeline element of Audio input */
+       _MMSTREAMRECORDER_AUDIOSRC_BIN,
+       _MMSTREAMRECORDER_AUDIOSRC_SRC, /* appsrc */
+       _MMSTREAMRECORDER_AUDIOSRC_FILT,
+
+       /* Pipeline element of Encodebin */
+       _MMSTREAMRECORDER_ENCSINK_BIN,
+       _MMSTREAMRECORDER_ENCSINK_SRC,  /* video appsrc */
+       _MMSTREAMRECORDER_ENCSINK_FILT,
+       _MMSTREAMRECORDER_ENCSINK_ENCBIN,
+       _MMSTREAMRECORDER_ENCSINK_AQUE,
+       _MMSTREAMRECORDER_ENCSINK_CONV,
+       _MMSTREAMRECORDER_ENCSINK_AENC,
+       _MMSTREAMRECORDER_ENCSINK_AENC_QUE,
+       _MMSTREAMRECORDER_ENCSINK_VQUE,
+       _MMSTREAMRECORDER_ENCSINK_VCONV,
+       _MMSTREAMRECORDER_ENCSINK_VENC,
+       _MMSTREAMRECORDER_ENCSINK_VENC_QUE,
+       _MMSTREAMRECORDER_ENCSINK_PARSER,
+       _MMSTREAMRECORDER_ENCSINK_ITOG,
+       _MMSTREAMRECORDER_ENCSINK_ICROP,
+       _MMSTREAMRECORDER_ENCSINK_ISCALE,
+       _MMSTREAMRECORDER_ENCSINK_IFILT,
+       _MMSTREAMRECORDER_ENCSINK_IQUE,
+       _MMSTREAMRECORDER_ENCSINK_IENC,
+       _MMSTREAMRECORDER_ENCSINK_MUX,
+       _MMSTREAMRECORDER_ENCSINK_SINK,
+
+       _MMSTREAMRECORDER_ENCODE_PIPELINE_ELEMENT_NUM,
+} _MMSTREAMRECORDER_ENCODE_PIPELINE_ELELMENT;
+
+/**
+ * Command type for streamrecorder.
+ */
+
+typedef enum {
+       _MM_STREAMRECORDER_CMD_CREATE,
+       _MM_STREAMRECORDER_CMD_DESTROY,
+       _MM_STREAMRECORDER_CMD_REALIZE,
+       _MM_STREAMRECORDER_CMD_UNREALIZE,
+       _MM_STREAMRECORDER_CMD_START,
+       _MM_STREAMRECORDER_CMD_STOP,
+       _MM_STREAMRECORDER_CMD_RECORD,
+       _MM_STREAMRECORDER_CMD_PAUSE,
+       _MM_STREAMRECORDER_CMD_COMMIT,
+       _MM_STREAMRECORDER_CMD_CANCEL,
+       _MM_STREAMRECORDER_CMD_QUIT,
+} _MMstreamrecorderCommandType;
+
+/**
+ * System state change cause
+ */
+typedef enum {
+       _MMSTREAMRECORDER_STATE_CHANGE_NORMAL = 0,
+} _MMstreamrecorderStateChange;
+
+
+/*=======================================================================================
+| STRUCTURE DEFINITIONS                                                                        |
+========================================================================================*/
+
+/**
+ * MMstreamrecorder information for Multi-Thread Safe
+ */
+typedef struct {
+       pthread_mutex_t lock;           /**< Mutex (for general use) */
+       pthread_cond_t cond;            /**< Condition (for general use) */
+       pthread_mutex_t cmd_lock;       /**< Mutex (for command) */
+       pthread_mutex_t state_lock;     /**< Mutex (for state change) */
+       pthread_mutex_t gst_state_lock; /**< Mutex (for state change) */
+       pthread_mutex_t message_cb_lock;/**< Mutex (for message callback) */
+} _MMStreamRecorderMTSafe;
+
+/**
+ * MMstreamrecorder information for command loop
+ */
+
+/**
+ * MMstreamrecorder Sub Context
+ */
+typedef struct {
+       bool isMaxsizePausing;                          /**< Because of size limit, pipeline is paused. */
+       bool isMaxtimePausing;                          /**< Because of time limit, pipeline is paused. */
+       int encode_element_num;                         /**< count of encode element */
+       GstClockTime pipeline_time;                     /**< current time of Gstreamer Pipeline */
+       GstClockTime pause_time;                        /**< amount of time while pipeline is in PAUSE state.*/
+       gboolean error_occurs;                          /**< flag for error */
+       int error_code;                                         /**< error code for internal gstreamer error */
+       gboolean ferror_send;                           /**< file write/seek error **/
+       guint ferror_count;                                     /**< file write/seek error count **/
+       gboolean bget_eos;                                      /**< Whether getting EOS */
+       gboolean video_enable;                          /**< whether video is disabled or not when record */
+       gboolean audio_enable;                          /**< whether audio is disabled or not when record */
+
+       /* INI information */
+       unsigned int fourcc;                            /**< Get fourcc value */
+       _MMStreamRecorderVideoInfo *info_video;  /**< extra information for video recording */
+       _MMStreamRecorderAudioInfo *info_audio;  /**< extra information for audio recording */
+       _MMStreamRecorderFileInfo *info_file;  /**< extra information for audio recording */
+       _MMStreamRecorderGstElement *encode_element;
+                                                                                        /**< array of encode element */
+
+//  type_element *VideosinkElement;         /**< configure data of videosink element */
+} _MMStreamRecorderSubContext;
+
+/**
+  * _MMstreamrecorderContext
+  */
+typedef struct mmf_streamrecorder {
+       /* information */
+       //  int type;               /**< mmstreamrecorder_mode_type */
+       int state;              /**< state of streamrecorder */
+       //  int target_state;       /**< Target state that want to set. This is a flag that
+       //                             * stands for async state changing. If this value differ from state,
+       //                             * it means state is changing now asychronously. */
+
+       /* handles */
+       MMHandleType attributes;                           /**< Attribute handle */
+       _MMStreamRecorderSubContext *sub_context;       /**< sub context */
+       GList *buffer_probes;                              /**< a list of buffer probe handle */
+       GList *event_probes;                               /**< a list of event probe handle */
+       GList *data_probes;                                        /**< a list of data probe handle */
+       GList *signals;                                            /**< a list of signal handle */
+       GList *msg_data;                                           /**< a list of msg data */
+       guint pipeline_cb_event_id;                        /**< Event source ID of pipeline message callback */
+       guint encode_pipeline_cb_event_id;         /**< Event source ID of encode pipeline message callback */
+
+       /* callback handlers */
+       MMMessageCallback msg_cb;                                                               /**< message callback */
+       void *msg_cb_param;                                                                             /**< message callback parameter */
+       int (*command) (MMHandleType, int);                                             /**< streamrecorder's command */
+
+       /* etc */
+       _MMStreamRecorderMTSafe mtsafe;                                                          /**< Thread safe */
+       mm_streamrecorder_ini_t ini;
+
+       int reserved[4];                        /**< reserved */
+} mmf_streamrecorder_t;
+
+/*=======================================================================================
+| EXTERN GLOBAL VARIABLE                                                               |
+========================================================================================*/
+
+/*=======================================================================================
+| GLOBAL FUNCTION PROTOTYPES                                                           |
+========================================================================================*/
+/**
+ *     This function creates streamrecorder for capturing still image and recording.
+ *
+ *     @param[out]     handle          Specifies the streamrecorder  handle
+ *     @param[in]      info            Preset information of streamrecorder
+ *     @return         This function returns zero on success, or negative value with error code.
+ *     @remarks        When this function calls successfully, streamrecorder  handle will be filled with a @n
+ *                     valid value and the state of  the streamrecorder  will become MM_streamrecorder_STATE_NULL.@n
+ *                     Note that  it's not ready to working streamrecorder. @n
+ *                     You should call mmstreamrecorder_realize before starting streamrecorder.
+ *     @see            _mmstreamrecorder_create
+ */
+int _mmstreamrecorder_create(MMHandleType *handle);
+
+/**
+*  This function gets the current state of streamreccorder.
+*  mm_streamrecorderr is working on the base of its state. An user should check the state of mm_streamrecorder before calling its functions.
+*  If the handle is avaiable, user can retrieve the value.
+*
+*  @param[in]  streamrecorder   A handle of streamrecorder.
+*  @param[out] state       On return, it contains current state of streamrecorder.
+*  @return     This function returns zero(MM_ERROR_NONE) on success, or negative value with error code.
+*          Please refer 'mm_error.h' to know the exact meaning of the error.
+*  @see        MMStreamRecorderStateType
+*  @pre        None
+*  @post       None
+*  @remarks    None
+*/
+
+MMStreamRecorderStateType _mmstreamrecorder_get_state(MMHandleType handle);
+
+/**
+ *     This function destroys instance of streamrecorder.
+ *
+ *     @param[in]      hstreamrecorder Specifies the streamrecorder  handle
+ *     @return         This function returns zero on success, or negative value with error code.
+ *     @see            _mmstreamrecorder_create
+ */
+int _mmstreamrecorder_destroy(MMHandleType handle);
+
+/**
+ *     This function allocates memory for streamrecorder.
+ *
+ *     @param[in]      hstreamrecorder Specifies the streamrecorder  handle
+ *     @return         This function returns zero on success, or negative value with error code.
+ *     @remarks        This function can  be called successfully when current state is MM_streamrecorder_STATE_NULL @n
+ *                     and  the state of the streamrecorder  will become MM_streamrecorder_STATE_READY. @n
+ *                     Otherwise, this function will return MM_ERROR_streamrecorder_INVALID_CONDITION.
+ *     @see            _mmstreamrecorder_unrealize
+ *     @pre            MM_streamrecorder_STATE_NULL
+ *     @post           MM_streamrecorder_STATE_READY
+ */
+int _mmstreamrecorder_realize(MMHandleType hstreamrecorder);
+
+/**
+ *     This function free allocated memory for streamrecorder.
+ *
+ *     @param[in]      hstreamrecorder Specifies the streamrecorder  handle
+ *     @return         This function returns zero on success, or negative value with error code.
+ *     @remarks        This function release all resources which are allocated for the streamrecorder engine.@n
+ *                     This function can  be called successfully when current state is MM_streamrecorder_STATE_READY and  @n
+ *                     the state of the streamrecorder  will become MM_streamrecorder_STATE_NULL. @n
+ *                     Otherwise, this function will return MM_ERROR_streamrecorder_INVALID_CONDITION.
+ *     @see            _mmstreamrecorder_realize
+ *     @pre            MM_streamrecorder_STATE_READY
+ *     @post           MM_streamrecorder_STATE_NULL
+ */
+int _mmstreamrecorder_unrealize(MMHandleType hstreamrecorder);
+
+/**
+ *     This function is to start previewing.
+ *
+ *     @param[in]      hstreamrecorder Specifies the streamrecorder  handle
+ *     @return         This function returns zero on success, or negative value with error code.
+ *     @remarks        This function can  be called successfully when current state is MM_streamrecorder_STATE_READY and  @n
+ *                     the state of the streamrecorder  will become MM_streamrecorder_STATE_PREPARE. @n
+ *                     Otherwise, this function will return MM_ERROR_streamrecorder_INVALID_CONDITION.
+ *     @see            _mmstreamrecorder_stop
+ */
+int _mmstreamrecorder_record(MMHandleType hstreamrecorder);
+
+int _mmstreamrecorder_push_stream_buffer(MMHandleType handle, MMStreamRecorderStreamType streamtype, unsigned long timestamp, void *buffer, int size);
+
+/**
+ *     This function is to pause video and audio recording
+ *
+ *     @param[in]      hstreamrecorder Specifies the streamrecorder  handle
+ *     @return         This function returns zero on success, or negative value with error code.
+ *     @remarks        This function can  be called successfully when current state is MM_streamrecorder_STATE_RECORDING and  @n
+ *                     the  state of the streamrecorder  will become MM_streamrecorder_STATE_PAUSED.@n
+ *                     Otherwise, this function will return MM_ERROR_streamrecorder_INVALID_CONDITION.@n
+ *     @see            _mmstreamrecorder_record
+ */
+int _mmstreamrecorder_pause(MMHandleType hstreamrecorder);
+
+/**
+ *     This function is to stop video and audio  recording and  save results.
+ *
+ *     @param[in]      hstreamrecorder Specifies the streamrecorder  handle
+ *     @return         This function returns zero on success, or negative value with error code.
+ *     @remarks        This function can  be called successfully when current state is @n
+ *                     MM_streamrecorder_STATE_PAUSED or MM_streamrecorder_STATE_RECORDING and  @n
+ *                     the state of the streamrecorder  will become MM_streamrecorder_STATE_PREPARE. @n
+ *                     Otherwise, this function will return MM_ERROR_streamrecorder_INVALID_CONDITION
+ *     @see            _mmstreamrecorder_cancel
+ */
+int _mmstreamrecorder_commit(MMHandleType hstreamrecorder);
+
+/**
+ *     This function is to stop video and audio recording and do not save results.
+ *
+ *     @param[in]      hstreamrecorder Specifies the streamrecorder  handle
+ *     @return         This function returns zero on success, or negative value with error code.
+ *     @remarks        This function can  be called successfully when current state is @n
+ *                     MM_streamrecorder_STATE_PAUSED or MM_streamrecorder_STATE_RECORDING and  @n
+ *                     the state of the streamrecorder  will become MM_streamrecorder_STATE_PREPARE. @n
+ *                     Otherwise, this function will return MM_ERROR_streamrecorder_INVALID_CONDITION.
+ *     @see            _mmstreamrecorder_commit
+ */
+int _mmstreamrecorder_cancel(MMHandleType hstreamrecorder);
+
+/**
+ *     This function is to set callback for receiving messages from streamrecorder.
+ *
+ *     @param[in]      hstreamrecorder Specifies the streamrecorder  handle
+ *     @param[in]      callback        Specifies the function pointer of callback function
+ *     @param[in]      user_data       Specifies the user poiner for passing to callback function
+ *
+ *     @return         This function returns zero on success, or negative value with error code.
+ *     @remarks        typedef bool (*mm_message_callback) (int msg, mm_messageType *param, void *user_param);@n
+ *             @n
+ *             typedef union                           @n
+ *             {                                                       @n
+ *                     int code;                               @n
+ *                     struct                                  @n
+ *                     {                                               @n
+ *                             int total;                      @n
+ *                             int elapsed;            @n
+ *                     } time;                                 @n
+ *                     struct                                  @n
+ *                     {                                               @n
+ *                             int previous;           @n
+ *                             int current;                    @n
+ *                     } state;                                        @n
+ *             } mm_message_type;      @n
+ *                                                                     @n
+ *             If a  message value for mm_message_callback is MM_MESSAGE_STATE_CHANGED, @n
+ *             state value in mm_message_type  will be a mmstreamrecorder_state_type enum value;@n
+ *             @n
+ *             If  a message value for mm_message_callback is MM_MESSAGE_ERROR,  @n
+ *             the code value in mm_message_type will be a mmplayer_error_type enum value;
+ *
+ *     @see            mm_message_type,  mmstreamrecorder_state_type,  mmstreamrecorder_error_type
+ */
+int _mmstreamrecorder_set_message_callback(MMHandleType hstreamrecorder, MMMessageCallback callback, void *user_data);
+
+/**
+ * This function allocates structure of subsidiary attributes.
+ *
+ * @param[in]  type            Allocation type of streamrecorder context.
+ * @return     This function returns structure pointer on success, NULL value on failure.
+ * @remarks
+ * @see                _mmstreamrecorder_dealloc_subcontext()
+ *
+ */
+int _mmstreamrecorder_alloc_subcontext(MMHandleType handle);
+
+int _mmstreamrecorder_alloc_subcontext_videoinfo(MMHandleType handle);
+
+int _mmstreamrecorder_alloc_subcontext_audioinfo(MMHandleType handle);
+
+int _mmstreamrecorder_alloc_subcontext_fileinfo(MMHandleType handle);
+
+/**
+ * This function releases structure of subsidiary attributes.
+ *
+ * @param[in]  sc              Handle of streamrecorder subcontext.
+ * @return     void
+ * @remarks
+ * @see                _mmstreamrecorder_alloc_subcontext()
+ *
+ */
+void _mmstreamrecorder_dealloc_subcontext(MMHandleType handle);
+
+/**
+ * This function sets command function according to the type.
+ *
+ * @param[in]  handle          Handle of streamrecorder context.
+ * @param[in]  type            Allocation type of streamrecorder context.
+ * @return     This function returns MM_ERROR_NONE on success, or other values with error code.
+ * @remarks
+ * @see                __mmstreamrecorder_video_command(), __mmstreamrecorder_audio_command(), __mmstreamrecorder_image_command()
+ *
+ */
+void _mmstreamrecorder_set_functions(MMHandleType handle);
+
+void _mmstreamrecorder_unset_functions(MMHandleType handle);
+
+#ifdef __cplusplus
+}
+#endif
+#endif                                                 /* __MM_streamrecorder_INTERNAL_H__ */
diff --git a/src/include/mm_streamrecorder_recorder.h b/src/include/mm_streamrecorder_recorder.h
new file mode 100644 (file)
index 0000000..f4f74db
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * libmm-streamrecorder
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Hyuntae Kim <ht1211.kim@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_STREAMRECORDER_RECORDER_H__
+#define __MM_STREAMRECORDER_RECORDER_H__
+
+/*=======================================================================================
+| INCLUDE FILES                                                                                |
+========================================================================================*/
+#include <mm_types.h>
+#include "mm_streamrecorder_gstdispatch.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*=======================================================================================
+| GLOBAL DEFINITIONS AND DECLARATIONS FOR STREAMCORDER                                 |
+========================================================================================*/
+
+/*=======================================================================================
+| MACRO DEFINITIONS                                                                    |
+========================================================================================*/
+
+/*=======================================================================================
+| ENUM DEFINITIONS                                                                     |
+========================================================================================*/
+
+/*=======================================================================================
+| STRUCTURE DEFINITIONS                                                                        |
+========================================================================================*/
+
+/*=======================================================================================
+| CONSTANT DEFINITIONS                                                                 |
+========================================================================================*/
+
+/*=======================================================================================
+| STATIC VARIABLES                                                                     |
+========================================================================================*/
+
+/*=======================================================================================
+| EXTERN GLOBAL VARIABLE                                                               |
+========================================================================================*/
+
+/*=======================================================================================
+| GLOBAL FUNCTION PROTOTYPES                                                           |
+========================================================================================*/
+
+/**
+ * This function create main pipeline according to type.
+ *
+ * @param[in]  handle          Handle of streamrecorder context.
+ * @param[in]  type            Allocation type of streamrecorder context.
+ * @return     This function returns zero on success, or negative value with error code.
+ * @remarks
+ * @see        _mmstreamrecorder_destroy_pipeline()
+ *
+ */
+int _mmstreamrecorder_create_pipeline(MMHandleType handle);
+
+/**
+ * This function release all element of main pipeline according to type.
+ *
+ * @param[in]  handle          Handle of streamrecorder context.
+ * @param[in]  type            Allocation type of streamrecorder context.
+ * @return     void
+ * @remarks
+ * @see                _mmstreamrecorder_create_pipeline()
+ *
+ */
+void _mmstreamrecorder_destroy_pipeline(MMHandleType handle);
+
+/**
+ * This function creates recorder pipeline.
+ * When application creates initial pipeline, there are only bins for preview.
+ * If application wants to record, recorder pipeline should be created.
+ *
+ * @param[in]  handle          Handle of streamrecorder context.
+ * @return     This function returns MM_ERROR_NONE on success, or the other values on error.
+ * @remarks
+ */
+int _mmstreamrecorder_create_recorder_pipeline(MMHandleType handle);
+
+/**
+ * This function creates bin of audio source.
+ * Basically, main pipeline of streamrecorder is composed of several bin(a bundle
+ *  of elements). Each bin operates its own function. This bin has a roll
+ * inputting audio data from audio source(such as mike).
+ *
+ * @param[in]  handle          Handle of streamrecorder context.
+ * @return     This function returns MM_ERROR_NONE on success, or the other values on error.
+ * @remarks
+ */
+int _mmstreamrecorder_create_audiosrc_bin(MMHandleType handle);
+
+int _mmstreamrecorder_destroy_audiosrc_bin(MMHandleType handle);
+
+/**
+ * This function creates outputsink bin.
+ *
+ * @param[in]  handle          Handle of streamrecorder context.
+ * @param[in]  profile         profile of encodesinkbin.
+ * @return     This function returns MM_ERROR_NONE on success, or the other values on error.
+ * @remarks
+ */
+int _mmstreamrecorder_create_encodesink_bin(MMHandleType handle, MMStreamRecorderEncodebinProfile profile);
+
+int _mmstreamrecorder_destroy_encodesink_bin(MMHandleType handle);
+
+/**
+ * This function handles EOS(end of stream) when commit video recording.
+ *
+ * @param[in]  handle          Handle of streamrecorder context.
+ * @return     This function returns TRUE on success, or FALSE on failure.
+ * @remarks
+ * @see                _mmstreamrecorder_set_functions()
+ */
+int _mmstreamrecorder_video_handle_eos(MMHandleType handle);
+
+int _mmstreamrecorder_destroy_recorder_pipeline(MMHandleType handle);
+
+// COMMAND
+int _mmstreamrecorder_video_command(MMHandleType handle, int command);
+
+/**
+ * This function creates audio pipeline for audio recording.
+ *
+ * @param[in]  handle          Handle of streamrecorder.
+ * @return     This function returns MM_ERROR_NONE on success, or others on failure.
+ * @remarks
+ * @see                _mmstreamrecorder_destroy_audio_pipeline()
+ *
+ */
+int _mmstreamrecorder_create_audio_pipeline(MMHandleType handle);
+
+/**
+ * This function destroy audio pipeline.
+ *
+ * @param[in]  handle          Handle of streamrecorder.
+ * @return     void
+ * @remarks
+ * @see                _mmstreamrecorder_destroy_pipeline()
+ *
+ */
+void _mmstreamrecorder_destroy_audio_pipeline(MMHandleType handle);
+
+/**
+ * This function runs command for audio recording.
+ *
+ * @param[in]  handle          Handle of streamrecorder.
+ * @param[in]  command         audio recording command.
+ * @return     This function returns MM_ERROR_NONE on success, or others on failure.
+ * @remarks
+ * @see
+ *
+ */
+int _mmstreamrecorder_audio_command(MMHandleType handle, int command);
+
+/**
+ * This function handles EOS(end of stream) when audio recording is finished.
+ *
+ * @param[in]  handle          Handle of streamrecorder.
+ * @return     This function returns TRUE on success, or FALSE on failure.
+ * @remarks
+ * @see
+ *
+ */
+int _mmstreamrecorder_audio_handle_eos(MMHandleType handle);
+
+int _mmstreamrecorder_create_audiop_with_encodebin(MMHandleType handle);
+
+int _mmstreamrecorder_push_videostream_buffer(MMHandleType handle, unsigned long timestamp, GstBuffer *buffer, int size);
+int _mmstreamrecorder_push_audiostream_buffer(MMHandleType handle, unsigned long timestamp, GstBuffer *buffer, int size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MM_STREAMRECORDER_RECORDER_H__ */
diff --git a/src/include/mm_streamrecorder_util.h b/src/include/mm_streamrecorder_util.h
new file mode 100644 (file)
index 0000000..f0806eb
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+ * libmm-streamrecorder
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Hyuntae Kim <ht1211.kim@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_STREAMRECORDER_UTIL_H__
+#define __MM_STREAMRECORDER_UTIL_H__
+
+/*=======================================================================================
+| INCLUDE FILES                                                                                |
+========================================================================================*/
+#include <gst/gst.h>
+#include <gst/gstutils.h>
+#include <gst/gstpad.h>
+#include "mm_debug.h"
+#include <glib.h>
+#include<stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*=======================================================================================
+| GLOBAL DEFINITIONS AND DECLARATIONS FOR STREAMRECORDER                                       |
+========================================================================================*/
+
+/*=======================================================================================
+| MACRO DEFINITIONS                                                                    |
+========================================================================================*/
+#ifndef CLEAR
+#define CLEAR(x)            memset (&(x), 0, sizeof (x))
+#endif
+
+#define SAFE_FREE(x) \
+       if (x) {\
+               g_free(x); \
+               x = NULL; \
+       }
+
+#define _mmstreamrec_dbg_verb(fmt, args...)  debug_verbose(" "fmt"\n", ##args);
+#define _mmstreamrec_dbg_log(fmt, args...)   debug_log(" "fmt"\n", ##args);
+#define _mmstreamrec_dbg_warn(fmt, args...)  debug_warning(" "fmt"\n", ##args);
+#define _mmstreamrec_dbg_err(fmt, args...)   debug_error(" "fmt"\n", ##args);
+#define _mmstreamrec_dbg_crit(fmt, args...)  debug_critical(" "fmt"\n", ##args);
+
+/**
+ *     Macro for checking validity and debugging
+ */
+#define mmf_return_if_fail( expr )     \
+       if( expr ){}                                    \
+       else                                            \
+       {                                                       \
+               _mmstreamrec_dbg_err( "failed [%s]", #expr);    \
+               return;                                         \
+       };
+
+/**
+ *     Macro for checking validity and debugging
+ */
+#define mmf_return_val_if_fail( expr, val )    \
+       if( expr ){}                                    \
+       else                                            \
+       {                                                       \
+               _mmstreamrec_dbg_err("failed [%s]", #expr);     \
+               return( val );                                          \
+       };
+
+/**
+ *     Minimum integer value
+ */
+#define _MMSTREAMRECORDER_MIN_INT      (INT_MIN)
+
+/**
+ *     Maximum integer value
+ */
+#define _MMSTREAMRECORDER_MAX_INT      (INT_MAX)
+
+/**
+ *     Minimum double value
+ */
+#define _MMSTREAMRECORDER_MIN_DOUBLE   (DBL_MIN)
+
+/**
+ *     Maximum integer value
+ */
+#define _MMSTREAMRECORDER_MAX_DOUBLE   (DBL_MAX)
+
+// TODO : MOVE OTHERS
+enum {
+       PUSH_ENCODING_BUFFER_INIT = 0,
+       PUSH_ENCODING_BUFFER_RUN,
+       PUSH_ENCODING_BUFFER_STOP,
+};
+
+#define FPUTC_CHECK(x_char, x_file)\
+{\
+       if (fputc(x_char, x_file) == EOF) \
+       {\
+               _mmstreamrec_dbg_err("[Critical] fputc() returns fail.\n");     \
+               return FALSE;\
+       }\
+}
+
+#define FPUTS_CHECK(x_str, x_file)\
+{\
+       if (fputs(x_str, x_file) == EOF) \
+       {\
+               _mmstreamrec_dbg_err("[Critical] fputs() returns fail.\n");\
+               SAFE_FREE(str); \
+               return FALSE;\
+       }\
+}
+
+#if 0
+#define MM_STREAMRECORDER_INI_DEFAULT_PATH     "/usr/etc/mmfw_transcode.ini"
+#define STREAMRECORDER_INI_MAX_STRLEN  100
+#endif
+/*=======================================================================================
+| ENUM DEFINITIONS                                                                     |
+========================================================================================*/
+#define MAX_ERROR_MESSAGE_LEN         128
+#define MM_STREAMRECORDER_MIN_LOG_COUNT 10
+
+/*=======================================================================================
+| STRUCTURE DEFINITIONS                                                                        |
+========================================================================================*/
+#if 0
+       typedef struct __mm_streamrecorder_ini {
+               /* video converter element */
+               gchar video_converter_element[STREAMRECORDER_INI_MAX_STRLEN];
+       } mm_streamrecorder_ini_t;
+#endif
+
+/*=======================================================================================
+| CONSTANT DEFINITIONS                                                                 |
+========================================================================================*/
+
+/*=======================================================================================
+| GLOBAL FUNCTION PROTOTYPES                                                           |
+========================================================================================*/
+
+/* Pixel format */
+
+int _mmstreamrecorder_get_pixel_format(GstCaps *caps);
+int _mmstreamrecorder_get_pixtype(unsigned int fourcc);
+unsigned int _mmstreamrecorder_get_fourcc(int pixtype, int codectype, int use_zero_copy_format);
+
+/* Recording */
+/* find top level tag only, do not use this function for finding sub level tags. tag_fourcc is Four-character-code (FOURCC) */
+gint32 _mmstreamrecorder_double_to_fix(gdouble d_number);
+
+/* File system */
+int _mmstreamrecorder_get_freespace(const gchar *path, guint64 *free_space);
+int _mmstreamrecorder_get_file_size(const char *filename, guint64 *size);
+
+/* Debug */
+void _mmstreamrecorder_err_trace_write(char *str_filename, char *func_name, int line_num, char *fmt, ...);
+
+guint16 get_language_code(const char *str);
+gchar *str_to_utf8(const gchar *str);
+inline gboolean write_tag(FILE *f, const gchar *tag);
+inline gboolean write_to_32(FILE *f, guint val);
+inline gboolean write_to_16(FILE *f, guint val);
+inline gboolean write_to_24(FILE *f, guint val);
+#ifdef __cplusplus
+}
+#endif
+#endif                                                 /* __MM_STREAMRECORDER_UTIL_H__ */
diff --git a/src/include/mm_streamrecorder_video.h b/src/include/mm_streamrecorder_video.h
new file mode 100644 (file)
index 0000000..6e8329e
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * libmm-streamrecorder
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Hyuntae Kim <ht1211.kim@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_STREAMRECORDER_VIDEO_H__
+#define __MM_STREAMRECORDER_VIDEO_H__
+
+/*=======================================================================================
+| INCLUDE FILES                                                                                |
+========================================================================================*/
+#include <glib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*=======================================================================================
+| STRUCTURE DEFINITIONS                                                                        |
+========================================================================================*/
+/**
+ * StreamRecorder VideoInfo information for video mode
+ */
+typedef struct {
+       int iVideoEncoder;              /**< Video Encoder */
+       gboolean b_commiting;   /**< Is it commiting now? */
+       guint64 video_frame_count;
+                                                       /**< current video frame */
+       guint64 filesize;       /**< current file size */
+       guint64 max_size;       /**< max recording size */
+       guint64 max_time;       /**< max recording time */
+} _MMStreamRecorderVideoInfo;
+
+/*=======================================================================================
+| GLOBAL FUNCTION PROTOTYPES                                                           |
+========================================================================================*/
+
+int _mmstreamrecorder_check_videocodec_fileformat_compatibility(unsigned int video_codec, unsigned int file_format);
+
+#ifdef __cplusplus
+}
+#endif
+#endif                                                 /* __MM_STREAMRECORDER_VIDEO_H__ */
diff --git a/src/mm_streamrecorder.c b/src/mm_streamrecorder.c
new file mode 100644 (file)
index 0000000..7e867fa
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+ * libmm-streamrecorder
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Hyuntae Kim <ht1211.kim@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 <stdio.h>
+#include <string.h>
+
+#include <mm_error.h>
+
+#include <mm_attrs_private.h>
+#include "mm_streamrecorder.h"
+#include "mm_streamrecorder_internal.h"
+#include "mm_streamrecorder_attribute.h"
+
+/*===============================================================================
+|  FUNCTION DEFINITIONS                                                                |
+===============================================================================*/
+/*-------------------------------------------------------------------------------
+|    GLOBAL FUNCTION DEFINITIONS:                                              |
+-------------------------------------------------------------------------------*/
+int mm_streamrecorder_create(MMHandleType *streamrecorder)
+{
+       int error = MM_ERROR_NONE;
+
+       mmf_return_val_if_fail((void *)streamrecorder, MM_ERROR_STREAMRECORDER_INVALID_ARGUMENT);
+
+       _mmstreamrec_dbg_log("");
+
+       error = _mmstreamrecorder_create(streamrecorder);
+
+       _mmstreamrec_dbg_log("END");
+
+       return error;
+}
+
+
+int mm_streamrecorder_get_state(MMHandleType streamrecorder, MMStreamRecorderStateType *status)
+{
+       int ret = MM_ERROR_NONE;
+
+       mmf_return_val_if_fail((void *)streamrecorder, MM_ERROR_STREAMRECORDER_INVALID_ARGUMENT);
+
+       mmf_return_val_if_fail((void *)status, MM_ERROR_STREAMRECORDER_INVALID_ARGUMENT);
+
+       _mmstreamrec_dbg_err("");
+
+       *status = _mmstreamrecorder_get_state(streamrecorder);
+
+       return ret;
+
+}
+
+int mm_streamrecorder_destroy(MMHandleType streamrecorder)
+{
+       int error = MM_ERROR_NONE;
+
+       mmf_return_val_if_fail((void *)streamrecorder, MM_ERROR_STREAMRECORDER_INVALID_ARGUMENT);
+
+       _mmstreamrec_dbg_log("");
+
+       error = _mmstreamrecorder_destroy(streamrecorder);
+
+       _mmstreamrec_dbg_log("END!!!");
+
+       return error;
+}
+
+int mm_streamrecorder_realize(MMHandleType streamrecorder)
+{
+       int error = MM_ERROR_NONE;
+
+       mmf_return_val_if_fail((void *)streamrecorder, MM_ERROR_STREAMRECORDER_INVALID_ARGUMENT);
+
+       _mmstreamrec_dbg_log("");
+
+       error = _mmstreamrecorder_realize(streamrecorder);
+
+       _mmstreamrec_dbg_log("END");
+
+       return error;
+}
+
+int mm_streamrecorder_pause(MMHandleType streamrecorder)
+{
+       int error = MM_ERROR_NONE;
+
+       mmf_return_val_if_fail((void *)streamrecorder, MM_ERROR_STREAMRECORDER_INVALID_ARGUMENT);
+
+       _mmstreamrec_dbg_err("");
+
+       error = _mmstreamrecorder_pause(streamrecorder);
+
+       _mmstreamrec_dbg_err("END");
+
+       return error;
+}
+
+
+int mm_streamrecorder_unrealize(MMHandleType streamrecorder)
+{
+       int error = MM_ERROR_NONE;
+
+       mmf_return_val_if_fail((void *)streamrecorder, MM_ERROR_STREAMRECORDER_INVALID_ARGUMENT);
+
+       _mmstreamrec_dbg_log("");
+
+       error = _mmstreamrecorder_unrealize(streamrecorder);
+
+       _mmstreamrec_dbg_log("END");
+
+       return error;
+}
+
+int mm_streamrecorder_record(MMHandleType streamrecorder)
+{
+       int error = MM_ERROR_NONE;
+
+       mmf_return_val_if_fail((void *)streamrecorder, MM_ERROR_STREAMRECORDER_INVALID_ARGUMENT);
+
+       _mmstreamrec_dbg_log("");
+
+       error = _mmstreamrecorder_record(streamrecorder);
+
+       _mmstreamrec_dbg_log("END");
+
+       return error;
+}
+
+int mm_streamrecorder_push_stream_buffer(MMHandleType streamrecorder, MMStreamRecorderStreamType streamtype, unsigned long timestamp, void *buffer, int size)
+{
+       int error = MM_ERROR_NONE;
+
+       mmf_return_val_if_fail((void *)streamrecorder, MM_ERROR_STREAMRECORDER_INVALID_ARGUMENT);
+
+       _mmstreamrec_dbg_log("");
+
+       error = _mmstreamrecorder_push_stream_buffer(streamrecorder, streamtype, timestamp, buffer, size);
+
+       _mmstreamrec_dbg_log("END");
+
+       return error;
+}
+
+int mm_streamrecorder_commit(MMHandleType streamrecorder)
+{
+       int error = MM_ERROR_NONE;
+
+       mmf_return_val_if_fail((void *)streamrecorder, MM_ERROR_STREAMRECORDER_INVALID_ARGUMENT);
+
+       _mmstreamrec_dbg_log("");
+
+       error = _mmstreamrecorder_commit(streamrecorder);
+
+       _mmstreamrec_dbg_log("END");
+
+       return error;
+}
+
+int mm_streamrecorder_cancel(MMHandleType streamrecorder)
+{
+       int error = MM_ERROR_NONE;
+
+       mmf_return_val_if_fail((void *)streamrecorder, MM_ERROR_STREAMRECORDER_INVALID_ARGUMENT);
+
+       _mmstreamrec_dbg_log("");
+
+       error = _mmstreamrecorder_cancel(streamrecorder);
+
+       _mmstreamrec_dbg_log("END");
+
+       return error;
+}
+
+int mm_streamrecorder_set_message_callback(MMHandleType streamrecorder, MMMessageCallback callback, void *user_data)
+{
+       int error = MM_ERROR_NONE;
+
+       mmf_return_val_if_fail((void *)streamrecorder, MM_ERROR_STREAMRECORDER_INVALID_ARGUMENT);
+
+       error = _mmstreamrecorder_set_message_callback(streamrecorder, callback, user_data);
+
+       return error;
+}
+
+int mm_streamrecorder_get_attributes(MMHandleType streamrecorder, char **err_attr_name, const char *attribute_name, ...)
+{
+       va_list var_args;
+       int ret = MM_ERROR_NONE;
+
+       return_val_if_fail(attribute_name, MM_ERROR_COMMON_INVALID_ARGUMENT);
+
+       va_start(var_args, attribute_name);
+       ret = _mmstreamrecorder_get_attributes(streamrecorder, err_attr_name, attribute_name, var_args);
+       va_end(var_args);
+
+       return ret;
+}
+
+int mm_streamrecorder_set_attributes(MMHandleType streamrecorder, char **err_attr_name, const char *attribute_name, ...)
+{
+       va_list var_args;
+       int ret = MM_ERROR_NONE;
+
+       return_val_if_fail(attribute_name, MM_ERROR_COMMON_INVALID_ARGUMENT);
+
+       va_start(var_args, attribute_name);
+       ret = _mmstreamrecorder_set_attributes(streamrecorder, err_attr_name, attribute_name, var_args);
+       va_end(var_args);
+
+       return ret;
+}
diff --git a/src/mm_streamrecorder_attribute.c b/src/mm_streamrecorder_attribute.c
new file mode 100644 (file)
index 0000000..d8bc8fd
--- /dev/null
@@ -0,0 +1,1153 @@
+/*
+ * libmm-streamrecorder
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Hyuntae Kim <ht1211.kim@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_error.h>
+
+#include "mm_streamrecorder_util.h"
+#include "mm_streamrecorder_attribute.h"
+#include "mm_streamrecorder_gstdispatch.h"
+
+/*-----------------------------------------------------------------------
+|    MACRO DEFINITIONS:                                                        |
+-----------------------------------------------------------------------*/
+#define MM_STREAMRECORDER_ATTRIBUTE_MAX_VALUE  15
+#define MM_STREAMRECORDER_RESOLUTION_MAX_VALUE 4080
+
+/*---------------------------------------------------------------------------------------
+|    GLOBAL VARIABLE DEFINITIONS for internal                                          |
+---------------------------------------------------------------------------------------*/
+
+/* basic attributes' info */
+mm_streamrecorder_attr_construct_info stream_attrs_const_info[] = {
+       /* 0 */
+       {
+        MM_STR_VIDEO_BUFFER_TYPE,      /* ID */
+        "videobuffer-type",            /* Name */
+        MMF_VALUE_TYPE_INT,            /* Type */
+        MM_ATTRS_FLAG_RW,                      /* Flag */
+        {(void *)MM_STREAMRECORDER_VIDEO_TYPE_TBM_BO}, /* Default value */
+        MM_ATTRS_VALID_TYPE_INT_RANGE, /* Validity type */
+        MM_STREAMRECORDER_VIDEO_TYPE_TBM_BO,   /* Validity val1 (min, *array,...) */
+        MM_STREAMRECORDER_VIDEO_TYPE_NORMAL_BUFFER,    /* Validity val2 (max, count, ...) */
+        NULL,                                          /* Runtime setting function of the attribute */
+        },
+       /* 1  */
+       {MM_STR_VIDEO_FORMAT,
+        "videosource-format",
+        MMF_VALUE_TYPE_INT,
+        MM_ATTRS_FLAG_RW,
+        {(void *)MM_STREAMRECORDER_INPUT_FORMAT_NV12},
+        MM_ATTRS_VALID_TYPE_INT_RANGE,
+        MM_STREAMRECORDER_INPUT_FORMAT_INVALID,
+        MM_STREAMRECORDER_INPUT_FORMAT_NUM,
+        NULL,
+        },
+       /* 2  */
+       {
+        MM_STR_VIDEO_FRAMERATE,
+        "video-framerate",
+        MMF_VALUE_TYPE_INT,
+        MM_ATTRS_FLAG_RW,
+        {(void *)0},
+        MM_ATTRS_VALID_TYPE_INT_RANGE,
+        0,
+        _MMSTREAMRECORDER_MAX_INT,
+        NULL,
+        },
+       /* 3  */
+       {
+        MM_STR_VIDEO_ENCODER_BITRATE,
+        "video-bitrate",
+        MMF_VALUE_TYPE_INT,
+        MM_ATTRS_FLAG_RW,
+        {(void *)0},
+        MM_ATTRS_VALID_TYPE_INT_RANGE,
+        0,
+        _MMSTREAMRECORDER_MAX_INT,
+        NULL,    /*_mmstreamrecorder_commit_video_bitrate, */
+        },
+       /* 4  */
+       {
+        MM_STR_VIDEO_RESOLUTION_WIDTH,
+        "video-resolution-width",
+        MMF_VALUE_TYPE_INT,
+        MM_ATTRS_FLAG_RW,
+        {(void *)0},
+        MM_ATTRS_VALID_TYPE_INT_ARRAY,
+        0,
+        0,
+        NULL,
+        },
+       /* 5  */
+       {
+        MM_STR_VIDEO_RESOLUTION_HEIGHT,
+        "video-resolution-height",
+        MMF_VALUE_TYPE_INT,
+        MM_ATTRS_FLAG_RW,
+        {(void *)0},
+        MM_ATTRS_VALID_TYPE_INT_ARRAY,
+        0,
+        0,
+        NULL,
+        },
+       /* 6  */
+       {
+        MM_STR_AUDIO_FORMAT,
+        "audio-source-format",
+        MMF_VALUE_TYPE_INT,
+        MM_ATTRS_FLAG_RW,
+        {(void *)MM_STREAMRECORDER_AUDIO_FORMAT_PCM_S16_LE},
+        MMF_VALUE_TYPE_INT,
+        MM_STREAMRECORDER_AUDIO_FORMAT_PCM_U8,
+        MM_STREAMRECORDER_AUDIO_FORMAT_PCM_S16_LE,
+        _mmstreamrecorder_commit_audio_bitformat,
+        },
+       /* 7  */
+       {
+        MM_STR_AUDIO_ENCODER_BITRATE,
+        "audio-bitrate",
+        MMF_VALUE_TYPE_INT,
+        MM_ATTRS_FLAG_RW,
+        {(void *)128000},
+        MM_ATTRS_VALID_TYPE_INT_RANGE,
+        0,
+        _MMSTREAMRECORDER_MAX_INT,
+        _mmstreamrecorder_commit_audio_bitrate,
+        },
+       /* 8  */
+       {
+        MM_STR_AUDIO_SAMPLERATE,
+        "audio-samplerate",
+        MMF_VALUE_TYPE_INT,
+        MM_ATTRS_FLAG_RW,
+        {(void *)0},
+        MM_ATTRS_VALID_TYPE_INT_RANGE,
+        0,
+        _MMSTREAMRECORDER_MAX_INT,
+        _mmstreamrecorder_commit_audio_samplingrate,
+        },
+       /* 9  */
+       {
+        MM_STR_VIDEO_ENCODER,
+        "video-encoder",
+        MMF_VALUE_TYPE_INT,
+        MM_ATTRS_FLAG_RW,
+        {(void *)0},
+        MM_ATTRS_VALID_TYPE_INT_ARRAY,
+        0,
+        0,
+        _mmstreamrecorder_commit_video_encoder,
+        },
+       /* 10  */
+       {
+        MM_STR_AUDIO_ENCODER,
+        "audio-encoder",
+        MMF_VALUE_TYPE_INT,
+        MM_ATTRS_FLAG_RW,
+        {(void *)0},
+        MM_ATTRS_VALID_TYPE_INT_ARRAY,
+        0,
+        0,
+        _mmstreamrecorder_commit_audio_encoder,
+        },
+       /* 11  */
+       {
+        MM_STR_AUDIO_CHENNEL_COUNT,
+        "audio-channel-count",
+        MMF_VALUE_TYPE_INT,
+        MM_ATTRS_FLAG_RW,
+        {(void *)2},
+        MM_ATTRS_VALID_TYPE_INT_RANGE,
+        0,
+        _MMSTREAMRECORDER_MAX_INT,
+        _mmstreamrecorder_commit_audio_channel,
+        },
+       /* 12  */
+       {
+        MM_STR_FILE_FORMAT,
+        "file-format",
+        MMF_VALUE_TYPE_INT,
+        MM_ATTRS_FLAG_RW,
+        {(void *)0},
+        MM_ATTRS_VALID_TYPE_INT_ARRAY,
+        0,
+        0,
+        NULL,
+        },
+       /* 13  */
+       {
+        MM_STR_TARGET_FILE_NAME,
+        "filename",
+        MMF_VALUE_TYPE_STRING,
+        MM_ATTRS_FLAG_RW,
+        {NULL},
+        MM_ATTRS_VALID_TYPE_NONE,
+        0,
+        0,
+        NULL,
+        },
+       /* 14  */
+       {
+        MM_STR_VIDEO_ENABLE,
+        "video-enable",
+        MMF_VALUE_TYPE_INT,
+        MM_ATTRS_FLAG_RW,
+        {(void *)FALSE},
+        MM_ATTRS_VALID_TYPE_NONE,
+        0,
+        _MMSTREAMRECORDER_MAX_INT,
+        _mmstreamrecorder_commit_video_enable,
+        },
+       /* 15  */
+       {
+        MM_STR_AUDIO_ENABLE,
+        "audio-enable",
+        MMF_VALUE_TYPE_INT,
+        MM_ATTRS_FLAG_RW,
+        {(void *)FALSE},
+        MM_ATTRS_VALID_TYPE_NONE,
+        0,
+        _MMSTREAMRECORDER_MAX_INT,
+        _mmstreamrecorder_commit_audio_enable,
+        },
+       /* 16 */
+       {
+        MM_STR_MODE,
+        "recorder-mode",
+        MMF_VALUE_TYPE_INT,
+        MM_ATTRS_FLAG_RW,
+        {(void *)MM_STREAMRECORDER_MODE_MEDIABUFFER},
+        MM_ATTRS_VALID_TYPE_NONE,
+        0,
+        _MMSTREAMRECORDER_MAX_INT,
+        NULL,
+        },
+       /*17*/
+       {
+        MM_STR_TARGET_MAX_SIZE,
+        "target-max-size",
+        MMF_VALUE_TYPE_INT,
+        MM_ATTRS_FLAG_RW,
+        {(void *)0},
+        MM_ATTRS_VALID_TYPE_INT_RANGE,
+        0,
+        _MMSTREAMRECORDER_MAX_INT,
+        NULL,
+       },
+       /*18*/
+       {
+        MM_STR_TARGET_TIME_LIMIT,
+        "target-time-limit",
+        MMF_VALUE_TYPE_INT,
+        MM_ATTRS_FLAG_RW,
+        {(void *)0},
+        MM_ATTRS_VALID_TYPE_INT_RANGE,
+        0,
+        _MMSTREAMRECORDER_MAX_INT,
+        NULL,
+       },
+
+};
+
+/*-----------------------------------------------------------------------
+|    LOCAL VARIABLE DEFINITIONS for internal                           |
+-----------------------------------------------------------------------*/
+
+/*-----------------------------------------------------------------------
+|    LOCAL FUNCTION PROTOTYPES:                                                |
+-----------------------------------------------------------------------*/
+/* STATIC INTERNAL FUNCTION */
+static int __mmstreamrecorder_set_conf_to_valid_info(MMHandleType handle)
+{
+       int *format = NULL;
+       int total_count = 0;
+
+       /* Video width */
+       total_count = _mmstreamrecorder_get_available_format(handle, KEYWORD_VIDEO_WIDTH, &format);
+       stream_attrs_const_info[MM_STR_VIDEO_RESOLUTION_WIDTH].validity_value1 = (int)format;
+       stream_attrs_const_info[MM_STR_VIDEO_RESOLUTION_WIDTH].validity_value2 = (int)total_count;
+
+       /* Video height */
+       total_count = _mmstreamrecorder_get_available_format(handle, KEYWORD_VIDEO_HEIGHT,  &format);
+       stream_attrs_const_info[MM_STR_VIDEO_RESOLUTION_HEIGHT].validity_value1 = (int)format;
+       stream_attrs_const_info[MM_STR_VIDEO_RESOLUTION_HEIGHT].validity_value2 = (int)total_count;
+
+       /* Audio encoder */
+       total_count = _mmstreamrecorder_get_available_format(handle, KEYWORD_AUDIO_ENCODERS, &format);
+       stream_attrs_const_info[MM_STR_AUDIO_ENCODER].validity_value1 = (int)format;
+       stream_attrs_const_info[MM_STR_AUDIO_ENCODER].validity_value2 = (int)total_count;
+
+       /*Video encoder*/
+       total_count = _mmstreamrecorder_get_available_format(handle, KEYWORD_VIDEO_ENCODERS, &format);
+       stream_attrs_const_info[MM_STR_VIDEO_ENCODER].validity_value1 = (int)format;
+       stream_attrs_const_info[MM_STR_VIDEO_ENCODER].validity_value2 = (int)total_count;
+
+       /* File Format */
+       total_count = _mmstreamrecorder_get_available_format(handle, KEYWORD_FILE_FORMATS, &format);
+       stream_attrs_const_info[MM_STR_FILE_FORMAT].validity_value1 = (int)format;
+       stream_attrs_const_info[MM_STR_FILE_FORMAT].validity_value2 = (int)total_count;
+
+       return MM_ERROR_NONE;
+}
+
+static int __mmstreamrecorder_release_conf_valid_info(MMHandleType handle)
+{
+       int *allocated_memory = NULL;
+
+       _mmstreamrec_dbg_log("START");
+
+       allocated_memory = (int *)(stream_attrs_const_info[MM_STR_VIDEO_RESOLUTION_WIDTH].validity_value1);
+       if (allocated_memory) {
+               free(allocated_memory);
+               stream_attrs_const_info[MM_STR_VIDEO_RESOLUTION_WIDTH].validity_value1 = (int)NULL;
+               stream_attrs_const_info[MM_STR_VIDEO_RESOLUTION_WIDTH].validity_value2 = (int)0;
+       }
+
+       allocated_memory = (int *)(stream_attrs_const_info[MM_STR_VIDEO_RESOLUTION_HEIGHT].validity_value1);
+       if (allocated_memory) {
+               free(allocated_memory);
+               stream_attrs_const_info[MM_STR_VIDEO_RESOLUTION_HEIGHT].validity_value1 = (int)NULL;
+               stream_attrs_const_info[MM_STR_VIDEO_RESOLUTION_HEIGHT].validity_value2 = (int)0;
+       }
+
+       allocated_memory = (int *)(stream_attrs_const_info[MM_STR_AUDIO_ENCODER].validity_value1);
+       if (allocated_memory) {
+               free(allocated_memory);
+               stream_attrs_const_info[MM_STR_AUDIO_ENCODER].validity_value1 = (int)NULL;
+               stream_attrs_const_info[MM_STR_AUDIO_ENCODER].validity_value2 = (int)0;
+       }
+
+       allocated_memory = (int *)(stream_attrs_const_info[MM_STR_VIDEO_ENCODER].validity_value1);
+       if (allocated_memory) {
+               free(allocated_memory);
+               stream_attrs_const_info[MM_STR_VIDEO_ENCODER].validity_value1 = (int)NULL;
+               stream_attrs_const_info[MM_STR_VIDEO_ENCODER].validity_value2 = (int)0;
+       }
+
+       allocated_memory = (int *)(stream_attrs_const_info[MM_STR_FILE_FORMAT].validity_value1);
+       if (allocated_memory) {
+               free(allocated_memory);
+               stream_attrs_const_info[MM_STR_FILE_FORMAT].validity_value1 = (int)NULL;
+               stream_attrs_const_info[MM_STR_FILE_FORMAT].validity_value2 = (int)0;
+       }
+       _mmstreamrec_dbg_log("DONE");
+
+       return MM_ERROR_NONE;
+}
+
+#if 0
+static bool __mmstreamrecorder_attrs_is_supported(MMHandleType handle, int idx)
+{
+       mmf_attrs_t *attr = (mmf_attrs_t *) handle;
+       int flag;
+
+       if (mm_attrs_get_flags(handle, idx, &flag) == MM_ERROR_NONE) {
+               if (flag == MM_ATTRS_FLAG_NONE)
+                       return FALSE;
+       } else {
+               return FALSE;
+       }
+
+       if (attr->items[idx].value_spec.type == MM_ATTRS_VALID_TYPE_INT_RANGE) {
+               int min, max;
+               mm_attrs_get_valid_range((MMHandleType) attr, idx, &min, &max);
+               if (max < min)
+                       return FALSE;
+       } else if (attr->items[idx].value_spec.type == MM_ATTRS_VALID_TYPE_INT_ARRAY) {
+               int count;
+               int *array;
+               mm_attrs_get_valid_array((MMHandleType) attr, idx, &count, &array);
+               if (count == 0)
+                       return FALSE;
+       }
+
+       return TRUE;
+}
+#endif
+static int __mmstreamrecorder_check_valid_pair(MMHandleType handle, char **err_attr_name, const char *attribute_name, va_list var_args)
+{
+#define INIT_VALUE            -1
+#define CHECK_COUNT           2
+#define CAPTURE_RESOLUTION    1
+
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+       MMHandleType attrs = 0;
+
+       int ret = MM_ERROR_NONE;
+       int i = 0, j = 0;
+       const char *name = NULL;
+       const char *check_pair_name[2][3] = {
+               {MMSTR_VIDEO_RESOLUTION_WIDTH, MMSTR_VIDEO_RESOLUTION_HEIGHT, "MMSTR_VIDEO_RESOLUTION_WIDTH and HEIGHT"},
+               {NULL, NULL, NULL}
+       };
+
+       int check_pair_value[2][2] = {
+               {INIT_VALUE, INIT_VALUE},
+               {INIT_VALUE, INIT_VALUE},
+       };
+
+       if (hstreamrecorder == NULL || attribute_name == NULL) {
+               _mmstreamrec_dbg_warn("handle[%p] or attribute_name[%p] is NULL.", hstreamrecorder, attribute_name);
+               return MM_ERROR_STREAMRECORDER_INVALID_ARGUMENT;
+       }
+
+       if (err_attr_name)
+               *err_attr_name = NULL;
+
+       /* _mmstreamrec_dbg_log( "ENTER" ); */
+
+       attrs = MMF_STREAMRECORDER_ATTRS(handle);
+
+       name = attribute_name;
+
+       while (name) {
+               int idx = -1;
+               MMAttrsType attr_type = MM_ATTRS_TYPE_INVALID;
+
+               /*_mmstreamrec_dbg_log( "NAME : %s", name );*/
+
+               /* attribute name check */
+               if ((ret = mm_attrs_get_index(attrs, name, &idx)) != MM_ERROR_NONE) {
+                       if (err_attr_name)
+                               *err_attr_name = strdup(name);
+
+                       if (ret == (int)MM_ERROR_COMMON_OUT_OF_ARRAY)
+                               return MM_ERROR_COMMON_ATTR_NOT_EXIST;
+                       else
+                               return ret;
+               }
+
+               /* type check */
+               if ((ret = mm_attrs_get_type(attrs, idx, &attr_type)) != MM_ERROR_NONE)
+                       return ret;
+
+               switch (attr_type) {
+               case MM_ATTRS_TYPE_INT:
+                       {
+                               va_arg((var_args), int);
+                               break;
+                       }
+               case MM_ATTRS_TYPE_DOUBLE:
+                       va_arg((var_args), double);
+                       break;
+               case MM_ATTRS_TYPE_STRING:
+                       va_arg((var_args), char *);     /* string */
+                       va_arg((var_args), int);        /* size */
+                       break;
+               case MM_ATTRS_TYPE_DATA:
+                       va_arg((var_args), void *);     /* data */
+                       va_arg((var_args), int);        /* size */
+                       break;
+               case MM_ATTRS_TYPE_INVALID:
+               default:
+                       _mmstreamrec_dbg_err("Not supported attribute type(%d, name:%s)", attr_type, name);
+                       if (err_attr_name)
+                               *err_attr_name = strdup(name);
+                       return MM_ERROR_STREAMRECORDER_INVALID_ARGUMENT;
+               }
+
+               /* next name */
+               name = va_arg(var_args, char *);
+       }
+
+       for (i = 0; i < CHECK_COUNT; i++) {
+               if (check_pair_value[i][0] != INIT_VALUE || check_pair_value[i][1] != INIT_VALUE) {
+                       gboolean check_result = FALSE;
+                       char *err_name = NULL;
+                       MMStreamRecorderAttrsInfo attr_info_0, attr_info_1;
+
+                       if (check_pair_value[i][0] == INIT_VALUE) {
+                               mm_attrs_get_int_by_name(attrs, check_pair_name[i][0], &check_pair_value[i][0]);
+                               err_name = strdup(check_pair_name[i][1]);
+                       } else if (check_pair_value[i][1] == INIT_VALUE) {
+                               mm_attrs_get_int_by_name(attrs, check_pair_name[i][1], &check_pair_value[i][1]);
+                               err_name = strdup(check_pair_name[i][0]);
+                       } else {
+                               err_name = strdup(check_pair_name[i][2]);
+                       }
+
+                       mm_streamrecorder_get_attribute_info(handle, check_pair_name[i][0], &attr_info_0);
+                       mm_streamrecorder_get_attribute_info(handle, check_pair_name[i][1], &attr_info_1);
+
+                       check_result = FALSE;
+
+                       for (j = 0; j < attr_info_0.int_array.count; j++) {
+                               if (attr_info_0.int_array.array[j] == check_pair_value[i][0]
+                                       && attr_info_1.int_array.array[j] == check_pair_value[i][1]) {
+                                       _mmstreamrec_dbg_log("Valid Pair[%s,%s] existed %dx%d[index:%d]", check_pair_name[i][0], check_pair_name[i][1], check_pair_value[i][0], check_pair_value[i][1], i);
+                                       check_result = TRUE;
+                                       break;
+                               }
+                       }
+
+                       if (check_result == FALSE) {
+                               _mmstreamrec_dbg_err("INVALID pair[%s,%s] %dx%d", check_pair_name[i][0], check_pair_name[i][1], check_pair_value[i][0], check_pair_value[i][1]);
+                               if (err_attr_name)
+                                       *err_attr_name = err_name;
+
+                               return MM_ERROR_STREAMRECORDER_INVALID_ARGUMENT;
+                       }
+
+                       if (err_name) {
+                               free(err_name);
+                               err_name = NULL;
+                       }
+               }
+       }
+
+       /*_mmstreamrec_dbg_log("DONE");*/
+
+       return MM_ERROR_NONE;
+}
+
+/* attribute commiter */
+void __mmstreamrecorder_print_attrs(const char *attr_name, const mmf_value_t * value, const char *cmt_way)
+{
+       switch (value->type) {
+       case MMF_VALUE_TYPE_INT:
+               _mmstreamrec_dbg_log("%s :(%s:%d)", cmt_way, attr_name, value->value.i_val);
+               break;
+       case MMF_VALUE_TYPE_DOUBLE:
+               _mmstreamrec_dbg_log("%s :(%s:%f)", cmt_way, attr_name, value->value.d_val);
+               break;
+       case MMF_VALUE_TYPE_STRING:
+               _mmstreamrec_dbg_log("%s :(%s:%s)", cmt_way, attr_name, value->value.s_val);
+               break;
+       case MMF_VALUE_TYPE_DATA:
+               _mmstreamrec_dbg_log("%s :(%s:%p)", cmt_way, attr_name, value->value.p_val);
+               break;
+       default:
+               break;
+       }
+
+       return;
+}
+
+int _mmstreamrecorder_get_audio_codec_format(MMHandleType handle, const char *name)
+{
+       int codec_index = MM_AUDIO_CODEC_INVALID;
+
+       if (!name) {
+               _mmstreamrec_dbg_err("name is NULL");
+               return MM_AUDIO_CODEC_INVALID;
+       }
+
+       if (!strcmp(name, "AMR"))
+               codec_index = MM_AUDIO_CODEC_AMR;
+       else if (!strcmp(name, "AAC"))
+               codec_index = MM_AUDIO_CODEC_AAC;
+       else if (!strcmp(name, "PCM"))
+               codec_index = MM_AUDIO_CODEC_PCM;
+       else if (!strcmp(name, "VORBIS"))
+               codec_index = MM_AUDIO_CODEC_VORBIS;
+
+       return codec_index;
+}
+
+int _mmstreamrecorder_get_video_codec_format(MMHandleType handle, const char *name)
+{
+       int codec_index = MM_VIDEO_CODEC_INVALID;
+
+       if (!name) {
+               _mmstreamrec_dbg_err("name is NULL");
+               return MM_VIDEO_CODEC_INVALID;
+       }
+
+       if (!strcmp(name, "H263"))
+               codec_index = MM_VIDEO_CODEC_H263;
+       else if (!strcmp(name, "H264"))
+               codec_index = MM_VIDEO_CODEC_H264;
+       else if (!strcmp(name, "MPEG4"))
+               codec_index = MM_VIDEO_CODEC_MPEG4;
+
+       return codec_index;
+}
+
+
+int _mmstreamrecorder_get_mux_format(MMHandleType handle, const char *name)
+{
+       int mux_index = MM_FILE_FORMAT_INVALID;
+
+       if (!name) {
+               _mmstreamrec_dbg_err("name is NULL");
+               return MM_FILE_FORMAT_INVALID;
+       }
+
+       if (!strcmp(name, "3GP"))
+               mux_index = MM_FILE_FORMAT_3GP;
+       else if (!strcmp(name, "AMR"))
+               mux_index = MM_FILE_FORMAT_AMR;
+       else if (!strcmp(name, "MP4"))
+               mux_index = MM_FILE_FORMAT_MP4;
+       else if (!strcmp(name, "WAV"))
+               mux_index = MM_FILE_FORMAT_WAV;
+       return mux_index;
+}
+
+
+int _mmstreamrecorder_get_format(MMHandleType handle , int category, const char *name)
+{
+       int fmt = -1;
+
+       mmf_return_val_if_fail(name, -1);
+
+       switch (category) {
+       case KEYWORD_AUDIO_ENCODERS:
+               fmt = _mmstreamrecorder_get_audio_codec_format(handle, name);
+               break;
+       case KEYWORD_VIDEO_ENCODERS:
+               fmt = _mmstreamrecorder_get_video_codec_format(handle, name);
+               break;
+       case KEYWORD_FILE_FORMATS:
+               fmt = _mmstreamrecorder_get_mux_format(handle, name);
+               break;
+       default:
+               break;
+       }
+       return fmt;
+}
+
+int _mmstreamrecorder_get_type_count(MMHandleType handle, int type)
+{
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+
+       int count = 0;
+       int i = 0;
+       if (type == KEYWORD_VIDEO_WIDTH) {
+               while (hstreamrecorder->ini.supported_video_width[i++])
+                       count++;
+       } else if (type == KEYWORD_VIDEO_HEIGHT) {
+               while (hstreamrecorder->ini.supported_video_height[i++])
+                       count++;
+       } else if (type == KEYWORD_AUDIO_ENCODERS) {
+               while (hstreamrecorder->ini.supported_audio_encoders[i++][0])
+                       count++;
+       } else if (type == KEYWORD_VIDEO_ENCODERS) {
+               while (hstreamrecorder->ini.supported_video_encoders[i++][0])
+                       count++;
+       } else if (type == KEYWORD_FILE_FORMATS) {
+               while (hstreamrecorder->ini.supported_file_formats[i++][0])
+                       count++;
+       }
+       return count;
+}
+
+void __mmstreamrecorder_get_supported_name(MMHandleType handle, int type , char **str, int i)
+{
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+       if (type == KEYWORD_AUDIO_ENCODERS) {
+               *str = hstreamrecorder->ini.supported_audio_encoders[i];
+               return;
+       } else if (type == KEYWORD_VIDEO_ENCODERS) {
+               *str = hstreamrecorder->ini.supported_video_encoders[i];
+               return;
+       } else if (type == KEYWORD_FILE_FORMATS) {
+               *str = hstreamrecorder->ini.supported_file_formats[i];
+               return;
+       } else {
+               *str = NULL;
+               return;
+       }
+}
+
+int __mmstreamrecorder_get_supported_value(MMHandleType handle, int type, int i)
+{
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+
+       if (type == KEYWORD_VIDEO_WIDTH)
+               return hstreamrecorder->ini.supported_video_width[i];
+       else if (type == KEYWORD_VIDEO_HEIGHT)
+               return hstreamrecorder->ini.supported_video_height[i];
+       else
+               return -1;
+}
+
+int
+_mmstreamrecorder_get_available_format(MMHandleType handle, int type, int ** format)
+{
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+       int *arr = NULL;
+       int total_count = 0;
+       int count = 0;
+       int i = 0;
+       int fmt = 0;
+       const char *name = NULL;
+
+       mmf_return_val_if_fail(hstreamrecorder, 0);
+
+       count = _mmstreamrecorder_get_type_count(handle, type);
+
+       if (count <= 0)
+               return -1;
+
+       arr = (int*) g_malloc0(count * sizeof(int));
+       if (arr == NULL) {
+               _mmstreamrec_dbg_err("malloc failed : %d", count * sizeof(int));
+               return -1;
+       }
+
+       if (type == KEYWORD_VIDEO_WIDTH || type == KEYWORD_VIDEO_HEIGHT) {
+               for (i = 0 ; i < count ; i++) {
+                       fmt = __mmstreamrecorder_get_supported_value(handle, type, i);
+                       if (fmt >= 0)
+                               arr[total_count++] = fmt;
+               }
+       } else {
+               for (i = 0 ; i < count ; i++) {
+                       __mmstreamrecorder_get_supported_name(handle, type, &name, i);
+                       fmt = _mmstreamrecorder_get_format(handle, type, name);
+                       if (fmt >= 0)
+                               arr[total_count++] = fmt;
+               }
+       }
+       *format = arr;
+       return total_count;
+}
+
+/*=======================================================================
+|  FUNCTION DEFINITIONS                                                        |
+=======================================================================*/
+/*-----------------------------------------------------------------------
+|    GLOBAL FUNCTION DEFINITIONS:                                      |
+-----------------------------------------------------------------------*/
+MMHandleType _mmstreamrecorder_alloc_attribute(MMHandleType handle)
+{
+       _mmstreamrec_dbg_log("");
+
+       MMHandleType attrs = 0;
+       mmf_attrs_construct_info_t *attrs_const_info = NULL;
+       unsigned int attr_count = 0;
+       unsigned int idx;
+
+       /* Create attribute constructor */
+       _mmstreamrec_dbg_log("start");
+
+       /* alloc 'mmf_attrs_construct_info_t' */
+       attr_count = ARRAY_SIZE(stream_attrs_const_info);
+       attrs_const_info = malloc(attr_count * sizeof(mmf_attrs_construct_info_t));
+
+       if (!attrs_const_info) {
+               _mmstreamrec_dbg_err("Fail to alloc constructor.");
+               return 0;
+       }
+
+       for (idx = 0; idx < attr_count; idx++) {
+               /* attribute order check. This should be same. */
+               if (idx != stream_attrs_const_info[idx].attrid) {
+                       _mmstreamrec_dbg_err("Please check attributes order. Is the idx same with enum val?");
+                       free(attrs_const_info);
+                       attrs_const_info = NULL;
+                       return 0;
+               }
+
+               attrs_const_info[idx].name = stream_attrs_const_info[idx].name;
+               attrs_const_info[idx].value_type = stream_attrs_const_info[idx].value_type;
+               attrs_const_info[idx].flags = stream_attrs_const_info[idx].flags;
+               attrs_const_info[idx].default_value = stream_attrs_const_info[idx].default_value.value_void;
+       }
+
+       _mmstreamrec_dbg_log("Create Streamrecorder Attributes[%p, %d]", attrs_const_info, attr_count);
+
+       attrs = mmf_attrs_new_from_data("Streamrecorder_Attributes", attrs_const_info, attr_count, _mmstreamrecorder_commit_streamrecorder_attrs, (void *)handle);
+
+       free(attrs_const_info);
+       attrs_const_info = NULL;
+
+       if (attrs == 0) {
+               _mmstreamrec_dbg_err("Fail to alloc attribute handle");
+               return 0;
+       }
+
+       __mmstreamrecorder_set_conf_to_valid_info(handle);
+
+       for (idx = 0; idx < attr_count; idx++) {
+               mmf_attrs_set_valid_type(attrs, idx, stream_attrs_const_info[idx].validity_type);
+
+               switch (stream_attrs_const_info[idx].validity_type) {
+               case MM_ATTRS_VALID_TYPE_INT_ARRAY:
+                       if (stream_attrs_const_info[idx].validity_value1 && stream_attrs_const_info[idx].validity_value2 > 0)
+                               mmf_attrs_set_valid_array(attrs, idx, (const int *)(stream_attrs_const_info[idx].validity_value1), stream_attrs_const_info[idx].validity_value2, (int)(stream_attrs_const_info[idx].default_value.value_int));
+                       break;
+               case MM_ATTRS_VALID_TYPE_INT_RANGE:
+                       mmf_attrs_set_valid_range(attrs, idx, stream_attrs_const_info[idx].validity_value1, stream_attrs_const_info[idx].validity_value2, (int)(stream_attrs_const_info[idx].default_value.value_int));
+                       break;
+               case MM_ATTRS_VALID_TYPE_DOUBLE_ARRAY:
+                       if (stream_attrs_const_info[idx].validity_value1 && stream_attrs_const_info[idx].validity_value2 > 0)
+                               mmf_attrs_set_valid_double_array(attrs, idx, (const double *)(stream_attrs_const_info[idx].validity_value1), stream_attrs_const_info[idx].validity_value2, (double)(stream_attrs_const_info[idx].default_value.value_double));
+                       break;
+               case MM_ATTRS_VALID_TYPE_DOUBLE_RANGE:
+                       mmf_attrs_set_valid_double_range(attrs, idx, (double)(stream_attrs_const_info[idx].validity_value1), (double)(stream_attrs_const_info[idx].validity_value2), (double)(stream_attrs_const_info[idx].default_value.value_double));
+                       break;
+               case MM_ATTRS_VALID_TYPE_NONE:
+                       break;
+               case MM_ATTRS_VALID_TYPE_INVALID:
+               default:
+                       _mmstreamrec_dbg_err("Valid type error.");
+                       break;
+               }
+       }
+
+       __mmstreamrecorder_release_conf_valid_info(handle);
+
+       return attrs;
+}
+
+void _mmstreamrecorder_dealloc_attribute(MMHandleType attrs)
+{
+       _mmstreamrec_dbg_log("");
+
+       if (attrs) {
+               mmf_attrs_free(attrs);
+
+               _mmstreamrec_dbg_log("released attribute");
+       }
+}
+
+int _mmstreamrecorder_get_attributes(MMHandleType handle, char **err_attr_name, const char *attribute_name, va_list var_args)
+{
+       MMHandleType attrs = 0;
+       int ret = MM_ERROR_NONE;
+
+       mmf_return_val_if_fail(handle, MM_ERROR_STREAMRECORDER_INVALID_ARGUMENT);
+
+       attrs = MMF_STREAMRECORDER_ATTRS(handle);
+       mmf_return_val_if_fail(attrs, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+
+       ret = mm_attrs_get_valist(attrs, err_attr_name, attribute_name, var_args);
+
+       return ret;
+}
+
+int _mmstreamrecorder_set_attributes(MMHandleType handle, char **err_attr_name, const char *attribute_name, va_list var_args)
+{
+       MMHandleType attrs = 0;
+       int ret = MM_ERROR_NONE;
+
+       mmf_return_val_if_fail(handle, MM_ERROR_STREAMRECORDER_INVALID_ARGUMENT);
+
+       attrs = MMF_STREAMRECORDER_ATTRS(handle);
+       if (!attrs) {
+               _mmstreamrec_dbg_err("handle 0x%x, attrs is NULL, attr name [%s]", handle, attribute_name);
+               return MM_ERROR_STREAMRECORDER_NOT_INITIALIZED;
+       }
+
+       ret = __mmstreamrecorder_check_valid_pair(handle, err_attr_name, attribute_name, var_args);
+
+       _mmstreamrec_dbg_err("__mmstreamrecorder_check_valid_pair handle 0x%x, attr name [%s] , ret = %d", handle, attribute_name, ret);
+
+       if (ret == MM_ERROR_NONE)
+               ret = mm_attrs_set_valist(attrs, err_attr_name, attribute_name, var_args);
+
+       _mmstreamrec_dbg_err("mm_attrs_set_valist handle 0x%x, attr name [%s] , ret = %d", handle, attribute_name, ret);
+       return ret;
+}
+
+int _mmstreamrecorder_get_attribute_info(MMHandleType handle, const char *attr_name, MMStreamRecorderAttrsInfo * info)
+{
+       MMHandleType attrs = 0;
+       MMAttrsInfo attrinfo;
+       int ret = MM_ERROR_NONE;
+
+       mmf_return_val_if_fail(handle, MM_ERROR_STREAMRECORDER_INVALID_ARGUMENT);
+       mmf_return_val_if_fail(attr_name, MM_ERROR_STREAMRECORDER_INVALID_ARGUMENT);
+       mmf_return_val_if_fail(info, MM_ERROR_STREAMRECORDER_INVALID_ARGUMENT);
+
+       attrs = MMF_STREAMRECORDER_ATTRS(handle);
+       mmf_return_val_if_fail(attrs, MM_ERROR_STREAMRECORDER_INVALID_ARGUMENT);
+
+       ret = mm_attrs_get_info_by_name(attrs, attr_name, (MMAttrsInfo *) & attrinfo);
+
+       if (ret == MM_ERROR_NONE) {
+               memset(info, 0x00, sizeof(MMStreamRecorderAttrsInfo));
+               info->type = attrinfo.type;
+               info->flag = attrinfo.flag;
+               info->validity_type = attrinfo.validity_type;
+
+               switch (attrinfo.validity_type) {
+               case MM_ATTRS_VALID_TYPE_INT_ARRAY:
+                       info->int_array.array = attrinfo.int_array.array;
+                       info->int_array.count = attrinfo.int_array.count;
+                       info->int_array.def = attrinfo.int_array.dval;
+                       break;
+               case MM_ATTRS_VALID_TYPE_INT_RANGE:
+                       info->int_range.min = attrinfo.int_range.min;
+                       info->int_range.max = attrinfo.int_range.max;
+                       info->int_range.def = attrinfo.int_range.dval;
+                       break;
+               case MM_ATTRS_VALID_TYPE_DOUBLE_ARRAY:
+                       info->double_array.array = attrinfo.double_array.array;
+                       info->double_array.count = attrinfo.double_array.count;
+                       info->double_array.def = attrinfo.double_array.dval;
+                       break;
+               case MM_ATTRS_VALID_TYPE_DOUBLE_RANGE:
+                       info->double_range.min = attrinfo.double_range.min;
+                       info->double_range.max = attrinfo.double_range.max;
+                       info->double_range.def = attrinfo.double_range.dval;
+                       break;
+               case MM_ATTRS_VALID_TYPE_NONE:
+                       break;
+               case MM_ATTRS_VALID_TYPE_INVALID:
+               default:
+                       break;
+               }
+       }
+
+       return ret;
+}
+
+bool _mmstreamrecorder_commit_streamrecorder_attrs(int attr_idx, const char *attr_name, const mmf_value_t * value, void *commit_param)
+{
+       bool bret = FALSE;
+
+       mmf_return_val_if_fail(commit_param, FALSE);
+       mmf_return_val_if_fail(attr_idx >= 0, FALSE);
+       mmf_return_val_if_fail(attr_name, FALSE);
+       mmf_return_val_if_fail(value, FALSE);
+
+       if (stream_attrs_const_info[attr_idx].attr_commit) {
+               /* _mmstreamrec_dbg_log("Dynamic commit:(%s)", attr_name); */
+               __mmstreamrecorder_print_attrs(attr_name, value, "Dynamic");
+               bret = stream_attrs_const_info[attr_idx].attr_commit((MMHandleType) commit_param, attr_idx, value);
+       } else {
+               /* _mmstreamrec_dbg_log("Static commit:(%s)", attr_name); */
+               __mmstreamrecorder_print_attrs(attr_name, value, "Static");
+               bret = TRUE;
+       }
+
+       return bret;
+}
+
+bool _mmstreamrecorder_commit_video_enable(MMHandleType handle, int attr_idx, const mmf_value_t *value)
+{
+       MMHandleType attr = 0;
+       /* mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle); */
+       _MMStreamRecorderSubContext *sc = NULL;
+       _MMStreamRecorderVideoInfo *info = NULL;
+
+       mmf_return_val_if_fail(handle, FALSE);
+       attr = MMF_STREAMRECORDER_ATTRS(handle);
+       mmf_return_val_if_fail(attr, FALSE);
+       sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
+
+       _mmstreamrec_dbg_log("(%d)", attr_idx);
+
+       mmf_return_val_if_fail(sc, FALSE);
+
+       info = (_MMStreamRecorderVideoInfo *) sc->info_video;
+
+       if (info == NULL && value->value.i_val != 0) {
+               if (_mmstreamrecorder_alloc_subcontext_videoinfo(handle))
+                       return FALSE;
+       }
+
+       return TRUE;
+}
+
+bool _mmstreamrecorder_commit_video_encoder(MMHandleType handle, int attr_idx, const mmf_value_t *value)
+{
+       MMHandleType attr = 0;
+       _MMStreamRecorderSubContext *sc = NULL;
+       _MMStreamRecorderVideoInfo *info = NULL;
+
+       mmf_return_val_if_fail(handle, FALSE);
+       attr = MMF_STREAMRECORDER_ATTRS(handle);
+       mmf_return_val_if_fail(attr, FALSE);
+       sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
+       mmf_return_val_if_fail(sc, FALSE);
+
+       info = (_MMStreamRecorderVideoInfo *) sc->info_video;
+       mmf_return_val_if_fail(info, FALSE);
+
+       _mmstreamrec_dbg_log("(%d)", attr_idx);
+
+       info->iVideoEncoder = value->value.i_val;
+
+       return TRUE;
+}
+
+bool _mmstreamrecorder_commit_audio_enable(MMHandleType handle, int attr_idx, const mmf_value_t *value)
+{
+       MMHandleType attr = 0;
+       /* mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle); */
+       _MMStreamRecorderSubContext *sc = NULL;
+       _MMStreamRecorderAudioInfo *info = NULL;
+
+       mmf_return_val_if_fail(handle, FALSE);
+       attr = MMF_STREAMRECORDER_ATTRS(handle);
+       mmf_return_val_if_fail(attr, FALSE);
+       sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
+       mmf_return_val_if_fail(sc, FALSE);
+
+       _mmstreamrec_dbg_log("(%d)", attr_idx);
+
+       info = (_MMStreamRecorderAudioInfo *) sc->info_audio;
+
+       if (info == NULL && value->value.i_val != 0) {
+               if (_mmstreamrecorder_alloc_subcontext_audioinfo(handle))
+                       return FALSE;
+       }
+
+       return TRUE;
+}
+
+bool _mmstreamrecorder_commit_audio_encoder(MMHandleType handle, int attr_idx, const mmf_value_t *value)
+{
+       MMHandleType attr = 0;
+       _MMStreamRecorderSubContext *sc = NULL;
+       _MMStreamRecorderAudioInfo *info = NULL;
+
+       mmf_return_val_if_fail(handle, FALSE);
+       attr = MMF_STREAMRECORDER_ATTRS(handle);
+       mmf_return_val_if_fail(attr, FALSE);
+       sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
+       mmf_return_val_if_fail(sc, FALSE);
+
+       info = (_MMStreamRecorderAudioInfo *) sc->info_audio;
+       mmf_return_val_if_fail(info, FALSE);
+
+       _mmstreamrec_dbg_log("(%d)", attr_idx);
+
+       info->iAudioEncoder = value->value.i_val;
+
+       return TRUE;
+}
+
+bool _mmstreamrecorder_commit_audio_samplingrate(MMHandleType handle, int attr_idx, const mmf_value_t *value)
+{
+       MMHandleType attr = 0;
+       _MMStreamRecorderSubContext *sc = NULL;
+       _MMStreamRecorderAudioInfo *info = NULL;
+
+       mmf_return_val_if_fail(handle, FALSE);
+       attr = MMF_STREAMRECORDER_ATTRS(handle);
+       mmf_return_val_if_fail(attr, FALSE);
+       sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
+       mmf_return_val_if_fail(sc, FALSE);
+
+       info = (_MMStreamRecorderAudioInfo *) sc->info_audio;
+       mmf_return_val_if_fail(info, FALSE);
+
+       _mmstreamrec_dbg_log("(%d)", attr_idx);
+
+       info->iSamplingRate = value->value.i_val;
+
+       return TRUE;
+}
+
+bool _mmstreamrecorder_commit_audio_bitformat(MMHandleType handle, int attr_idx, const mmf_value_t *value)
+{
+       MMHandleType attr = 0;
+       _MMStreamRecorderSubContext *sc = NULL;
+       _MMStreamRecorderAudioInfo *info = NULL;
+
+       mmf_return_val_if_fail(handle, FALSE);
+       attr = MMF_STREAMRECORDER_ATTRS(handle);
+       mmf_return_val_if_fail(attr, FALSE);
+       sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
+       mmf_return_val_if_fail(sc, FALSE);
+
+       info = (_MMStreamRecorderAudioInfo *) sc->info_audio;
+       mmf_return_val_if_fail(info, FALSE);
+
+       _mmstreamrec_dbg_log("(%d)", attr_idx);
+
+       if (value->value.i_val == MM_STREAMRECORDER_AUDIO_FORMAT_PCM_U8)
+               info->audio_encode_depth = 16;
+       else
+               info->audio_encode_depth = 8;
+
+       return TRUE;
+}
+
+bool _mmstreamrecorder_commit_video_bitrate(MMHandleType handle, int attr_idx, const mmf_value_t *value)
+{
+       MMHandleType attr = 0;
+       _MMStreamRecorderSubContext *sc = NULL;
+       int v_bitrate;
+
+       mmf_return_val_if_fail(handle, FALSE);
+       attr = MMF_STREAMRECORDER_ATTRS(handle);
+       mmf_return_val_if_fail(attr, FALSE);
+       sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
+       mmf_return_val_if_fail(sc, FALSE);
+
+       v_bitrate = value->value.i_val;
+
+       if (sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst) {
+               MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst, "bitrate", v_bitrate);
+               _mmstreamrec_dbg_log("video bitrate set to encoder success = %d", v_bitrate);
+       } else {
+               _mmstreamrec_dbg_log("_MMSTREAMRECORDER_ENCSINK_VENC is null %d", attr_idx);
+       }
+       return TRUE;
+}
+
+bool _mmstreamrecorder_commit_audio_bitrate(MMHandleType handle, int attr_idx, const mmf_value_t *value)
+{
+       MMHandleType attr = 0;
+       _MMStreamRecorderSubContext *sc = NULL;
+       _MMStreamRecorderAudioInfo *info = NULL;
+
+       mmf_return_val_if_fail(handle, FALSE);
+       attr = MMF_STREAMRECORDER_ATTRS(handle);
+       mmf_return_val_if_fail(attr, FALSE);
+       sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
+       mmf_return_val_if_fail(sc, FALSE);
+
+       info = (_MMStreamRecorderAudioInfo *) sc->info_audio;
+       mmf_return_val_if_fail(info, FALSE);
+
+       _mmstreamrec_dbg_log("(%d)", attr_idx);
+
+       info->iBitrate = value->value.i_val;
+
+       return TRUE;
+}
+
+bool _mmstreamrecorder_commit_audio_channel(MMHandleType handle, int attr_idx, const mmf_value_t *value)
+{
+       MMHandleType attr = 0;
+       _MMStreamRecorderSubContext *sc = NULL;
+       _MMStreamRecorderAudioInfo *info = NULL;
+
+       mmf_return_val_if_fail(handle, FALSE);
+       attr = MMF_STREAMRECORDER_ATTRS(handle);
+       mmf_return_val_if_fail(attr, FALSE);
+       sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
+       mmf_return_val_if_fail(sc, FALSE);
+
+       info = (_MMStreamRecorderAudioInfo *) sc->info_audio;
+       mmf_return_val_if_fail(info, FALSE);
+
+       _mmstreamrec_dbg_log("(%d)", attr_idx);
+
+       info->iChannels = value->value.i_val;
+
+       return TRUE;
+}
+
+int mm_streamrecorder_get_attribute_info(MMHandleType streamrecorder, const char *attribute_name, MMStreamRecorderAttrsInfo * info)
+{
+       return _mmstreamrecorder_get_attribute_info(streamrecorder, attribute_name, info);
+}
diff --git a/src/mm_streamrecorder_audio.c b/src/mm_streamrecorder_audio.c
new file mode 100644 (file)
index 0000000..4b6b342
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * libmm-streamrecorder
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Hyuntae Kim <ht1211.kim@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 <math.h>
+#include <mm_types.h>
+#include <mm_error.h>
+#include "mm_streamrecorder_audio.h"
+#include "mm_streamrecorder_util.h"
+
+/*---------------------------------------------------------------------------------------
+|    LOCAL ARRAY DEFINITIONS for internal                                              |
+---------------------------------------------------------------------------------------*/
+
+/* Table for compatibility between audio codec and file format */
+gboolean common_audiocodec_fileformat_compatibility_table[MM_AUDIO_CODEC_NUM][MM_FILE_FORMAT_NUM] = {
+       /* 3GP ASF AVI MATROSKA MP4 OGG NUT QT REAL AMR AAC MP3 AIFF AU WAV MID MMF DIVX FLV VOB IMELODY WMA WMV JPG */
+        /*AMR*/ {1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+/*G723.1*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+/*MP3*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+        /*OGG*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+        /*AAC*/ {1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+        /*WMA*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+        /*MMF*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+        /*ADPCM*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+        /*WAVE*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+/*WAVE_NEW*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+        /*MIDI*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+        /*IMELODY*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+        /*MXMF*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+        /*MPA*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+/*MP2*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+/*G711*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+/*G722*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+/*G722.1*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+/*G722.2*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+/*G723*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+/*G726*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+/*G728*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+/*G729*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+/*G729A*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+/*G729.1*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+        /*REAL*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+/*AAC_LC*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+/*AAC_MAIN*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+/*AAC_SRS*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+/*AAC_LTP*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+/*AAC_HE_V1*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+/*AAC_HE_V2*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+/*AC3*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+        /*ALAC*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+        /*ATRAC*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+        /*SPEEX*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+        /*VORBIS*/ {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+        /*AIFF*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+        /*AU*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+        /*NONE*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+        /*PCM*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+        /*ALAW*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+        /*MULAW*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+/*MS_ADPCM*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+};
+
+int _mmstreamrecorder_check_audiocodec_fileformat_compatibility(unsigned int audio_codec, unsigned int file_format)
+{
+
+       /* Check compatibility between audio codec and file format */
+       if (audio_codec < MM_AUDIO_CODEC_NUM && file_format < MM_FILE_FORMAT_NUM) {
+               if (common_audiocodec_fileformat_compatibility_table[audio_codec][file_format] == 0) {
+                       _mmstreamrec_dbg_err("Audio codec[%d] and file format[%d] compatibility FAILED.", audio_codec, file_format);
+                       return MM_ERROR_STREAMRECORDER_ENCODER_WRONG_TYPE;
+               }
+               _mmstreamrec_dbg_log("Audio codec[%d] and file format[%d] compatibility SUCCESS.", audio_codec, file_format);
+       } else {
+               _mmstreamrec_dbg_err("Audio codec[%d] or file format[%d] is INVALID.", audio_codec, file_format);
+               return MM_ERROR_STREAMRECORDER_ENCODER_WRONG_TYPE;
+       }
+
+       return MM_ERROR_NONE;
+}
+
+int _mmstreamrecorder_get_amrnb_bitrate_mode(int bitrate)
+{
+       int result = MM_STREAMRECORDER_MR475;
+
+       if (bitrate < 5150)
+               result = MM_STREAMRECORDER_MR475;       /*AMR475 */
+       else if (bitrate < 5900)
+               result = MM_STREAMRECORDER_MR515;       /*AMR515 */
+       else if (bitrate < 6700)
+               result = MM_STREAMRECORDER_MR59;        /*AMR59 */
+       else if (bitrate < 7400)
+               result = MM_STREAMRECORDER_MR67;        /*AMR67 */
+       else if (bitrate < 7950)
+               result = MM_STREAMRECORDER_MR74;        /*AMR74 */
+       else if (bitrate < 10200)
+               result = MM_STREAMRECORDER_MR795;       /*AMR795 */
+       else if (bitrate < 12200)
+               result = MM_STREAMRECORDER_MR102;       /*AMR102 */
+       else
+               result = MM_STREAMRECORDER_MR122;       /*AMR122 */
+
+       return result;
+}
diff --git a/src/mm_streamrecorder_buffer_manager.c b/src/mm_streamrecorder_buffer_manager.c
new file mode 100644 (file)
index 0000000..35d264f
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * libmm-streamrecorder
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Hyuntae Kim <ht1211.kim@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_types.h>
+#include <mm_error.h>
+#include <mm_message.h>
+#include "mm_streamrecorder_video.h"
+#include "mm_streamrecorder_util.h"
+#include "mm_streamrecorder_buffer_manager.h"
+#include "mm_streamrecorder_internal.h"
+#include "mm_streamrecorder_gstdispatch.h"
+
+/*---------------------------------------------------------------------------------------
+|    GLOBAL VARIABLE DEFINITIONS for internal                                          |
+---------------------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------------------
+|    LOCAL VARIABLE DEFINITIONS for internal                                           |
+---------------------------------------------------------------------------------------*/
+
+/*-----------------------------------------------------------------------
+|    GLOBAL VARIABLE DEFINITIONS for internal                          |
+-----------------------------------------------------------------------*/
+
+void _mmstreamrecorder_buffer_destroy(gpointer p_stream_buffer)
+{
+       _MMStreamRecorderMsgItem msg;
+       GstStreamRecorderBuffer *stream_buffer = (GstStreamRecorderBuffer *) p_stream_buffer;
+
+       msg.id = MM_MESSAGE_STREAMRECORDER_CONSUME_COMPLETE;
+       msg.param.union_type = MM_MSG_UNION_CONSUME_RECORDER_BUFFER;
+       msg.param.consumed_mediabuffer.consumed_buffer = stream_buffer->user_buffer;
+       _mmstreamrecorder_send_message(stream_buffer->str_handle, &msg);
+       free(stream_buffer);
+       return;
+}
diff --git a/src/mm_streamrecorder_fileinfo.c b/src/mm_streamrecorder_fileinfo.c
new file mode 100644 (file)
index 0000000..61d9968
--- /dev/null
@@ -0,0 +1,350 @@
+/*
+ * libmm-streamrecorder
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Hyuntae Kim <ht1211.kim@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 <stdio.h>
+#include <stdarg.h>
+#include <sys/vfs.h>                   /* struct statfs */
+
+#include "mm_streamrecorder_internal.h"
+#include "mm_streamrecorder_util.h"
+#include "mm_streamrecorder_fileinfo.h"
+
+/*-----------------------------------------------------------------------
+|    GLOBAL VARIABLE DEFINITIONS for internal                          |
+-----------------------------------------------------------------------*/
+
+/*-----------------------------------------------------------------------
+|    LOCAL VARIABLE DEFINITIONS for internal                           |
+-----------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+|    LOCAL FUNCTION PROTOTYPES:                                                                                                |
+---------------------------------------------------------------------------*/
+/* STATIC INTERNAL FUNCTION */
+
+/*===========================================================================================
+|                                                                                                                                                                                      |
+|  FUNCTION DEFINITIONS                                                                                                                                                |
+========================================================================================== */
+/*---------------------------------------------------------------------------
+|    GLOBAL FUNCTION DEFINITIONS:                                                                                      |
+---------------------------------------------------------------------------*/
+
+gboolean _mmstreamrecorder_find_fourcc(FILE *f, guint32 tag_fourcc, gboolean do_rewind)
+{
+       guchar buf[8];
+
+       if (do_rewind)
+               rewind(f);
+
+       while (fread(&buf, sizeof(guchar), 8, f) > 0) {
+               unsigned long long buf_size = 0;
+               unsigned int buf_fourcc = MMSTREAMRECORDER_FOURCC(buf[4], buf[5], buf[6], buf[7]);
+
+               if (tag_fourcc == buf_fourcc) {
+                       _mmstreamrec_dbg_log("find tag : %c%c%c%c", MMSTREAMRECORDER_FOURCC_ARGS(tag_fourcc));
+                       return TRUE;
+               } else if ((buf_fourcc == MMSTREAMRECORDER_FOURCC('m', 'o', 'o', 'v')) && (tag_fourcc != buf_fourcc)) {
+                       if (_mmstreamrecorder_find_fourcc(f, tag_fourcc, FALSE))
+                               return TRUE;
+                       else
+                               continue;
+               } else {
+                       _mmstreamrec_dbg_log("skip [%c%c%c%c] tag", MMSTREAMRECORDER_FOURCC_ARGS(buf_fourcc));
+
+                       buf_size = (unsigned long long)_mmstreamrecorder_get_container_size(buf);
+                       buf_size = buf_size - 8;        /* include tag */
+
+                       do {
+                               if (buf_size > _MMSTREAMRECORDER_MAX_INT) {
+                                       _mmstreamrec_dbg_log("seek %d", _MMSTREAMRECORDER_MAX_INT);
+                                       if (fseek(f, _MMSTREAMRECORDER_MAX_INT, SEEK_CUR) != 0) {
+                                               _mmstreamrec_dbg_err("fseek() fail");
+                                               return FALSE;
+                                       }
+
+                                       buf_size -= _MMSTREAMRECORDER_MAX_INT;
+                               } else {
+                                       _mmstreamrec_dbg_log("seek %d", buf_size);
+                                       if (fseek(f, buf_size, SEEK_CUR) != 0) {
+                                               _mmstreamrec_dbg_err("fseek() fail");
+                                               return FALSE;
+                                       }
+                                       break;
+                               }
+                       } while (TRUE);
+               }
+       }
+
+       _mmstreamrec_dbg_log("cannot find tag : %c%c%c%c", MMSTREAMRECORDER_FOURCC_ARGS(tag_fourcc));
+
+       return FALSE;
+}
+
+gboolean _mmstreamrecorder_update_composition_matrix(FILE *f, int orientation)
+{
+       /* for 0 degree */
+       guint32 a = 0x00010000;
+       guint32 b = 0;
+       guint32 c = 0;
+       guint32 d = 0x00010000;
+
+       switch (orientation) {
+       case MM_STREAMRECORDER_TAG_VIDEO_ORT_90:        /* 90 degree */
+               a = 0;
+               b = 0x00010000;
+               c = 0xffff0000;
+               d = 0;
+               break;
+       case MM_STREAMRECORDER_TAG_VIDEO_ORT_180:       /* 180 degree */
+               a = 0xffff0000;
+               d = 0xffff0000;
+               break;
+       case MM_STREAMRECORDER_TAG_VIDEO_ORT_270:       /* 270 degree */
+               a = 0;
+               b = 0xffff0000;
+               c = 0x00010000;
+               d = 0;
+               break;
+       case MM_STREAMRECORDER_TAG_VIDEO_ORT_NONE:      /* 0 degree */
+       default:
+               break;
+       }
+
+       write_to_32(f, a);
+       write_to_32(f, b);
+       write_to_32(f, 0);
+       write_to_32(f, c);
+       write_to_32(f, d);
+       write_to_32(f, 0);
+       write_to_32(f, 0);
+       write_to_32(f, 0);
+       write_to_32(f, 0x40000000);
+
+       _mmstreamrec_dbg_log("orientation : %d, write data 0x%x 0x%x 0x%x 0x%x", orientation, a, b, c, d);
+
+       return TRUE;
+}
+
+guint64 _mmstreamrecorder_get_container_size(const guchar *size)
+{
+       guint64 result = 0;
+       guint64 temp = 0;
+
+       temp = size[0];
+       result = temp << 24;
+       temp = size[1];
+       result = result | (temp << 16);
+       temp = size[2];
+       result = result | (temp << 8);
+       result = result | size[3];
+
+       _mmstreamrec_dbg_log("result : %lld", (unsigned long long)result);
+
+       return result;
+}
+
+gboolean _mmstreamrecorder_update_size(FILE *f, gint64 prev_pos, gint64 curr_pos)
+{
+       _mmstreamrec_dbg_log("size : %" G_GINT64_FORMAT "", curr_pos - prev_pos);
+       if (fseek(f, prev_pos, SEEK_SET) != 0) {
+               _mmstreamrec_dbg_err("fseek() fail");
+               return FALSE;
+       }
+
+       if (!write_to_32(f, curr_pos - prev_pos))
+               return FALSE;
+
+       if (fseek(f, curr_pos, SEEK_SET) != 0) {
+               _mmstreamrec_dbg_err("fseek() fail");
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+gboolean _mmstreamrecorder_write_udta_m4a(FILE *f)
+{
+       gint64 current_pos, pos;
+
+       _mmstreamrec_dbg_log("");
+
+       if ((pos = ftell(f)) < 0) {
+               _mmstreamrec_dbg_err("ftell() returns negative value");
+               return FALSE;
+       }
+
+       if (!write_to_32(f, 0))         /* udta atomic size */
+               return FALSE;
+
+       if (!write_tag(f, "udta"))      /* user data fourcc */
+               return FALSE;
+
+       if ((current_pos = ftell(f)) < 0) {
+               _mmstreamrec_dbg_err("ftell() returns negative value");
+               return FALSE;
+       }
+
+       if (!_mmstreamrecorder_update_size(f, pos, current_pos))
+               return FALSE;
+
+       return TRUE;
+}
+
+gboolean _mmstreamrecorder_write_udta(FILE *f, _MMStreamRecorderLocationInfo info)
+{
+       gint64 current_pos, pos;
+
+       _mmstreamrec_dbg_log("");
+
+       if ((pos = ftell(f)) < 0) {
+               _mmstreamrec_dbg_err("ftell() returns negative value");
+               return FALSE;
+       }
+
+       if (!write_to_32(f, 0))         /*size */
+               return FALSE;
+
+       if (!write_tag(f, "udta"))      /* type */
+               return FALSE;
+
+       if ((current_pos = ftell(f)) < 0) {
+               _mmstreamrec_dbg_err("ftell() returns negative value");
+               return FALSE;
+       }
+
+       if (!_mmstreamrecorder_update_size(f, pos, current_pos))
+               return FALSE;
+
+       return TRUE;
+}
+
+/* START TAG HERE */
+gboolean _mmstreamrecorder_audio_add_metadata_info_m4a(MMHandleType handle)
+{
+       FILE *f = NULL;
+       guchar buf[4];
+       guint64 udta_size = 0;
+       gint64 current_pos = 0;
+       gint64 moov_pos = 0;
+       gint64 udta_pos = 0;
+       char err_msg[128] = { '\0', };
+
+       _MMStreamRecorderFileInfo *finfo = NULL;
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+       _MMStreamRecorderSubContext *sc = NULL;
+
+       mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+       sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
+
+       mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+       mmf_return_val_if_fail(sc->info_file, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+
+       finfo = sc->info_file;
+
+       f = fopen(finfo->filename, "rb+");
+       if (f == NULL) {
+               strerror_r(errno, err_msg, 128);
+               _mmstreamrec_dbg_err("file open failed [%s]", err_msg);
+               return FALSE;
+       }
+
+       /* find udta container.
+          if, there are udta container, write loci box after that
+          else, make udta container and write loci box. */
+       if (_mmstreamrecorder_find_fourcc(f, MMSTREAMRECORDER_FOURCC('u', 'd', 't', 'a'), TRUE)) {
+               size_t nread = 0;
+
+               _mmstreamrec_dbg_log("find udta container");
+
+               /* read size */
+               if (fseek(f, -8L, SEEK_CUR) != 0)
+                       goto fail;
+
+               udta_pos = ftell(f);
+               if (udta_pos < 0)
+                       goto ftell_fail;
+
+               nread = fread(&buf, sizeof(char), sizeof(buf), f);
+
+               _mmstreamrec_dbg_log("recorded file fread %d", nread);
+
+               udta_size = _mmstreamrecorder_get_container_size(buf);
+
+               /* goto end of udta and write 'smta' box */
+               if (fseek(f, (udta_size - 4L), SEEK_CUR) != 0)
+                       goto fail;
+
+               current_pos = ftell(f);
+               if (current_pos < 0)
+                       goto ftell_fail;
+
+               if (!_mmstreamrecorder_update_size(f, udta_pos, current_pos))
+                       goto fail;
+       } else {
+               _mmstreamrec_dbg_log("No udta container");
+               if (fseek(f, 0, SEEK_END) != 0)
+                       goto fail;
+
+               if (!_mmstreamrecorder_write_udta_m4a(f))
+                       goto fail;
+       }
+
+       /* find moov container.
+          update moov container size. */
+       if ((current_pos = ftell(f)) < 0)
+               goto ftell_fail;
+
+       if (_mmstreamrecorder_find_fourcc(f, MMSTREAMRECORDER_FOURCC('m', 'o', 'o', 'v'), TRUE)) {
+
+               _mmstreamrec_dbg_log("found moov container");
+               if (fseek(f, -8L, SEEK_CUR) != 0)
+                       goto fail;
+
+               moov_pos = ftell(f);
+               if (moov_pos < 0)
+                       goto ftell_fail;
+
+               if (!_mmstreamrecorder_update_size(f, moov_pos, current_pos))
+                       goto fail;
+
+       } else {
+               _mmstreamrec_dbg_err("No 'moov' container");
+               goto fail;
+       }
+
+       fclose(f);
+       return TRUE;
+
+ fail:
+       fclose(f);
+       return FALSE;
+
+ ftell_fail:
+       _mmstreamrec_dbg_err("ftell() returns negative value.");
+       fclose(f);
+       return FALSE;
+}
+
+/* END TAG HERE */
diff --git a/src/mm_streamrecorder_gstcommon.c b/src/mm_streamrecorder_gstcommon.c
new file mode 100644 (file)
index 0000000..1a437fa
--- /dev/null
@@ -0,0 +1,376 @@
+/*
+ * libmm-streamrecorder
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Hyuntae Kim <ht1211.kim@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 <sys/time.h>
+#include <unistd.h>
+
+#include "mm_streamrecorder_internal.h"
+#include "mm_streamrecorder_gstcommon.h"
+#include "mm_streamrecorder_gstdispatch.h"
+#include "mm_streamrecorder_util.h"
+#include "mm_streamrecorder.h"
+
+/*-----------------------------------------------------------------------
+|    GLOBAL VARIABLE DEFINITIONS for internal                          |
+-----------------------------------------------------------------------*/
+
+/*-----------------------------------------------------------------------
+|    LOCAL VARIABLE DEFINITIONS for internal                           |
+-----------------------------------------------------------------------*/
+#define USE_AUDIO_CLOCK_TUNE
+#define _MMSTREAMRECORDER_WAIT_EOS_TIME              5.0       /* sec */
+#define _MMSTREAMRECORDER_STATE_SET_COUNT                      3
+
+/*-----------------------------------------------------------------------
+|    LOCAL FUNCTION PROTOTYPES:                                                |
+-----------------------------------------------------------------------*/
+/* STATIC INTERNAL FUNCTION */
+
+/*=======================================================================================
+|  FUNCTION DEFINITIONS                                                                        |
+=======================================================================================*/
+/*-----------------------------------------------------------------------
+|    GLOBAL FUNCTION DEFINITIONS:                                      |
+-----------------------------------------------------------------------*/
+gboolean _mmstreamrecorder_gstreamer_init()
+{
+       static const int max_argc = 10;
+       int i = 0;
+       gint *argc = NULL;
+       gchar **argv = NULL;
+       GError *err = NULL;
+       gboolean ret = FALSE;
+       /* type_string_array *GSTInitOption = NULL; */
+
+       /* mmf_return_val_if_fail(conf, FALSE); */
+
+       _mmstreamrec_dbg_log("");
+
+       /* alloc */
+       argc = malloc(sizeof(int));
+       argv = malloc(sizeof(gchar *) * max_argc);
+
+       if (!argc || !argv)
+               goto ERROR;
+
+       memset(argv, 0, sizeof(gchar *) * max_argc);
+
+       /* add initial */
+       *argc = 1;
+       argv[0] = g_strdup("mmstreamrecorder");
+
+       _mmstreamrec_dbg_log("initializing gstreamer with following parameter[argc:%d]", *argc);
+
+       for (i = 0; i < *argc; i++)
+               _mmstreamrec_dbg_log("argv[%d] : %s", i, argv[i]);
+
+       /* initializing gstreamer */
+       ret = gst_init_check(argc, &argv, &err);
+
+       if (!ret) {
+               _mmstreamrec_dbg_err("Could not initialize GStreamer: %s ", err ? err->message : "unknown error occurred");
+               if (err)
+                       g_error_free(err);
+       }
+
+       /* release */
+
+       for (i = 0; i < *argc; i++) {
+               if (argv[i]) {
+                       g_free(argv[i]);
+                       argv[i] = NULL;
+               }
+       }
+
+       if (argv) {
+               g_free(argv);
+               argv = NULL;
+       }
+
+       if (argc) {
+               g_free(argc);
+               argc = NULL;
+       }
+
+       return ret;
+
+ ERROR:
+       _mmstreamrec_dbg_err("failed to initialize gstreamer");
+
+       if (argv) {
+               g_free(argv);
+               argv = NULL;
+       }
+
+       if (argc) {
+               g_free(argc);
+               argc = NULL;
+       }
+
+       return FALSE;
+}
+
+int _mmstreamrecorder_get_eos_message(MMHandleType handle)
+{
+       double elapsed = 0.0;
+
+       GstMessage *gMessage = NULL;
+       GstBus *bus = NULL;
+       GstClockTime timeout = 1 * GST_SECOND;  /* maximum waiting time */
+       GTimer *timer = NULL;
+
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+       _MMStreamRecorderSubContext *sc = NULL;
+
+       mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+       sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
+
+       _mmstreamrec_dbg_log("");
+       if (sc) {
+               bus = gst_pipeline_get_bus(GST_PIPELINE(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst));
+               timer = g_timer_new();
+
+               if (!(sc->bget_eos)) {
+                       while (TRUE) {
+                               elapsed = g_timer_elapsed(timer, NULL);
+
+                               /*_mmstreamrec_dbg_log("elapsed:%f sec", elapsed);*/
+
+                               if (elapsed > _MMSTREAMRECORDER_WAIT_EOS_TIME) {
+                                       _mmstreamrec_dbg_warn("Timeout. EOS isn't received.");
+                                       g_timer_destroy(timer);
+                                       gst_object_unref(bus);
+                                       return MM_ERROR_STREAMRECORDER_RESPONSE_TIMEOUT;
+                               }
+
+                               gMessage = gst_bus_timed_pop(bus, timeout);
+                               if (gMessage != NULL) {
+                                       _mmstreamrec_dbg_log("Get message(%x).", GST_MESSAGE_TYPE(gMessage));
+                                       _mmstreamrecorder_pipeline_cb_message(bus, gMessage, (void *)hstreamrecorder);
+
+                                       if (GST_MESSAGE_TYPE(gMessage) == GST_MESSAGE_EOS || sc->bget_eos) {
+                                               gst_message_unref(gMessage);
+                                               break;
+                                       }
+                                       gst_message_unref(gMessage);
+                               } else {
+                                       _mmstreamrec_dbg_log("timeout of gst_bus_timed_pop()");
+                                       if (sc->bget_eos) {
+                                               _mmstreamrec_dbg_log("Get EOS in another thread.");
+                                               break;
+                                       }
+                               }
+                       }
+               }
+
+               g_timer_destroy(timer);
+               timer = NULL;
+               gst_object_unref(bus);
+               bus = NULL;
+       } else {
+               _mmstreamrec_dbg_err("subcontext error NULL");
+       }
+       _mmstreamrec_dbg_log("END");
+
+       return MM_ERROR_NONE;
+}
+
+void _mmstreamrecorder_remove_element_handle(MMHandleType handle, void *element, int first_elem, int last_elem)
+{
+       int i = 0;
+       _MMStreamRecorderGstElement *remove_element = (_MMStreamRecorderGstElement *) element;
+
+       mmf_return_if_fail(handle && remove_element);
+       mmf_return_if_fail((first_elem >= 0) && (last_elem > 0) && (last_elem > first_elem));
+
+       _mmstreamrec_dbg_log("");
+
+       for (i = first_elem; i <= last_elem; i++) {
+               remove_element[i].gst = NULL;
+               remove_element[i].id = _MMSTREAMRECORDER_ENCODE_NONE;
+       }
+
+       return;
+}
+
+gboolean _mmstreamrecorder_add_elements_to_bin(GstBin *bin, GList *element_list)
+{
+       GList *local_list = element_list;
+       _MMStreamRecorderGstElement *element = NULL;
+
+       mmf_return_val_if_fail(bin && local_list, FALSE);
+
+       while (local_list) {
+               element = (_MMStreamRecorderGstElement *) local_list->data;
+               if (element && element->gst) {
+                       if (!gst_bin_add(bin, GST_ELEMENT(element->gst))) {
+                               _mmstreamrec_dbg_err("Add element [%s] to bin [%s] FAILED", GST_ELEMENT_NAME(GST_ELEMENT(element->gst)), GST_ELEMENT_NAME(GST_ELEMENT(bin)));
+                               return FALSE;
+                       } else {
+                               _mmstreamrec_dbg_log("Add element [%s] to bin [%s] OK", GST_ELEMENT_NAME(GST_ELEMENT(element->gst)), GST_ELEMENT_NAME(GST_ELEMENT(bin)));
+                       }
+               }
+               local_list = local_list->next;
+       }
+
+       return TRUE;
+}
+
+gboolean _mmstreamrecorder_link_elements(GList * element_list)
+{
+       GList *local_list = element_list;
+       _MMStreamRecorderGstElement *element = NULL;
+       _MMStreamRecorderGstElement *pre_element = NULL;
+
+       mmf_return_val_if_fail(local_list, FALSE);
+
+       pre_element = (_MMStreamRecorderGstElement *) local_list->data;
+       local_list = local_list->next;
+
+       while (local_list) {
+               element = (_MMStreamRecorderGstElement *) local_list->data;
+               if (element && element->gst) {
+                       if (pre_element != NULL) {
+                               if (_MM_GST_ELEMENT_LINK(GST_ELEMENT(pre_element->gst), GST_ELEMENT(element->gst))) {
+                                       _mmstreamrec_dbg_log("Link [%s] to [%s] OK", GST_ELEMENT_NAME(GST_ELEMENT(pre_element->gst)), GST_ELEMENT_NAME(GST_ELEMENT(element->gst)));
+                               } else {
+                                       _mmstreamrec_dbg_err("Link [%s] to [%s] FAILED", GST_ELEMENT_NAME(GST_ELEMENT(pre_element->gst)), GST_ELEMENT_NAME(GST_ELEMENT(element->gst)));
+                                       return FALSE;
+                               }
+                       } else {
+                               _mmstreamrec_dbg_err("pre_element is null");
+                               return FALSE;
+                       }
+               }
+
+               pre_element = element;
+               local_list = local_list->next;
+       }
+
+       return TRUE;
+}
+
+int _mmstreamrecorder_gst_set_state(MMHandleType handle, GstElement *pipeline, GstState target_state)
+{
+       unsigned int k = 0;
+       GstState pipeline_state = GST_STATE_VOID_PENDING;
+       GstStateChangeReturn setChangeReturn = GST_STATE_CHANGE_FAILURE;
+       GstStateChangeReturn getChangeReturn = GST_STATE_CHANGE_FAILURE;
+       GstClockTime get_timeout = __MMSTREAMRECORDER_SET_GST_STATE_TIMEOUT * GST_SECOND;
+
+       mmf_return_val_if_fail(handle, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+
+       _mmstreamrec_dbg_log("Set state to %d", target_state);
+
+       _MMSTREAMRECORDER_LOCK_GST_STATE(handle);
+
+       for (k = 0; k < _MMSTREAMRECORDER_STATE_SET_COUNT; k++) {
+               setChangeReturn = gst_element_set_state(pipeline, target_state);
+               _mmstreamrec_dbg_log("gst_element_set_state[%d] return %d", target_state, setChangeReturn);
+               if (setChangeReturn != GST_STATE_CHANGE_FAILURE) {
+                       getChangeReturn = gst_element_get_state(pipeline, &pipeline_state, NULL, get_timeout);
+                       switch (getChangeReturn) {
+                       case GST_STATE_CHANGE_NO_PREROLL:
+                               _mmstreamrec_dbg_log("status=GST_STATE_CHANGE_NO_PREROLL.");
+                       case GST_STATE_CHANGE_SUCCESS:
+                               /* if we reached the final target state, exit */
+                               if (pipeline_state == target_state) {
+                                       _MMSTREAMRECORDER_UNLOCK_GST_STATE(handle);
+                                       return MM_ERROR_NONE;
+                               }
+                               break;
+                       case GST_STATE_CHANGE_ASYNC:
+                               _mmstreamrec_dbg_log("status=GST_STATE_CHANGE_ASYNC.");
+                               break;
+                       default:
+                               _MMSTREAMRECORDER_UNLOCK_GST_STATE(handle);
+                               _mmstreamrec_dbg_log("status=GST_STATE_CHANGE_FAILURE.");
+                               return MM_ERROR_STREAMRECORDER_GST_STATECHANGE;
+                       }
+
+                       _MMSTREAMRECORDER_UNLOCK_GST_STATE(handle);
+                       _mmstreamrec_dbg_err("timeout of gst_element_get_state()!!");
+                       return MM_ERROR_STREAMRECORDER_RESPONSE_TIMEOUT;
+               }
+               usleep(_MMSTREAMRECORDER_STATE_CHECK_INTERVAL);
+       }
+
+       _MMSTREAMRECORDER_UNLOCK_GST_STATE(handle);
+
+       _mmstreamrec_dbg_err("Failure. gst_element_set_state timeout!!");
+
+       return MM_ERROR_STREAMRECORDER_RESPONSE_TIMEOUT;
+}
+
+GstCaps *gst_set_videosrcpad_caps(gint srcfmt, gint width, gint height, gint rate, gint scale)
+{
+
+       GstCaps *caps = NULL;
+
+       if (srcfmt == MM_STREAMRECORDER_INPUT_FORMAT_NV12)
+               caps = gst_caps_new_simple("video/x-raw", "format", G_TYPE_STRING, "NV12", "width", G_TYPE_INT, width, "height", G_TYPE_INT, height, "framerate", GST_TYPE_FRACTION, rate, scale, NULL);
+       else if (srcfmt == MM_STREAMRECORDER_INPUT_FORMAT_I420)
+               caps = gst_caps_new_simple("video/x-raw", "format", G_TYPE_STRING, "I420", "width", G_TYPE_INT, width, "height", G_TYPE_INT, height, "framerate", GST_TYPE_FRACTION, rate, scale, NULL);
+       else
+               caps = gst_caps_new_simple("video/x-raw", "format", G_TYPE_STRING, "BGRA8888", "bpp", G_TYPE_INT, 32, "depth", G_TYPE_INT, 24, "endianness", G_TYPE_INT, 4321, "red_mask", G_TYPE_INT, 65280, "green_mask", G_TYPE_INT, 16711680, "blue_mask", G_TYPE_INT, -16777216, "width", G_TYPE_INT, width, "height", G_TYPE_INT, height, "framerate", GST_TYPE_FRACTION, rate, scale, NULL);
+
+       if (!caps) {
+               _mmstreamrec_dbg_err("failed to alloc caps");
+               return NULL;
+       }
+
+       /* gchar *type = gst_caps_to_string(caps); */
+
+       /* _mmstreamrec_dbg_warn("Set srcpad caps: %s",type); */
+
+       /* g_free(type); */
+
+       return caps;
+}
+
+GstCaps *gst_set_audiosrcpad_caps(gint samplerate, gint channel, gint depth, gint width, gint datatype)
+{
+
+       GstCaps *caps = gst_caps_new_simple("audio/x-raw",
+                                                                               "rate", G_TYPE_INT, samplerate,
+                                                                               "channels", G_TYPE_INT, 2,
+                                                                               "depth", G_TYPE_INT, depth,
+                                                                               "width", G_TYPE_INT, width,
+                                                                               "signed", G_TYPE_BOOLEAN, TRUE,
+                                                                               "endianness", G_TYPE_INT, 1234,
+                                                                               NULL);
+
+       if (!caps) {
+               _mmstreamrec_dbg_err("failed to alloc caps");
+               return NULL;
+       }
+
+       /* gchar *type = gst_caps_to_string(caps); */
+
+       /* _mmstreamrec_dbg_log("Set srcpad caps: %s", type); */
+
+       /* g_free(type); */
+
+       return caps;
+}
diff --git a/src/mm_streamrecorder_gstdispatch.c b/src/mm_streamrecorder_gstdispatch.c
new file mode 100644 (file)
index 0000000..45b42f1
--- /dev/null
@@ -0,0 +1,1399 @@
+/*
+ * libmm-streamrecorder
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Hyuntae Kim <ht1211.kim@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 <stdio.h>
+#include <stdarg.h>
+#include <sys/vfs.h>                   /* struct statfs */
+
+#include "mm_streamrecorder_internal.h"
+#include "mm_streamrecorder_gstdispatch.h"
+#include "mm_streamrecorder_gstcommon.h"
+#include "mm_streamrecorder_util.h"
+#include "mm_streamrecorder_recorder.h"
+
+/*-----------------------------------------------------------------------
+|    GLOBAL VARIABLE DEFINITIONS for internal                          |
+-----------------------------------------------------------------------*/
+
+#define _MMSTREAMRECORDER_MINIMUM_FRAME              5
+#define _MMSTREAMRECORDER_FREE_SPACE_CHECK_INTERVAL  5
+#define _MMSTREAMRECORDER_MINIMUM_SPACE                (512*1024)      /* byte */
+#define _MMSTREAMRECORDER_MMS_MARGIN_SPACE             (512)   /* byte */
+#define _MMSTREAMRECORDER_AUDIO_FREE_SPACE_CHECK_INTERVAL  10
+#define _MMSTREAMRECORDER_AUDIO_MINIMUM_SPACE        (100*1024)
+
+/*-----------------------------------------------------------------------
+|    LOCAL VARIABLE DEFINITIONS for internal                           |
+-----------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+|    LOCAL FUNCTION PROTOTYPES:                                                                                                |
+---------------------------------------------------------------------------*/
+/* STATIC INTERNAL FUNCTION */
+
+/*===========================================================================================
+|                                                                                                                                                                                      |
+|  FUNCTION DEFINITIONS                                                                                                                                                |
+========================================================================================== */
+/*---------------------------------------------------------------------------
+|    GLOBAL FUNCTION DEFINITIONS:                                                                                      |
+---------------------------------------------------------------------------*/
+void _mmstreamrecorder_remove_buffer_probe(MMHandleType handle, _MMStreamRecorderHandlerCategory category)
+{
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+       GList *list = NULL;
+       MMStreamRecorderHandlerItem *item = NULL;
+
+       mmf_return_if_fail(hstreamrecorder);
+
+       if (!hstreamrecorder->buffer_probes) {
+               _mmstreamrec_dbg_warn("list for buffer probe is NULL");
+               return;
+       }
+
+       _mmstreamrec_dbg_log("start - category : 0x%x", category);
+
+       list = hstreamrecorder->buffer_probes;
+       while (list) {
+               item = list->data;
+               if (!item) {
+                       _mmstreamrec_dbg_err("Remove buffer probe faild, the item is NULL");
+                       list = g_list_next(list);
+                       continue;
+               }
+
+               if (item->category & category) {
+                       if (item->object && GST_IS_PAD(item->object)) {
+                               _mmstreamrec_dbg_log("Remove buffer probe on [%s:%s] - [ID : %lu], [Category : %x]", GST_DEBUG_PAD_NAME(item->object), item->handler_id, item->category);
+                               gst_pad_remove_probe(GST_PAD(item->object), item->handler_id);
+                       } else {
+                               _mmstreamrec_dbg_warn("Remove buffer probe faild, the pad is null or not pad, just remove item from list and free it");
+                       }
+
+                       list = g_list_next(list);
+                       hstreamrecorder->buffer_probes = g_list_remove(hstreamrecorder->buffer_probes, item);
+                       SAFE_FREE(item);
+               } else {
+                       _mmstreamrec_dbg_log("Skip item : [ID : %lu], [Category : %x] ", item->handler_id, item->category);
+                       list = g_list_next(list);
+               }
+       }
+
+       if (category == _MMSTREAMRECORDER_HANDLER_CATEGORY_ALL) {
+               g_list_free(hstreamrecorder->buffer_probes);
+               hstreamrecorder->buffer_probes = NULL;
+       }
+
+       _mmstreamrec_dbg_log("done");
+
+       return;
+}
+
+void _mmstreamrecorder_remove_event_probe(MMHandleType handle, _MMStreamRecorderHandlerCategory category)
+{
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+       GList *list = NULL;
+       MMStreamRecorderHandlerItem *item = NULL;
+
+       mmf_return_if_fail(hstreamrecorder);
+
+       if (!hstreamrecorder->event_probes) {
+               _mmstreamrec_dbg_warn("list for event probe is NULL");
+               return;
+       }
+
+       _mmstreamrec_dbg_log("start - category : 0x%x", category);
+
+       list = hstreamrecorder->event_probes;
+       while (list) {
+               item = list->data;
+               if (!item) {
+                       _mmstreamrec_dbg_err("Remove event probe faild, the item is NULL");
+                       list = g_list_next(list);
+                       continue;
+               }
+
+               if (item->category & category) {
+                       if (item->object && GST_IS_PAD(item->object)) {
+                               _mmstreamrec_dbg_log("Remove event probe on [%s:%s] - [ID : %lu], [Category : %x]", GST_DEBUG_PAD_NAME(item->object), item->handler_id, item->category);
+                               gst_pad_remove_probe(GST_PAD(item->object), item->handler_id);
+                       } else {
+                               _mmstreamrec_dbg_warn("Remove event probe faild, the pad is null or not pad, just remove item from list and free it");
+                       }
+
+                       list = g_list_next(list);
+                       hstreamrecorder->event_probes = g_list_remove(hstreamrecorder->event_probes, item);
+                       SAFE_FREE(item);
+               } else {
+                       _mmstreamrec_dbg_log("Skip item : [ID : %lu], [Category : %x] ", item->handler_id, item->category);
+                       list = g_list_next(list);
+               }
+       }
+
+       if (category == _MMSTREAMRECORDER_HANDLER_CATEGORY_ALL) {
+               g_list_free(hstreamrecorder->event_probes);
+               hstreamrecorder->event_probes = NULL;
+       }
+
+       _mmstreamrec_dbg_log("done");
+
+       return;
+}
+
+void _mmstreamrecorder_remove_data_probe(MMHandleType handle, _MMStreamRecorderHandlerCategory category)
+{
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+       GList *list = NULL;
+       MMStreamRecorderHandlerItem *item = NULL;
+
+       mmf_return_if_fail(hstreamrecorder);
+
+       if (!hstreamrecorder->data_probes) {
+               _mmstreamrec_dbg_warn("list for data probe is NULL");
+               return;
+       }
+
+       _mmstreamrec_dbg_log("start - category : 0x%x", category);
+
+       list = hstreamrecorder->data_probes;
+       while (list) {
+               item = list->data;
+               if (!item) {
+                       _mmstreamrec_dbg_err("Remove data probe faild, the item is NULL");
+                       list = g_list_next(list);
+                       continue;
+               }
+
+               if (item->category & category) {
+                       if (item->object && GST_IS_PAD(item->object)) {
+                               _mmstreamrec_dbg_log("Remove data probe on [%s:%s] - [ID : %lu], [Category : %x]", GST_DEBUG_PAD_NAME(item->object), item->handler_id, item->category);
+                               gst_pad_remove_probe(GST_PAD(item->object), item->handler_id);
+                       } else {
+                               _mmstreamrec_dbg_warn("Remove data probe faild, the pad is null or not pad, just remove item from list and free it");
+                       }
+
+                       list = g_list_next(list);
+                       hstreamrecorder->data_probes = g_list_remove(hstreamrecorder->data_probes, item);
+                       SAFE_FREE(item);
+               } else {
+                       _mmstreamrec_dbg_log("Skip item : [ID : %lu], [Category : %x] ", item->handler_id, item->category);
+                       list = g_list_next(list);
+               }
+       }
+
+       if (category == _MMSTREAMRECORDER_HANDLER_CATEGORY_ALL) {
+               g_list_free(hstreamrecorder->data_probes);
+               hstreamrecorder->data_probes = NULL;
+       }
+
+       _mmstreamrec_dbg_log("done");
+
+       return;
+}
+
+void _mmstreamrecorder_disconnect_signal(MMHandleType handle, _MMStreamRecorderHandlerCategory category)
+{
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+       GList *list = NULL;
+       MMStreamRecorderHandlerItem *item = NULL;
+
+       mmf_return_if_fail(hstreamrecorder);
+
+       if (!hstreamrecorder->signals) {
+               _mmstreamrec_dbg_warn("list for signal is NULL");
+               return;
+       }
+
+       _mmstreamrec_dbg_log("start - category : 0x%x", category);
+
+       list = hstreamrecorder->signals;
+       while (list) {
+               item = list->data;
+               if (!item) {
+                       _mmstreamrec_dbg_err("Fail to Disconnecting signal, the item is NULL");
+                       list = g_list_next(list);
+                       continue;
+               }
+
+               if (item->category & category) {
+                       if (item->object && GST_IS_ELEMENT(item->object)) {
+                               if (g_signal_handler_is_connected(item->object, item->handler_id)) {
+                                       _mmstreamrec_dbg_log("Disconnect signal from [%s] : [ID : %lu], [Category : %x]", GST_OBJECT_NAME(item->object), item->handler_id, item->category);
+                                       g_signal_handler_disconnect(item->object, item->handler_id);
+                               } else {
+                                       _mmstreamrec_dbg_warn("Signal was not connected, cannot disconnect it :  [%s]  [ID : %lu], [Category : %x]", GST_OBJECT_NAME(item->object), item->handler_id, item->category);
+                               }
+                       } else {
+                               _mmstreamrec_dbg_err("Fail to Disconnecting signal, the element is null or not element, just remove item from list and free it");
+                       }
+
+                       list = g_list_next(list);
+                       hstreamrecorder->signals = g_list_remove(hstreamrecorder->signals, item);
+                       SAFE_FREE(item);
+               } else {
+                       _mmstreamrec_dbg_log("Skip item : [ID : %lu], [Category : %x] ", item->handler_id, item->category);
+                       list = g_list_next(list);
+               }
+       }
+
+       if (category == _MMSTREAMRECORDER_HANDLER_CATEGORY_ALL) {
+               g_list_free(hstreamrecorder->signals);
+               hstreamrecorder->signals = NULL;
+       }
+
+       _mmstreamrec_dbg_log("done");
+
+       return;
+}
+
+void _mmstreamrecorder_element_release_noti(gpointer data, GObject *where_the_object_was)
+{
+       int i = 0;
+       _MMStreamRecorderSubContext *sc = (_MMStreamRecorderSubContext *) data;
+
+       mmf_return_if_fail(sc);
+
+       mmf_return_if_fail(sc->encode_element);
+
+       for (i = 0; i < _MMSTREAMRECORDER_ENCODE_PIPELINE_ELEMENT_NUM; i++) {
+               if (sc->encode_element[i].gst && (G_OBJECT(sc->encode_element[i].gst) == where_the_object_was)) {
+                       _mmstreamrec_dbg_warn("The encode element[%d][%p] is finalized", sc->encode_element[i].id, sc->encode_element[i].gst);
+                       sc->encode_element[i].gst = NULL;
+                       sc->encode_element[i].id = _MMSTREAMRECORDER_ENCODE_NONE;
+                       return;
+               }
+       }
+
+       _mmstreamrec_dbg_warn("there is no matching element %p", where_the_object_was);
+
+       return;
+}
+
+gboolean _mmstreamrecorder_msg_callback(void *data)
+{
+       _MMStreamRecorderMsgItem *item = (_MMStreamRecorderMsgItem *) data;
+       mmf_streamrecorder_t *hstreamrecorder = NULL;
+       mmf_return_val_if_fail(item, FALSE);
+
+       hstreamrecorder = MMF_STREAMRECORDER(item->handle);
+       mmf_return_val_if_fail(hstreamrecorder, FALSE);
+
+       /* _mmstreamrec_dbg_log("msg id:%x, msg_cb:%p, msg_data:%p, item:%p", item->id, hstreamrecorder->msg_cb, hstreamrecorder->msg_data, item); */
+       _MMSTREAMRECORDER_LOCK_MESSAGE_CALLBACK(hstreamrecorder);
+
+       if ((hstreamrecorder) && (hstreamrecorder->msg_cb))
+               hstreamrecorder->msg_cb(item->id, (MMMessageParamType *) (&(item->param)), hstreamrecorder->msg_cb_param);
+
+       _MMSTREAMRECORDER_UNLOCK_MESSAGE_CALLBACK(hstreamrecorder);
+
+       _MMSTREAMRECORDER_LOCK((MMHandleType) hstreamrecorder);
+       if (hstreamrecorder->msg_data)
+               hstreamrecorder->msg_data = g_list_remove(hstreamrecorder->msg_data, item);
+
+       free(item);
+       item = NULL;
+       _MMSTREAMRECORDER_UNLOCK((MMHandleType) hstreamrecorder);
+       /* For not being called again */
+       return FALSE;
+}
+
+void _mmstreamrecorder_remove_all_handlers(MMHandleType handle, _MMStreamRecorderHandlerCategory category)
+{
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+
+       _mmstreamrec_dbg_log("ENTER");
+
+       if (hstreamrecorder->signals)
+               _mmstreamrecorder_disconnect_signal((MMHandleType) hstreamrecorder, category);
+       if (hstreamrecorder->data_probes)
+               _mmstreamrecorder_remove_data_probe((MMHandleType) hstreamrecorder, category);
+       if (hstreamrecorder->event_probes)
+               _mmstreamrecorder_remove_event_probe((MMHandleType) hstreamrecorder, category);
+       if (hstreamrecorder->buffer_probes)
+               _mmstreamrecorder_remove_buffer_probe((MMHandleType) hstreamrecorder, category);
+
+       _mmstreamrec_dbg_log("LEAVE");
+}
+
+gboolean _mmstreamrecorder_send_message(MMHandleType handle, _MMStreamRecorderMsgItem *data)
+{
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+       _MMStreamRecorderMsgItem *item = NULL;
+
+       mmf_return_val_if_fail(hstreamrecorder, FALSE);
+       mmf_return_val_if_fail(data, FALSE);
+
+       /* _mmstreamrec_dbg_err("ENTER"); */
+
+       /* _mmstreamrec_dbg_err("data->id =  %x",data->id); */
+
+       switch (data->id) {
+       case MM_MESSAGE_STREAMRECORDER_STATE_CHANGED:
+               data->param.union_type = MM_MSG_UNION_STATE;
+               break;
+       case MM_MESSAGE_STREAMRECORDER_RECORDING_STATUS:
+               data->param.union_type = MM_MSG_UNION_RECORDING_STATUS;
+               break;
+       case MM_MESSAGE_STREAMRECORDER_CONSUME_COMPLETE:        /* 0x801 */
+               data->param.union_type = MM_MSG_UNION_CONSUME_RECORDER_BUFFER;
+               break;
+       case MM_MESSAGE_STREAMRECORDER_TIME_LIMIT:
+       case MM_MESSAGE_STREAMRECORDER_MAX_SIZE:
+       case MM_MESSAGE_STREAMRECORDER_NO_FREE_SPACE:
+       case MM_MESSAGE_STREAMRECORDER_ERROR:
+       case MM_MESSAGE_STREAMRECORDER_VIDEO_CAPTURED:
+       case MM_MESSAGE_STREAMRECORDER_AUDIO_CAPTURED:
+       case MM_MESSAGE_READY_TO_RESUME:
+       default:
+               data->param.union_type = MM_MSG_UNION_CODE;
+               break;
+       }
+
+       item = g_malloc(sizeof(_MMStreamRecorderMsgItem));
+       if (!item)
+               return FALSE;
+       memcpy(item, data, sizeof(_MMStreamRecorderMsgItem));
+       item->handle = handle;
+
+       _MMSTREAMRECORDER_LOCK(handle);
+       hstreamrecorder->msg_data = g_list_append(hstreamrecorder->msg_data, item);
+       /* _mmstreamrec_dbg_log("item[%p]", item); */
+
+       /* Use DEFAULT priority */
+       g_idle_add_full(G_PRIORITY_DEFAULT, _mmstreamrecorder_msg_callback, item, NULL);
+
+       _MMSTREAMRECORDER_UNLOCK(handle);
+
+       return TRUE;
+}
+
+gboolean _mmstreamrecorder_remove_message_all(MMHandleType handle)
+{
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+       _MMStreamRecorderMsgItem *item = NULL;
+       gboolean ret = TRUE;
+       GList *list = NULL;
+
+       mmf_return_val_if_fail(hstreamrecorder, FALSE);
+
+       _MMSTREAMRECORDER_LOCK(handle);
+
+       if (hstreamrecorder->msg_data) {
+               list = hstreamrecorder->msg_data;
+
+               while (list) {
+                       item = list->data;
+                       list = g_list_next(list);
+
+                       if (item) {
+                               ret = g_idle_remove_by_data(item);
+                               _mmstreamrec_dbg_log("Remove item[%p]. ret[%d]", item, ret);
+
+                               hstreamrecorder->msg_data = g_list_remove(hstreamrecorder->msg_data, item);
+
+                               SAFE_FREE(item);
+                       }
+               }
+
+               g_list_free(hstreamrecorder->msg_data);
+               hstreamrecorder->msg_data = NULL;
+       }
+
+       /* remove idle function for playing capture sound */
+       do {
+               ret = g_idle_remove_by_data(hstreamrecorder);
+               _mmstreamrec_dbg_log("remove idle function for playing capture sound. ret[%d]", ret);
+       } while (ret);
+
+       _MMSTREAMRECORDER_UNLOCK(handle);
+
+       return ret;
+}
+
+gboolean _mmstreamrecorder_handle_gst_error(MMHandleType handle, GstMessage *message, GError *error)
+{
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+       /* _MMstreamrecorderMsgItem msg; */
+       gchar *msg_src_element;
+       _MMStreamRecorderSubContext *sc = NULL;
+
+       return_val_if_fail(hstreamrecorder, FALSE);
+       return_val_if_fail(error, FALSE);
+       sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
+       mmf_return_val_if_fail(sc, FALSE);
+
+       _mmstreamrec_dbg_log("");
+
+       /* filtering filesink related errors */
+       if ((error->code == GST_RESOURCE_ERROR_WRITE || error->code == GST_RESOURCE_ERROR_SEEK)) {
+               if (sc->ferror_count == 2 && sc->ferror_send == FALSE) {
+                       sc->ferror_send = TRUE;
+                       /* msg.param.code = __mmstreamrecorder_gst_handle_resource_error(handle, error->code, message); */
+               } else {
+                       sc->ferror_count++;
+                       _mmstreamrec_dbg_warn("Skip error");
+                       return TRUE;
+               }
+       }
+
+       if (error->domain == GST_CORE_ERROR) {
+               /* msg.param.code = __mmstreamrecorder_gst_handle_core_error(handle, error->code, message); */
+       } else if (error->domain == GST_LIBRARY_ERROR) {
+               /* msg.param.code = __mmstreamrecorder_gst_handle_library_error(handle, error->code, message); */
+       } else if (error->domain == GST_RESOURCE_ERROR) {
+               /* msg.param.code = __mmstreamrecorder_gst_handle_resource_error(handle, error->code, message); */
+       } else if (error->domain == GST_STREAM_ERROR) {
+               /* msg.param.code = __mmstreamrecorder_gst_handle_stream_error(handle, error->code, message); */
+       } else {
+               _mmstreamrec_dbg_warn("This error domain is not defined.");
+
+               /* we treat system error as an internal error */
+               /* msg.param.code = MM_ERROR_streamrecorder_INTERNAL; */
+       }
+
+       if (message->src) {
+               msg_src_element = GST_ELEMENT_NAME(GST_ELEMENT_CAST(message->src));
+/*             _mmstreamrec_dbg_err("-Msg src : [%s] Domain : [%s]   Error : [%s]  Code : [%d] is tranlated to error code : [0x%x]",
+                                                               msg_src_element, g_quark_to_string (error->domain), error->message, error->code, msg.param.code); */
+       } else {
+/*             _mmstreamrec_dbg_err("Domain : [%s]   Error : [%s]  Code : [%d] is tranlated to error code : [0x%x]",
+                                                               g_quark_to_string (error->domain), error->message, error->code, msg.param.code); */
+       }
+
+#ifdef _MMSTREAMRECORDER_SKIP_GST_FLOW_ERROR
+       /* Check whether send this error to application */
+/*     if (msg.param.code == MM_ERROR_streamrecorder_GST_FLOW_ERROR) {
+               _mmstreamrec_dbg_log("We got the error. But skip it.");
+               return TRUE;
+       } */
+#endif                                                 /* _MMstreamrecorder_SKIP_GST_FLOW_ERROR */
+
+       /* post error to application */
+       sc->error_occurs = TRUE;
+/*     msg.id = MM_MESSAGE_streamrecorder_ERROR;
+       _mmstreamrecorder_send_message(handle, &msg); */
+
+       return TRUE;
+}
+
+gint _mmstreamrecorder_gst_handle_core_error(MMHandleType handle, int code, GstMessage *message)
+{
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+       _MMStreamRecorderSubContext *sc = NULL;
+       GstElement *element = NULL;
+
+       _mmstreamrec_dbg_log("");
+
+       mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+
+       sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
+       mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+
+       /* Specific plugin - video encoder plugin */
+       element = GST_ELEMENT_CAST(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst);
+
+       if (GST_ELEMENT_CAST(message->src) == element) {
+               if (code == GST_CORE_ERROR_NEGOTIATION)
+                       return MM_ERROR_STREAMRECORDER_GST_NEGOTIATION;
+               else
+                       return MM_ERROR_STREAMRECORDER_ENCODER;
+       }
+
+       /* General */
+       switch (code) {
+       case GST_CORE_ERROR_STATE_CHANGE:
+               return MM_ERROR_STREAMRECORDER_GST_STATECHANGE;
+       case GST_CORE_ERROR_NEGOTIATION:
+               return MM_ERROR_STREAMRECORDER_GST_NEGOTIATION;
+       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_EVENT:
+       case GST_CORE_ERROR_CAPS:
+       case GST_CORE_ERROR_TAG:
+       case GST_CORE_ERROR_CLOCK:
+       case GST_CORE_ERROR_DISABLED:
+       default:
+               return MM_ERROR_STREAMRECORDER_GST_CORE;
+               break;
+       }
+}
+
+gint _mmstreamrecorder_gst_handle_library_error(MMHandleType handle, int code, GstMessage *message)
+{
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+       return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+
+       _mmstreamrec_dbg_log("");
+
+       /* Specific plugin - NONE */
+
+       /* General */
+       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:
+               _mmstreamrec_dbg_err("Library error(%d)", code);
+               return MM_ERROR_STREAMRECORDER_GST_LIBRARY;
+       }
+}
+
+gint _mmstreamrecorder_gst_handle_resource_error(MMHandleType handle, int code, GstMessage *message)
+{
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+       _MMStreamRecorderSubContext *sc = NULL;
+       GstElement *element = NULL;
+
+       mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+
+       sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
+       mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+
+       _mmstreamrec_dbg_log("");
+
+       /* Specific plugin */
+
+       /* encodebin */
+       element = GST_ELEMENT_CAST(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst);
+       if (GST_ELEMENT_CAST(message->src) == element) {
+               if (code == GST_RESOURCE_ERROR_FAILED) {
+                       _mmstreamrec_dbg_err("Encoder [Resource error]");
+                       return MM_ERROR_STREAMRECORDER_ENCODER_BUFFER;
+               } else {
+                       _mmstreamrec_dbg_err("Encoder [General(%d)]", code);
+                       return MM_ERROR_STREAMRECORDER_ENCODER;
+               }
+       }
+
+       /* General */
+       switch (code) {
+       case GST_RESOURCE_ERROR_WRITE:
+               _mmstreamrec_dbg_err("File write error");
+               return MM_ERROR_FILE_WRITE;
+       case GST_RESOURCE_ERROR_NO_SPACE_LEFT:
+               _mmstreamrec_dbg_err("No left space");
+               return MM_MESSAGE_STREAMRECORDER_NO_FREE_SPACE;
+       case GST_RESOURCE_ERROR_OPEN_WRITE:
+               _mmstreamrec_dbg_err("Out of storage");
+               return MM_ERROR_OUT_OF_STORAGE;
+       case GST_RESOURCE_ERROR_SEEK:
+               _mmstreamrec_dbg_err("File read(seek)");
+               return MM_ERROR_FILE_READ;
+       case GST_RESOURCE_ERROR_NOT_FOUND:
+       case GST_RESOURCE_ERROR_FAILED:
+       case GST_RESOURCE_ERROR_TOO_LAZY:
+       case GST_RESOURCE_ERROR_BUSY:
+       case GST_RESOURCE_ERROR_OPEN_READ:
+       case GST_RESOURCE_ERROR_OPEN_READ_WRITE:
+       case GST_RESOURCE_ERROR_CLOSE:
+       case GST_RESOURCE_ERROR_READ:
+       case GST_RESOURCE_ERROR_SYNC:
+       case GST_RESOURCE_ERROR_SETTINGS:
+       default:
+               _mmstreamrec_dbg_err("Resource error(%d)", code);
+               return MM_ERROR_STREAMRECORDER_GST_RESOURCE;
+       }
+}
+
+gint _mmstreamrecorder_gst_handle_stream_error(MMHandleType handle, int code, GstMessage *message)
+{
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+       _MMStreamRecorderSubContext *sc = NULL;
+       GstElement *element = NULL;
+
+       mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+
+       sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
+       mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+
+       _mmstreamrec_dbg_log("");
+
+       /* Specific plugin */
+       /* video encoder */
+       element = GST_ELEMENT_CAST(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst);
+       if (GST_ELEMENT_CAST(message->src) == element) {
+               switch (code) {
+               case GST_STREAM_ERROR_WRONG_TYPE:
+                       _mmstreamrec_dbg_err("Video encoder [wrong stream type]");
+                       return MM_ERROR_STREAMRECORDER_ENCODER_WRONG_TYPE;
+               case GST_STREAM_ERROR_ENCODE:
+                       _mmstreamrec_dbg_err("Video encoder [encode error]");
+                       return MM_ERROR_STREAMRECORDER_ENCODER_WORKING;
+               case GST_STREAM_ERROR_FAILED:
+                       _mmstreamrec_dbg_err("Video encoder [stream failed]");
+                       return MM_ERROR_STREAMRECORDER_ENCODER_WORKING;
+               default:
+                       _mmstreamrec_dbg_err("Video encoder [General(%d)]", code);
+                       return MM_ERROR_STREAMRECORDER_ENCODER;
+               }
+       }
+
+       /* General plugin */
+       switch (code) {
+       case GST_STREAM_ERROR_FORMAT:
+               _mmstreamrec_dbg_err("General [negotiation error(%d)]", code);
+               return MM_ERROR_STREAMRECORDER_GST_NEGOTIATION;
+       case GST_STREAM_ERROR_FAILED:
+               _mmstreamrec_dbg_err("General [flow error(%d)]", code);
+               return MM_ERROR_STREAMRECORDER_GST_FLOW_ERROR;
+       case GST_STREAM_ERROR_TYPE_NOT_FOUND:
+       case GST_STREAM_ERROR_DECODE:
+       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_DECRYPT:
+       case GST_STREAM_ERROR_DECRYPT_NOKEY:
+       case GST_STREAM_ERROR_WRONG_TYPE:
+       default:
+               _mmstreamrec_dbg_err("General [error(%d)]", code);
+               return MM_ERROR_STREAMRECORDER_GST_STREAM;
+       }
+}
+
+gboolean _mmstreamrecorder_handle_gst_warning(MMHandleType handle, GstMessage *message, GError *error)
+{
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+       gchar *debug = NULL;
+       GError *err = NULL;
+
+       return_val_if_fail(hstreamrecorder, FALSE);
+       return_val_if_fail(error, FALSE);
+
+       _mmstreamrec_dbg_log("");
+
+       gst_message_parse_warning(message, &err, &debug);
+
+       if (error->domain == GST_CORE_ERROR) {
+               _mmstreamrec_dbg_warn("GST warning: GST_CORE domain");
+       } else if (error->domain == GST_LIBRARY_ERROR) {
+               _mmstreamrec_dbg_warn("GST warning: GST_LIBRARY domain");
+       } else if (error->domain == GST_RESOURCE_ERROR) {
+               _mmstreamrec_dbg_warn("GST warning: GST_RESOURCE domain");
+               /* _mmstreamrecorder_gst_handle_resource_warning(handle, message, error); */
+       } else if (error->domain == GST_STREAM_ERROR) {
+               _mmstreamrec_dbg_warn("GST warning: GST_STREAM domain");
+       } else {
+               _mmstreamrec_dbg_warn("This error domain(%d) is not defined.", error->domain);
+       }
+
+       if (err != NULL) {
+               g_error_free(err);
+               err = NULL;
+       }
+       if (debug != NULL) {
+               _mmstreamrec_dbg_err("Debug: %s", debug);
+               g_free(debug);
+               debug = NULL;
+       }
+
+       return TRUE;
+}
+
+gboolean _mmstreamrecorder_pipeline_cb_message(GstBus *bus, GstMessage *message, gpointer data)
+{
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(data);
+       /* _MMstreamrecorderMsgItem msg; */
+       _MMStreamRecorderSubContext *sc = NULL;
+
+       mmf_return_val_if_fail(hstreamrecorder, FALSE);
+       mmf_return_val_if_fail(message, FALSE);
+       /* _mmstreamrec_dbg_log("message type=(%d)", GST_MESSAGE_TYPE(message)); */
+
+       switch (GST_MESSAGE_TYPE(message)) {
+       case GST_MESSAGE_UNKNOWN:
+               _mmstreamrec_dbg_log("GST_MESSAGE_UNKNOWN");
+               break;
+       case GST_MESSAGE_EOS:
+               {
+                       _mmstreamrec_dbg_log("Got EOS from element \"%s\".", GST_STR_NULL(GST_ELEMENT_NAME(GST_MESSAGE_SRC(message))));
+
+                       sc = MMF_STREAMRECORDER_SUBCONTEXT(hstreamrecorder);
+                       mmf_return_val_if_fail(sc, TRUE);
+
+                       /*if (hstreamrecorder->type != MM_STREAMRECORDER_MODE_AUDIO) { */
+                       mmf_return_val_if_fail(sc->info_video, TRUE);
+                       if (sc->info_video->b_commiting) {
+                               _mmstreamrecorder_video_handle_eos((MMHandleType) hstreamrecorder);
+                       }
+                       /*} else {
+                          mmf_return_val_if_fail(sc->info_audio, TRUE);
+                          if (sc->info_audio->b_commiting) {
+                          _mmstreamrecorder_audio_handle_eos((MMHandleType)hstreamrecorder);
+                          }
+                          } */
+
+                       sc->bget_eos = TRUE;
+
+                       break;
+               }
+       case GST_MESSAGE_ERROR:
+               {
+                       GError *err;
+                       gchar *debug;
+                       gst_message_parse_error(message, &err, &debug);
+
+                       _mmstreamrec_dbg_err("GSTERR: %s", err->message);
+                       _mmstreamrec_dbg_err("Error Debug: %s", debug);
+
+                       _mmstreamrecorder_handle_gst_error((MMHandleType) hstreamrecorder, message, err);
+
+                       g_error_free(err);
+                       g_free(debug);
+                       break;
+               }
+       case GST_MESSAGE_WARNING:
+               {
+                       GError *err;
+                       gchar *debug;
+                       gst_message_parse_warning(message, &err, &debug);
+
+                       _mmstreamrec_dbg_warn("GSTWARN: %s", err->message);
+
+                       _mmstreamrecorder_handle_gst_warning((MMHandleType) hstreamrecorder, message, err);
+
+                       g_error_free(err);
+                       g_free(debug);
+                       break;
+               }
+       case GST_MESSAGE_INFO:
+               _mmstreamrec_dbg_log("GST_MESSAGE_INFO");
+               break;
+       case GST_MESSAGE_TAG:
+               _mmstreamrec_dbg_log("GST_MESSAGE_TAG");
+               break;
+       case GST_MESSAGE_BUFFERING:
+               _mmstreamrec_dbg_log("GST_MESSAGE_BUFFERING");
+               break;
+       case GST_MESSAGE_STATE_CHANGED:
+               {
+                       const GValue *vnewstate;
+                       GstState newstate;
+                       GstElement *pipeline = NULL;
+
+                       sc = MMF_STREAMRECORDER_SUBCONTEXT(hstreamrecorder);
+                       if ((sc) && (sc->encode_element)) {
+                               if (sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst) {
+                                       pipeline = sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst;
+                                       if (message->src == (GstObject *) pipeline) {
+                                               vnewstate = (GValue *) gst_structure_get_value(gst_message_get_structure(message), "new-state");
+                                               newstate = (GstState) vnewstate->data[0].v_int;
+                                               _mmstreamrec_dbg_log("GST_MESSAGE_STATE_CHANGED[%s]", gst_element_state_get_name(newstate));
+                                       }
+                               }
+                       }
+                       break;
+               }
+       case GST_MESSAGE_STATE_DIRTY:
+               _mmstreamrec_dbg_log("GST_MESSAGE_STATE_DIRTY");
+               break;
+       case GST_MESSAGE_STEP_DONE:
+               _mmstreamrec_dbg_log("GST_MESSAGE_STEP_DONE");
+               break;
+       case GST_MESSAGE_CLOCK_PROVIDE:
+               _mmstreamrec_dbg_log("GST_MESSAGE_CLOCK_PROVIDE");
+               break;
+       case GST_MESSAGE_CLOCK_LOST:
+               _mmstreamrec_dbg_log("GST_MESSAGE_CLOCK_LOST");
+               break;
+       case GST_MESSAGE_NEW_CLOCK:
+               {
+                       GstClock *l_clock;
+                       gst_message_parse_new_clock(message, &l_clock);
+                       _mmstreamrec_dbg_log("GST_MESSAGE_NEW_CLOCK : %s", (l_clock ? GST_OBJECT_NAME(l_clock) : "NULL"));
+                       break;
+               }
+       case GST_MESSAGE_STRUCTURE_CHANGE:
+               _mmstreamrec_dbg_log("GST_MESSAGE_STRUCTURE_CHANGE");
+               break;
+       case GST_MESSAGE_STREAM_STATUS:
+               _mmstreamrec_dbg_log("GST_MESSAGE_STREAM_STATUS");
+               break;
+       case GST_MESSAGE_APPLICATION:
+               _mmstreamrec_dbg_log("GST_MESSAGE_APPLICATION");
+               break;
+       case GST_MESSAGE_ELEMENT:
+               _mmstreamrec_dbg_log("GST_MESSAGE_ELEMENT");
+               break;
+       case GST_MESSAGE_SEGMENT_START:
+               _mmstreamrec_dbg_log("GST_MESSAGE_SEGMENT_START");
+               break;
+       case GST_MESSAGE_SEGMENT_DONE:
+               _mmstreamrec_dbg_log("GST_MESSAGE_SEGMENT_DONE");
+               break;
+       case GST_MESSAGE_DURATION:
+               _mmstreamrec_dbg_log("GST_MESSAGE_DURATION");
+               break;
+       case GST_MESSAGE_LATENCY:
+               _mmstreamrec_dbg_log("GST_MESSAGE_LATENCY");
+               break;
+       case GST_MESSAGE_ASYNC_START:
+               _mmstreamrec_dbg_log("GST_MESSAGE_ASYNC_START");
+               break;
+       case GST_MESSAGE_ASYNC_DONE:
+               _mmstreamrec_dbg_log("GST_MESSAGE_ASYNC_DONE");
+               break;
+       case GST_MESSAGE_ANY:
+               _mmstreamrec_dbg_log("GST_MESSAGE_ANY");
+               break;
+       default:
+               _mmstreamrec_dbg_log("not handled message type=(%d)", GST_MESSAGE_TYPE(message));
+               break;
+       }
+
+       return TRUE;
+}
+
+/**
+ * This function is record video data probing function.
+ * If this function is linked with certain pad by gst_pad_add_buffer_probe(),
+ * this function will be called when data stream pass through the pad.
+ *
+ * @param[in]  pad             probing pad which calls this function.
+ * @param[in]  buffer          buffer which contains stream data.
+ * @param[in]  u_data          user data.
+ * @return     This function returns true on success, or false value with error
+ * @remarks
+ * @see
+ */
+GstPadProbeReturn __mmstreamrecorder_eventprobe_monitor(GstPad *pad, GstPadProbeInfo *info, gpointer u_data)
+{
+       GstEvent *event = GST_PAD_PROBE_INFO_EVENT(info);
+       switch (GST_EVENT_TYPE(event)) {
+       case GST_EVENT_UNKNOWN:
+               /* upstream events */
+       case GST_EVENT_QOS:
+       case GST_EVENT_SEEK:
+       case GST_EVENT_NAVIGATION:
+       case GST_EVENT_LATENCY:
+               /* downstream serialized events */
+       case GST_EVENT_SEGMENT:
+       case GST_EVENT_TAG:
+       case GST_EVENT_BUFFERSIZE:
+               _mmstreamrec_dbg_log("[%s:%s] gots %s", GST_DEBUG_PAD_NAME(pad), GST_EVENT_TYPE_NAME(event));
+               break;
+       case GST_EVENT_EOS:
+               _mmstreamrec_dbg_warn("[%s:%s] gots %s", GST_DEBUG_PAD_NAME(pad), GST_EVENT_TYPE_NAME(event));
+               break;
+               /* bidirectional events */
+       case GST_EVENT_FLUSH_START:
+       case GST_EVENT_FLUSH_STOP:
+               _mmstreamrec_dbg_err("[%s:%s] gots %s", GST_DEBUG_PAD_NAME(pad), GST_EVENT_TYPE_NAME(event));
+               break;
+       default:
+               _mmstreamrec_dbg_log("[%s:%s] gots %s", GST_DEBUG_PAD_NAME(pad), GST_EVENT_TYPE_NAME(event));
+               break;
+       }
+
+       return GST_PAD_PROBE_OK;
+}
+
+GstPadProbeReturn __mmstreamrecorder_audio_dataprobe_check(GstPad *pad, GstPadProbeInfo *info, gpointer u_data)
+{
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(u_data);
+       GstBuffer *buffer = GST_PAD_PROBE_INFO_BUFFER(info);
+       GstMapInfo mapinfo = GST_MAP_INFO_INIT;
+       guint64 buffer_size = 0;
+
+       _MMStreamRecorderSubContext *sc = NULL;
+       _MMStreamRecorderAudioInfo *audioinfo = NULL;
+
+       mmf_return_val_if_fail(hstreamrecorder, GST_PAD_PROBE_OK);
+       mmf_return_val_if_fail(buffer, GST_PAD_PROBE_DROP);
+       sc = MMF_STREAMRECORDER_SUBCONTEXT(hstreamrecorder);
+
+       mmf_return_val_if_fail(sc && sc->info_audio, GST_PAD_PROBE_OK);
+       memset(&mapinfo, 0x0, sizeof(GstMapInfo));
+
+       audioinfo = sc->info_audio;
+
+       gst_buffer_map(buffer, &mapinfo, GST_MAP_READ);
+       buffer_size = mapinfo.size;
+       gst_buffer_unmap(buffer, &mapinfo);
+
+       /*_mmstreamrec_dbg_err("[%" GST_TIME_FORMAT "]", GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)));*/
+
+       if (audioinfo->audio_frame_count == 0) {
+               audioinfo->filesize += buffer_size;
+               audioinfo->audio_frame_count++;
+               return GST_PAD_PROBE_OK;
+       }
+
+       if (sc->ferror_send || sc->isMaxsizePausing) {
+               _mmstreamrec_dbg_warn("Recording is paused, drop frames");
+               return GST_PAD_PROBE_DROP;
+       }
+
+       audioinfo->filesize += buffer_size;
+       audioinfo->audio_frame_count++;
+
+       return GST_PAD_PROBE_OK;
+}
+
+GstPadProbeReturn __mmstreamrecorder_video_dataprobe_record(GstPad *pad, GstPadProbeInfo *info, gpointer u_data)
+{
+       static int count = 0;
+       gint ret = 0;
+       guint vq_size = 0;
+       guint aq_size = 0;
+       guint64 free_space = 0;
+       guint64 buffer_size = 0;
+       guint64 trailer_size = 0;
+       guint64 queued_buffer = 0;
+       char *filename = NULL;
+       GstBuffer *buffer = GST_PAD_PROBE_INFO_BUFFER(info);
+       GstMapInfo mapinfo = GST_MAP_INFO_INIT;
+
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(u_data);
+       _MMStreamRecorderMsgItem msg;
+       _MMStreamRecorderSubContext *sc = NULL;
+       _MMStreamRecorderVideoInfo *videoinfo = NULL;
+       _MMStreamRecorderFileInfo *finfo = NULL;
+
+       mmf_return_val_if_fail(hstreamrecorder, GST_PAD_PROBE_OK);
+       mmf_return_val_if_fail(buffer, GST_PAD_PROBE_DROP);
+
+       sc = MMF_STREAMRECORDER_SUBCONTEXT(hstreamrecorder);
+       mmf_return_val_if_fail(sc && sc->info_video && sc->info_file, TRUE);
+       memset(&mapinfo, 0x0, sizeof(GstMapInfo));
+
+       videoinfo = sc->info_video;
+       finfo = sc->info_file;
+
+       /*_mmstreamrec_dbg_log("[%" GST_TIME_FORMAT "]", GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)));*/
+       if (sc->ferror_send) {
+               _mmstreamrec_dbg_warn("file write error, drop frames");
+               return GST_PAD_PROBE_DROP;
+       }
+       gst_buffer_map(buffer, &mapinfo, GST_MAP_READ);
+       buffer_size = mapinfo.size;
+       gst_buffer_unmap(buffer, &mapinfo);
+
+       videoinfo->video_frame_count++;
+       if (videoinfo->video_frame_count <= (guint64) _MMSTREAMRECORDER_MINIMUM_FRAME) {
+               /* _mmstreamrec_dbg_log("Pass minimum frame: info->video_frame_count: %" G_GUINT64_FORMAT " ", info->video_frame_count); */
+               videoinfo->filesize += buffer_size;
+               return GST_PAD_PROBE_OK;
+       }
+
+       /* get trailer size */
+       if (finfo->fileformat == MM_FILE_FORMAT_3GP || finfo->fileformat == MM_FILE_FORMAT_MP4) {
+               MMSTREAMRECORDER_G_OBJECT_GET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_MUX].gst, "expected-trailer-size", &trailer_size);
+       } else {
+               trailer_size = 0;
+       }
+
+       /* to minimizing free space check overhead */
+       count = count % _MMSTREAMRECORDER_FREE_SPACE_CHECK_INTERVAL;
+       if (count++ == 0) {
+               filename = finfo->filename;
+               ret = _mmstreamrecorder_get_freespace(filename, &free_space);
+
+               /*_mmstreamrec_dbg_log("check free space for recording");*/
+
+               switch (ret) {
+               case -2:                                /* file not exist */
+               case -1:                                /* failed to get free space */
+                       _mmstreamrec_dbg_err("Error occured. [%d]", ret);
+                       if (sc->ferror_count == 2 && sc->ferror_send == FALSE) {
+                               sc->ferror_send = TRUE;
+                               msg.id = MM_MESSAGE_STREAMRECORDER_ERROR;
+                               if (ret == -2) {
+                                       msg.param.code = MM_ERROR_FILE_NOT_FOUND;
+                               } else {
+                                       msg.param.code = MM_ERROR_FILE_READ;
+                               }
+                               _mmstreamrecorder_send_message((MMHandleType) hstreamrecorder, &msg);
+                       } else {
+                               sc->ferror_count++;
+                       }
+
+                       return GST_PAD_PROBE_DROP;      /* skip this buffer */
+                       break;
+               default:                                /* succeeded to get free space */
+                       /* check free space for recording */
+                       /* get queued buffer size */
+                       if (sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC_QUE].gst) {
+                               MMSTREAMRECORDER_G_OBJECT_GET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC_QUE].gst, "current-level-bytes", &aq_size);
+                       }
+                       if (sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC_QUE].gst) {
+                               MMSTREAMRECORDER_G_OBJECT_GET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC_QUE].gst, "current-level-bytes", &vq_size);
+                       }
+
+                       queued_buffer = aq_size + vq_size;
+
+                       /* check free space */
+                       if (free_space < (_MMSTREAMRECORDER_MINIMUM_SPACE + buffer_size + trailer_size + queued_buffer)) {
+                               _mmstreamrec_dbg_warn("No more space for recording!!! Recording is paused.");
+                               _mmstreamrec_dbg_warn("Free Space : [%" G_GUINT64_FORMAT "], trailer size : [%" G_GUINT64_FORMAT "]," " buffer size : [%" G_GUINT64_FORMAT "], queued buffer size : [%" G_GUINT64_FORMAT "]", free_space, trailer_size, buffer_size, queued_buffer);
+
+                               if (!sc->isMaxsizePausing) {
+                                       MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "block", TRUE);
+                                       sc->isMaxsizePausing = TRUE;
+
+                                       msg.id = MM_MESSAGE_STREAMRECORDER_NO_FREE_SPACE;
+                                       _mmstreamrecorder_send_message((MMHandleType) hstreamrecorder, &msg);
+                               }
+
+                               return GST_PAD_PROBE_DROP;
+                       }
+                       break;
+               }
+       }
+
+       videoinfo->filesize += (guint64) buffer_size;
+
+       /*
+          _mmstreamrec_dbg_log("filesize %lld Byte, ", info->filesize);
+        */
+
+       return GST_PAD_PROBE_OK;
+}
+
+GstPadProbeReturn __mmstreamrecorder_video_dataprobe_audio_disable(GstPad *pad, GstPadProbeInfo *info, gpointer u_data)
+{
+       guint64 trailer_size = 0;
+       guint64 rec_pipe_time = 0;
+       unsigned int remained_time = 0;
+
+       GstBuffer *buffer = GST_PAD_PROBE_INFO_BUFFER(info);
+       GstClockTime b_time;
+
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(u_data);
+       _MMStreamRecorderMsgItem msg;
+       _MMStreamRecorderSubContext *sc = NULL;
+       _MMStreamRecorderVideoInfo *videoinfo = NULL;
+       _MMStreamRecorderFileInfo *finfo = NULL;
+
+       mmf_return_val_if_fail(buffer, GST_PAD_PROBE_DROP);
+       mmf_return_val_if_fail(hstreamrecorder, GST_PAD_PROBE_OK);
+
+       sc = MMF_STREAMRECORDER_SUBCONTEXT(u_data);
+       mmf_return_val_if_fail(sc, GST_PAD_PROBE_OK);
+       mmf_return_val_if_fail(sc->info_video, GST_PAD_PROBE_OK);
+       mmf_return_val_if_fail(sc->info_file, GST_PAD_PROBE_OK);
+
+       videoinfo = sc->info_video;
+       finfo = sc->info_file;
+
+       b_time = GST_BUFFER_TIMESTAMP(buffer);
+
+       rec_pipe_time = GST_TIME_AS_MSECONDS(b_time);
+
+       if (finfo->fileformat == MM_FILE_FORMAT_3GP || finfo->fileformat == MM_FILE_FORMAT_MP4) {
+               MMSTREAMRECORDER_G_OBJECT_GET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_MUX].gst, "expected-trailer-size", &trailer_size);
+       } else {
+               trailer_size = 0;
+       }
+
+       /* check max time */
+       if (videoinfo->max_time > 0 && rec_pipe_time > videoinfo->max_time) {
+               _mmstreamrec_dbg_warn("Current time : [%" G_GUINT64_FORMAT "], Maximum time : [%" G_GUINT64_FORMAT "]", rec_pipe_time, videoinfo->max_time);
+
+               if (!sc->isMaxtimePausing) {
+                       MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "block", TRUE);
+
+                       sc->isMaxtimePausing = TRUE;
+
+                       msg.id = MM_MESSAGE_STREAMRECORDER_RECORDING_STATUS;
+                       msg.param.recording_status.elapsed = (unsigned long long)rec_pipe_time;
+                       msg.param.recording_status.filesize = (unsigned long long)((videoinfo->filesize + trailer_size) >> 10);
+                       msg.param.recording_status.remained_time = 0;
+                       _mmstreamrecorder_send_message((MMHandleType) hstreamrecorder, &msg);
+
+                       msg.id = MM_MESSAGE_STREAMRECORDER_TIME_LIMIT;
+                       _mmstreamrecorder_send_message((MMHandleType) hstreamrecorder, &msg);
+               }
+
+               return GST_PAD_PROBE_DROP;
+       }
+
+       if (videoinfo->max_time > 0 && videoinfo->max_time < (remained_time + rec_pipe_time))
+               remained_time = videoinfo->max_time - rec_pipe_time;
+
+       msg.id = MM_MESSAGE_STREAMRECORDER_RECORDING_STATUS;
+       msg.param.recording_status.elapsed = (unsigned long long)rec_pipe_time;
+       msg.param.recording_status.filesize = (unsigned long long)((videoinfo->filesize + trailer_size) >> 10);
+       msg.param.recording_status.remained_time = remained_time;
+       _mmstreamrecorder_send_message((MMHandleType) hstreamrecorder, &msg);
+
+       /*
+          _mmstreamrec_dbg_log("time [%" GST_TIME_FORMAT "], size [%d]",
+          GST_TIME_ARGS(rec_pipe_time), msg.param.recording_status.filesize);
+        */
+
+       return GST_PAD_PROBE_OK;
+}
+
+GstPadProbeReturn __mmstreamrecorder_audioque_dataprobe(GstPad *pad, GstPadProbeInfo *info, gpointer u_data)
+{
+       _MMStreamRecorderMsgItem msg;
+       guint64 trailer_size = 0;
+       guint64 rec_pipe_time = 0;
+       _MMStreamRecorderSubContext *sc = NULL;
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(u_data);
+       _MMStreamRecorderVideoInfo *videoinfo = NULL;
+       _MMStreamRecorderFileInfo *finfo = NULL;
+       unsigned int remained_time = 0;
+       GstBuffer *buffer = GST_PAD_PROBE_INFO_BUFFER(info);
+
+       mmf_return_val_if_fail(buffer, GST_PAD_PROBE_DROP);
+       mmf_return_val_if_fail(hstreamrecorder, GST_PAD_PROBE_OK);
+       sc = MMF_STREAMRECORDER_SUBCONTEXT(u_data);
+
+       mmf_return_val_if_fail(sc, GST_PAD_PROBE_OK);
+       mmf_return_val_if_fail(sc->info_video, GST_PAD_PROBE_OK);
+       mmf_return_val_if_fail(sc->info_file, GST_PAD_PROBE_OK);
+
+       videoinfo = sc->info_video;
+       finfo = sc->info_file;
+
+       if (!GST_CLOCK_TIME_IS_VALID(GST_BUFFER_PTS(buffer))) {
+               _mmstreamrec_dbg_err("Buffer timestamp is invalid, check it");
+               return GST_PAD_PROBE_OK;
+       }
+
+       rec_pipe_time = GST_TIME_AS_MSECONDS(GST_BUFFER_TIMESTAMP(buffer));
+
+       if (finfo->fileformat == MM_FILE_FORMAT_3GP || finfo->fileformat == MM_FILE_FORMAT_MP4) {
+               MMSTREAMRECORDER_G_OBJECT_GET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_MUX].gst, "expected-trailer-size", &trailer_size);
+       } else {
+               trailer_size = 0;
+       }
+
+       if (videoinfo->max_time > 0 && videoinfo->max_time < (remained_time + rec_pipe_time))
+               remained_time = videoinfo->max_time - rec_pipe_time;
+
+       if (videoinfo->max_time > 0 && rec_pipe_time > videoinfo->max_time) {
+               _mmstreamrec_dbg_warn("Current time : [%" G_GUINT64_FORMAT "], Maximum time : [%" G_GUINT64_FORMAT "]", rec_pipe_time, videoinfo->max_time);
+
+               if (!sc->isMaxtimePausing) {
+                       MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "block", TRUE);
+
+                       sc->isMaxtimePausing = TRUE;
+
+                       msg.id = MM_MESSAGE_STREAMRECORDER_RECORDING_STATUS;
+                       msg.param.recording_status.elapsed = (unsigned long long)rec_pipe_time;
+                       msg.param.recording_status.filesize = (unsigned long long)((videoinfo->filesize + trailer_size) >> 10);
+                       msg.param.recording_status.remained_time = 0;
+                       _mmstreamrecorder_send_message((MMHandleType) hstreamrecorder, &msg);
+
+                       msg.id = MM_MESSAGE_STREAMRECORDER_TIME_LIMIT;
+                       _mmstreamrecorder_send_message((MMHandleType) hstreamrecorder, &msg);
+               }
+
+               return GST_PAD_PROBE_DROP;
+       }
+
+       msg.id = MM_MESSAGE_STREAMRECORDER_RECORDING_STATUS;
+       msg.param.recording_status.elapsed = (unsigned long long)rec_pipe_time;
+       msg.param.recording_status.filesize = (unsigned long long)((videoinfo->filesize + trailer_size) >> 10);
+       msg.param.recording_status.remained_time = remained_time;
+       _mmstreamrecorder_send_message((MMHandleType) hstreamrecorder, &msg);
+
+       /*
+          _mmstreamrec_dbg_log("audio data probe :: time [%" GST_TIME_FORMAT "], size [%lld KB]",
+          GST_TIME_ARGS(rec_pipe_time), msg.param.recording_status.filesize);
+        */
+
+       return GST_PAD_PROBE_OK;
+}
+
+void __mmstreamrecorder_audiorec_pad_added_cb(GstElement *element, GstPad *pad, MMHandleType handle)
+{
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+
+       _mmstreamrec_dbg_log("ENTER(%s)", GST_PAD_NAME(pad));
+       /* FIXME : the name of audio sink pad of wavparse, oggmux doesn't have 'audio'. How could I handle the name? */
+       if ((strstr(GST_PAD_NAME(pad), "audio")) || (strstr(GST_PAD_NAME(pad), "sink"))) {
+               MMSTREAMRECORDER_ADD_BUFFER_PROBE(pad, _MMSTREAMRECORDER_HANDLER_AUDIOREC, __mmstreamrecorder_audio_dataprobe_record, hstreamrecorder);
+       } else {
+               _mmstreamrec_dbg_warn("Unknow pad is added, check it : [%s]", GST_PAD_NAME(pad));
+       }
+
+       return;
+}
+
+GstPadProbeReturn __mmstreamrecorder_audio_dataprobe_record(GstPad *pad, GstPadProbeInfo *info, gpointer u_data)
+{
+       static int count = 0;
+       guint64 rec_pipe_time = 0;
+       guint64 free_space = 0;
+       guint64 buffer_size = 0;
+       guint64 trailer_size = 0;
+       char *filename = NULL;
+       unsigned long long remained_time = 0;
+       GstBuffer *buffer = GST_PAD_PROBE_INFO_BUFFER(info);
+
+       _MMStreamRecorderSubContext *sc = NULL;
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(u_data);
+       _MMStreamRecorderAudioInfo *audioinfo = NULL;
+       _MMStreamRecorderFileInfo *finfo = NULL;
+       _MMStreamRecorderMsgItem msg;
+
+       mmf_return_val_if_fail(hstreamrecorder, GST_PAD_PROBE_DROP);
+       mmf_return_val_if_fail(buffer, GST_PAD_PROBE_DROP);
+
+       sc = MMF_STREAMRECORDER_SUBCONTEXT(hstreamrecorder);
+       mmf_return_val_if_fail(sc && sc->info_audio && sc->info_file, FALSE);
+       audioinfo = sc->info_audio;
+       finfo = sc->info_file;
+
+       if (sc->isMaxtimePausing || sc->isMaxsizePausing) {
+               _mmstreamrec_dbg_warn("isMaxtimePausing[%d],isMaxsizePausing[%d]", sc->isMaxtimePausing, sc->isMaxsizePausing);
+               return GST_PAD_PROBE_DROP;
+       }
+
+       buffer_size = gst_buffer_get_size(buffer);
+
+       if (audioinfo->filesize == 0) {
+               if (finfo->fileformat == MM_FILE_FORMAT_WAV) {
+                       audioinfo->filesize += 44;      /* wave header size */
+               } else if (finfo->fileformat == MM_FILE_FORMAT_AMR) {
+                       audioinfo->filesize += 6;       /* amr header size */
+               }
+
+               audioinfo->filesize += buffer_size;
+               return GST_PAD_PROBE_OK;
+       }
+
+       if (sc->ferror_send) {
+               _mmstreamrec_dbg_warn("file write error, drop frames");
+               return GST_PAD_PROBE_DROP;
+       }
+
+       /* get trailer size */
+       if (finfo->fileformat == MM_FILE_FORMAT_3GP || finfo->fileformat == MM_FILE_FORMAT_MP4 || finfo->fileformat == MM_FILE_FORMAT_AAC) {
+               MMSTREAMRECORDER_G_OBJECT_GET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_MUX].gst, "expected-trailer-size", &trailer_size);
+               /*_mmstreamrec_dbg_log("trailer_size %d", trailer_size);*/
+       } else {
+               trailer_size = 0;               /* no trailer */
+       }
+
+       filename = finfo->filename;
+
+       /* to minimizing free space check overhead */
+       count = count % _MMSTREAMRECORDER_AUDIO_FREE_SPACE_CHECK_INTERVAL;
+       if (count++ == 0) {
+               gint free_space_ret = _mmstreamrecorder_get_freespace(filename, &free_space);
+
+               /*_mmstreamrec_dbg_log("check free space for recording");*/
+
+               switch (free_space_ret) {
+               case -2:                                /* file not exist */
+               case -1:                                /* failed to get free space */
+                       _mmstreamrec_dbg_err("Error occured. [%d]", free_space_ret);
+                       if (sc->ferror_count == 2 && sc->ferror_send == FALSE) {
+                               sc->ferror_send = TRUE;
+                               msg.id = MM_MESSAGE_STREAMRECORDER_ERROR;
+                               if (free_space_ret == -2) {
+                                       msg.param.code = MM_ERROR_FILE_NOT_FOUND;
+                               } else {
+                                       msg.param.code = MM_ERROR_FILE_READ;
+                               }
+                               _mmstreamrecorder_send_message((MMHandleType) hstreamrecorder, &msg);
+                       } else {
+                               sc->ferror_count++;
+                       }
+
+                       return GST_PAD_PROBE_DROP;      /* skip this buffer */
+
+               default:                                /* succeeded to get free space */
+                       /* check free space for recording */
+                       if (free_space < (guint64) (_MMSTREAMRECORDER_AUDIO_MINIMUM_SPACE + buffer_size + trailer_size)) {
+                               _mmstreamrec_dbg_warn("No more space for recording!!!");
+                               _mmstreamrec_dbg_warn("Free Space : [%" G_GUINT64_FORMAT "], file size : [%" G_GUINT64_FORMAT "]", free_space, audioinfo->filesize);
+
+                               if (audioinfo->bMuxing) {
+                                       MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "block", TRUE);
+                               } else {
+                                       MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AQUE].gst, "empty-buffers", TRUE);
+                               }
+
+                               sc->isMaxsizePausing = TRUE;
+                               msg.id = MM_MESSAGE_STREAMRECORDER_NO_FREE_SPACE;
+                               _mmstreamrecorder_send_message((MMHandleType) hstreamrecorder, &msg);
+
+                               return FALSE;   /* skip this buffer */
+                       }
+                       break;
+               }
+       }
+
+       if (!GST_CLOCK_TIME_IS_VALID(GST_BUFFER_PTS(buffer))) {
+               _mmstreamrec_dbg_err("Buffer timestamp is invalid, check it");
+               return GST_PAD_PROBE_DROP;
+       }
+
+       rec_pipe_time = GST_TIME_AS_MSECONDS(GST_BUFFER_TIMESTAMP(buffer));
+
+       if (audioinfo->max_time > 0 && audioinfo->max_time < (remained_time + rec_pipe_time))
+               remained_time = audioinfo->max_time - rec_pipe_time;
+
+       /*_mmstreamrec_dbg_log("remained time : %u", remained_time);*/
+
+       /* check recording time limit and send recording status message */
+       if (audioinfo->max_time > 0 && rec_pipe_time > audioinfo->max_time) {
+               _mmstreamrec_dbg_warn("Current time : [%" G_GUINT64_FORMAT "], Maximum time : [%" G_GUINT64_FORMAT "]", rec_pipe_time, audioinfo->max_time);
+
+               if (audioinfo->bMuxing) {
+                       MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "block", TRUE);
+               } else {
+                       MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AQUE].gst, "empty-buffers", TRUE);
+               }
+
+               sc->isMaxtimePausing = TRUE;
+               msg.id = MM_MESSAGE_STREAMRECORDER_TIME_LIMIT;
+               _mmstreamrecorder_send_message((MMHandleType) hstreamrecorder, &msg);
+
+               /* skip this buffer */
+               return GST_PAD_PROBE_DROP;
+       }
+
+       /* send message for recording time and recorded file size */
+       if (audioinfo->b_commiting == FALSE) {
+               audioinfo->filesize += buffer_size;
+
+               msg.id = MM_MESSAGE_STREAMRECORDER_RECORDING_STATUS;
+               msg.param.recording_status.elapsed = (unsigned long long)rec_pipe_time;
+               msg.param.recording_status.filesize = (unsigned long long)((audioinfo->filesize + trailer_size) >> 10);
+               msg.param.recording_status.remained_time = remained_time;
+               _mmstreamrecorder_send_message((MMHandleType) hstreamrecorder, &msg);
+
+               return GST_PAD_PROBE_OK;
+       } else {
+               /* skip this buffer if commit process has been started */
+               return GST_PAD_PROBE_DROP;
+       }
+}
diff --git a/src/mm_streamrecorder_ini.c b/src/mm_streamrecorder_ini.c
new file mode 100644 (file)
index 0000000..5b9b3bb
--- /dev/null
@@ -0,0 +1,367 @@
+/*
+ * libmm-streamrecorder
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Hyuntae Kim <ht1211.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <stdlib.h>
+#include <iniparser.h>
+#include <mm_debug.h>
+#include <mm_error.h>
+#include "mm_streamrecorder_ini.h"
+
+static gboolean loaded = FALSE;
+
+/* global variables here */
+#ifdef MM_STREAMRECORDER_DEFAULT_INI
+static gboolean __generate_default_ini(void);
+#endif
+static  void    __get_element_list(mm_streamrecorder_ini_t* ini, gchar* str, int keyword_type);
+
+static void __mm_streamrecorder_ini_check_status(void);
+
+/* macro */
+#define MM_STREAMRECORDER_INI_GET_STRING(x_dict, x_item, x_ini, x_default) \
+do { \
+       gchar *str = NULL; \
+       gint length = 0; \
+       str = iniparser_getstring(x_dict, x_ini, x_default); \
+       if (str) { \
+               length = strlen(str); \
+               if ((length > 1) && (length < STREAMRECORDER_INI_MAX_STRLEN)) \
+                       strncpy(x_item, str, length+1); \
+               else \
+                       strncpy(x_item, x_default, STREAMRECORDER_INI_MAX_STRLEN-1); \
+       } else { \
+               strncpy(x_item, x_default, STREAMRECORDER_INI_MAX_STRLEN-1); \
+       } \
+} while (0)
+
+/* x_ini is the list of value to be set at x_list[index] */
+#define MMSTREAMRECORDER_INI_GET_INT_FROM_LIST(x_dict, x_list, x_list_max, x_ini, x_default) \
+do { \
+       int index = 0; \
+       int value = 0; \
+       const char *delimiters = " ,"; \
+       char *usr_ptr = NULL; \
+       char *token = NULL; \
+       gchar temp_arr[STREAMRECORDER_INI_MAX_STRLEN] = {0}; \
+       MM_STREAMRECORDER_INI_GET_STRING(x_dict, temp_arr, x_ini, x_default); \
+       token = strtok_r(temp_arr, delimiters, &usr_ptr); \
+       while (token) { \
+               if (index > x_list_max -1) { \
+                       debug_error("%d is not valid index\n", index); \
+                       break; \
+               } else { \
+                       value = atoi(token); \
+                       x_list[index] = value; \
+                       index++; \
+               } \
+               token = strtok_r(NULL, delimiters, &usr_ptr); \
+       } \
+} while (0)
+
+
+#ifdef MM_STREAMRECORDER_DEFAULT_INI
+static
+gboolean __generate_default_ini(void)
+{
+       FILE *fp = NULL;
+       const gchar *default_ini = MM_STREAMRECORDER_DEFAULT_INI;
+
+       /* create new file */
+       fp = fopen(MM_STREAMRECORDER_INI_DEFAULT_PATH, "wt");
+
+       if (!fp)
+               return FALSE;
+
+       /* writing default ini file */
+       if (strlen(default_ini) != fwrite(default_ini, 1, strlen(default_ini), fp)) {
+               fclose(fp);
+               return FALSE;
+       }
+
+       fclose(fp);
+       return TRUE;
+}
+#endif
+
+int _mm_streamrecorder_ini_load(mm_streamrecorder_ini_t *ini)
+{
+       dictionary *dict = NULL;
+
+       debug_fenter();
+
+       __mm_streamrecorder_ini_check_status();
+
+       /* first, try to load existing ini file */
+       dict = iniparser_load(MM_STREAMRECORDER_INI_DEFAULT_PATH);
+
+       /* if no file exists. create one with set of default values */
+       if (!dict) {
+               _mmstreamrec_dbg_err("No ini file found. \n");
+               return MM_ERROR_FILE_NOT_FOUND;
+       }
+
+       /* get ini values */
+       memset(ini, 0, sizeof(mm_streamrecorder_ini_t));
+
+       if (dict) {                                     /* if dict is available */
+               /* general */
+               ini->encsink_src_islive = iniparser_getboolean(dict, "general:encscink source is live", DEFAULT_ENCSINK_SRC_IS_LIVE);
+               ini->retrial_count = iniparser_getint(dict, "general:retrialcount", DEFAULT_RETRIAL_COUNT);
+               ini->minimum_frame = iniparser_getint(dict, "general:minimum frame", DEFAULT_MINIMUM_FRAME);
+               ini->convert_output_buffer_num = iniparser_getint(dict, "general:convert output buffer num", DEFAULT_CONVERT_OUTPUT_BUFFER_NUM);
+               ini->reset_pause_time = iniparser_getint(dict, "general:reset pause time", DEFAULT_RESET_PAUSE_TIME);
+               ini->screen_record = iniparser_getint(dict, "general:screen record", DEFAULT_SCREEN_RECORD);
+
+               /*encodebin */
+               ini->encsink_bin_profile = iniparser_getint(dict, "encodebin:encsink bin profile", DEFAULT_ENCSINK_BIN_PROFILE);
+               ini->encsink_bin_auto_audio_resample = iniparser_getboolean(dict, "encodebin:encsink bin auto audio resample", DEFAULT_ENCSINK_BIN_AUTO_AUDIO_RESAMPLE);
+               ini->encsink_bin_auto_colorspace = iniparser_getboolean(dict, "encodebin: encsink bin auto colorspace", DEFAULT_ENCSINK_BIN_AUTO_COLORSPACE);
+               ini->encsink_bin_use_video_toggle = iniparser_getboolean(dict, "encodebin:encsink bin use video toggle", DEFAULT_ENCSINK_BIN_USE_VIDEO_TOGGLE);
+               ini->encsink_bin_auto_audio_convert = iniparser_getboolean(dict, "encodebin:encsink bin auto audio convert", DEFAULT_ENCSINK_BIN_AUTO_CONVERT);
+
+               /* pipeline */
+               MM_STREAMRECORDER_INI_GET_STRING(dict, ini->name_of_encsink_src, (const char *)"pipeline:encsink bin source", (char *)DEFAULT_VIDEO_SOURCE);
+               MM_STREAMRECORDER_INI_GET_STRING(dict, ini->name_of_audio_src, (const char *)"pipeline:name of audio src", (char *)DEFAULT_AUDIO_SRC);
+               MM_STREAMRECORDER_INI_GET_STRING(dict, ini->h264_video_encoder, (const char *)"pipeline:h264 encoder", (char *)DEFAULT_NAME_OF_H264_VIDEO_ENCODER);
+               MM_STREAMRECORDER_INI_GET_STRING(dict, ini->h263_video_encoder, (const char *)"pipeline:h263 encoder", (char *)DEFAULT_NAME_OF_H263_VIDEO_ENCODER);
+               MM_STREAMRECORDER_INI_GET_STRING(dict, ini->mpeg4_video_encoder, (const char *)"pipeline:mpeg4 encoder", (char *)DEFAULT_NAME_OF_MPEG4_VIDEO_ENCODER);
+               MM_STREAMRECORDER_INI_GET_STRING(dict, ini->name_of_encsink_bin_audio_encoder, (const char *)"pipeline:name of audio encoder", (char *)DEFAULT_NAME_OF_AUDIO_ENCODER);
+               MM_STREAMRECORDER_INI_GET_STRING(dict, ini->encsink_bin_use_parser, (const char *)"pipeline:use parser", (char *)DEFAULT_USE_PARSER);
+               MM_STREAMRECORDER_INI_GET_STRING(dict, ini->name_of_encsink_bin_video_converter, (const char *)"pipeline:name of video converter", (char *)DEFAULT_NAME_OF_VIDEO_CONVERTER);
+               MM_STREAMRECORDER_INI_GET_STRING(dict, ini->name_of_encsink_bin_3GPMUXER, (const char *)"pipeline:name of 3GP muxer", (char *)DEFAULT_NAME_OF_3GP_MUXER);
+               MM_STREAMRECORDER_INI_GET_STRING(dict, ini->name_of_encsink_bin_MP4MUXER, (const char *)"pipeline:name of MP4 muxer", (char *)DEFAULT_NAME_OF_MP4_MUXER);
+               MM_STREAMRECORDER_INI_GET_STRING(dict, ini->name_of_encsink_sink, (const char *)"pipeline:name of sink", (char *)DEFAULT_NAME_OF_BIN_SINK);
+
+               /* audio parameter */
+               ini->audio_frame_minimum_space = iniparser_getint(dict, "audio param:audio frame minimum space", DEFAULT_AUDIO_FRAME_MINIMUM_SPACE);
+               ini->audio_frame_wait_time = iniparser_getint(dict, "audio param:audio frame wait time", DEFAULT_AUDIO_FRAME_WAIT_TIME);
+
+               /* video parameter */
+               ini->video_frame_wait_time = iniparser_getint(dict, "video param:video frame wait time", DEFAULT_VIDEO_FRAME_WAIT_TIME);
+
+               /*supported attribute*/
+                MMSTREAMRECORDER_INI_GET_INT_FROM_LIST(dict, ini->supported_video_width, STREAMRECORDER_ATTRIBUTE_NUM_MAX, "attribute:supported width", DEFAULT_SUPPORTED_WIDTH);
+               MMSTREAMRECORDER_INI_GET_INT_FROM_LIST(dict, ini->supported_video_height, STREAMRECORDER_ATTRIBUTE_NUM_MAX, "attribute:supported height", DEFAULT_SUPPORTED_HEIGHT);
+               __get_element_list(ini, iniparser_getstring(dict, "attribute:supported audio encoders", DEFAULT_SUPPORTED_AUDIO_ENCODERS), KEYWORD_AUDIO_ENCODERS);
+               __get_element_list(ini, iniparser_getstring(dict, "attribute:supported video encoders", DEFAULT_SUPPORTED_VIDEO_ENCODERS), KEYWORD_VIDEO_ENCODERS);
+               __get_element_list(ini, iniparser_getstring(dict, "attribute:supported file formats", DEFAULT_SUPPORTED_FILE_FORMATS), KEYWORD_FILE_FORMATS);
+
+       } else {                                        /* if dict is not available just fill the structure with default value */
+               _mmstreamrec_dbg_err("failed to load ini. using hardcoded default\n");
+               /* general */
+               ini->encsink_src_islive = DEFAULT_ENCSINK_SRC_IS_LIVE;
+               ini->retrial_count = DEFAULT_RETRIAL_COUNT;
+               ini->minimum_frame = DEFAULT_MINIMUM_FRAME;
+               ini->convert_output_buffer_num = DEFAULT_CONVERT_OUTPUT_BUFFER_NUM;
+               ini->reset_pause_time = DEFAULT_RESET_PAUSE_TIME;
+               ini->screen_record = DEFAULT_SCREEN_RECORD;
+
+               /*encodebin */
+               ini->encsink_bin_profile = DEFAULT_ENCSINK_BIN_PROFILE;
+               ini->encsink_bin_auto_audio_resample = DEFAULT_ENCSINK_BIN_AUTO_AUDIO_RESAMPLE;
+               ini->encsink_bin_auto_colorspace = DEFAULT_ENCSINK_BIN_AUTO_COLORSPACE;
+               ini->encsink_bin_use_video_toggle = DEFAULT_ENCSINK_BIN_USE_VIDEO_TOGGLE;
+               ini->encsink_bin_auto_audio_convert = DEFAULT_ENCSINK_BIN_AUTO_CONVERT;
+
+               /* pipeline */
+               strncpy(ini->name_of_encsink_src, DEFAULT_VIDEO_SOURCE, STREAMRECORDER_INI_MAX_STRLEN - 1);
+               strncpy(ini->name_of_audio_src, DEFAULT_AUDIO_SRC, STREAMRECORDER_INI_MAX_STRLEN - 1);
+               strncpy(ini->h264_video_encoder, DEFAULT_NAME_OF_H264_VIDEO_ENCODER, STREAMRECORDER_INI_MAX_STRLEN - 1);
+               strncpy(ini->h263_video_encoder, DEFAULT_NAME_OF_H263_VIDEO_ENCODER, STREAMRECORDER_INI_MAX_STRLEN - 1);
+               strncpy(ini->mpeg4_video_encoder, DEFAULT_NAME_OF_MPEG4_VIDEO_ENCODER, STREAMRECORDER_INI_MAX_STRLEN - 1);
+               strncpy(ini->name_of_encsink_bin_audio_encoder, DEFAULT_NAME_OF_AUDIO_ENCODER, STREAMRECORDER_INI_MAX_STRLEN - 1);
+               strncpy(ini->encsink_bin_use_parser, DEFAULT_USE_PARSER, STREAMRECORDER_INI_MAX_STRLEN - 1);
+               strncpy(ini->name_of_encsink_bin_video_converter, DEFAULT_NAME_OF_VIDEO_CONVERTER, STREAMRECORDER_INI_MAX_STRLEN - 1);
+               strncpy(ini->name_of_encsink_bin_3GPMUXER, DEFAULT_NAME_OF_3GP_MUXER, STREAMRECORDER_INI_MAX_STRLEN - 1);
+               strncpy(ini->name_of_encsink_bin_MP4MUXER, DEFAULT_NAME_OF_MP4_MUXER, STREAMRECORDER_INI_MAX_STRLEN - 1);
+               strncpy(ini->name_of_encsink_sink, DEFAULT_NAME_OF_BIN_SINK, STREAMRECORDER_INI_MAX_STRLEN - 1);
+
+               /* audio parameter */
+               ini->audio_frame_minimum_space = DEFAULT_AUDIO_FRAME_MINIMUM_SPACE;
+               ini->audio_frame_wait_time = DEFAULT_AUDIO_FRAME_WAIT_TIME;
+
+               /* video parameter */
+               ini->video_frame_wait_time = DEFAULT_VIDEO_FRAME_WAIT_TIME;
+
+               /*supported attributes*/
+               __get_element_list(ini, DEFAULT_SUPPORTED_AUDIO_ENCODERS, KEYWORD_AUDIO_ENCODERS);
+               __get_element_list(ini, DEFAULT_SUPPORTED_VIDEO_ENCODERS, KEYWORD_VIDEO_ENCODERS);
+               __get_element_list(ini, DEFAULT_SUPPORTED_FILE_FORMATS, KEYWORD_FILE_FORMATS);
+       }
+
+       /* free dict as we got our own structure */
+       iniparser_freedict(dict);
+
+       /* dump structure */
+       _mmstreamrec_dbg_log("Stream Recorder initial settings.......................................\n");
+
+       /* general */
+       _mmstreamrec_dbg_log("encsink_src_islive : %d\n", ini->encsink_src_islive);
+       _mmstreamrec_dbg_log("retrial_count : %d\n", ini->retrial_count);
+       _mmstreamrec_dbg_log("minimum_frame : %d\n", ini->minimum_frame);
+       _mmstreamrec_dbg_log("convert_output_buffer_num : %d\n", ini->convert_output_buffer_num);
+       _mmstreamrec_dbg_log("reset_pause_time : %d\n", ini->reset_pause_time);
+       _mmstreamrec_dbg_log("screen_record : %d\n", ini->screen_record);
+
+       /*encodebin */
+       _mmstreamrec_dbg_log("encode bin profile : %d\n", ini->encsink_bin_profile);
+       _mmstreamrec_dbg_log("encode bin auto audio resample property  : %d\n", ini->encsink_bin_auto_audio_resample);
+       _mmstreamrec_dbg_log("encode bin auto colorspace property : %d\n", ini->encsink_bin_auto_colorspace);
+       _mmstreamrec_dbg_log("encode bin use video toggle property : %d\n", ini->encsink_bin_use_video_toggle);
+       _mmstreamrec_dbg_log("encode bin auto audio convert property : %d\n", ini->encsink_bin_auto_audio_convert);
+
+       /* pipeline */
+       _mmstreamrec_dbg_log("name_of_encodebin_source : %s\n", ini->name_of_encsink_src);
+       _mmstreamrec_dbg_log("name_of_audio_source : %s\n", ini->name_of_audio_src);
+       _mmstreamrec_dbg_log("name_of_h264_video_encoder : %s\n", ini->h264_video_encoder);
+       _mmstreamrec_dbg_log("name_of_h263_video_encoder : %s\n", ini->h263_video_encoder);
+       _mmstreamrec_dbg_log("name_of_mpeg4_video_encoder : %s\n", ini->mpeg4_video_encoder);
+       _mmstreamrec_dbg_log("name_of_audio_encoder : %s\n", ini->name_of_encsink_bin_audio_encoder);
+       _mmstreamrec_dbg_log("name_of_video_converter : %s\n", ini->name_of_encsink_bin_video_converter);
+       _mmstreamrec_dbg_log("name_of_3GP_muxer : %s\n", ini->name_of_encsink_bin_3GPMUXER);
+       _mmstreamrec_dbg_log("name_of_MP4_muxer : %s\n", ini->name_of_encsink_bin_MP4MUXER);
+       _mmstreamrec_dbg_log("name_of_sink : %s\n", ini->name_of_encsink_sink);
+
+       /* audio parameter */
+       _mmstreamrec_dbg_log("audio_frame_minimum_space : %d\n", ini->audio_frame_minimum_space);
+       _mmstreamrec_dbg_log("audio_frame_wait_time : %d\n", ini->audio_frame_wait_time);
+
+       /* video parameter */
+       _mmstreamrec_dbg_log("video_frame_wait_time : %d\n", ini->video_frame_wait_time);
+
+       _mmstreamrec_dbg_log("---------------------------------------------------\n");
+
+       loaded = TRUE;
+
+       debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+static
+void    __get_element_list(mm_streamrecorder_ini_t* ini, gchar* str, int keyword_type)
+{
+       gchar** list = NULL;
+       gchar** walk = NULL;
+       int i = 0;
+       gchar* strtmp = NULL;
+
+       if (!str)
+               return;
+
+       if (strlen(str) < 1)
+               return;
+
+       strtmp = g_strdup(str);
+
+       /* trimming. it works inplace */
+       g_strstrip(strtmp);
+
+
+       /* split */
+       list = g_strsplit(strtmp, ",", 10);
+
+       if (!list) {
+               if (strtmp)
+                       g_free(strtmp);
+
+               return;
+       }
+
+       /* copy list */
+       switch (keyword_type) {
+       case KEYWORD_AUDIO_ENCODERS:
+       {
+               for (walk = list; *walk; walk++) {
+                       strncpy(ini->supported_audio_encoders[i], *walk, (STREAMRECORDER_INI_MAX_STRLEN - 1));
+                       g_strstrip(ini->supported_audio_encoders[i]);
+                       ini->supported_audio_encoders[i][STREAMRECORDER_INI_MAX_STRLEN -1] = '\0';
+                       i++;
+               }
+               /* mark last item to NULL*/
+               ini->supported_audio_encoders[i][0] = '\0';
+               break;
+       }
+       case KEYWORD_VIDEO_ENCODERS:
+       {
+               for (walk = list; *walk; walk++) {
+                       strncpy(ini->supported_video_encoders[i], *walk, (STREAMRECORDER_INI_MAX_STRLEN - 1));
+                       g_strstrip(ini->supported_video_encoders[i]);
+                       ini->supported_video_encoders[i][STREAMRECORDER_INI_MAX_STRLEN -1] = '\0';
+                       i++;
+               }
+               /* mark last item to NULL */
+               ini->supported_video_encoders[i][0] = '\0';
+               break;
+       }
+       case KEYWORD_FILE_FORMATS:
+       {
+               for (walk = list; *walk; walk++) {
+                       strncpy(ini->supported_file_formats[i], *walk, (STREAMRECORDER_INI_MAX_STRLEN - 1));
+                       g_strstrip(ini->supported_file_formats[i]);
+                       ini->supported_file_formats[i][STREAMRECORDER_INI_MAX_STRLEN -1] = '\0';
+                       i++;
+               }
+               /* mark last item to NULL*/
+               ini->supported_file_formats[i][0] = '\0';
+               break;
+       }
+       default:
+       break;
+       }
+
+       g_strfreev(list);
+       if (strtmp)
+               g_free(strtmp);
+}
+
+
+static
+void __mm_streamrecorder_ini_check_status(void)
+{
+       struct stat ini_buff;
+
+       debug_fenter();
+
+       if (g_stat(MM_STREAMRECORDER_INI_DEFAULT_PATH, &ini_buff) < 0) {
+               _mmstreamrec_dbg_err("failed to get mmfw_wfd_sink ini status\n");
+       } else {
+               if (ini_buff.st_size < 5) {
+                       _mmstreamrec_dbg_err("mmfw_wfd_sink.ini file size=%d, Corrupted! So, Removed\n", (int)ini_buff.st_size);
+                       g_remove(MM_STREAMRECORDER_INI_DEFAULT_PATH);
+               }
+       }
+
+       debug_fleave();
+}
+
+int _mm_streamrecorder_ini_unload(mm_streamrecorder_ini_t *ini)
+{
+       debug_fenter();
+
+       loaded = FALSE;
+
+       debug_fleave();
+
+       return MM_ERROR_NONE;
+}
diff --git a/src/mm_streamrecorder_internal.c b/src/mm_streamrecorder_internal.c
new file mode 100644 (file)
index 0000000..5532002
--- /dev/null
@@ -0,0 +1,803 @@
+/*
+ * libmm-streamrecorder
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Hyuntae Kim <ht1211.kim@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 <stdio.h>
+#include <string.h>
+#include <mm_types.h>
+#include <mm_error.h>
+
+#include "mm_streamrecorder_internal.h"
+#include "mm_streamrecorder_recorder.h"
+#include "mm_streamrecorder_attribute.h"
+#include "mm_streamrecorder_gstdispatch.h"
+
+#include <asm/types.h>
+
+/*---------------------------------------------------------------------------------------
+|    GLOBAL VARIABLE DEFINITIONS for internal                                          |
+---------------------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------------------
+|    LOCAL VARIABLE DEFINITIONS for internal                                           |
+---------------------------------------------------------------------------------------*/
+#define __MMSTREAMRECORDER_CMD_ITERATE_MAX           3
+
+/*---------------------------------------------------------------------------------------
+|    LOCAL FUNCTION PROTOTYPES:                                                                |
+---------------------------------------------------------------------------------------*/
+
+/*=======================================================================================
+|  FUNCTION DEFINITIONS                                                                        |
+=======================================================================================*/
+/*---------------------------------------------------------------------------------------
+|    GLOBAL FUNCTION DEFINITIONS:                                                      |
+---------------------------------------------------------------------------------------*/
+
+/* Internal command functions {*/
+int _mmstreamrecorder_create(MMHandleType *handle)
+{
+       int ret = MM_ERROR_NONE;
+       /* char *err_attr_name = NULL; */
+       mmf_streamrecorder_t *hstreamrecorder = NULL;
+
+       _mmstreamrec_dbg_log("Entered");
+       mmf_return_val_if_fail(handle, MM_ERROR_STREAMRECORDER_INVALID_ARGUMENT);
+
+       /* Create mmf_streamrecorder_t handle and initialize every variable */
+       hstreamrecorder = (mmf_streamrecorder_t *) malloc(sizeof(mmf_streamrecorder_t));
+       mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_LOW_MEMORY);
+       memset(hstreamrecorder, 0x00, sizeof(mmf_streamrecorder_t));
+
+       /* init values */
+       hstreamrecorder->sub_context = NULL;
+
+       pthread_mutex_init(&((hstreamrecorder->mtsafe).lock), NULL);
+       pthread_cond_init(&((hstreamrecorder->mtsafe).cond), NULL);
+
+       pthread_mutex_init(&((hstreamrecorder->mtsafe).cmd_lock), NULL);
+       pthread_mutex_init(&((hstreamrecorder->mtsafe).state_lock), NULL);
+       pthread_mutex_init(&((hstreamrecorder->mtsafe).gst_state_lock), NULL);
+       pthread_mutex_init(&((hstreamrecorder->mtsafe).message_cb_lock), NULL);
+
+       ret = _mm_streamrecorder_ini_load(&hstreamrecorder->ini);
+       if (ret != MM_ERROR_NONE) {
+               _mmstreamrec_dbg_warn("failed to load ini file\n");
+               goto _ERR_INITIAL_INI;
+       }
+
+       hstreamrecorder->attributes = _mmstreamrecorder_alloc_attribute((MMHandleType) hstreamrecorder);
+
+       if (!(hstreamrecorder->attributes)) {
+               _mmstreamrec_dbg_err("_mmstreamrecorder_create::alloc attribute error.");
+
+               ret = MM_ERROR_STREAMRECORDER_RESOURCE_CREATION;
+               goto _ERR_ALLOC_ATTRIBUTE;
+       }
+
+       _mmstreamrecorder_alloc_subcontext((MMHandleType) hstreamrecorder);
+       if (!hstreamrecorder->sub_context) {
+               ret = MM_ERROR_STREAMRECORDER_RESOURCE_CREATION;
+               goto _ERR_ALLOC_SUBCONTEXT;
+       }
+
+       /* Initial GSTREAMER */
+       ret = _mmstreamrecorder_gstreamer_init();
+
+       if (!ret) {
+               _mmstreamrec_dbg_err("Failed to initialize gstreamer!!");
+               ret = MM_ERROR_STREAMRECORDER_NOT_INITIALIZED;
+               goto _ERR_INITIAL_GSTREAMER;
+       }
+
+       _mmstreamrecorder_set_state((MMHandleType)hstreamrecorder, MM_STREAMRECORDER_STATE_CREATED);
+
+       *handle = (MMHandleType) hstreamrecorder;
+
+       return MM_ERROR_NONE;
+
+ _ERR_INITIAL_GSTREAMER:
+       _mmstreamrecorder_dealloc_subcontext((MMHandleType) hstreamrecorder);
+ _ERR_ALLOC_ATTRIBUTE:
+ _ERR_ALLOC_SUBCONTEXT:
+ _ERR_INITIAL_INI:
+       pthread_mutex_destroy(&((hstreamrecorder->mtsafe).lock));
+       pthread_cond_destroy(&((hstreamrecorder->mtsafe).cond));
+       pthread_mutex_destroy(&((hstreamrecorder->mtsafe).cmd_lock));
+       pthread_mutex_destroy(&((hstreamrecorder->mtsafe).state_lock));
+       pthread_mutex_destroy(&((hstreamrecorder->mtsafe).gst_state_lock));
+       pthread_mutex_destroy(&((hstreamrecorder->mtsafe).message_cb_lock));
+       /* Release handle */
+       memset(hstreamrecorder, 0x00, sizeof(mmf_streamrecorder_t));
+       free(hstreamrecorder);
+
+       return ret;
+}
+
+MMStreamRecorderStateType _mmstreamrecorder_get_state(MMHandleType handle)
+{
+       int state;
+       mmf_streamrecorder_t *streamrecorder = MMF_STREAMRECORDER(handle);
+
+       mmf_return_val_if_fail(streamrecorder, MM_ERROR_STREAMRECORDER_INVALID_ARGUMENT);
+
+       _MMSTREAMRECORDER_LOCK_STATE(handle);
+
+       state = streamrecorder->state;
+
+       _MMSTREAMRECORDER_UNLOCK_STATE(handle);
+
+       return state;
+}
+
+void _mmstreamrecorder_set_state(MMHandleType handle, int state)
+{
+       int old_state;
+       mmf_streamrecorder_t *streamrecorder = MMF_STREAMRECORDER(handle);
+       _MMStreamRecorderMsgItem msg;
+
+       mmf_return_val_if_fail(streamrecorder, MM_ERROR_STREAMRECORDER_INVALID_ARGUMENT);
+
+       /*_mmstreamrec_dbg_log("");*/
+
+       _MMSTREAMRECORDER_LOCK_STATE(handle);
+
+       old_state = streamrecorder->state;
+
+       if (old_state != state) {
+               streamrecorder->state = state;
+
+               _mmstreamrec_dbg_log("set state[%d] and send state-changed message", state);
+
+               msg.id = MM_MESSAGE_STREAMRECORDER_STATE_CHANGED;
+               msg.param.state.code = MM_ERROR_NONE;
+
+               msg.param.state.previous = old_state;
+               msg.param.state.current = state;
+
+               /*_mmstreamrec_dbg_log("_mmstreamcorder_send_message : msg : %p, id:%x", &msg, msg.id);*/
+               _mmstreamrecorder_send_message(handle, &msg);
+       }
+
+       _MMSTREAMRECORDER_UNLOCK_STATE(handle);
+
+       return;
+}
+
+
+
+int _mmstreamrecorder_destroy(MMHandleType handle)
+{
+       int ret = MM_ERROR_NONE;
+
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+
+       _mmstreamrec_dbg_log("");
+
+       if (!hstreamrecorder) {
+               _mmstreamrec_dbg_err("Not initialized");
+               ret = MM_ERROR_STREAMRECORDER_NOT_INITIALIZED;
+               goto _ERR_STREAMRECORDER_CMD_PRECON;
+       }
+
+       if (!_MMSTREAMRECORDER_TRYLOCK_CMD(hstreamrecorder)) {
+               _mmstreamrec_dbg_err("Another command is running.");
+               ret = MM_ERROR_STREAMRECORDER_CMD_IS_RUNNING;
+               goto _ERR_STREAMRECORDER_CMD_PRECON;
+       }
+
+       /* Release SubContext and pipeline */
+       if (hstreamrecorder->sub_context) {
+               if (hstreamrecorder->sub_context->encode_element)
+                       _mmstreamrecorder_destroy_pipeline(handle);
+
+               _mmstreamrecorder_dealloc_subcontext(handle);
+       }
+
+       /* Remove attributes */
+       if (hstreamrecorder->attributes) {
+               _mmstreamrecorder_dealloc_attribute(hstreamrecorder->attributes);
+               hstreamrecorder->attributes = 0;
+       }
+
+       /* Remove messages which are not called yet */
+       _mmstreamrecorder_remove_message_all(handle);
+
+       _MMSTREAMRECORDER_UNLOCK_CMD(hstreamrecorder);
+
+       /* Release lock, cond */
+       pthread_mutex_destroy(&((hstreamrecorder->mtsafe).lock));
+       pthread_cond_destroy(&((hstreamrecorder->mtsafe).cond));
+       pthread_mutex_destroy(&((hstreamrecorder->mtsafe).cmd_lock));
+       pthread_mutex_destroy(&((hstreamrecorder->mtsafe).state_lock));
+       pthread_mutex_destroy(&((hstreamrecorder->mtsafe).gst_state_lock));
+       pthread_mutex_destroy(&((hstreamrecorder->mtsafe).message_cb_lock));
+
+       /* Release handle */
+       memset(hstreamrecorder, 0x00, sizeof(mmf_streamrecorder_t));
+       free(hstreamrecorder);
+
+       return MM_ERROR_NONE;
+
+ _ERR_STREAMRECORDER_CMD_PRECON:
+
+       _mmstreamrec_dbg_err("Destroy fail (ret %x)", ret);
+
+       return ret;
+}
+
+int _mmstreamrecorder_realize(MMHandleType handle)
+{
+       int ret = MM_ERROR_NONE;
+/*     int errorcode = MM_ERROR_NONE;
+       char *videosink_element_type = NULL;
+       char *videosink_name = NULL; */
+
+       _mmstreamrec_dbg_log("");
+
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+
+       if (!hstreamrecorder) {
+               _mmstreamrec_dbg_err("Not initialized");
+               ret = MM_ERROR_STREAMRECORDER_NOT_INITIALIZED;
+               return ret;
+       }
+
+       if (!_MMSTREAMRECORDER_TRYLOCK_CMD(hstreamrecorder)) {
+               _mmstreamrec_dbg_err("Another command is running.");
+               ret = MM_ERROR_STREAMRECORDER_CMD_IS_RUNNING;
+               goto _ERR_STREAMRECORDER_CMD_PRECON;
+       }
+
+       /* create pipeline */
+       ret = _mmstreamrecorder_create_pipeline(handle);
+       if (ret != MM_ERROR_NONE) {
+               /* check internal error of gstreamer */
+               if (hstreamrecorder->sub_context->error_code != MM_ERROR_NONE) {
+                       ret = hstreamrecorder->sub_context->error_code;
+                       _mmstreamrec_dbg_log("gstreamer error is occurred. return it %x", ret);
+               }
+               /* release sub context */
+               _mmstreamrecorder_dealloc_subcontext(handle);
+               goto _ERR_STREAMRECORDER_CMD;
+       }
+
+       /* set command function */
+       _mmstreamrecorder_set_functions(handle);
+
+       _mmstreamrecorder_set_state(handle, MM_STREAMRECORDER_STATE_PREPARED);
+
+       _MMSTREAMRECORDER_UNLOCK_CMD(hstreamrecorder);
+
+       return MM_ERROR_NONE;
+
+ _ERR_STREAMRECORDER_CMD:
+/* _ERR_STREAMRECORDER_CMD_PRECON_AFTER_LOCK: */
+       /* Security thread release */
+       _MMSTREAMRECORDER_UNLOCK_CMD(hstreamrecorder);
+
+ _ERR_STREAMRECORDER_CMD_PRECON:
+/*     _mmstreamrec_dbg_err("Realize fail (type %d, state %d, ret %x)", hstreamrecorder->type, state, ret); */
+
+       return ret;
+}
+
+int _mmstreamrecorder_unrealize(MMHandleType handle)
+{
+       int ret = MM_ERROR_NONE;
+
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+
+       _mmstreamrec_dbg_log("");
+
+       if (!hstreamrecorder) {
+               _mmstreamrec_dbg_err("Not initialized");
+               ret = MM_ERROR_STREAMRECORDER_NOT_INITIALIZED;
+               return ret;
+       }
+
+       if (!_MMSTREAMRECORDER_TRYLOCK_CMD(hstreamrecorder)) {
+               _mmstreamrec_dbg_err("Another command is running.");
+               ret = MM_ERROR_STREAMRECORDER_CMD_IS_RUNNING;
+               goto _ERR_STREAMRECORDER_CMD_PRECON;
+       }
+
+       /* Release SubContext */
+       if (hstreamrecorder->sub_context) {
+               /* destroy pipeline */
+               _mmstreamrecorder_destroy_pipeline(handle);
+               /* Deallocate SubContext */
+       }
+
+       /* Deinitialize main context member */
+       _mmstreamrecorder_unset_functions(handle);
+
+       _mmstreamrecorder_set_state(handle, MM_STREAMRECORDER_STATE_CREATED);
+
+       _MMSTREAMRECORDER_UNLOCK_CMD(hstreamrecorder);
+
+       return MM_ERROR_NONE;
+
+ _ERR_STREAMRECORDER_CMD_PRECON:
+       /* send message */
+       return ret;
+}
+
+int _mmstreamrecorder_record(MMHandleType handle)
+{
+       int ret = MM_ERROR_NONE;
+
+       _MMStreamRecorderSubContext *sc = NULL;
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+
+       _mmstreamrec_dbg_log("");
+
+       if (!hstreamrecorder) {
+               _mmstreamrec_dbg_err("Not initialized");
+               ret = MM_ERROR_STREAMRECORDER_NOT_INITIALIZED;
+               return ret;
+       }
+
+       sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
+       mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+
+       /* initialize error code */
+       hstreamrecorder->sub_context->error_code = MM_ERROR_NONE;
+
+       ret = hstreamrecorder->command((MMHandleType) hstreamrecorder, _MM_STREAMRECORDER_CMD_RECORD);
+       if (ret != MM_ERROR_NONE) {
+               _mmstreamrec_dbg_err("_mmstreamrecorder_record does not work!");
+               goto _ERR_STREAMRECORDER_CMD;
+       }
+
+       _mmstreamrecorder_set_state(handle, MM_STREAMRECORDER_STATE_RECORDING);
+
+       return MM_ERROR_NONE;
+
+ _ERR_STREAMRECORDER_CMD:
+ _ERR_STREAMRECORDER_CMD_PRECON:
+       /* check internal error of gstreamer */
+       if (hstreamrecorder->sub_context->error_code != MM_ERROR_NONE) {
+               ret = hstreamrecorder->sub_context->error_code;
+               hstreamrecorder->sub_context->error_code = MM_ERROR_NONE;
+
+               _mmstreamrec_dbg_log("gstreamer error is occurred. return it %x", ret);
+       }
+       return ret;
+}
+
+int _mmstreamrecorder_push_stream_buffer(MMHandleType handle, MMStreamRecorderStreamType streamtype, unsigned long timestamp, void *buffer, int size)
+{
+       int ret = MM_ERROR_NONE;
+
+       int format;
+       GstMapInfo map;
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+
+       /* _mmstreamrec_dbg_log(""); */
+
+       if (!hstreamrecorder) {
+               _mmstreamrec_dbg_err("Not initialized");
+               ret = MM_ERROR_STREAMRECORDER_NOT_INITIALIZED;
+               return ret;
+       }
+       mm_streamrecorder_get_attributes(handle, NULL,
+                                       MMSTR_VIDEO_SOURCE_FORMAT, &format,
+                                       NULL);
+       GstStreamRecorderBuffer *stream_buffer = NULL;
+       stream_buffer = (GstStreamRecorderBuffer *) malloc(sizeof(GstStreamRecorderBuffer));
+       if (stream_buffer == NULL) {
+               _mmstreamrec_dbg_err("stream buffer allocation fail");
+               return MM_ERROR_STREAMRECORDER_LOW_MEMORY;
+       }
+       stream_buffer->str_handle = handle;
+       stream_buffer->buffer = gst_buffer_new();
+       if (stream_buffer->buffer == NULL) {
+               free(stream_buffer);
+               stream_buffer = NULL;
+               _mmstreamrec_dbg_err("gst buffer allocation fail");
+               return MM_ERROR_STREAMRECORDER_LOW_MEMORY;
+       }
+       stream_buffer->user_buffer = buffer;
+       /* Get Media Packet to Surface to MMVideoBuffer */
+
+       stream_buffer->buffer->pts = timestamp;
+       GST_BUFFER_DURATION(stream_buffer->buffer) = GST_CLOCK_TIME_NONE;
+
+       gst_buffer_map(stream_buffer->buffer, &map, GST_MAP_READWRITE);
+       if (streamtype == MM_STREAM_TYPE_VIDEO) {
+               if (format == MM_STREAMRECORDER_INPUT_FORMAT_NV12 || format == MM_STREAMRECORDER_INPUT_FORMAT_NV21) {
+
+                       MMVideoBuffer *video_buf = (MMVideoBuffer *)buffer;
+                       /* Buffer at 0th position */
+                       gst_buffer_append_memory(stream_buffer->buffer, gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY,
+                                                               video_buf->handle.paddr[0], size, 0, size, video_buf->handle.paddr[0], NULL));
+                       /* Buffer at 1st position */
+                       gst_buffer_append_memory(stream_buffer->buffer, gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY,
+                                                               video_buf, sizeof(MMVideoBuffer), 0, sizeof(MMVideoBuffer), stream_buffer, _mmstreamrecorder_buffer_destroy));
+               } else {
+                               gst_buffer_append_memory(stream_buffer->buffer, gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY,
+                                                               buffer, size, 0, size, stream_buffer, _mmstreamrecorder_buffer_destroy));
+               }
+               ret = _mmstreamrecorder_push_videostream_buffer(handle, timestamp, stream_buffer->buffer, size);
+       } else if (streamtype == MM_STREAM_TYPE_AUDIO) {
+               gst_buffer_append_memory(stream_buffer->buffer, gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY,
+                                                               buffer, size, 0, buffer, stream_buffer, _mmstreamrecorder_buffer_destroy));
+               ret = _mmstreamrecorder_push_audiostream_buffer(handle, timestamp, stream_buffer->buffer, size);
+       } else {
+               gst_buffer_unmap(stream_buffer->buffer, &map);
+               gst_object_unref(stream_buffer->buffer);
+               free(stream_buffer);
+               stream_buffer = NULL;
+               return MM_ERROR_STREAMRECORDER_INVALID_CONDITION;
+       }
+       gst_buffer_unmap(stream_buffer->buffer, &map);
+       return ret;
+
+}
+
+int _mmstreamrecorder_pause(MMHandleType handle)
+{
+       int ret = MM_ERROR_NONE;
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+
+       _mmstreamrec_dbg_log("");
+
+       if (!hstreamrecorder) {
+               _mmstreamrec_dbg_err("Not initialized");
+               ret = MM_ERROR_STREAMRECORDER_NOT_INITIALIZED;
+               return ret;
+       }
+
+       if (!_MMSTREAMRECORDER_TRYLOCK_CMD(hstreamrecorder)) {
+               _mmstreamrec_dbg_err("Another command is running.");
+               ret = MM_ERROR_STREAMRECORDER_CMD_IS_RUNNING;
+               goto _ERR_STREAMRECORDER_CMD_PRECON;
+       }
+
+       ret = hstreamrecorder->command((MMHandleType) hstreamrecorder, _MM_STREAMRECORDER_CMD_PAUSE);
+       if (ret != MM_ERROR_NONE)
+               goto _ERR_STREAMRECORDER_CMD;
+
+       _mmstreamrecorder_set_state(handle, MM_STREAMRECORDER_STATE_PAUSED);
+
+       _MMSTREAMRECORDER_UNLOCK_CMD(hstreamrecorder);
+
+       return MM_ERROR_NONE;
+
+ _ERR_STREAMRECORDER_CMD:
+       _MMSTREAMRECORDER_UNLOCK_CMD(hstreamrecorder);
+ _ERR_STREAMRECORDER_CMD_PRECON:
+       /* send message */
+       return ret;
+}
+
+int _mmstreamrecorder_commit(MMHandleType handle)
+{
+       int ret = MM_ERROR_NONE;
+
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+
+       _mmstreamrec_dbg_log("");
+
+       if (!hstreamrecorder) {
+               _mmstreamrec_dbg_err("Not initialized");
+               ret = MM_ERROR_STREAMRECORDER_NOT_INITIALIZED;
+               return ret;
+       }
+
+       if (!_MMSTREAMRECORDER_TRYLOCK_CMD(hstreamrecorder)) {
+               _mmstreamrec_dbg_err("Another command is running.");
+               ret = MM_ERROR_STREAMRECORDER_CMD_IS_RUNNING;
+               goto _ERR_STREAMRECORDER_CMD_PRECON;
+       }
+
+       ret = hstreamrecorder->command((MMHandleType) hstreamrecorder, _MM_STREAMRECORDER_CMD_COMMIT);
+       if (ret != MM_ERROR_NONE)
+               goto _ERR_STREAMRECORDER_CMD;
+
+       _mmstreamrecorder_set_state(handle, MM_STREAMRECORDER_STATE_PREPARED);
+
+       _MMSTREAMRECORDER_UNLOCK_CMD(hstreamrecorder);
+
+       return MM_ERROR_NONE;
+
+ _ERR_STREAMRECORDER_CMD:
+       _MMSTREAMRECORDER_UNLOCK_CMD(hstreamrecorder);
+ _ERR_STREAMRECORDER_CMD_PRECON:
+       /* send message */
+
+       return ret;
+}
+
+int _mmstreamrecorder_cancel(MMHandleType handle)
+{
+       int ret = MM_ERROR_NONE;
+
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+
+       _mmstreamrec_dbg_log("");
+
+       if (!hstreamrecorder) {
+               _mmstreamrec_dbg_err("Not initialized");
+               ret = MM_ERROR_STREAMRECORDER_NOT_INITIALIZED;
+               return ret;
+       }
+
+       if (!_MMSTREAMRECORDER_TRYLOCK_CMD(hstreamrecorder)) {
+               _mmstreamrec_dbg_err("Another command is running.");
+               ret = MM_ERROR_STREAMRECORDER_CMD_IS_RUNNING;
+               goto _ERR_STREAMRECORDER_CMD_PRECON;
+       }
+
+       ret = hstreamrecorder->command((MMHandleType) hstreamrecorder, _MM_STREAMRECORDER_CMD_CANCEL);
+       if (ret != MM_ERROR_NONE)
+               goto _ERR_STREAMRECORDER_CMD;
+
+       _mmstreamrecorder_set_state(handle, MM_STREAMRECORDER_STATE_PREPARED);
+
+       _MMSTREAMRECORDER_UNLOCK_CMD(hstreamrecorder);
+
+       return MM_ERROR_NONE;
+
+ _ERR_STREAMRECORDER_CMD:
+       _MMSTREAMRECORDER_UNLOCK_CMD(hstreamrecorder);
+ _ERR_STREAMRECORDER_CMD_PRECON:
+       /* send message */
+
+       return ret;
+}
+
+/* } Internal command functions */
+
+int _mmstreamrecorder_set_message_callback(MMHandleType handle, MMMessageCallback callback, void *user_data)
+{
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+
+       _mmstreamrec_dbg_log("%p", hstreamrecorder);
+
+       mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+
+       if (callback == NULL) {
+               _mmstreamrec_dbg_warn("Message Callback is disabled");
+               _mmstreamrec_dbg_warn("Application sets callback as NULL");
+       }
+
+       if (!_MMSTREAMRECORDER_TRYLOCK_MESSAGE_CALLBACK(hstreamrecorder)) {
+               _mmstreamrec_dbg_warn("Application's message callback is running now");
+               return MM_ERROR_STREAMRECORDER_INVALID_CONDITION;
+       }
+
+       /* set message callback to message handle */
+       hstreamrecorder->msg_cb = callback;
+       hstreamrecorder->msg_cb_param = user_data;
+
+       _MMSTREAMRECORDER_UNLOCK_MESSAGE_CALLBACK(hstreamrecorder);
+
+       return MM_ERROR_NONE;
+}
+
+int _mmstreamrecorder_alloc_subcontext(MMHandleType handle)
+{
+       int i;
+       int ret = MM_ERROR_NONE;
+       _MMStreamRecorderSubContext *sc = NULL;
+
+       _mmstreamrec_dbg_log("");
+
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+
+       mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_RESOURCE_CREATION);
+
+       /* alloc container */
+       sc = (_MMStreamRecorderSubContext *) malloc(sizeof(_MMStreamRecorderSubContext));
+       mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_LOW_MEMORY);
+
+       /* init members */
+       memset(sc, 0x00, sizeof(_MMStreamRecorderSubContext));
+
+       sc->encode_element_num = _MMSTREAMRECORDER_ENCODE_PIPELINE_ELEMENT_NUM;
+
+       /* alloc element array */
+       sc->encode_element = (_MMStreamRecorderGstElement *) malloc(sizeof(_MMStreamRecorderGstElement) * sc->encode_element_num);
+       if (!sc->encode_element) {
+               _mmstreamrec_dbg_err("Failed to alloc encode element structure");
+               goto ALLOC_SUBCONTEXT_FAILED;
+       }
+
+       for (i = 0; i < sc->encode_element_num; i++) {
+               sc->encode_element[i].id = _MMSTREAMRECORDER_ENCODE_NONE;
+               sc->encode_element[i].gst = NULL;
+       }
+
+       sc->fourcc = 0x80000000;
+
+       hstreamrecorder->sub_context = sc;
+
+       ret = _mmstreamrecorder_alloc_subcontext_fileinfo((MMHandleType) hstreamrecorder);
+       if (ret != MM_ERROR_NONE) {
+               _mmstreamrec_dbg_err("Failed to allocate subcontext fileinfo");
+               goto ALLOC_SUBCONTEXT_FAILED;
+       }
+
+       ret = _mmstreamrecorder_alloc_subcontext_videoinfo((MMHandleType) hstreamrecorder);
+       if (ret != MM_ERROR_NONE) {
+               _mmstreamrec_dbg_err("Failed to allocate subcontext videoinfo");
+               goto ALLOC_SUBCONTEXT_FAILED;
+       }
+
+       _mmstreamrecorder_alloc_subcontext_audioinfo((MMHandleType) hstreamrecorder);
+       if (ret != MM_ERROR_NONE) {
+               _mmstreamrec_dbg_err("Failed to allocate subcontext audioinfo");
+               goto ALLOC_SUBCONTEXT_FAILED;
+       }
+
+       return MM_ERROR_NONE;
+
+ ALLOC_SUBCONTEXT_FAILED:
+
+       if (sc) {
+               if (sc->encode_element) {
+                       free(sc->encode_element);
+                       sc->encode_element = NULL;
+               }
+               free(sc);
+               sc = NULL;
+       }
+       if (hstreamrecorder->sub_context != NULL)
+               hstreamrecorder->sub_context = NULL;
+       return MM_ERROR_STREAMRECORDER_LOW_MEMORY;
+}
+
+int _mmstreamrecorder_alloc_subcontext_videoinfo(MMHandleType handle)
+{
+       _MMStreamRecorderSubContext *sc = NULL;
+
+       _mmstreamrec_dbg_log("");
+
+       sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
+       mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+
+       /* alloc info for each mode */
+
+       sc->info_video = malloc(sizeof(_MMStreamRecorderVideoInfo));
+       if (!sc->info_video) {
+               _mmstreamrec_dbg_err("Failed to alloc info structure");
+               return MM_ERROR_STREAMRECORDER_LOW_MEMORY;
+       }
+       memset(sc->info_video, 0x00, sizeof(_MMStreamRecorderVideoInfo));
+
+       return MM_ERROR_NONE;
+}
+
+int _mmstreamrecorder_alloc_subcontext_audioinfo(MMHandleType handle)
+{
+       _MMStreamRecorderSubContext *sc = NULL;
+
+       _mmstreamrec_dbg_log("");
+
+       sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
+       mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+
+       /* alloc info for each mode */
+       sc->info_audio = malloc(sizeof(_MMStreamRecorderAudioInfo));
+       if (!sc->info_audio) {
+               _mmstreamrec_dbg_err("Failed to alloc info structure");
+               return MM_ERROR_STREAMRECORDER_LOW_MEMORY;
+       }
+       memset(sc->info_audio, 0x00, sizeof(_MMStreamRecorderAudioInfo));
+
+       return MM_ERROR_NONE;
+}
+
+int _mmstreamrecorder_alloc_subcontext_fileinfo(MMHandleType handle)
+{
+       _MMStreamRecorderSubContext *sc = NULL;
+
+       _mmstreamrec_dbg_log("");
+
+       sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
+       mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+
+       /* alloc info for each mode */
+       sc->info_file = malloc(sizeof(_MMStreamRecorderFileInfo));
+       if (!sc->info_file) {
+               _mmstreamrec_dbg_err("Failed to alloc info structure");
+               return MM_ERROR_STREAMRECORDER_LOW_MEMORY;
+       }
+       memset(sc->info_file, 0x00, sizeof(_MMStreamRecorderFileInfo));
+
+       return MM_ERROR_NONE;
+}
+
+void _mmstreamrecorder_dealloc_subcontext(MMHandleType handle)
+{
+       _MMStreamRecorderSubContext *sc = NULL;
+
+       _mmstreamrec_dbg_log("");
+
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+
+       mmf_return_if_fail(hstreamrecorder);
+       mmf_return_if_fail(hstreamrecorder->sub_context);
+
+       sc = hstreamrecorder->sub_context;
+
+       if (sc) {
+
+               if (sc->encode_element) {
+                       _mmstreamrec_dbg_log("release encode_element");
+                       free(sc->encode_element);
+                       sc->encode_element = NULL;
+               }
+
+               if (sc->info_video) {
+                       _mmstreamrec_dbg_log("release info_video");
+                       free(sc->info_video);
+                       sc->info_video = NULL;
+               }
+
+               if (sc->info_audio) {
+                       _mmstreamrec_dbg_log("release info_audio");
+                       free(sc->info_audio);
+                       sc->info_audio = NULL;
+               }
+
+               if (sc->info_file) {
+                       _mmstreamrec_dbg_log("release info_file");
+                       free(sc->info_file);
+                       sc->info_file = NULL;
+               }
+
+               free(sc);
+               sc = NULL;
+       }
+       if (hstreamrecorder->sub_context != NULL)
+               hstreamrecorder->sub_context = NULL;
+
+       return;
+}
+
+void _mmstreamrecorder_set_functions(MMHandleType handle)
+{
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+
+       _mmstreamrec_dbg_log("");
+
+       /* Now only video type */
+
+       hstreamrecorder->command = _mmstreamrecorder_video_command;
+
+       return;
+}
+
+void _mmstreamrecorder_unset_functions(MMHandleType handle)
+{
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+
+       _mmstreamrec_dbg_log("");
+
+       hstreamrecorder->command = NULL;
+
+       return;
+}
diff --git a/src/mm_streamrecorder_recorder.c b/src/mm_streamrecorder_recorder.c
new file mode 100644 (file)
index 0000000..02cb2b1
--- /dev/null
@@ -0,0 +1,1937 @@
+/*
+ * libmm-streamrecorder
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Hyuntae Kim <ht1211.kim@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_streamrecorder_internal.h"
+#include "mm_streamrecorder_video.h"
+#include "mm_streamrecorder_gstcommon.h"
+#include "mm_streamrecorder_recorder.h"
+#include "mm_streamrecorder_util.h"
+#include "mm_streamrecorder_buffer_manager.h"
+#include "mm_streamrecorder_fileinfo.h"
+#include "mm_streamrecorder_attribute.h"
+
+#include <gst/gst.h>
+#include <gst/base/gstadapter.h>
+#include <gst/app/gstappsrc.h>
+#include <gst/app/gstappsink.h>
+
+
+/*---------------------------------------------------------------------------------------
+|    GLOBAL VARIABLE DEFINITIONS for internal                                          |
+---------------------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------------------
+|    LOCAL VARIABLE DEFINITIONS for internal                                           |
+---------------------------------------------------------------------------------------*/
+
+/*-----------------------------------------------------------------------
+|    GLOBAL VARIABLE DEFINITIONS for internal                          |
+-----------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------------------
+|    LOCAL FUNCTION PROTOTYPES:                                                                |
+---------------------------------------------------------------------------------------*/
+/* STATIC INTERNAL FUNCTION */
+
+/*=======================================================================================
+|  FUNCTION DEFINITIONS                                                                        |
+=======================================================================================*/
+/*---------------------------------------------------------------------------------------
+|    GLOBAL FUNCTION DEFINITIONS:                                                      |
+---------------------------------------------------------------------------------------*/
+int _mmstreamrecorder_create_pipeline(MMHandleType handle)
+{
+       int ret = MM_ERROR_NONE;
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+       _MMStreamRecorderSubContext *sc = NULL;
+       GstElement *pipeline = NULL;
+
+       _mmstreamrec_dbg_log("handle : %x", handle);
+
+       mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+
+       sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
+       mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+
+       /* ENCODER MODE */
+       ret = _mmstreamrecorder_create_recorder_pipeline(handle);
+
+       pipeline = sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst;
+
+       ret = _mmstreamrecorder_gst_set_state(handle, pipeline, GST_STATE_READY);
+
+       _mmstreamrec_dbg_log("ret[%x]", ret);
+       return ret;
+}
+
+void _mmstreamrecorder_destroy_pipeline(MMHandleType handle)
+{
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+       _MMStreamRecorderSubContext *sc = NULL;
+       gint i = 0;
+       int element_num = 0;
+       _MMStreamRecorderGstElement *element = NULL;
+       GstBus *bus = NULL;
+
+       mmf_return_if_fail(hstreamrecorder);
+
+       sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
+       mmf_return_if_fail(sc);
+
+       _mmstreamrec_dbg_log("");
+
+       element = sc->encode_element;
+       element_num = sc->encode_element_num;
+       if (element == NULL) {
+               _mmstreamrec_dbg_log("encode element is null!!");
+               return;
+       }
+
+       if (sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst != NULL) {
+               bus = gst_pipeline_get_bus(GST_PIPELINE(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst));
+
+               _mmstreamrec_dbg_log("Pipeline clear!!");
+
+               /* Remove pipeline message callback */
+               if (hstreamrecorder->pipeline_cb_event_id != 0) {
+                       g_source_remove(hstreamrecorder->pipeline_cb_event_id);
+                       hstreamrecorder->pipeline_cb_event_id = 0;
+               }
+
+               /* Remove remained message in bus */
+               if (bus) {
+                       GstMessage *gst_msg = NULL;
+                       while ((gst_msg = gst_bus_pop(bus)) != NULL) {
+                               _mmstreamrecorder_pipeline_cb_message(bus, gst_msg, (gpointer) hstreamrecorder);
+                               gst_message_unref(gst_msg);
+                               gst_msg = NULL;
+                       }
+                       gst_object_unref(bus);
+                       bus = NULL;
+               }
+
+               /* Inside each pipeline destroy function, Set GST_STATE_NULL to Main pipeline */
+               _mmstreamrecorder_destroy_recorder_pipeline(handle);
+       }
+
+       if (element != NULL) {
+               /* checking unreleased element */
+               for (i = 0; i < element_num; i++) {
+                       if (element[i].gst) {
+                               if (GST_IS_ELEMENT(element[i].gst)) {
+                                       _mmstreamrec_dbg_warn("Still alive element - ID[%d], name [%s], ref count[%d], status[%s]", element[i].id, GST_OBJECT_NAME(element[i].gst), GST_OBJECT_REFCOUNT(element[i].gst), gst_element_state_get_name(GST_STATE(element[i].gst)));
+                                       g_object_weak_unref(G_OBJECT(element[i].gst), (GWeakNotify) _mmstreamrecorder_element_release_noti, sc);
+                               } else {
+                                       _mmstreamrec_dbg_warn("The element[%d] is still aliving, check it", element[i].id);
+                               }
+
+                               element[i].id = _MMSTREAMRECORDER_ENCODE_NONE;
+                               element[i].gst = NULL;
+                       }
+               }
+       }
+       return;
+}
+
+int _mmstreamrecorder_create_recorder_pipeline(MMHandleType handle)
+{
+       int i = 0;
+       int err = MM_ERROR_NONE;
+       int audio_enable = FALSE;
+       GstBus *bus = NULL;
+       GstPad *srcpad = NULL;
+       GstPad *sinkpad = NULL;
+
+       unsigned int video_codec = MM_VIDEO_CODEC_INVALID;
+       unsigned int file_format = MM_FILE_FORMAT_INVALID;
+       char *err_name = NULL;
+
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+       _MMStreamRecorderSubContext *sc = NULL;
+
+       mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+
+       sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
+       mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+
+       _mmstreamrec_dbg_warn("start");
+
+       err = mm_streamrecorder_get_attributes(handle, &err_name, MMSTR_VIDEO_ENCODER, &video_codec, MMSTR_FILE_FORMAT, &file_format, NULL);
+       if (err != MM_ERROR_NONE) {
+               _mmstreamrec_dbg_warn("Get attrs fail. (%s:%x)", err_name, err);
+               SAFE_FREE(err_name);
+               return err;
+       }
+
+       err = _mmstreamrecorder_check_videocodec_fileformat_compatibility(video_codec, file_format);
+       if (err != MM_ERROR_NONE)
+               return err;
+
+       /* Main pipeline */
+       _MMSTREAMRECORDER_PIPELINE_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCODE_MAIN_PIPE, "recorder_pipeline", err);
+
+       /* get audio disable */
+       mm_streamrecorder_get_attributes(handle, NULL, MMSTR_AUDIO_ENABLE, &audio_enable, NULL);
+       sc->audio_enable = audio_enable;
+
+       _mmstreamrec_dbg_log("AUDIO DISABLE : %d", sc->audio_enable);
+
+       if (sc->audio_enable == TRUE) {
+               /* create audiosrc bin */
+               err = _mmstreamrecorder_create_audiosrc_bin((MMHandleType) hstreamrecorder);
+               if (err != MM_ERROR_NONE)
+                       return err;
+       }
+
+       err = _mmstreamrecorder_create_encodesink_bin((MMHandleType) hstreamrecorder, MM_STREAMRECORDER_ENCBIN_PROFILE_VIDEO);
+       if (err != MM_ERROR_NONE)
+               return err;
+
+       if (sc->audio_enable == TRUE) {
+               gst_bin_add(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst), sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst);
+       }
+
+       /* add element and encodesink bin to encode main pipeline */
+       gst_bin_add_many(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst), sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_FILT].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, NULL);
+
+       /* Link each element : appsrc - capsfilter - encodesink bin */
+       srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, "src");
+       sinkpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_FILT].gst, "sink");
+       _MM_GST_PAD_LINK_UNREF(srcpad, sinkpad, err, pipeline_creation_error);
+
+       srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_FILT].gst, "src");
+       sinkpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, "video_sink0");
+       _MM_GST_PAD_LINK_UNREF(srcpad, sinkpad, err, pipeline_creation_error);
+
+       if (sc->audio_enable == TRUE) {
+               srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst, "src");
+               sinkpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, "audio_sink0");
+               _MM_GST_PAD_LINK_UNREF(srcpad, sinkpad, err, pipeline_creation_error);
+       }
+
+       if (sc->audio_enable == TRUE) {
+               sinkpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, "sink");
+               MMSTREAMRECORDER_ADD_BUFFER_PROBE(sinkpad, _MMSTREAMRECORDER_HANDLER_VIDEOREC, __mmstreamrecorder_audioque_dataprobe, hstreamrecorder);
+               gst_object_unref(sinkpad);
+               sinkpad = NULL;
+
+               if (sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC_QUE].gst) {
+                       srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC_QUE].gst, "src");
+                       MMSTREAMRECORDER_ADD_EVENT_PROBE(srcpad, _MMSTREAMRECORDER_HANDLER_VIDEOREC, __mmstreamrecorder_eventprobe_monitor, hstreamrecorder);
+                       gst_object_unref(srcpad);
+                       srcpad = NULL;
+               }
+       }
+
+       if (sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC_QUE].gst) {
+               srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC_QUE].gst, "src");
+               MMSTREAMRECORDER_ADD_EVENT_PROBE(srcpad, _MMSTREAMRECORDER_HANDLER_VIDEOREC, __mmstreamrecorder_eventprobe_monitor, hstreamrecorder);
+               gst_object_unref(srcpad);
+               srcpad = NULL;
+       }
+
+       if (sc->audio_enable == FALSE) {
+               sinkpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst, "sink");
+               MMSTREAMRECORDER_ADD_BUFFER_PROBE(sinkpad, _MMSTREAMRECORDER_HANDLER_VIDEOREC, __mmstreamrecorder_video_dataprobe_audio_disable, hstreamrecorder);
+               gst_object_unref(sinkpad);
+               sinkpad = NULL;
+       }
+
+       if (!strcmp(/*gst_element_rsink_name */"filesink", "filesink")) {
+               srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst, "src");
+               MMSTREAMRECORDER_ADD_BUFFER_PROBE(srcpad, _MMSTREAMRECORDER_HANDLER_VIDEOREC, __mmstreamrecorder_video_dataprobe_record, hstreamrecorder);
+               gst_object_unref(srcpad);
+               srcpad = NULL;
+
+               if (sc->audio_enable == TRUE) {
+                       srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, "src");
+                       MMSTREAMRECORDER_ADD_BUFFER_PROBE(srcpad, _MMSTREAMRECORDER_HANDLER_VIDEOREC, __mmstreamrecorder_audio_dataprobe_check, hstreamrecorder);
+                       gst_object_unref(srcpad);
+                       srcpad = NULL;
+               }
+       }
+
+       bus = gst_pipeline_get_bus(GST_PIPELINE(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst));
+
+       /* register pipeline message callback */
+       hstreamrecorder->encode_pipeline_cb_event_id = gst_bus_add_watch(bus, (GstBusFunc) _mmstreamrecorder_pipeline_cb_message, hstreamrecorder);
+
+       gst_object_unref(bus);
+       bus = NULL;
+
+       return MM_ERROR_NONE;
+
+ pipeline_creation_error:
+       for (i = _MMSTREAMRECORDER_AUDIOSRC_BIN; i <= _MMSTREAMRECORDER_ENCSINK_SINK; i++) {
+               _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, i);
+       }
+       _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCODE_MAIN_PIPE);
+       return err;
+}
+
+int _mmstreamrecorder_destroy_recorder_pipeline(MMHandleType handle)
+{
+       int ret = MM_ERROR_NONE;
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+       _MMStreamRecorderSubContext *sc = NULL;
+
+       GstBus *bus = NULL;
+
+       mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+       sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
+       mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+
+       _mmstreamrec_dbg_log("start");
+
+       if (!sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst) {
+               _mmstreamrec_dbg_warn("pipeline is not existed.");
+               return MM_ERROR_NONE;
+       }
+
+       _mmstreamrecorder_remove_all_handlers((MMHandleType) hstreamrecorder, _MMSTREAMRECORDER_HANDLER_VIDEOREC);
+
+       ret = _mmstreamrecorder_gst_set_state(handle, sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst, GST_STATE_NULL);
+       if (ret != MM_ERROR_NONE) {
+               _mmstreamrec_dbg_err("Faile to change encode main pipeline [0x%x]", ret);
+               return ret;
+       }
+
+       bus = gst_pipeline_get_bus(GST_PIPELINE(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst));
+
+       /* Remove remained message */
+       if (bus) {
+               GstMessage *gst_msg = NULL;
+               while ((gst_msg = gst_bus_pop(bus)) != NULL) {
+                       _mmstreamrecorder_pipeline_cb_message(bus, gst_msg, (gpointer) hstreamrecorder);
+                       gst_message_unref(gst_msg);
+                       gst_msg = NULL;
+               }
+               gst_object_unref(bus);
+               bus = NULL;
+       }
+
+       /* remove audio pipeline first */
+       ret = _mmstreamrecorder_destroy_audiosrc_bin(handle);
+       if (ret != MM_ERROR_NONE) {
+               _mmstreamrec_dbg_err("Fail to remove audio pipeline");
+               return ret;
+       }
+
+       ret = _mmstreamrecorder_destroy_encodesink_bin(handle);
+       if (ret != MM_ERROR_NONE) {
+               _mmstreamrec_dbg_err("Fail to remove encoder pipeline");
+               return ret;
+       }
+
+       /* Remove pipeline message callback */
+       if (hstreamrecorder->encode_pipeline_cb_event_id != 0) {
+               g_source_remove(hstreamrecorder->encode_pipeline_cb_event_id);
+               hstreamrecorder->encode_pipeline_cb_event_id = 0;
+       }
+
+       _mmstreamrec_dbg_log("done");
+
+       return ret;
+}
+
+int _mmstreamrecorder_create_encodesink_bin(MMHandleType handle, MMStreamRecorderEncodebinProfile profile)
+{
+       int err = MM_ERROR_NONE;
+       int result = 0;
+       int channel = 0;
+       int audio_enc = 0;
+       int video_enc = 0;
+       int v_bitrate = 0;
+       int a_bitrate = 0;
+       int video_width = 0;
+       int video_height = 0;
+       int video_fps = 0;
+       int file_format = 0;
+       int audio_src_format = 0;
+       int video_src_format = 0;
+       int audio_samplerate = 0;
+       const char *str_profile = NULL;
+       const char *str_aac = NULL;
+       const char *str_aar = NULL;
+       const char *str_acs = NULL;
+       char *err_name = NULL;
+
+       GstCaps *caps = NULL;
+       GstPad *pad = NULL;
+       GList *element_list = NULL;
+       char *temp_filename = NULL;
+       int fileformat = 0;
+       int size = 0;
+       guint imax_size = 0;
+       guint imax_time = 0;
+       int rec_mode = 0;
+
+       _MMStreamRecorderVideoInfo *info = NULL;
+       _MMStreamRecorderFileInfo *finfo = NULL;
+
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+       _MMStreamRecorderSubContext *sc = NULL;
+       /* type_element *VideoencElement = NULL; */
+       /* type_element *AudioencElement = NULL; */
+       /* type_element *MuxElement = NULL; */
+       /* type_element *RecordsinkElement = NULL; */
+
+       mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+
+       sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
+       mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+
+       _mmstreamrec_dbg_log("start - profile : %d", profile);
+
+       info = sc->info_video;
+       finfo = sc->info_file;
+
+       /* check element availability */
+       mm_streamrecorder_get_attributes(handle, &err_name, MMSTR_AUDIO_ENCODER, &audio_enc, MMSTR_AUDIO_CHANNEL, &channel, MMSTR_VIDEO_BITRATE, &v_bitrate, MMSTR_VIDEO_ENCODER, &video_enc, MMSTR_AUDIO_BITRATE, &a_bitrate, MMSTR_VIDEO_RESOLUTION_WIDTH, &video_width, MMSTR_VIDEO_RESOLUTION_HEIGHT, &video_height, MMSTR_VIDEO_FRAMERATE, &video_fps, MMSTR_FILE_FORMAT, &file_format, MMSTR_AUDIO_SAMPLERATE, &audio_samplerate, MMSTR_AUDIO_SOURCE_FORMAT, &audio_src_format, MMSTR_VIDEO_SOURCE_FORMAT, &video_src_format, MMSTR_RECORDER_MODE, &rec_mode, NULL);
+
+       _mmstreamrec_dbg_err("audio encoder - %d , video encoder : %d", audio_enc, video_enc);
+       _mmstreamrec_dbg_err("audio channel - %d , video v_bitrate : %d", channel, v_bitrate);
+       _mmstreamrec_dbg_err("audio a_bitrate - %d , video video_width : %d ,video video_height : %d ", a_bitrate, video_width, video_height);
+       _mmstreamrec_dbg_err("video_fps - %d , video file_format : %d", video_fps, file_format);
+
+       /* Check existence */
+       if (sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst) {
+               if (((GObject *) sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst)->ref_count > 0)
+                       gst_object_unref(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst);
+
+               _mmstreamrec_dbg_log("_MMSTREAMRECORDER_ENCSINK_BIN is Already existed.");
+       }
+
+       /* Create bin element */
+       _MMSTREAMRECORDER_BIN_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCSINK_BIN, "encodesink_bin", err);
+
+       /* Create child element */
+       if (hstreamrecorder->ini.encsink_bin_profile != MM_STREAMRECORDER_ENCBIN_PROFILE_AUDIO) {
+               /* create appsrc and capsfilter */
+               _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCSINK_SRC, hstreamrecorder->ini.name_of_encsink_src, "encodesink_src", element_list, err);
+               _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCSINK_FILT, "capsfilter", "encodesink_filter", element_list, err);
+
+               caps = gst_set_videosrcpad_caps(video_src_format, video_width, video_height, video_fps, 1);
+               MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, "caps", caps);
+               if (caps) {
+                       gst_caps_unref(caps);
+                       caps = NULL;
+               }
+
+               caps = gst_set_videosrcpad_caps(video_src_format, video_width, video_height, video_fps, 1);
+               MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_FILT].gst, "caps", caps);
+               if (caps) {
+                       gst_caps_unref(caps);
+                       caps = NULL;
+               }
+
+
+               /* release element_list, they will be placed out of encodesink bin */
+               if (element_list) {
+                       g_list_free(element_list);
+                       element_list = NULL;
+               }
+               if (rec_mode == MM_STREAMRECORDER_MODE_MEDIABUFFER) {
+                       /* set appsrc as live source */
+                       MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, "is-live", hstreamrecorder->ini.encsink_src_islive);
+               }
+
+       }
+
+       _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCSINK_ENCBIN, "encodebin", "encodesink_encbin", element_list, err);
+
+       _mmstreamrec_dbg_log("Profile[%d]", profile);
+
+       /* Set information */
+       if (hstreamrecorder->ini.encsink_bin_profile == MM_STREAMRECORDER_ENCBIN_PROFILE_VIDEO) {
+               str_profile = "VideoProfile";
+               str_aac = "VideoAutoAudioConvert";
+               str_aar = "VideoAutoAudioResample";
+               str_acs = "VideoAutoColorSpace";
+       } else if (hstreamrecorder->ini.encsink_bin_profile == MM_STREAMRECORDER_ENCBIN_PROFILE_AUDIO) {
+               str_profile = "AudioProfile";
+               str_aac = "AudioAutoAudioConvert";
+               str_aar = "AudioAutoAudioResample";
+               str_acs = "AudioAutoColorSpace";
+       }
+
+       /* TODO : check the last value ( set ) */
+       MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "profile", hstreamrecorder->ini.encsink_bin_profile);
+       if (rec_mode == MM_STREAMRECORDER_MODE_MEDIABUFFER) {
+               MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "auto-audio-convert", hstreamrecorder->ini.encsink_bin_auto_audio_convert);
+       }
+       MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "auto-audio-resample", hstreamrecorder->ini.encsink_bin_auto_audio_resample);
+       MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "auto-colorspace", hstreamrecorder->ini.encsink_bin_auto_colorspace);
+       MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "use-video-toggle", hstreamrecorder->ini.encsink_bin_use_video_toggle);
+
+       /* Codec */
+       if (hstreamrecorder->ini.encsink_bin_profile == MM_STREAMRECORDER_ENCBIN_PROFILE_VIDEO) {
+               switch (video_enc) {
+               case MM_VIDEO_CODEC_H263:
+                       MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "venc-name", hstreamrecorder->ini.h263_video_encoder);
+                       break;
+               case MM_VIDEO_CODEC_H264:
+                       MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "venc-name", hstreamrecorder->ini.h264_video_encoder);
+                       break;
+               case MM_VIDEO_CODEC_MPEG4:
+                       MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "venc-name", hstreamrecorder->ini.mpeg4_video_encoder);
+                       break;
+               default:
+                       MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "venc-name", hstreamrecorder->ini.h264_video_encoder);
+                       break;
+               }
+               _MMSTREAMRECORDER_ENCODEBIN_ELMGET(sc, _MMSTREAMRECORDER_ENCSINK_VENC, "video-encode", err);
+               /* _mmstreamrec_dbg_err(" hyuntae log = %p sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst = %p" ,sc, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst); */
+
+
+               /* set color converter size */
+               MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "vconv-name", hstreamrecorder->ini.name_of_encsink_bin_video_converter);
+               _MMSTREAMRECORDER_ENCODEBIN_ELMGET(sc, _MMSTREAMRECORDER_ENCSINK_VCONV, "video-convert", err);
+
+               MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "auto-colorspace", hstreamrecorder->ini.encsink_bin_auto_colorspace);
+
+               if (video_src_format == MM_STREAMRECORDER_INPUT_FORMAT_NV12) {
+                       video_src_format = MM_STREAMRECORDER_INPUT_FORMAT_I420;
+               }
+               caps = gst_set_videosrcpad_caps(video_src_format, video_width, video_height, video_fps, 1);
+               MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "vcaps", caps);
+               if (video_src_format != MM_STREAMRECORDER_INPUT_FORMAT_NV12) {
+                       MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VCONV].gst, "dst-buffer-num", hstreamrecorder->ini.convert_output_buffer_num);
+               }
+               /* state tuning */
+               err = gst_pad_set_caps(gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst, "sink"), caps);
+               err = MM_ERROR_NONE;
+               /* MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst, "state-tuning", TRUE); */
+
+               if (caps) {
+                       gst_caps_unref(caps);
+                       caps = NULL;
+               }
+               _mmstreamrec_dbg_log("size %dx%d, dst-buffer-num %d", video_width, video_height, hstreamrecorder->ini.convert_output_buffer_num);
+
+               _mmstreamrec_dbg_warn("encoder set caps result : 0x%x", err);
+
+               if (hstreamrecorder->ini.encsink_bin_use_parser[0]) {
+                       GstElement *parser = gst_element_factory_make(hstreamrecorder->ini.encsink_bin_use_parser, "parse");
+                       MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "use-venc-queue", parser);
+                       _MMSTREAMRECORDER_ENCODEBIN_ELMGET(sc, _MMSTREAMRECORDER_ENCSINK_PARSER, "use-venc-queue", err);
+               }
+       }
+
+       if (sc->audio_enable == TRUE) {
+
+               MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "aenc-name", hstreamrecorder->ini.name_of_encsink_bin_audio_encoder);
+               _MMSTREAMRECORDER_ENCODEBIN_ELMGET(sc, _MMSTREAMRECORDER_ENCSINK_AENC, "audio-encode", err);
+               _mmstreamrec_dbg_err("audio-encode err = %x ", err);
+
+               /* Set basic infomation */
+               if (audio_enc != MM_AUDIO_CODEC_VORBIS) {
+                       int depth = 0;
+
+                       if (audio_src_format == MM_STREAMRECORDER_AUDIO_FORMAT_PCM_S16_LE) {
+                               depth = 16;
+                       } else {                        /* MM_STREAMRECORDER_AUDIO_FORMAT_PCM_U8 */
+                               depth = 8;
+                       }
+
+                       /* TODO : set rate , channel , depth */
+
+                       caps = gst_set_audiosrcpad_caps(audio_samplerate, 2, depth, 16, 1);
+                       /* MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "auto-audio-convert", TRUE); */
+                       MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "acaps", caps);
+                       {
+                               gchar *type = gst_caps_to_string(caps);
+
+                               _mmstreamrec_dbg_warn("Set srcpad caps: %s", type);
+                       }
+                       gst_caps_unref(caps);
+                       caps = NULL;
+               } else {
+                       /* what are the audio encoder which should get audio/x-raw-float? */
+                       caps = gst_caps_new_simple("audio/x-raw", "rate", G_TYPE_INT, audio_samplerate, "channels", G_TYPE_INT, channel, "endianness", G_TYPE_INT, BYTE_ORDER, "width", G_TYPE_INT, 32, NULL);
+                       _mmstreamrec_dbg_log("caps [x-raw-float, rate:%d, channel:%d, endianness:%d, width:32]", audio_samplerate, channel, BYTE_ORDER);
+                       MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "auto-audio-convert", TRUE);
+                       MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "acaps", caps);
+                       gst_caps_unref(caps);
+                       caps = NULL;
+               }
+
+#if 0
+               if (audio_enc == MM_AUDIO_CODEC_AMR && channel == 2) {
+                       caps = gst_caps_new_simple("audio/x-raw-int", "channels", G_TYPE_INT, 1, NULL);
+                       MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "auto-audio-convert", TRUE);
+                       MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "acaps", caps);
+                       gst_caps_unref(caps);
+                       caps = NULL;
+               }
+
+               if (audio_enc == MM_AUDIO_CODEC_OGG) {
+                       caps = gst_caps_new_simple("audio/x-raw-int", NULL);
+                       MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "auto-audio-convert", TRUE);
+                       MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "acaps", caps);
+                       gst_caps_unref(caps);
+                       caps = NULL;
+               }
+#endif
+
+               _MMSTREAMRECORDER_ENCODEBIN_ELMGET(sc, _MMSTREAMRECORDER_ENCSINK_AENC_QUE, "use-aenc-queue", err);
+       }
+
+       /* Mux */
+       switch (file_format) {
+       case MM_FILE_FORMAT_3GP:{
+                       MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "mux-name", hstreamrecorder->ini.name_of_encsink_bin_3GPMUXER);
+               }
+               break;
+
+       case MM_FILE_FORMAT_MP4:{
+                       MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "mux-name", hstreamrecorder->ini.name_of_encsink_bin_MP4MUXER);
+               }
+               break;
+
+       default:{
+                       MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "mux-name", hstreamrecorder->ini.name_of_encsink_bin_MP4MUXER);
+               }
+               break;
+
+       }
+       _MMSTREAMRECORDER_ENCODEBIN_ELMGET(sc, _MMSTREAMRECORDER_ENCSINK_MUX, "mux", err);
+
+       /* Sink */
+       /* for recording */
+       _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCSINK_SINK, "filesink", NULL, element_list, err);
+       MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SINK].gst, "async", 0);
+
+       err = mm_streamrecorder_get_attributes(handle, &err_name,
+                                                                                  MMSTR_FILE_FORMAT, &fileformat, MMSTR_FILENAME, &temp_filename, &size,
+                                                                                  MMSTR_TARGET_MAX_SIZE, &imax_size,
+                                                                                  MMSTR_TARGET_TIME_LIMIT, &imax_time,
+                                                                                  NULL);
+
+       if (err != MM_ERROR_NONE) {
+               _mmstreamrec_dbg_warn("Get attrs fail. (%s:%x)", err_name, err);
+               SAFE_FREE(err_name);
+               return err;
+       }
+
+       finfo->fileformat = fileformat;
+
+       /* set max size */
+       if (imax_size <= 0)
+               info->max_size = 0;             /* do not check */
+       else
+               info->max_size = ((guint64) imax_size) << 10;   /* to byte */
+
+       /* set max time */
+       if (imax_time <= 0)
+               info->max_time = 0;             /* do not check */
+       else
+               info->max_time = ((guint64) imax_time) * 1000;  /* to millisecond */
+
+       finfo->filename = strdup(temp_filename);
+       if (!finfo->filename) {
+               _mmstreamrec_dbg_err("strdup was failed");
+               return err;
+       }
+
+       _mmstreamrec_dbg_log("Record start : set file name using attribute - %s ", finfo->filename);
+
+       MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SINK].gst, "location", finfo->filename);
+
+       if (profile == MM_STREAMRECORDER_ENCBIN_PROFILE_VIDEO) {
+               /* video encoder attribute setting */
+               if (v_bitrate > 0) {
+                       MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst, "bitrate", v_bitrate);
+               } else {
+                       _mmstreamrec_dbg_warn("video bitrate is too small[%d], so skip setting. Use DEFAULT value.", v_bitrate);
+               }
+       }
+
+       if (sc->audio_enable == TRUE) {
+               /* audio encoder attribute setting */
+               if (a_bitrate > 0) {
+                       switch (audio_enc) {
+                       case MM_AUDIO_CODEC_AMR:
+                               result = _mmstreamrecorder_get_amrnb_bitrate_mode(a_bitrate);
+                               _mmstreamrec_dbg_log("Set AMR encoder mode [%d]", result);
+                               MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, "band-mode", result);
+                               break;
+                       case MM_AUDIO_CODEC_AAC:
+                               _mmstreamrec_dbg_log("Set AAC encoder bitrate [%d]", a_bitrate);
+                               MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, "bitrate", a_bitrate);
+                               break;
+                       default:
+                               _mmstreamrec_dbg_log("Audio codec is not AMR or AAC... you need to implement setting function for audio encoder bit-rate");
+                               break;
+                       }
+               } else {
+                       _mmstreamrec_dbg_warn("Setting bitrate is too small, so skip setting. Use DEFAULT value.");
+               }
+       }
+
+       _mmstreamrec_dbg_log("Element creation complete");
+
+       /* Add element to bin */
+       if (!_mmstreamrecorder_add_elements_to_bin(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst), element_list)) {
+               _mmstreamrec_dbg_err("element add error.");
+               err = MM_ERROR_STREAMRECORDER_RESOURCE_CREATION;
+               goto pipeline_creation_error;
+       }
+
+       _mmstreamrec_dbg_log("Element add complete");
+
+       if (profile == MM_STREAMRECORDER_ENCBIN_PROFILE_VIDEO) {
+               pad = gst_element_get_request_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "video");
+               if (gst_element_add_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, gst_ghost_pad_new("video_sink0", pad)) < 0) {
+                       gst_object_unref(pad);
+                       pad = NULL;
+                       _mmstreamrec_dbg_err("failed to create ghost video_sink0 on _MMSTREAMRECORDER_ENCSINK_BIN.");
+                       err = MM_ERROR_STREAMRECORDER_GST_LINK;
+                       goto pipeline_creation_error;
+               }
+               gst_object_unref(pad);
+               pad = NULL;
+
+               if (sc->audio_enable == TRUE) {
+                       pad = gst_element_get_request_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "audio");
+                       if (gst_element_add_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, gst_ghost_pad_new("audio_sink0", pad)) < 0) {
+                               gst_object_unref(pad);
+                               pad = NULL;
+                               _mmstreamrec_dbg_err("failed to create ghost audio_sink0 on _MMSTREAMRECORDER_ENCSINK_BIN.");
+                               err = MM_ERROR_STREAMRECORDER_GST_LINK;
+                               goto pipeline_creation_error;
+                       }
+                       gst_object_unref(pad);
+                       pad = NULL;
+               }
+       } else if (profile == MM_STREAMRECORDER_ENCBIN_PROFILE_AUDIO) {
+               pad = gst_element_get_request_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "audio");
+               if (gst_element_add_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, gst_ghost_pad_new("audio_sink0", pad)) < 0) {
+                       gst_object_unref(pad);
+                       pad = NULL;
+                       _mmstreamrec_dbg_err("failed to create ghost audio_sink0 on _MMSTREAMRECORDER_ENCSINK_BIN.");
+                       err = MM_ERROR_STREAMRECORDER_GST_LINK;
+                       goto pipeline_creation_error;
+               }
+               gst_object_unref(pad);
+               pad = NULL;
+       } else {
+               /* for stillshot */
+               pad = gst_element_get_request_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "image");
+               if (gst_element_add_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, gst_ghost_pad_new("image_sink0", pad)) < 0) {
+                       gst_object_unref(pad);
+                       pad = NULL;
+                       _mmstreamrec_dbg_err("failed to create ghost image_sink0 on _MMSTREAMRECORDER_ENCSINK_BIN.");
+                       err = MM_ERROR_STREAMRECORDER_GST_LINK;
+                       goto pipeline_creation_error;
+               }
+               gst_object_unref(pad);
+               pad = NULL;
+       }
+
+       _mmstreamrec_dbg_log("Get pad complete");
+
+       /* Link internal element */
+       if (!_mmstreamrecorder_link_elements(element_list)) {
+               _mmstreamrec_dbg_err("element link error.");
+               err = MM_ERROR_STREAMRECORDER_GST_LINK;
+               goto pipeline_creation_error;
+       }
+
+       if (element_list) {
+               g_list_free(element_list);
+               element_list = NULL;
+       }
+
+       _mmstreamrec_dbg_log("done");
+
+       return MM_ERROR_NONE;
+
+ pipeline_creation_error:
+       _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_ENCBIN);
+       _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_SRC);
+       _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_FILT);
+       _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_VENC);
+       _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_AENC);
+       _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_IENC);
+       _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_MUX);
+       _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_SINK);
+       _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_BIN);
+
+       if (element_list) {
+               g_list_free(element_list);
+               element_list = NULL;
+       }
+
+       return err;
+}
+
+int _mmstreamrecorder_destroy_encodesink_bin(MMHandleType handle)
+{
+       GstPad *reqpad = NULL;
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+       _MMStreamRecorderSubContext *sc = NULL;
+
+       mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+
+       sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
+       mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+
+       _mmstreamrec_dbg_log("");
+
+       if (sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst != NULL) {
+               /* release request pad */
+               reqpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "audio");
+               if (reqpad) {
+                       gst_element_release_request_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, reqpad);
+                       gst_object_unref(reqpad);
+                       reqpad = NULL;
+               }
+
+               reqpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "video");
+               if (reqpad) {
+                       gst_element_release_request_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, reqpad);
+                       gst_object_unref(reqpad);
+                       reqpad = NULL;
+               }
+
+               /* release encode main pipeline */
+               gst_object_unref(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst);
+
+               _mmstreamrec_dbg_log("Encoder pipeline removed");
+       }
+
+       return MM_ERROR_NONE;
+}
+
+int _mmstreamrecorder_create_audiosrc_bin(MMHandleType handle)
+{
+       int err = MM_ERROR_NONE;
+       int val = 0;
+       int rate = 0;
+       int format = 0;
+       int channel = 0;
+       unsigned int a_enc = MM_AUDIO_CODEC_INVALID;
+       unsigned int file_format = MM_FILE_FORMAT_INVALID;
+       char *err_name = NULL;
+       int rec_mode = 0;
+
+       GstCaps *caps = NULL;
+       GstPad *pad = NULL;
+       GList *element_list = NULL;
+
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+       _MMStreamRecorderSubContext *sc = NULL;
+       _MMStreamRecorderGstElement *last_element = NULL;
+       /* type_element *AudiosrcElement = NULL; */
+
+       mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+
+       sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
+       mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+
+       _mmstreamrec_dbg_log("");
+
+       err = mm_streamrecorder_get_attributes(handle, &err_name, MMSTR_AUDIO_ENCODER, &a_enc, MMSTR_AUDIO_BITRATE, &val, MMSTR_AUDIO_SAMPLERATE, &rate, MMSTR_AUDIO_SOURCE_FORMAT, &format, MMSTR_AUDIO_CHANNEL, &channel, MMSTR_FILE_FORMAT, &file_format, MMSTR_RECORDER_MODE, &rec_mode, NULL);
+
+       if (err != MM_ERROR_NONE) {
+               _mmstreamrec_dbg_warn("Get attrs fail. (%s:%x)", err_name, err);
+               SAFE_FREE(err_name);
+               return err;
+       }
+
+       err = _mmstreamrecorder_check_audiocodec_fileformat_compatibility(a_enc, file_format);
+       if (err != MM_ERROR_NONE) {
+               _mmstreamrec_dbg_err("error name :%s , audio format %d , fileformat %d. error : %x)", err_name, a_enc, file_format, err);
+               SAFE_FREE(err_name);
+               return err;
+       }
+
+       /* Check existence */
+       if (sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst) {
+               if (((GObject *) sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst)->ref_count > 0)
+                       gst_object_unref(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst);
+
+               _mmstreamrec_dbg_log("_MMSTREAMRECORDER_AUDIOSRC_BIN is Already existed. Unref once...");
+       }
+
+       /* Create bin element */
+       _MMSTREAMRECORDER_BIN_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_AUDIOSRC_BIN, "audiosource_bin", err);
+
+       _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_AUDIOSRC_SRC, "appsrc", hstreamrecorder->ini.name_of_audio_src, element_list, err);
+
+       _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_AUDIOSRC_FILT, "capsfilter", "audiosrc_capsfilter", element_list, err);
+
+       /* Set basic infomation */
+       if (a_enc != MM_AUDIO_CODEC_VORBIS) {
+               int depth = 0;
+
+               if (format == MM_STREAMRECORDER_AUDIO_FORMAT_PCM_S16_LE) {
+                       depth = 16;
+               } else {                                /* MM_STREAMRECORDER_AUDIO_FORMAT_PCM_U8 */
+                       depth = 8;
+               }
+
+               caps = gst_set_audiosrcpad_caps(rate, channel, depth, 16, 1);
+
+               _mmstreamrec_dbg_log("caps [x-raw-int, rate:%d, channel:%d, depth:%d]", rate, channel, depth);
+       } else {
+               /* what are the audio encoder which should get audio/x-raw-float? */
+               caps = gst_caps_new_simple("audio/x-raw-float", "rate", G_TYPE_INT, rate, "channels", G_TYPE_INT, channel, "endianness", G_TYPE_INT, BYTE_ORDER, "width", G_TYPE_INT, 32, NULL);
+               _mmstreamrec_dbg_log("caps [x-raw-float, rate:%d, channel:%d, endianness:%d, width:32]", rate, channel, BYTE_ORDER);
+       }
+
+       if (caps) {
+               if (rec_mode == MM_STREAMRECORDER_MODE_MEDIABUFFER) {
+                       MMSTREAMRECORDER_G_OBJECT_SET((sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst), "caps", caps);
+               }
+               MMSTREAMRECORDER_G_OBJECT_SET((sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_FILT].gst), "caps", caps);
+               {
+                       gchar *type = gst_caps_to_string(caps);
+
+                       _mmstreamrec_dbg_err("_MMSTREAMRECORDER_AUDIOSRC_FILT %s", type);
+
+               }
+               gst_caps_unref(caps);
+               caps = NULL;
+       } else {
+               _mmstreamrec_dbg_err("create caps error");
+               err = MM_ERROR_STREAMRECORDER_RESOURCE_CREATION;
+               goto pipeline_creation_error;
+       }
+
+       if (rec_mode == MM_STREAMRECORDER_MODE_SCREENRECORD) {
+#if 1                                                  /* mic mode */
+               MMSTREAMRECORDER_G_OBJECT_SET((sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst), "do-timestamp", TRUE);
+#else                                                  /* speaker mode with alsasrc */
+               MMSTREAMRECORDER_G_OBJECT_SET((sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst), "device", "hw:0,8");
+               MMSTREAMRECORDER_G_OBJECT_SET((sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst), "latency-time", 256000);
+               MMSTREAMRECORDER_G_OBJECT_SET((sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst), "buffer-time", 10000);
+               MMSTREAMRECORDER_G_OBJECT_SET((sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst), "do-timestamp", FALSE);
+#endif
+       } else {
+               MMSTREAMRECORDER_G_OBJECT_SET((sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst), "do-timestamp", FALSE);
+       }
+
+       if (!_mmstreamrecorder_add_elements_to_bin(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst), element_list)) {
+               _mmstreamrec_dbg_err("element add error.");
+               err = MM_ERROR_STREAMRECORDER_RESOURCE_CREATION;
+               goto pipeline_creation_error;
+       }
+
+       if (!_mmstreamrecorder_link_elements(element_list)) {
+               _mmstreamrec_dbg_err("element link error.");
+               err = MM_ERROR_STREAMRECORDER_GST_LINK;
+               goto pipeline_creation_error;
+       }
+
+       last_element = (_MMStreamRecorderGstElement *) (g_list_last(element_list)->data);
+       pad = gst_element_get_static_pad(last_element->gst, "src");
+       if ((gst_element_add_pad(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst, gst_ghost_pad_new("src", pad))) < 0) {
+               gst_object_unref(pad);
+               pad = NULL;
+               _mmstreamrec_dbg_err("failed to create ghost pad on _MMSTREAMRECORDER_AUDIOSRC_BIN.");
+               err = MM_ERROR_STREAMRECORDER_GST_LINK;
+               goto pipeline_creation_error;
+       }
+
+       gst_object_unref(pad);
+       pad = NULL;
+
+       if (element_list) {
+               g_list_free(element_list);
+               element_list = NULL;
+       }
+
+       return MM_ERROR_NONE;
+
+ pipeline_creation_error:
+       _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_AUDIOSRC_SRC);
+       _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_AUDIOSRC_FILT);
+       _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_AUDIOSRC_BIN);
+
+       if (element_list) {
+               g_list_free(element_list);
+               element_list = NULL;
+       }
+
+       return err;
+}
+
+int _mmstreamrecorder_destroy_audiosrc_bin(MMHandleType handle)
+{
+       GstPad *srcpad = NULL;
+       GstPad *sinkpad = NULL;
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+       _MMStreamRecorderSubContext *sc = NULL;
+
+       mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+
+       sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
+       mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+
+       _mmstreamrec_dbg_log("");
+
+       if (sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst != NULL) {
+               srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst, "src");
+               sinkpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, "audio_sink0");
+               _MM_GST_PAD_UNLINK_UNREF(srcpad, sinkpad);
+
+               /* release audiosrc bin */
+               gst_bin_remove(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst), sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst);
+
+               _mmstreamrecorder_remove_element_handle(handle, (void *)sc->encode_element, _MMSTREAMRECORDER_AUDIOSRC_BIN, _MMSTREAMRECORDER_AUDIOSRC_FILT);
+
+               _mmstreamrec_dbg_log("Audio pipeline removed");
+       }
+
+       return MM_ERROR_NONE;
+}
+
+/* COMMAND - VIDEO */
+int _mmstreamrecorder_video_command(MMHandleType handle, int command)
+{
+       int ret = MM_ERROR_NONE;
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+       _MMStreamRecorderVideoInfo *info = NULL;
+       _MMStreamRecorderAudioInfo *info_audio = NULL;
+       _MMStreamRecorderFileInfo *finfo = NULL;
+       _MMStreamRecorderSubContext *sc = NULL;
+       GstElement *pipeline = NULL;
+       GstPad *pad = NULL;
+       guint count = 0;
+
+       mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+
+       sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
+       mmf_return_val_if_fail(sc && sc->encode_element, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+
+       mmf_return_val_if_fail(sc->info_video, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+       if (sc->audio_enable == TRUE) {
+               mmf_return_val_if_fail(sc->info_audio, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+       }
+       mmf_return_val_if_fail(sc->info_file, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+
+       info = sc->info_video;
+       if (sc->audio_enable == TRUE)
+               info_audio = sc->info_audio;
+
+       finfo = sc->info_file;
+
+       _mmstreamrec_dbg_log("command %d", command);
+
+       pipeline = sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst;
+
+       switch (command) {
+       case _MM_STREAMRECORDER_CMD_RECORD:
+               {
+
+                       /* Recording */
+                       _mmstreamrec_dbg_log("Record Start");
+                       MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "block", FALSE);
+
+                       /* Adjust display FPS */
+                       info->video_frame_count = 0;
+                       if (info_audio)
+                               info_audio->audio_frame_count = 0;
+
+                       info->filesize = 0;
+                       sc->ferror_send = FALSE;
+                       sc->ferror_count = 0;
+                       sc->error_occurs = FALSE;
+                       sc->bget_eos = FALSE;
+
+                       ret = _mmstreamrecorder_gst_set_state(handle, sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst, GST_STATE_PLAYING);
+                       if (ret != MM_ERROR_NONE) {
+                               /* Remove recorder pipeline and recording file which size maybe zero */
+                               ret = _mmstreamrecorder_destroy_recorder_pipeline(handle);
+
+                               if (finfo->filename) {
+                                       _mmstreamrec_dbg_log("file delete(%s)", finfo->filename);
+                                       unlink(finfo->filename);
+                                       g_free(finfo->filename);
+                                       finfo->filename = NULL;
+                               }
+                               goto _ERR_STREAMRECORDER_VIDEO_COMMAND;
+                       }
+
+               }
+               break;
+       case _MM_STREAMRECORDER_CMD_PAUSE:
+               {
+
+                       if (info->b_commiting) {
+                               _mmstreamrec_dbg_warn("now on commiting previous file!!(command : %d)", command);
+                               return MM_ERROR_STREAMRECORDER_CMD_IS_RUNNING;
+                       }
+
+                       for (count = 0; count <= hstreamrecorder->ini.retrial_count; count++) {
+                               if (sc->audio_enable == FALSE) {
+                                       /* check only video frame */
+                                       if (info->video_frame_count >= hstreamrecorder->ini.minimum_frame) {
+                                               break;
+                                       } else if (count == hstreamrecorder->ini.retrial_count) {
+                                               _mmstreamrec_dbg_err("Pause fail, frame count %" G_GUINT64_FORMAT "", info->video_frame_count);
+                                               return MM_ERROR_STREAMRECORDER_INVALID_CONDITION;
+                                       } else {
+                                               _mmstreamrec_dbg_warn("Waiting for enough video frame, retrial[%d], frame %" G_GUINT64_FORMAT "", count, info->video_frame_count);
+                                       }
+
+                                       usleep(hstreamrecorder->ini.video_frame_wait_time);
+                               } else {
+                                       /* check both of video and audio frame */
+                                       if (info->video_frame_count >= hstreamrecorder->ini.minimum_frame && info_audio->audio_frame_count) {
+                                               break;
+                                       } else if (count == hstreamrecorder->ini.retrial_count) {
+                                               _mmstreamrec_dbg_err("Pause fail, frame count VIDEO[%" G_GUINT64_FORMAT "], AUDIO [%" G_GUINT64_FORMAT "]", info->video_frame_count, info_audio->audio_frame_count);
+                                               return MM_ERROR_STREAMRECORDER_INVALID_CONDITION;
+                                       } else {
+                                               _mmstreamrec_dbg_warn("Waiting for enough frames, retrial [%d], VIDEO[%" G_GUINT64_FORMAT "], AUDIO [%" G_GUINT64_FORMAT "]", count, info->video_frame_count, info_audio->audio_frame_count);
+                                       }
+
+                                       usleep(hstreamrecorder->ini.video_frame_wait_time);
+                               }
+                       }
+                       /* tee block */
+                       MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "runtime-pause", TRUE);
+
+                       break;
+               }
+               break;
+       case _MM_STREAMRECORDER_CMD_CANCEL:
+               {
+                       if (info->b_commiting) {
+                               _mmstreamrec_dbg_warn("now on commiting previous file!!(command : %d)", command);
+                               return MM_ERROR_STREAMRECORDER_CMD_IS_RUNNING;
+                       }
+
+                       ret = _mmstreamrecorder_destroy_recorder_pipeline(handle);
+                       if (ret != MM_ERROR_NONE)
+                               goto _ERR_STREAMRECORDER_VIDEO_COMMAND;
+
+                       /* remove target file */
+                       if (finfo->filename) {
+                               _mmstreamrec_dbg_log("file delete(%s)", finfo->filename);
+                               unlink(finfo->filename);
+                               g_free(finfo->filename);
+                               finfo->filename = NULL;
+                       }
+
+                       sc->isMaxsizePausing = FALSE;
+                       sc->isMaxtimePausing = FALSE;
+
+                       info->video_frame_count = 0;
+                       if (info_audio)
+                               info_audio->audio_frame_count = 0;
+
+                       info->filesize = 0;
+                       break;
+               }
+               break;
+       case _MM_STREAMRECORDER_CMD_COMMIT:
+               /* video recording command */
+               {
+
+                       if (info->b_commiting) {
+                               _mmstreamrec_dbg_err("now on commiting previous file!!(command : %d)", command);
+                               return MM_ERROR_STREAMRECORDER_CMD_IS_RUNNING;
+                       } else {
+                               _mmstreamrec_dbg_log("_MM_STREAMRECORDER_CMD_COMMIT : start");
+                               info->b_commiting = TRUE;
+                       }
+
+                       for (count = 0; count <= hstreamrecorder->ini.retrial_count; count++) {
+                               if (sc->audio_enable == FALSE) {
+                                       /* check only video frame */
+                                       if (info->video_frame_count >= hstreamrecorder->ini.minimum_frame) {
+                                               break;
+                                       } else if (count == hstreamrecorder->ini.retrial_count) {
+                                               _mmstreamrec_dbg_err("Commit fail, frame count is %" G_GUINT64_FORMAT "", info->video_frame_count);
+                                               info->b_commiting = FALSE;
+                                               return MM_ERROR_STREAMRECORDER_INVALID_CONDITION;
+                                       } else {
+                                               _mmstreamrec_dbg_warn("Waiting for enough video frame, retrial [%d], frame %" G_GUINT64_FORMAT "", count, info->video_frame_count);
+                                       }
+
+                                       usleep(hstreamrecorder->ini.video_frame_wait_time);
+                               } else {
+                                       /* check both of video and audio frame */
+                                       if (info->video_frame_count >= hstreamrecorder->ini.minimum_frame && info_audio->audio_frame_count) {
+                                               break;
+                                       } else if (count == hstreamrecorder->ini.retrial_count) {
+                                               _mmstreamrec_dbg_err("Commit fail, VIDEO[%" G_GUINT64_FORMAT "], AUDIO [%" G_GUINT64_FORMAT "]", info->video_frame_count, info_audio->audio_frame_count);
+
+                                               info->b_commiting = FALSE;
+                                               return MM_ERROR_STREAMRECORDER_INVALID_CONDITION;
+                                       } else {
+                                               _mmstreamrec_dbg_warn("Waiting for enough frames, retrial [%d], VIDEO[%" G_GUINT64_FORMAT "], AUDIO [%" G_GUINT64_FORMAT "]", count, info->video_frame_count, info_audio->audio_frame_count);
+                                       }
+
+                                       usleep(hstreamrecorder->ini.video_frame_wait_time);
+                               }
+                       }
+
+                       if (sc->error_occurs) {
+                               GstPad *video = NULL;
+                               GstPad *audio = NULL;
+
+                               _mmstreamrec_dbg_err("Committing Error case");
+#if 0
+                               video = gst_element_get_static_pad(sc->element[_MMSTREAMRECORDER_VIDEOSINK_SINK].gst, "sink");
+                               ret = gst_pad_send_event(video, gst_event_new_eos());
+                               _mmstreamrec_dbg_err("Sending EOS video sink  : %d", ret);
+                               gst_object_unref(video);
+#endif
+                               video = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst, "src");
+                               gst_pad_push_event(video, gst_event_new_flush_start());
+                               gst_pad_push_event(video, gst_event_new_flush_stop(TRUE));
+                               ret = gst_pad_push_event(video, gst_event_new_eos());
+                               _mmstreamrec_dbg_err("Sending EOS video encoder src pad  : %d", ret);
+                               gst_object_unref(video);
+
+                               if (sc->audio_enable == TRUE) {
+                                       audio = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, "src");
+                                       gst_pad_push_event(audio, gst_event_new_flush_start());
+                                       gst_pad_push_event(audio, gst_event_new_flush_stop(TRUE));
+                                       ret = gst_element_send_event(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst, gst_event_new_eos());
+                                       _mmstreamrec_dbg_err("Sending EOS audio encoder src pad  : %d", ret);
+                                       gst_object_unref(audio);
+                               }
+                       } else {
+                               if (sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst != NULL) {
+                                       ret = gst_element_send_event(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, gst_event_new_eos());
+                                       _mmstreamrec_dbg_warn("send eos to appsrc result : %d", ret);
+                               }
+
+                               if (sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst != NULL) {
+                                       pad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst, "src");
+                                       ret = gst_element_send_event(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst, gst_event_new_eos());
+                                       gst_object_unref(pad);
+                                       pad = NULL;
+
+                                       _mmstreamrec_dbg_warn("send eos to audiosrc result : %d", ret);
+                               }
+                       }
+
+                       /* Wait EOS */
+                       _mmstreamrec_dbg_log("Start to wait EOS");
+                       ret = _mmstreamrecorder_get_eos_message(handle);
+                       if (ret != MM_ERROR_NONE) {
+                               info->b_commiting = FALSE;
+                               goto _ERR_STREAMRECORDER_VIDEO_COMMAND;
+                       }
+               }
+               break;
+       default:
+               ret = MM_ERROR_STREAMRECORDER_INVALID_ARGUMENT;
+               break;
+       }
+       return MM_ERROR_NONE;
+
+ _ERR_STREAMRECORDER_VIDEO_COMMAND:
+       if (ret != MM_ERROR_NONE)
+               _mmstreamrec_dbg_err("Current Videosrc status");
+
+       return ret;
+}
+
+int _mmstreamrecorder_video_handle_eos(MMHandleType handle)
+{
+       int ret = MM_ERROR_NONE;
+
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+       _MMStreamRecorderSubContext *sc = NULL;
+       _MMStreamRecorderVideoInfo *info = NULL;
+       _MMStreamRecorderAudioInfo *info_audio = NULL;
+       _MMStreamRecorderFileInfo *finfo = NULL;
+       _MMStreamRecorderMsgItem msg;
+       MMStreamRecordingReport *report = NULL;
+
+       mmf_return_val_if_fail(hstreamrecorder, FALSE);
+
+       sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
+       mmf_return_val_if_fail(sc, FALSE);
+       mmf_return_val_if_fail(sc->info_video, FALSE);
+       if (sc->audio_enable == TRUE)
+               mmf_return_val_if_fail(sc->info_audio, FALSE);
+
+       mmf_return_val_if_fail(sc->info_file, FALSE);
+
+       info = sc->info_video;
+       if (sc->audio_enable == TRUE)
+               info_audio = sc->info_audio;
+
+       finfo = sc->info_file;
+
+       _mmstreamrec_dbg_err("");
+
+       /* remove blocking part */
+       MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "block", FALSE);
+
+       ret = _mmstreamrecorder_destroy_recorder_pipeline(handle);
+       if (ret != MM_ERROR_NONE)
+               _mmstreamrec_dbg_warn("_mmstreamrecorder_destroy_recorder_pipeline failed. error[%x]", ret);
+
+       /* Send recording report to application */
+       msg.id = MM_MESSAGE_STREAMRECORDER_VIDEO_CAPTURED;
+       report = (MMStreamRecordingReport *) malloc(sizeof(MMStreamRecordingReport));
+       if (!report) {
+               _mmstreamrec_dbg_err("Recording report fail(%s). Out of memory.", finfo->filename);
+       } else {
+               report->recording_filename = strdup(finfo->filename);
+               msg.param.data = report;
+               msg.param.code = 1;
+               _mmstreamrecorder_send_message((MMHandleType) hstreamrecorder, &msg);
+       }
+
+       /* Finishing */
+       sc->pipeline_time = 0;
+       sc->pause_time = 0;
+       sc->isMaxsizePausing = FALSE;   /*In async function, this variable should set in callback function. */
+       sc->isMaxtimePausing = FALSE;
+       sc->error_occurs = FALSE;
+
+       info->video_frame_count = 0;
+       if (info_audio)
+               info_audio->audio_frame_count = 0;
+
+       info->filesize = 0;
+       g_free(finfo->filename);
+       finfo->filename = NULL;
+       info->b_commiting = FALSE;
+
+       _mmstreamrec_dbg_err("_mmstreamrecorder_video_handle_eos : end");
+
+       return TRUE;
+}
+
+/* AUDIO */
+
+int _mmstreamrecorder_create_audio_pipeline(MMHandleType handle)
+{
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+       _MMStreamRecorderSubContext *sc = NULL;
+
+       mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+       sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
+
+       mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+
+       return _mmstreamrecorder_create_audiop_with_encodebin(handle);
+}
+
+/**
+ * This function destroy audio pipeline.
+ *
+ * @param[in]  handle          Handle of streamrecorder.
+ * @return     void
+ * @remarks
+ * @see                _mmstreamrecorder_destroy_audio_pipeline()
+ *
+ */
+void _mmstreamrecorder_destroy_audio_pipeline(MMHandleType handle)
+{
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+       _MMStreamRecorderSubContext *sc = NULL;
+       _MMStreamRecorderAudioInfo *info = NULL;
+       mmf_return_if_fail(hstreamrecorder);
+       sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
+
+       mmf_return_if_fail(sc && sc->info_audio);
+
+       info = sc->info_audio;
+
+       _mmstreamrec_dbg_log("start");
+
+       if (sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst) {
+               _mmstreamrec_dbg_warn("release audio pipeline");
+
+               _mmstreamrecorder_gst_set_state(handle, sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst, GST_STATE_NULL);
+
+               _mmstreamrecorder_remove_all_handlers((MMHandleType) hstreamrecorder, _MMSTREAMRECORDER_HANDLER_CATEGORY_ALL);
+
+               if (info->bMuxing) {
+                       GstPad *reqpad = NULL;
+                       /* FIXME:
+                          Release request pad
+                          The ref_count of mux is always # of streams in here, i don't know why it happens.
+                          So, i unref the mux manually
+                        */
+                       reqpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "audio");
+                       gst_element_release_request_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, reqpad);
+                       gst_object_unref(reqpad);
+
+                       if (GST_IS_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_MUX].gst) && GST_OBJECT_REFCOUNT(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_MUX].gst) > 1) {
+                               gst_object_unref(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_MUX].gst);
+                       }
+               }
+               gst_object_unref(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst);
+       }
+
+       _mmstreamrec_dbg_log("done");
+
+       return;
+}
+
+int _mmstreamrecorder_create_audiop_with_encodebin(MMHandleType handle)
+{
+       int err = MM_ERROR_NONE;
+       char *aenc_name = NULL;
+       char *mux_name = NULL;
+       char *err_name = NULL;
+       int rec_mode = 0;
+
+       GstBus *bus = NULL;
+       GstPad *srcpad = NULL;
+       GstPad *sinkpad = NULL;
+       GList *element_list = NULL;
+
+       _MMStreamRecorderAudioInfo *info = NULL;
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+       _MMStreamRecorderSubContext *sc = NULL;
+       /* type_element *aenc_elem = NULL; */
+       /* type_element *mux_elem = NULL; */
+
+       mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+       sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
+
+       mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+       mmf_return_val_if_fail(sc->info_audio, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+
+       info = (_MMStreamRecorderAudioInfo *) sc->info_audio;
+
+       _mmstreamrec_dbg_log("");
+
+       err = mm_streamrecorder_get_attributes(handle, &err_name, MMSTR_RECORDER_MODE, &rec_mode, NULL);
+
+       if (!mux_name || !strcmp(mux_name, "wavenc")) {
+               /* IF MUX in not chosen then record in raw file */
+               _mmstreamrec_dbg_log("Record without muxing.");
+               info->bMuxing = FALSE;
+       } else {
+               _mmstreamrec_dbg_log("Record with mux.");
+               info->bMuxing = TRUE;
+       }
+
+       /* Create GStreamer pipeline */
+       _MMSTREAMRECORDER_PIPELINE_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCODE_MAIN_PIPE, "recorder_pipeline", err);
+
+       err = _mmstreamrecorder_create_audiosrc_bin(handle);
+       if (err != MM_ERROR_NONE)
+               return err;
+
+       if (info->bMuxing) {
+               /* Muxing. can use encodebin. */
+               err = _mmstreamrecorder_create_encodesink_bin((MMHandleType) hstreamrecorder, MM_STREAMRECORDER_ENCBIN_PROFILE_AUDIO);
+               if (err != MM_ERROR_NONE)
+                       return err;
+
+       } else {
+               /* without muxing. can't use encodebin. */
+
+               _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCSINK_AQUE, "queue", NULL, element_list, err);
+
+               if (rec_mode == MM_STREAMRECORDER_MODE_MEDIABUFFER) {
+                       if (strcmp(hstreamrecorder->ini.name_of_encsink_bin_audio_encoder, "wavenc") != 0) {
+                               _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCSINK_CONV, "audioconvert", NULL, element_list, err);
+                       }
+               }
+
+               _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCSINK_AENC, aenc_name, NULL, element_list, err);
+
+               _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCSINK_SINK, hstreamrecorder->ini.name_of_encsink_sink, NULL, element_list, err);
+       }
+
+       /* Add and link elements */
+       if (info->bMuxing) {
+               /* IF MUX is indicated create MUX */
+               gst_bin_add_many(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst), sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, NULL);
+
+               srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst, "src");
+               sinkpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, "audio_sink0");
+               _MM_GST_PAD_LINK_UNREF(srcpad, sinkpad, err, pipeline_creation_error);
+       } else {
+               /* IF MUX in not chosen then record in raw amr file */
+               if (!strcmp(aenc_name, "wavenc")) {
+                       gst_bin_add_many(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst), sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AQUE].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SINK].gst, NULL);
+
+                       if (!_MM_GST_ELEMENT_LINK_MANY(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AQUE].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SINK].gst, NULL)) {
+                               err = MM_ERROR_STREAMRECORDER_GST_LINK;
+                               goto pipeline_creation_error;
+                       }
+               } else {
+                       if (rec_mode == MM_STREAMRECORDER_MODE_MEDIABUFFER) {
+                               gst_bin_add_many(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst), sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AQUE].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_CONV].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SINK].gst, NULL);
+
+                               if (!_MM_GST_ELEMENT_LINK_MANY(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AQUE].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_CONV].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SINK].gst, NULL)) {
+                                       err = MM_ERROR_STREAMRECORDER_GST_LINK;
+                                       goto pipeline_creation_error;
+                               }
+                       } else {
+                               gst_bin_add_many(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst), sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AQUE].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SINK].gst, NULL);
+
+                               if (!_MM_GST_ELEMENT_LINK_MANY(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AQUE].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SINK].gst, NULL)) {
+                                       err = MM_ERROR_STREAMRECORDER_GST_LINK;
+                                       goto pipeline_creation_error;
+                               }
+                       }
+               }
+       }
+
+       if (info->bMuxing) {
+               MMSTREAMRECORDER_SIGNAL_CONNECT(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_MUX].gst, _MMSTREAMRECORDER_HANDLER_AUDIOREC, "pad-added", __mmstreamrecorder_audiorec_pad_added_cb, hstreamrecorder);
+       } else {
+               srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, "src");
+               MMSTREAMRECORDER_ADD_BUFFER_PROBE(srcpad, _MMSTREAMRECORDER_HANDLER_AUDIOREC, __mmstreamrecorder_audio_dataprobe_record, hstreamrecorder);
+               gst_object_unref(srcpad);
+               srcpad = NULL;
+       }
+
+       bus = gst_pipeline_get_bus(GST_PIPELINE(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst));
+
+       /* register message callback  */
+       hstreamrecorder->pipeline_cb_event_id = gst_bus_add_watch(bus, (GstBusFunc) _mmstreamrecorder_pipeline_cb_message, hstreamrecorder);
+
+       /* set sync callback */
+       gst_bus_set_sync_handler(bus, gst_bus_sync_signal_handler, hstreamrecorder, NULL);
+
+       gst_object_unref(bus);
+       bus = NULL;
+
+       if (element_list) {
+               g_list_free(element_list);
+               element_list = NULL;
+       }
+
+       return MM_ERROR_NONE;
+
+ pipeline_creation_error:
+       _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCODE_MAIN_PIPE);
+       _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_AUDIOSRC_BIN);
+       _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_AQUE);
+       if (rec_mode == MM_STREAMRECORDER_MODE_MEDIABUFFER) {
+               _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_CONV);
+       }
+       _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_AENC);
+       _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_SINK);
+       _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_BIN);
+
+       if (element_list) {
+               g_list_free(element_list);
+               element_list = NULL;
+       }
+
+       return err;
+}
+
+int _mmstreamrecorder_audio_command(MMHandleType handle, int command)
+{
+       int cmd = command;
+       int ret = MM_ERROR_NONE;
+       int err = 0;
+       guint64 free_space = 0;
+       guint64 cal_space = 0;
+       char *dir_name = NULL;
+       char *err_attr_name = NULL;
+       guint count = 0;
+       int size = 0;
+
+       GstElement *pipeline = NULL;
+       GstElement *audioSrc = NULL;
+
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+       _MMStreamRecorderSubContext *sc = NULL;
+       _MMStreamRecorderAudioInfo *info = NULL;
+       _MMStreamRecorderFileInfo *finfo = NULL;
+
+       mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+       sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
+
+       mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+       mmf_return_val_if_fail(sc->info_audio, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+       mmf_return_val_if_fail(sc->info_file, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+       pipeline = sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst;
+       info = sc->info_audio;
+       finfo = sc->info_file;
+
+       _mmstreamrec_dbg_log("");
+
+       pipeline = sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst;
+       audioSrc = sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst;
+       switch (cmd) {
+       case _MM_STREAMRECORDER_CMD_RECORD:
+               /* check status for resume case */
+               {
+                       guint imax_size = 0;
+                       guint imax_time = 0;
+                       char *temp_filename = NULL;
+
+                       if (sc->pipeline_time)
+                               gst_element_set_start_time((GstElement *) GST_PIPELINE(pipeline), sc->pipeline_time);
+
+                       sc->pipeline_time = hstreamrecorder->ini.reset_pause_time;
+
+                       ret = mm_streamrecorder_get_attributes(handle, &err_attr_name, MMSTR_TARGET_MAX_SIZE, &imax_size, MMSTR_TARGET_TIME_LIMIT, &imax_time, MMSTR_FILE_FORMAT, &(finfo->fileformat), MMSTR_FILENAME, &temp_filename, &size, NULL);
+                       if (ret != MM_ERROR_NONE) {
+                               _mmstreamrec_dbg_warn("failed to get attribute. (%s:%x)", err_attr_name, ret);
+                               SAFE_FREE(err_attr_name);
+                               goto _ERR_STREAMRECORDER_AUDIO_COMMAND;
+                       }
+
+                       finfo->filename = strdup(temp_filename);
+                       if (!finfo->filename) {
+                               _mmstreamrec_dbg_err("STRDUP was failed");
+                               goto _ERR_STREAMRECORDER_AUDIO_COMMAND;
+                       }
+
+                       _mmstreamrec_dbg_log("Record start : set file name using attribute - %s\n ", finfo->filename);
+
+                       MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SINK].gst, "location", finfo->filename);
+
+                       sc->ferror_send = FALSE;
+                       sc->ferror_count = 0;
+                       sc->bget_eos = FALSE;
+                       info->filesize = 0;
+
+                       /* set max size */
+                       if (imax_size <= 0)
+                               info->max_size = 0;     /* do not check */
+                       else
+                               info->max_size = ((guint64) imax_size) << 10;   /* to byte */
+
+                       /* set max time */
+                       if (imax_time <= 0)
+                               info->max_time = 0;     /* do not check */
+                       else
+                               info->max_time = ((guint64) imax_time) * 1000;  /* to millisecond */
+
+                       /* TODO : check free space before recording start, need to more discussion */
+                       dir_name = g_path_get_dirname(finfo->filename);
+                       err = _mmstreamrecorder_get_freespace(dir_name, &free_space);
+
+                       _mmstreamrec_dbg_warn("current space for recording - %s : [%" G_GUINT64_FORMAT "]", dir_name, free_space);
+
+                       if (dir_name) {
+                               g_free(dir_name);
+                               dir_name = NULL;
+                       }
+                       cal_space = (guint64)(hstreamrecorder->ini.audio_frame_minimum_space);
+                       cal_space = cal_space + (5 * 1024);
+                       if ((err == -1) || free_space <= cal_space) {
+                               _mmstreamrec_dbg_err("No more space for recording");
+                               return MM_MESSAGE_STREAMRECORDER_NO_FREE_SPACE;
+                       }
+               }
+
+               ret = _mmstreamrecorder_gst_set_state(handle, pipeline, GST_STATE_PLAYING);
+               if (ret != MM_ERROR_NONE)
+                       goto _ERR_STREAMRECORDER_AUDIO_COMMAND;
+
+               break;
+
+       case _MM_STREAMRECORDER_CMD_PAUSE:
+               {
+                       GstClock *l_clock = NULL;
+
+                       if (info->b_commiting) {
+                               _mmstreamrec_dbg_warn("now on commiting previous file!!(cmd : %d)", cmd);
+                               return MM_ERROR_STREAMRECORDER_CMD_IS_RUNNING;
+                       }
+
+                       for (count = 0; count <= hstreamrecorder->ini.retrial_count; count++) {
+                               if (info->filesize > 0) {
+                                       break;
+                               } else if (count == hstreamrecorder->ini.retrial_count) {
+                                       _mmstreamrec_dbg_err("Pause fail, wait 200 ms, but file size is %lld", info->filesize);
+                                       return MM_ERROR_STREAMRECORDER_INVALID_CONDITION;
+                               } else {
+                                       _mmstreamrec_dbg_warn("Wait for enough audio frame, retry count[%d], file size is %lld", count, info->filesize);
+                               }
+                               usleep(hstreamrecorder->ini.audio_frame_wait_time);
+                       }
+
+                       ret = _mmstreamrecorder_gst_set_state(handle, pipeline, GST_STATE_PAUSED);
+                       if (ret != MM_ERROR_NONE)
+                               goto _ERR_STREAMRECORDER_AUDIO_COMMAND;
+
+                       /* FIXME: consider delay. */
+                       l_clock = gst_pipeline_get_clock(GST_PIPELINE(pipeline));
+                       sc->pipeline_time = gst_clock_get_time(l_clock) - gst_element_get_base_time(GST_ELEMENT(pipeline));
+                       break;
+               }
+
+       case _MM_STREAMRECORDER_CMD_CANCEL:
+               if (info->b_commiting) {
+                       _mmstreamrec_dbg_warn("now on commiting previous file!!(cmd : %d)", cmd);
+                       return MM_ERROR_STREAMRECORDER_CMD_IS_RUNNING;
+               }
+
+               ret = _mmstreamrecorder_gst_set_state(handle, pipeline, GST_STATE_READY);
+               if (ret != MM_ERROR_NONE)
+                       goto _ERR_STREAMRECORDER_AUDIO_COMMAND;
+
+               if (info->bMuxing) {
+                       MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "block", FALSE);
+               } else {
+                       MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AQUE].gst, "empty-buffers", FALSE);
+               }
+
+               _mmstreamrecorder_gst_set_state(handle, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SINK].gst, GST_STATE_NULL);
+
+               sc->pipeline_time = 0;
+               sc->pause_time = 0;
+               sc->isMaxsizePausing = FALSE;
+               sc->isMaxtimePausing = FALSE;
+
+               if (finfo->filename) {
+                       _mmstreamrec_dbg_log("file delete(%s)", finfo->filename);
+                       unlink(finfo->filename);
+                       g_free(finfo->filename);
+                       finfo->filename = NULL;
+               }
+               break;
+
+       case _MM_STREAMRECORDER_CMD_COMMIT:
+               {
+
+                       _mmstreamrec_dbg_log("_MM_STREAMRECORDER_CMD_COMMIT");
+
+                       if (info->b_commiting) {
+                               _mmstreamrec_dbg_warn("now on commiting previous file!!(cmd : %d)", cmd);
+                               return MM_ERROR_STREAMRECORDER_CMD_IS_RUNNING;
+                       } else {
+                               _mmstreamrec_dbg_log("_MM_STREAMRECORDER_CMD_COMMIT : start");
+                               info->b_commiting = TRUE;
+                       }
+
+                       for (count = 0; count <= hstreamrecorder->ini.retrial_count; count++) {
+                               if (info->filesize > 0) {
+                                       break;
+                               } else if (count == hstreamrecorder->ini.retrial_count) {
+                                       _mmstreamrec_dbg_err("Commit fail, waited 200 ms, but file size is %lld", info->filesize);
+                                       info->b_commiting = FALSE;
+                                       return MM_ERROR_STREAMRECORDER_INVALID_CONDITION;
+                               } else {
+                                       _mmstreamrec_dbg_warn("Waiting for enough audio frame, re-count[%d], file size is %lld", count, info->filesize);
+                               }
+                               usleep(hstreamrecorder->ini.audio_frame_wait_time);
+                       }
+
+                       if (audioSrc) {
+                               GstPad *pad = gst_element_get_static_pad(audioSrc, "src");
+                               ret = gst_element_send_event(audioSrc, gst_event_new_eos());
+                               gst_object_unref(pad);
+                               pad = NULL;
+                               /* for pause -> commit case */
+                               /*if (_mmstreamrecorder_get_state((MMHandleType)hstreamrecorder) == MM_STREAMRECORDER_STATE_PAUSED) {
+                                  ret = _mmstreamrecorder_gst_set_state(handle, pipeline, GST_STATE_PLAYING);
+                                  if (ret != MM_ERROR_NONE) {
+                                  goto _ERR_STREAMRECORDER_AUDIO_COMMAND;
+                                  }
+                                  } */
+                       }
+
+                       /* wait until finishing EOS */
+                       _mmstreamrec_dbg_log("Start to wait EOS");
+                       if ((ret = _mmstreamrecorder_get_eos_message(handle)) != MM_ERROR_NONE)
+                               goto _ERR_STREAMRECORDER_AUDIO_COMMAND;
+
+                       break;
+               }
+       default:
+               ret = MM_ERROR_STREAMRECORDER_INVALID_ARGUMENT;
+               break;
+       }
+
+ _ERR_STREAMRECORDER_AUDIO_COMMAND:
+       return ret;
+}
+
+int _mmstreamrecorder_audio_handle_eos(MMHandleType handle)
+{
+       int err = MM_ERROR_NONE;
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+       _MMStreamRecorderSubContext *sc = NULL;
+       _MMStreamRecorderAudioInfo *info = NULL;
+       _MMStreamRecorderFileInfo *finfo = NULL;
+       GstElement *pipeline = NULL;
+       _MMStreamRecorderMsgItem msg;
+       MMStreamRecordingReport *report;
+
+       mmf_return_val_if_fail(hstreamrecorder, FALSE);
+       sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
+
+       mmf_return_val_if_fail(sc, FALSE);
+       mmf_return_val_if_fail(sc->info_audio, FALSE);
+       mmf_return_val_if_fail(sc->info_file, FALSE);
+
+       _mmstreamrec_dbg_err("");
+
+       info = sc->info_audio;
+       finfo = sc->info_file;
+
+       pipeline = sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst;
+
+       err = _mmstreamrecorder_gst_set_state(handle, pipeline, GST_STATE_READY);
+
+       if (err != MM_ERROR_NONE)
+               _mmstreamrec_dbg_warn("Failed:_MM_STREAMRECORDER_CMD_COMMIT:GST_STATE_READY. err[%x]", err);
+
+       /* Send recording report message to application */
+       msg.id = MM_MESSAGE_STREAMRECORDER_AUDIO_CAPTURED;
+       report = (MMStreamRecordingReport *) malloc(sizeof(MMStreamRecordingReport));
+       if (!report) {
+               _mmstreamrec_dbg_err("Recording report fail(%s). Out of memory.", finfo->filename);
+               return FALSE;
+       }
+
+       /* START TAG HERE */
+       /* MM_AUDIO_CODEC_AAC + MM_FILE_FORMAT_MP4 */
+       if (finfo->fileformat == MM_FILE_FORMAT_3GP || finfo->fileformat == MM_FILE_FORMAT_MP4)
+               _mmstreamrecorder_audio_add_metadata_info_m4a(handle);
+       /* END TAG HERE */
+
+       report->recording_filename = strdup(finfo->filename);
+       msg.param.data = report;
+
+       _mmstreamrecorder_send_message(handle, &msg);
+
+       if (info->bMuxing) {
+               MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "block", FALSE);
+       } else {
+               MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AQUE].gst, "empty-buffers", FALSE);
+       }
+
+       _mmstreamrecorder_gst_set_state(handle, pipeline, GST_STATE_NULL);
+
+       sc->pipeline_time = 0;
+       sc->pause_time = 0;
+       sc->isMaxsizePausing = FALSE;
+       sc->isMaxtimePausing = FALSE;
+
+       g_free(finfo->filename);
+       finfo->filename = NULL;
+
+       _mmstreamrec_dbg_err("_MM_STREAMRECORDER_CMD_COMMIT : end");
+
+       info->b_commiting = FALSE;
+
+       return TRUE;
+}
+
+int _mmstreamrecorder_push_videostream_buffer(MMHandleType handle, unsigned long timestamp, GstBuffer *buffer, int size)
+{
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+       _MMStreamRecorderSubContext *sc = NULL;
+       GstPad *srcpad = NULL;
+       GstCaps *srccaps = NULL;
+       char *err_name = NULL;
+       int video_fps = 0;
+       int video_src = 0;
+       int video_width = 0;
+       int video_height = 0;
+       int ret = MM_ERROR_NONE;
+       int video_source_format = 0;
+
+       mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+
+       sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
+       mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+
+       if (buffer == NULL || size == 0) {
+               _mmstreamrec_dbg_err("video : Buffer is %p , size %d, time stamp is %ld", buffer, size, timestamp);
+               return MM_ERROR_STREAMRECORDER_RESOURCE_CREATION;
+       }
+
+       _mmstreamrec_dbg_log("video : Buffer is %p , size %d, time stamp is %ld", buffer, size, timestamp);
+
+       /* check element availability */
+       ret = mm_streamrecorder_get_attributes(handle, &err_name, MMSTR_VIDEO_FRAMERATE, &video_fps, MMSTR_VIDEO_SOURCE_FORMAT, &video_src, MMSTR_VIDEO_RESOLUTION_WIDTH, &video_width, MMSTR_VIDEO_RESOLUTION_HEIGHT, &video_height, MMSTR_VIDEO_SOURCE_FORMAT, &video_source_format, NULL);
+
+       if (sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst) {
+
+               /*_mmstreamrec_dbg_log("Buffer Push start , time stamp %ld",timestamp);*/
+               srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, "src");
+               srccaps = gst_pad_get_current_caps(srcpad);
+               srccaps = gst_set_videosrcpad_caps(video_src, video_width, video_height, video_fps, 1);
+               gst_app_src_set_caps((GstAppSrc *) sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, srccaps);
+               /*_mmstreamrec_dbg_err("newbuf streamrecorder(%p) ",newbuf);*/
+
+               ret = gst_app_src_push_buffer((GstAppSrc *) sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, buffer);
+               if (ret) {
+                       _mmstreamrec_dbg_err("video gst_app_src_push_buffer %d", ret);
+                       ret = MM_ERROR_STREAMRECORDER_VIDEOBUFFER_PUSH;
+               }
+
+               /* g_signal_emit_by_name(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, "push-buffer", newbuf, &ret); */
+       }
+
+       return ret;
+}
+
+int _mmstreamrecorder_push_audiostream_buffer(MMHandleType handle, unsigned long timestamp, GstBuffer *buffer, int size)
+{
+       mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
+       _MMStreamRecorderSubContext *sc = NULL;
+       _MMStreamRecorderAudioInfo *info = NULL;
+       GstFlowReturn err = GST_FLOW_OK;
+       GstPad *srcpad = NULL;
+       GstCaps *srccaps = NULL;
+       int rate = 0;
+       int channel = 0;
+       int depth = 0;
+
+       mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+
+       sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
+       mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+
+       info = (_MMStreamRecorderAudioInfo *) sc->info_audio;
+       mmf_return_val_if_fail(info, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
+
+       rate = info->iSamplingRate;
+       depth = info->audio_encode_depth;
+       channel = info->iChannels;
+
+       /*_mmstreamrec_dbg_log("Audio Buffer Push start , time stamp %ld",timestamp); */
+
+       if (sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst) {
+
+               srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst, "src");
+               /* TODO : CHANNEL , WIDTH, DATATYPE */
+               srccaps = gst_pad_get_current_caps(srcpad);
+               srccaps = gst_set_audiosrcpad_caps(rate, channel, depth, 16, 1);
+               gst_base_src_set_caps(GST_BASE_SRC(srcpad), srccaps);
+
+               err = gst_app_src_push_buffer((GstAppSrc *) sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst, buffer);
+
+               if (err) {
+                       _mmstreamrec_dbg_err("Audio gst_app_src_push_buffer %d", err);
+                       return MM_ERROR_STREAMRECORDER_AUDIOBUFFER_PUSH;
+               }
+       }
+
+       return MM_ERROR_NONE;
+}
+
diff --git a/src/mm_streamrecorder_util.c b/src/mm_streamrecorder_util.c
new file mode 100644 (file)
index 0000000..d7a5b96
--- /dev/null
@@ -0,0 +1,345 @@
+/*
+ * libmm-streamrecorder
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Hyuntae Kim <ht1211.kim@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 <stdio.h>
+#include <stdarg.h>
+#include <sys/vfs.h>                   /* struct statfs */
+
+#include "mm_streamrecorder_util.h"
+#include <mm_types.h>
+#include <mm_error.h>
+#include <glib.h>
+#include <stdlib.h>
+#include "iniparser.h"
+#include <glib/gstdio.h>
+#include <gst/video/video-info.h>
+
+/*-----------------------------------------------------------------------
+|    GLOBAL VARIABLE DEFINITIONS for internal                          |
+-----------------------------------------------------------------------*/
+
+/*-----------------------------------------------------------------------
+|    LOCAL VARIABLE DEFINITIONS for internal                           |
+-----------------------------------------------------------------------*/
+#define TIME_STRING_MAX_LEN     64
+
+/*---------------------------------------------------------------------------
+|    LOCAL FUNCTION PROTOTYPES:                                                                                                |
+---------------------------------------------------------------------------*/
+/* STATIC INTERNAL FUNCTION */
+
+/* static gint         skip_mdat(FILE *f); */
+
+/*===========================================================================================
+|                                                                                                                                                                                      |
+|  FUNCTION DEFINITIONS                                                                                                                                                |
+========================================================================================== */
+/*---------------------------------------------------------------------------
+|    GLOBAL FUNCTION DEFINITIONS:                                                                                      |
+---------------------------------------------------------------------------*/
+
+gint32 _mmstreamrecorder_double_to_fix(gdouble d_number)
+{
+       return (gint32) (d_number * 65536.0);
+}
+
+int _mmstreamrecorder_get_freespace(const gchar *path, guint64 *free_space)
+{
+       struct statfs fs;
+
+       g_assert(path);
+
+       if (!g_file_test(path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) {
+               _mmstreamrec_dbg_log("File(%s) doesn't exist.", path);
+               return -2;
+       }
+
+       if (-1 == statfs(path, &fs)) {
+               _mmstreamrec_dbg_log("Getting free space is failed.(%s)", path);
+               return -1;
+       }
+
+       *free_space = (guint64) fs.f_bsize * fs.f_bavail;
+       return 1;
+}
+
+int _mmstreamrecorder_get_file_size(const char *filename, guint64 * size)
+{
+       struct stat buf;
+
+       if (stat(filename, &buf) != 0)
+               return -1;
+       *size = (guint64) buf.st_size;
+       return 1;
+}
+
+void _mmstreamrecorder_err_trace_write(char *str_filename, char *func_name, int line_num, char *fmt, ...)
+{
+       FILE *f = NULL;
+       va_list ap = { 0 };
+       char time_string[TIME_STRING_MAX_LEN] = { '\0', };
+
+       time_t current_time;
+       struct tm new_time;
+
+       mmf_return_if_fail(str_filename);
+
+       current_time = time(NULL);
+       localtime_r(&current_time, &new_time);
+
+       f = fopen(str_filename, "a");
+       if (f == NULL) {
+               _mmstreamrec_dbg_warn("Failed to open file.[%s]", str_filename);
+               return;
+       }
+
+       asctime_r(&new_time, time_string);
+       fprintf(f, "[%.19s][%05d][%s]", time_string, line_num, func_name);
+
+       va_start(ap, fmt);
+       vfprintf(f, fmt, ap);
+       va_end(ap);
+
+       fprintf(f, "\n");
+
+       fclose(f);
+}
+
+int _mmstreamrecorder_get_pixel_format(GstCaps *caps)
+{
+       const GstStructure *structure;
+       const char *media_type = NULL;
+       MMPixelFormatType type = 0;
+       unsigned int fourcc = 0;
+       GstVideoInfo media_info;
+
+       mmf_return_val_if_fail(caps != NULL, MM_PIXEL_FORMAT_INVALID);
+
+       structure = gst_caps_get_structure(caps, 0);
+       media_type = gst_structure_get_name(structure);
+
+       if (media_type == NULL) {
+               _mmstreamrec_dbg_log("failed to get media_type");
+               return MM_PIXEL_FORMAT_INVALID;
+       }
+
+       if (!strcmp(media_type, "image/jpeg")) {
+               _mmstreamrec_dbg_log("It is jpeg.");
+               type = MM_PIXEL_FORMAT_ENCODED;
+       } else if (!strcmp(media_type, "video/x-raw-yuv")) {
+               _mmstreamrec_dbg_log("It is yuv.");
+               gst_video_info_init(&media_info);
+               gst_video_info_from_caps(&media_info, caps);
+               fourcc = gst_video_format_to_fourcc(GST_VIDEO_INFO_FORMAT(&media_info));
+               type = _mmstreamrecorder_get_pixtype(fourcc);
+       } else if (!strcmp(media_type, "video/x-raw-rgb")) {
+               _mmstreamrec_dbg_log("It is rgb.");
+               type = MM_PIXEL_FORMAT_RGB888;
+       } else {
+               _mmstreamrec_dbg_err("Not supported format");
+               type = MM_PIXEL_FORMAT_INVALID;
+       }
+
+       _mmstreamrec_dbg_log("Type [%d]", type);
+
+       gst_caps_unref(caps);
+       caps = NULL;
+
+       return type;
+}
+
+unsigned int _mmstreamrecorder_get_fourcc(int pixtype, int codectype, int use_zero_copy_format)
+{
+       unsigned int fourcc = 0;
+
+       _mmstreamrec_dbg_log("pixtype(%d)", pixtype);
+
+       switch (pixtype) {
+       case MM_PIXEL_FORMAT_NV12:
+               if (use_zero_copy_format)
+                       fourcc = GST_MAKE_FOURCC('S', 'N', '1', '2');
+               else
+                       fourcc = GST_MAKE_FOURCC('N', 'V', '1', '2');
+               break;
+       case MM_PIXEL_FORMAT_YUYV:
+               if (use_zero_copy_format)
+                       fourcc = GST_MAKE_FOURCC('S', 'U', 'Y', 'V');
+               else
+                       fourcc = GST_MAKE_FOURCC('Y', 'U', 'Y', '2');
+               break;
+       case MM_PIXEL_FORMAT_UYVY:
+               if (use_zero_copy_format)
+                       fourcc = GST_MAKE_FOURCC('S', 'Y', 'V', 'Y');
+               else
+                       fourcc = GST_MAKE_FOURCC('U', 'Y', 'V', 'Y');
+
+               break;
+       case MM_PIXEL_FORMAT_I420:
+               if (use_zero_copy_format)
+                       fourcc = GST_MAKE_FOURCC('S', '4', '2', '0');
+               else
+                       fourcc = GST_MAKE_FOURCC('I', '4', '2', '0');
+               break;
+       case MM_PIXEL_FORMAT_YV12:
+               fourcc = GST_MAKE_FOURCC('Y', 'V', '1', '2');
+               break;
+       case MM_PIXEL_FORMAT_422P:
+               fourcc = GST_MAKE_FOURCC('4', '2', '2', 'P');
+               break;
+       case MM_PIXEL_FORMAT_RGB565:
+               fourcc = GST_MAKE_FOURCC('R', 'G', 'B', 'P');
+               break;
+       case MM_PIXEL_FORMAT_RGB888:
+               fourcc = GST_MAKE_FOURCC('R', 'G', 'B', ' ');
+               break;
+       case MM_PIXEL_FORMAT_ENCODED:
+               if (codectype == MM_IMAGE_CODEC_JPEG) {
+                       fourcc = GST_MAKE_FOURCC('J', 'P', 'E', 'G');
+               } else if (codectype == MM_IMAGE_CODEC_JPEG_SRW) {
+                       fourcc = GST_MAKE_FOURCC('J', 'P', 'E', 'G');   /*TODO: JPEG+SamsungRAW format */
+               } else if (codectype == MM_IMAGE_CODEC_SRW) {
+                       fourcc = GST_MAKE_FOURCC('J', 'P', 'E', 'G');   /*TODO: SamsungRAW format */
+               } else if (codectype == MM_IMAGE_CODEC_PNG) {
+                       fourcc = GST_MAKE_FOURCC('P', 'N', 'G', ' ');
+               } else {
+                       /* Please let us know what other fourcces are. ex) BMP, GIF? */
+                       fourcc = GST_MAKE_FOURCC('J', 'P', 'E', 'G');
+               }
+               break;
+       case MM_PIXEL_FORMAT_ITLV_JPEG_UYVY:
+               fourcc = GST_MAKE_FOURCC('I', 'T', 'L', 'V');
+               break;
+       default:
+               _mmstreamrec_dbg_log("Not proper pixel type[%d]. Set default - I420", pixtype);
+               if (use_zero_copy_format)
+                       fourcc = GST_MAKE_FOURCC('S', '4', '2', '0');
+               else
+                       fourcc = GST_MAKE_FOURCC('I', '4', '2', '0');
+               break;
+       }
+
+       return fourcc;
+}
+
+int _mmstreamrecorder_get_pixtype(unsigned int fourcc)
+{
+       int pixtype = MM_PIXEL_FORMAT_INVALID;
+/*
+       char *pfourcc = (char*)&fourcc;
+       _mmstreamrec_dbg_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', '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'):
+               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*/ case GST_MAKE_FOURCC('I', 'T', 'L', 'V'):
+               pixtype = MM_PIXEL_FORMAT_ITLV_JPEG_UYVY;
+               break;
+       default:
+               _mmstreamrec_dbg_log("Not supported fourcc type(%x)", fourcc);
+               pixtype = MM_PIXEL_FORMAT_INVALID;
+               break;
+       }
+
+       return pixtype;
+}
+
+guint16 get_language_code(const char *str)
+{
+       return (guint16) (((str[0] - 0x60) & 0x1F) << 10) + (((str[1] - 0x60) & 0x1F) << 5) + ((str[2] - 0x60) & 0x1F);
+}
+
+gchar *str_to_utf8(const gchar * str)
+{
+       return g_convert(str, -1, "UTF-8", "ASCII", NULL, NULL, NULL);
+}
+
+inline gboolean write_tag(FILE *f, const gchar *tag)
+{
+       while (*tag)
+               FPUTC_CHECK(*tag++, f);
+
+       return TRUE;
+}
+
+inline gboolean write_to_32(FILE *f, guint val)
+{
+       FPUTC_CHECK(val >> 24, f);
+       FPUTC_CHECK(val >> 16, f);
+       FPUTC_CHECK(val >> 8, f);
+       FPUTC_CHECK(val, f);
+       return TRUE;
+}
+
+inline gboolean write_to_16(FILE *f, guint val)
+{
+       FPUTC_CHECK(val >> 8, f);
+       FPUTC_CHECK(val, f);
+       return TRUE;
+}
+
+inline gboolean write_to_24(FILE *f, guint val)
+{
+       write_to_16(f, val >> 8);
+       FPUTC_CHECK(val, f);
+       return TRUE;
+}
diff --git a/src/mm_streamrecorder_video.c b/src/mm_streamrecorder_video.c
new file mode 100644 (file)
index 0000000..3300283
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * libmm-streamrecorder
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Hyuntae Kim <ht1211.kim@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_types.h>
+#include <mm_error.h>
+#include "mm_streamrecorder_video.h"
+#include "mm_streamrecorder_util.h"
+
+/*---------------------------------------------------------------------------------------
+|    GLOBAL VARIABLE DEFINITIONS for internal                                          |
+---------------------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------------------
+|    LOCAL VARIABLE DEFINITIONS for internal                                           |
+---------------------------------------------------------------------------------------*/
+
+/*-----------------------------------------------------------------------
+|    GLOBAL VARIABLE DEFINITIONS for internal                          |
+-----------------------------------------------------------------------*/
+/* Table for compatibility between video codec and file format */
+gboolean common_videocodec_fileformat_compatibility_table[MM_VIDEO_CODEC_NUM][MM_FILE_FORMAT_NUM] = {
+       /* 3GP ASF AVI MATROSKA MP4 OGG NUT QT REAL AMR AAC MP3 AIFF AU WAV MID MMF DIVX FLV VOB IMELODY WMA WMV JPG */
+        /*NONE*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+/*H263*/ {1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+/*H264*/ {1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+/*H26L*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+/*MPEG4*/ {1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+/*MPEG1*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+        /*WMV*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+        /*DIVX*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+        /*XVID*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+/*H261*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+/*H262*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+/*H263V2*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+/*H263V3*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+        /*MJPEG*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+/*MPEG2*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+/*MPEG4_SIMPLE*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+/*MPEG4_ADV*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+/*MPEG4_MAIN*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+/*MPEG4_CORE*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+/*MPEG4_ACE*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+/*MPEG4_ARTS*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+/*MPEG4_AVC*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+        /*REAL*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+/*VC1*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+        /*AVS*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+        /*CINEPAK*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+        /*INDEO*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+        /*THEORA*/ {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}
+       ,
+};
+
+/*---------------------------------------------------------------------------------------
+|    LOCAL FUNCTION PROTOTYPES:                                                                |
+---------------------------------------------------------------------------------------*/
+/* STATIC INTERNAL FUNCTION */
+
+/*=======================================================================================
+|  FUNCTION DEFINITIONS                                                                        |
+=======================================================================================*/
+/*---------------------------------------------------------------------------------------
+|    GLOBAL FUNCTION DEFINITIONS:                                                      |
+---------------------------------------------------------------------------------------*/
+int _mmstreamrecorder_check_videocodec_fileformat_compatibility(unsigned int video_codec, unsigned int file_format)
+{
+       /* Check compatibility between audio codec and file format */
+       if (video_codec < MM_VIDEO_CODEC_NUM && file_format < MM_FILE_FORMAT_NUM) {
+               if (common_videocodec_fileformat_compatibility_table[video_codec][file_format] == 0) {
+                       _mmstreamrec_dbg_err("Video codec[%d] and file format[%d] compatibility FAILED.", video_codec, file_format);
+                       return MM_ERROR_STREAMRECORDER_ENCODER_WRONG_TYPE;
+               }
+
+               _mmstreamrec_dbg_log("Video codec[%d] and file format[%d] compatibility SUCCESS.", video_codec, file_format);
+       } else {
+               _mmstreamrec_dbg_err("Video codec[%d] or file format[%d] is INVALID.", video_codec, file_format);
+               return MM_ERROR_STREAMRECORDER_ENCODER_WRONG_TYPE;
+       }
+
+       return MM_ERROR_NONE;
+}
diff --git a/test/Makefile.am b/test/Makefile.am
new file mode 100644 (file)
index 0000000..5cd87f7
--- /dev/null
@@ -0,0 +1,25 @@
+bin_PROGRAMS = mm_streamrecorder_testsuite
+
+mm_streamrecorder_testsuite_SOURCES = mm_streamrecorder_testsuite.c
+
+mm_streamrecorder_testsuite_CFLAGS = -I$(srcdir)/../src/include \
+                            $(GLIB_CFLAGS)\
+                            $(GST_CFLAGS)\
+                            $(MM_COMMON_CFLAGS)\
+                            $(MM_SOUND_CFLAGS)\
+                            $(MDM_CFLAGS)
+
+
+############################################
+#mm_streamrecorder_testsuite_CFLAGS += -DAPPSRC_TEST
+############################################
+
+mm_streamrecorder_testsuite_DEPENDENCIES = $(top_builddir)/src/libmmfstreamrecorder.la
+mm_streamrecorder_testsuite_LDADD = $(top_builddir)/src/libmmfstreamrecorder.la \
+                            $(GLIB_LIBS)\
+                            $(GST_LIBS)\
+                            $(MM_COMMON_LIBS)\
+                            $(MM_SOUND_LIBS)\
+                            $(MDM_LIBS)
+
+
diff --git a/test/mm_streamrecorder_testsuite.c b/test/mm_streamrecorder_testsuite.c
new file mode 100644 (file)
index 0000000..91403ca
--- /dev/null
@@ -0,0 +1,1280 @@
+/*
+ * mm_streamrecorder_testsuite
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Hyuntae Kim <ht1211.kim@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 <stdio.h>
+#include <stdlib.h>
+#include <glib.h>
+#include <gst/gst.h>
+#include <sys/time.h>
+#include "../src/include/mm_streamrecorder.h"
+#include "../src/include/mm_streamrecorder_internal.h"
+#include "../src/include/mm_streamrecorder_util.h"
+#include "../src/include/mm_streamrecorder_attribute.h"
+#include <gst/video/colorbalance.h>
+
+/*-----------------------------------------------------------------------
+|    GLOBAL VARIABLE DEFINITIONS:                                       |
+-----------------------------------------------------------------------*/
+#define EXPORT_API __attribute__((__visibility__("default")))
+
+#define PACKAGE "mm_streamrecorder_testsuite"
+
+GMainLoop *g_loop;
+GIOChannel *stdin_channel;
+int resolution_set;
+int g_current_state;
+int src_w, src_h;
+GstCaps *filtercaps;
+bool isMultishot;
+int multishot_num;
+static int audio_stream_cb_cnt;
+static int video_stream_cb_cnt;
+static GTimer *timer = NULL;
+int g_state;
+
+enum {
+       STREAMRECORDER_NULL,
+       STREAMRECORDER_NONE,
+       STREAMRECORDER_CREATED,
+       STREAMRECORDER_STARTED,
+       STREAMRECORDER_COMMITED
+};
+
+void streamrecorder_set_state(int new_state)
+{
+       g_state = new_state;
+       return;
+}
+
+int streamrecorder_get_state()
+{
+       return g_state;
+}
+
+
+
+/*-----------------------------------------------------------------------
+|    GLOBAL CONSTANT DEFINITIONS:                                       |
+-----------------------------------------------------------------------*/
+
+
+/*-----------------------------------------------------------------------
+|    IMPORTED VARIABLE DECLARATIONS:                                    |
+-----------------------------------------------------------------------*/
+
+
+/*-----------------------------------------------------------------------
+|    IMPORTED FUNCTION DECLARATIONS:                                    |
+-----------------------------------------------------------------------*/
+
+
+/*-----------------------------------------------------------------------
+|    LOCAL #defines:                                                    |
+-----------------------------------------------------------------------*/
+#define test_ffmux_mp4
+
+#define DISPLAY_X_0                                                    0                                               /* for direct FB */
+#define DISPLAY_Y_0                                                    0                                               /* for direct FB */
+
+#define SRC_VIDEO_FRAME_RATE_15         15    /* video input frame rate */
+#define SRC_VIDEO_FRAME_RATE_30         30    /* video input frame rate */
+
+#define STILL_CAPTURE_FILE_PATH_NAME    "/opt/StillshotCapture"
+#define MULTI_CAPTURE_FILE_PATH_NAME    "/opt/MultishotCapture"
+#define TARGET_FILENAME_PATH            "/opt/"
+#define CAPTURE_FILENAME_LEN            256
+
+#define AUDIO_SOURCE_SAMPLERATE_AAC     44100
+#define AUDIO_SOURCE_SAMPLERATE_AMR     8000
+#define AUDIO_SOURCE_FORMAT             MM_STREAMRECORDER_AUDIO_FORMAT_PCM_S16_LE
+#define AUDIO_SOURCE_CHANNEL_AAC        2
+#define AUDIO_SOURCE_CHANNEL_AMR        1
+#define VIDEO_ENCODE_BITRATE            40000000 /* bps */
+/*
+ * D E B U G   M E S S A G E
+ */
+#define MMF_DEBUG                       "** (mmstreamrecorder testsuite) DEBUG: "
+#define MMF_ERR                         "** (mmstreamrecorder testsuite) ERROR: "
+#define MMF_INFO                        "** (mmstreamrecorder testsuite) INFO: "
+#define MMF_WARN                        "** (mmstreamrecorder testsuite) WARNING: "
+#define MMF_TIME                        "** (mmstreamrecorder testsuite) TIME: "
+
+#define CHECK_MM_ERROR(expr) \
+do {\
+       int ret = 0; \
+       ret = expr; \
+       if (ret != MM_ERROR_NONE) {\
+               printf("[%s:%d] error code : %x \n", __func__, __LINE__, ret); \
+               return; \
+       } \
+} while (0)
+
+#define time_msg_t(fmt, arg...)        \
+do { \
+       fprintf(stderr, "\x1b[44m\x1b[37m"MMF_TIME"[%s:%05d]  " fmt , __func__, __LINE__, ##arg); \
+       fprintf(stderr, "\x1b[0m\n"); \
+} while (0)
+
+#define debug_msg_t(fmt, arg...)\
+do { \
+       fprintf(stderr, MMF_DEBUG"[%s:%05d]  " fmt "\n", __func__, __LINE__, ##arg); \
+} while (0)
+
+#define err_msg_t(fmt, arg...) \
+do { \
+       fprintf(stderr, MMF_ERR"[%s:%05d]  " fmt "\n", __func__, __LINE__, ##arg); \
+} while (0)
+
+#define info_msg_t(fmt, arg...)        \
+do { \
+       fprintf(stderr, MMF_INFO"[%s:%05d]  " fmt "\n", __func__, __LINE__, ##arg); \
+} while (0)
+
+#define warn_msg_t(fmt, arg...)        \
+do { \
+       fprintf(stderr, MMF_WARN"[%s:%05d]  " fmt "\n", __func__, __LINE__, ##arg); \
+} while (0)
+
+#ifndef SAFE_FREE
+#define SAFE_FREE(x)       if (x) {g_free(x); x = NULL; }
+#endif
+
+
+GTimeVal previous;
+GTimeVal current;
+GTimeVal result;
+/* temporary buffer */
+char buffer[460800] = {0x0,};
+
+
+/**
+ * Enumerations for command
+ */
+#define SENSOR_FLIP_NUM                        3
+#define SENSOR_PROGRAM_MODE_NUM                15
+#define SENSOR_FOCUS_NUM               6
+#define SENSOR_INPUT_ROTATION          4
+#define SENSOR_AF_SCAN_NUM             4
+#define SENSOR_ISO_NUM                 8
+#define SENSOR_EXPOSURE_NUM            9
+#define SENSOR_IMAGE_FORMAT            9
+
+
+/*-----------------------------------------------------------------------
+|    LOCAL CONSTANT DEFINITIONS:                                        |
+-----------------------------------------------------------------------*/
+enum {
+       MODE_VIDEO_CAPTURE,     /* recording and image capture mode */
+       MODE_AUDIO,             /* audio recording*/
+       MODE_NUM,
+};
+
+enum {
+       MENU_STATE_MAIN,
+       MENU_STATE_SETTING,
+       MENU_STATE_NUM,
+};
+
+/*-----------------------------------------------------------------------
+|    LOCAL DATA TYPE DEFINITIONS:                                      |
+-----------------------------------------------------------------------*/
+typedef struct _streamrecorder_handle {
+       MMHandleType streamrecorder;
+       int mode;                       /* image(capture)/video(recording) mode */
+       bool isMultishot;               /* flag for multishot mode */
+       int stillshot_count;            /* total stillshot count */
+       int multishot_count;            /* total multishot count */
+       const char *stillshot_filename;       /* stored filename of  stillshot  */
+       const char *multishot_filename;       /* stored filename of  multishot  */
+       int menu_state;
+       int fps;
+       bool isMute;
+       unsigned long long elapsed_time;
+} streamrecorder_handle_t;
+
+typedef struct _str_xypair {
+       char* attr_subcat_x;
+       char* attr_subcat_y;
+       int x;
+       int y;
+} str_xypair_t;
+
+/*---------------------------------------------------------------------------
+|    LOCAL VARIABLE DEFINITIONS:                                                                                       |
+---------------------------------------------------------------------------*/
+static streamrecorder_handle_t *hstreamrecorder ;
+
+const char *image_fmt[SENSOR_IMAGE_FORMAT] = {
+       "NV12",
+       "NV12T",
+       "NV16",
+       "NV21",
+       "YUYV",
+       "UYVY",
+       "422P",
+       "I420",
+       "YV12",
+};
+
+const char *face_zoom_mode[] = {
+       "Face Zoom OFF",
+       "Face Zoom ON",
+};
+
+const char *display_mode[] = {
+       "Default",
+       "Primary Video ON and Secondary Video Full Screen",
+       "Primary Video OFF and Secondary Video Full Screen",
+};
+
+const char *output_mode[] = {
+       "Letter Box mode",
+       "Original Size mode",
+       "Full Screen mode",
+       "Cropped Full Screen mode",
+       "ROI mode",
+};
+
+const char *rotate_mode[] = {
+       "0",
+       "90",
+       "180",
+       "270",
+};
+
+const char* strobe_mode[] = {
+       "Strobe OFF",
+       "Strobe ON",
+       "Strobe Auto",
+       "Strobe RedEyeReduction",
+       "Strobe SlowSync",
+       "Strobe FrontCurtain",
+       "Strobe RearCurtain",
+       "Strobe Permanent",
+};
+
+const char *detection_mode[2] = {
+       "Face Detection OFF",
+       "Face Detection ON",
+};
+
+const char *wdr_mode[] = {
+       "WDR OFF",
+       "WDR ON",
+       "WDR AUTO",
+};
+
+const char *hdr_mode[] = {
+       "HDR OFF",
+       "HDR ON",
+       "HDR ON and Original",
+};
+
+const char *ahs_mode[] = {
+       "Anti-handshake OFF",
+       "Anti-handshake ON",
+       "Anti-handshake AUTO",
+       "Anti-handshake MOVIE",
+};
+
+const char *vs_mode[] = {
+       "Video-stabilization OFF",
+       "Video-stabilization ON",
+};
+
+const char *visible_mode[] = {
+       "Display OFF",
+       "Display ON",
+};
+
+
+/*---------------------------------------------------------------------------
+|    LOCAL FUNCTION PROTOTYPES:                                                                                                |
+---------------------------------------------------------------------------*/
+static void print_menu();
+void  get_me_out();
+static gboolean cmd_input(GIOChannel *channel);
+static gboolean init(int type);
+static gboolean mode_change();
+int streamrecordertest_set_attr_int(const char* attr_subcategory, int value);
+
+
+static inline void flush_stdin()
+{
+       int ch;
+       while ((ch = getchar()) != EOF && ch != '\n');
+}
+
+#if 0
+static gboolean test_idle_capture_start()
+{
+       int err;
+
+       streamrecordertest_set_attr_int(MMSTR_VIDEO_SOURCE_FORMAT, MM_STREAMRECORDER_INPUT_FORMAT_NV12);
+       streamrecordertest_set_attr_int(MMSTR_VIDEO_ENCODER, MM_VIDEO_CODEC_H264);
+       streamrecordertest_set_attr_int(MMSTR_AUDIO_SOURCE_FORMAT, MM_STREAMRECORDER_AUDIO_FORMAT_PCM_U8);
+       streamrecordertest_set_attr_int(MMSTR_AUDIO_ENCODER, MM_AUDIO_CODEC_AAC);
+
+       g_timer_reset(timer);
+       err = mm_streamrecorder_record(hstreamrecorder->streamrecorder);
+
+       return FALSE;
+}
+#endif
+
+int streamrecordertest_set_attr_int(const char * attr_subcategory, int value)
+{
+       char * err_attr_name = NULL;
+       int err;
+
+       if (hstreamrecorder) {
+               if (hstreamrecorder->streamrecorder) {
+                       debug_msg_t("streamrecordertest_set_attr_int(%s, %d)", attr_subcategory, value);
+
+                       err = mm_streamrecorder_set_attributes(hstreamrecorder->streamrecorder, &err_attr_name, attr_subcategory, value, NULL);
+                       if (err != MM_ERROR_NONE) {
+                               err_msg_t("streamrecordertest_set_attr_int : Error(%s:%x)!!!!!!!", err_attr_name, err);
+                               SAFE_FREE(err_attr_name);
+                               return FALSE;
+                       }
+
+                       return TRUE;
+               }
+
+               debug_msg_t("streamrecordertest_set_attr_int(!hstreamrecorder->streamrecorder)");
+       }
+
+       debug_msg_t("streamrecordertest_set_attr_int(!hstreamrecorder)");
+
+       return FALSE;
+}
+
+int streamrecordertest_set_attr_string(const char * attr_subcategory, char  *value)
+{
+       char * err_attr_name = NULL;
+       int err;
+       if (value == NULL) {
+               err_msg_t("streamrecordertest_set_attr_string : value is null !");
+               return FALSE;
+       }
+       if (hstreamrecorder) {
+               if (hstreamrecorder->streamrecorder) {
+                       debug_msg_t("streamrecordertest_set_attr_string(%s, %s)", attr_subcategory, value);
+
+                       err = mm_streamrecorder_set_attributes(hstreamrecorder->streamrecorder, &err_attr_name, attr_subcategory, value, NULL);
+                       if (err != MM_ERROR_NONE) {
+                               err_msg_t("streamrecordertest_set_attr_string : Error(%s:%x)!!!!!!!", err_attr_name, err);
+                               SAFE_FREE(err_attr_name);
+                               return FALSE;
+                       }
+
+                       return TRUE;
+               }
+
+               debug_msg_t("streamrecordertest_set_attr_string(!hstreamrecorder->streamrecorder)");
+       }
+
+       debug_msg_t("streamrecordertest_set_attr_string(!hstreamrecorder)");
+
+       return FALSE;
+}
+
+int streamrecordertest_set_attr_xypair(str_xypair_t pair)
+{
+       char * err_attr_name = NULL;
+       int err;
+
+       if (hstreamrecorder) {
+               if (hstreamrecorder->streamrecorder) {
+                       debug_msg_t("streamrecordertest_set_attr_xypair((%s, %s), (%d, %d))",  pair.attr_subcat_x, pair.attr_subcat_y, pair.x, pair.y);
+
+                       err = mm_streamrecorder_set_attributes(hstreamrecorder->streamrecorder, &err_attr_name,
+                                                                       pair.attr_subcat_x, pair.x,
+                                                                       pair.attr_subcat_y, pair.y,
+                                                                       NULL);
+                       if (err < 0) {
+                               err_msg_t("streamrecordertest_set_attr_xypair : Error(%s:%x)!!", err_attr_name, err);
+                               SAFE_FREE(err_attr_name);
+                               return FALSE;
+                       }
+
+                       return TRUE;
+               }
+
+               debug_msg_t("streamrecordertest_set_attr_xypair(!hstreamrecorder->streamrecorder)");
+       }
+
+       debug_msg_t("streamrecordertest_set_attr_xypair(!hstreamrecorder)");
+       return FALSE;
+}
+
+int streamrecordertest_get_attr_valid_intarray(const char * attr_name, int ** array, int *count)
+{
+       MMStreamRecorderAttrsInfo info;
+       int err = MM_ERROR_NONE;
+
+       if (hstreamrecorder) {
+               if (hstreamrecorder->streamrecorder) {
+                       debug_msg_t("streamrecordertest_get_attr_valid_intarray(%s)", attr_name);
+
+                       err = mm_streamrecorder_get_attribute_info(hstreamrecorder->streamrecorder, attr_name, &info);
+                       if (err != MM_ERROR_NONE) {
+                               err_msg_t("streamrecordertest_get_attr_valid_intarray : Error(%x)!!", err);
+                               return FALSE;
+                       } else {
+                               if (info.type == MM_STR_REC_ATTRS_TYPE_INT) {
+                                       if (info.validity_type == MM_STR_REC_ATTRS_VALID_TYPE_INT_ARRAY) {
+                                               *array = info.int_array.array;
+                                               *count = info.int_array.count;
+                                               debug_msg_t("INT ARRAY - default value : %d", info.int_array.def);
+                                               return TRUE;
+                                       }
+                               }
+
+                               err_msg_t("streamrecordertest_get_attr_valid_intarray : Type mismatched!!");
+                               return FALSE;
+                       }
+               }
+
+               debug_msg_t("streamrecordertest_get_attr_valid_intarray(!hstreamrecorder->streamrecorder)");
+       }
+
+
+       debug_msg_t("streamrecordertest_get_attr_valid_intarray(!hstreamrecorder)");
+       return FALSE;
+}
+
+int streamrecordertest_get_attr_valid_intrange(const char * attr_name, int *min, int *max)
+{
+       MMStreamRecorderAttrsInfo info;
+       int err = MM_ERROR_NONE;
+
+       if (hstreamrecorder) {
+               if (hstreamrecorder->streamrecorder) {
+                       debug_msg_t("streamrecordertest_get_attr_valid_intrange(%s)", attr_name);
+
+                       err = mm_streamrecorder_get_attribute_info(hstreamrecorder->streamrecorder, attr_name, &info);
+                       if (err != MM_ERROR_NONE) {
+                               err_msg_t("streamrecordertest_get_attr_valid_intarray : Error(%x)!!",  err);
+                               return FALSE;
+                       } else {
+                               if (info.type == MM_STR_REC_ATTRS_TYPE_INT) {
+                                       if (info.validity_type == MM_STR_REC_ATTRS_VALID_TYPE_INT_RANGE) {
+                                               *min = info.int_range.min;
+                                               *max = info.int_range.max;
+                                               debug_msg_t("INT RANGE - default : %d", info.int_range.def);
+                                               return TRUE;
+                                       }
+                               }
+
+                               err_msg_t("streamrecordertest_get_attr_valid_intarray : Type mismatched!!");
+                               return FALSE;
+                       }
+
+               }
+
+               debug_msg_t("streamrecordertest_get_attr_valid_intarray(!hstreamrecorder->streamrecorder)");
+       }
+
+       debug_msg_t("streamrecordertest_get_attr_valid_intarray(!hstreamrecorder)");
+       return FALSE;
+}
+
+
+void  get_me_out()
+{
+}
+
+static void print_menu()
+{
+       switch (hstreamrecorder->menu_state) {
+       case MENU_STATE_MAIN:
+                       g_print("\n\t=======================================\n");
+                       g_print("\t   Stream Recorder Menu \n");
+                       g_print("\t=======================================\n");
+                       if (hstreamrecorder->mode == MODE_VIDEO_CAPTURE) {
+                               if (streamrecorder_get_state() <= STREAMRECORDER_CREATED) {
+                                       g_print("\t   '1' Start Recording\n");
+                                       g_print("\t   '2' Setting\n");
+                                       g_print("\t   '3' Print frame rate\n");
+                                       g_print("\t   'b' back\n");
+                               } else if (streamrecorder_get_state() == STREAMRECORDER_STARTED) {
+                                       g_print("\t   'r' Resume\n");
+                                       g_print("\t   'c' Cancel Recording\n");
+                                       g_print("\t   's' Save\n");
+                               }
+                       } else if (hstreamrecorder->mode == MODE_AUDIO) {
+                               if (streamrecorder_get_state() <= STREAMRECORDER_CREATED) {
+                                       g_print("\t   '1' Start Recording\n");
+                                       g_print("\t   'b' back\n");
+                               } else if (streamrecorder_get_state() == STREAMRECORDER_STARTED) {
+                                       g_print("\t   'r' Resume Recording\n");
+                                       g_print("\t   'c' Cancel Recording\n");
+                                       g_print("\t   's' Save Recording\n");
+                               }
+                       }
+               break;
+       case MENU_STATE_SETTING:
+               g_print("\n\t=======================================\n");
+               g_print("\t   Stream Recorder > Setting\n");
+               g_print("\t=======================================\n");
+               g_print("\t  >>>>>>>>>>>>>>>>>>>>>>>>>>>> [Stream Recorder]  \n");
+               g_print("\t     'T' videobuffer type \n");
+               g_print("\t     'F' videosource  format \n");
+               g_print("\t     'A' video framerate \n");
+               g_print("\t     'B' video bitrate \n");
+               g_print("\t     'D' audio source format\n");
+               g_print("\t     'I'  audio bitrate \n");
+               g_print("\t     'S' audio samplerate \n");
+               g_print("\t     'O' video encoder \n");
+               g_print("\t     'C' audio encoder \n");
+               g_print("\t     'N' audio channel count \n");
+               g_print("\t     'm' file format\n");
+               g_print("\t     'b'  back \n");
+               g_print("\t=======================================\n");
+               break;
+       default:
+               warn_msg_t("unknow menu state !!\n");
+               break;
+       }
+
+       return;
+}
+
+static void main_menu(gchar buf)
+{
+       int err = 0;
+
+       if (hstreamrecorder->mode == MODE_VIDEO_CAPTURE) {
+               if (streamrecorder_get_state() == STREAMRECORDER_CREATED) {
+                       switch (buf) {
+                       case '1': /* Start Recording */
+                               g_print("*Recording start!\n");
+                               video_stream_cb_cnt = 0;
+                               audio_stream_cb_cnt = 0;
+
+                               g_timer_reset(timer);
+                               err = mm_streamrecorder_record(hstreamrecorder->streamrecorder);
+
+                               mm_streamrecorder_push_stream_buffer(hstreamrecorder->streamrecorder, MM_STREAM_TYPE_VIDEO, 1000, buffer, (640*480*3/2));
+                               mm_streamrecorder_push_stream_buffer(hstreamrecorder->streamrecorder, MM_STREAM_TYPE_VIDEO, 2000, buffer, (640*480*3/2));
+                               mm_streamrecorder_push_stream_buffer(hstreamrecorder->streamrecorder, MM_STREAM_TYPE_VIDEO, 3000, buffer, (640*480*3/2));
+                               mm_streamrecorder_push_stream_buffer(hstreamrecorder->streamrecorder, MM_STREAM_TYPE_VIDEO, 4000, buffer, (640*480*3/2));
+                               mm_streamrecorder_push_stream_buffer(hstreamrecorder->streamrecorder, MM_STREAM_TYPE_VIDEO, 5000, buffer, (640*480*3/2));
+                               mm_streamrecorder_push_stream_buffer(hstreamrecorder->streamrecorder, MM_STREAM_TYPE_VIDEO, 6000, buffer, (640*480*3/2));
+                               mm_streamrecorder_push_stream_buffer(hstreamrecorder->streamrecorder, MM_STREAM_TYPE_VIDEO, 7000, buffer, (640*480*3/2));
+                               mm_streamrecorder_push_stream_buffer(hstreamrecorder->streamrecorder, MM_STREAM_TYPE_VIDEO, 8000, buffer, (640*480*3/2));
+                               mm_streamrecorder_push_stream_buffer(hstreamrecorder->streamrecorder, MM_STREAM_TYPE_VIDEO, 9000, buffer, (640*480*3/2));
+                               mm_streamrecorder_push_stream_buffer(hstreamrecorder->streamrecorder, MM_STREAM_TYPE_VIDEO, 10000, buffer, (640*480*3/2));
+                               mm_streamrecorder_push_stream_buffer(hstreamrecorder->streamrecorder, MM_STREAM_TYPE_VIDEO, 11000, buffer, (640*480*3/2));
+
+                               if (err != MM_ERROR_NONE)
+                                       warn_msg_t("Rec start mm_streamrecorder_record 0x%x", err);
+
+                               streamrecorder_set_state(STREAMRECORDER_STARTED);
+                               break;
+
+                       case '2': /* Setting */
+                               hstreamrecorder->menu_state = MENU_STATE_SETTING;
+                               break;
+
+                       case '3': /* Print frame rate */
+                               break;
+
+                       case 'b': /* back */
+                               hstreamrecorder->menu_state = MENU_STATE_MAIN;
+                               mode_change();
+                               break;
+
+                       default:
+                               g_print("\t Invalid input \n");
+                               break;
+                       }
+               } else if (streamrecorder_get_state() == STREAMRECORDER_STARTED) {
+                       switch (buf) {
+                       case 'r': /* Resume Recording */
+                               g_print("*Resume!\n");
+                               break;
+
+                       case 'c': /* Cancel */
+                               g_print("*Cancel Recording !\n");
+                               err = mm_streamrecorder_cancel(hstreamrecorder->streamrecorder);
+
+                               if (err < 0)
+                                       warn_msg_t("Cancel recording mm_streamrecorder_cancel  = %x", err);
+
+                               break;
+
+                       case 's': /* Save */
+                               g_print("*Save Recording!\n");
+                               g_timer_reset(timer);
+
+                               err = mm_streamrecorder_commit(hstreamrecorder->streamrecorder);
+                               streamrecorder_set_state(STREAMRECORDER_CREATED);
+
+                               if (err < 0)
+                                       warn_msg_t("Save recording mm_streamrecorder_commit  = %x", err);
+
+                               break;
+
+                       case 'n': /* Capture video snapshot */
+                               break;
+
+                       default:
+                               g_print("\t Invalid input \n");
+                               break;
+                       } /* switch */
+               } else {
+                       err_msg_t("Wrong streamrecorder state, check status!!");
+               }
+       } else if (hstreamrecorder->mode == MODE_AUDIO) {
+                       switch (buf) {
+                       case '1': /* Start Recording */
+                               g_print("*Recording start!\n");
+                               g_timer_reset(timer);
+                               err = mm_streamrecorder_record(hstreamrecorder->streamrecorder);
+
+                               if (err < 0)
+                                       warn_msg_t("Rec start mm_streamrecorder_record  = %x", err);
+
+                               break;
+
+                       case 'b': /* back */
+                                       hstreamrecorder->menu_state = MENU_STATE_MAIN;
+                                       mode_change();
+                                       break;
+
+                       default:
+                               g_print("\t Invalid input \n");
+                               break;
+                       }
+       } else {
+               g_print("\t Invalid mode, back to upper menu \n");
+               hstreamrecorder->menu_state = MENU_STATE_MAIN;
+               mode_change();
+       }
+}
+
+
+static void setting_menu(gchar buf)
+{
+       gboolean bret = FALSE;
+       int index_menu = 0;
+       int min = 0;
+       int max = 0;
+       int width_count = 0;
+       int height_count = 0;
+       int i = 0;
+       int count = 0;
+       int value = 0;
+       int* array = NULL;
+       int *width_array = NULL;
+       int *height_array = NULL;
+       char *err_attr_name = NULL;
+       str_xypair_t input_pair;
+       char filename[100];
+       int err = MM_ERROR_NONE;
+       int x = 0, y = 0, width = 0, height = 0;
+
+       if (hstreamrecorder->mode == MODE_VIDEO_CAPTURE) {
+               switch (buf) {
+               case '0':  /* Setting */
+                       g_print("*Select the preview resolution!\n");
+                       streamrecordertest_get_attr_valid_intarray(MMSTR_VIDEO_RESOLUTION_WIDTH, &width_array, &width_count);
+                       streamrecordertest_get_attr_valid_intarray(MMSTR_VIDEO_RESOLUTION_HEIGHT, &height_array, &height_count);
+
+                       if (width_count != height_count) {
+                               err_msg_t("System has wrong information!!\n");
+                       } else if (width_count == 0) {
+                               g_print("Not supported!!\n");
+                       } else {
+                               flush_stdin();
+
+                               for (i = 0; i < width_count; i++)
+                                       g_print("\t %d. %d*%d\n", i+1, width_array[i], height_array[i]);
+
+                               err = scanf("%d", &index_menu);
+                               if (err == EOF) {
+                                       printf("\nscanf error : errno %d\n", errno);
+                               } else {
+                                       if (index_menu > 0 && index_menu <= width_count) {
+                                               input_pair.x = width_array[index_menu-1];
+                                               input_pair.y = height_array[index_menu-1];
+                                               bret = streamrecordertest_set_attr_xypair(input_pair);
+                                       }
+                               }
+                       }
+                       break;
+
+               case '1': /* Setting > Capture Resolution setting */
+                       break;
+
+               case 'r': /* Setting > Rotate input when recording */
+                       g_print("Not supported !! \n");
+                       break;
+
+               case 'H': /* Setting > Hybrid mode */
+                       g_print("* Hybrid mode\n");
+
+                       g_print("\t 0. DISABLE\n");
+                       g_print("\t 1. ENABLE\n");
+
+                       flush_stdin();
+                       err = scanf("%d", &index_menu);
+
+                       if (index_menu < 0 || index_menu > 1)
+                               g_print("Wrong INPUT[%d]!! \n", index_menu);
+
+                       break;
+
+               case 'R': /*  Setting > Stream Recorder-rotation setting */
+                       g_print("*Stream Recorder-Rotation setting!\n");
+
+                       g_print("\t0.  0 degree\n");
+                       g_print("\t1.  90 degree\n");
+                       g_print("\t2.  180 degree\n");
+                       g_print("\t3.  270 degree\n");
+                       flush_stdin();
+                       err = scanf("%d", &index_menu);
+                       if (index_menu < 0 || index_menu > 3)
+                               g_print("Wrong Input[%d] !!\n\n", index_menu);
+
+                       g_print("*Stream Recorder-Flip setting!\n");
+                       g_print("\t0.  NONE\n");
+                       g_print("\t1.  HORIZONTAL\n");
+                       g_print("\t2.  VERTICAL\n");
+                       g_print("\t3.  BOTH\n");
+                       flush_stdin();
+                       err = scanf("%d", &index_menu);
+                       if (index_menu < 0 || index_menu > 3)
+                               g_print("Wrong Input[%d] !!\n\n", index_menu);
+
+                       break;
+
+               case 'T': /* Setting > videobuffer-type setting */
+                       g_print("*videobuffer type  !\n");
+                       streamrecordertest_get_attr_valid_intrange("videobuffer-type", &min, &max);
+
+                       if (min >= max) {
+                               g_print("Not supported !! \n");
+                       } else {
+                               flush_stdin();
+                               g_print("\n Select  videobuffer type (%d ~ %d)\n", min, max);
+                               err = scanf("%d", &index_menu);
+                               bret = streamrecordertest_set_attr_int("videobuffer-type", index_menu);
+                       }
+                       break;
+
+               case 'F': /* Setting > videosource-format setting */
+                       g_print("*videosource  format  !\n");
+                       streamrecordertest_get_attr_valid_intrange("videosource-format", &min, &max);
+
+                       if (min >= max) {
+                               g_print("Not supported !! \n");
+                       } else {
+                               flush_stdin();
+                               g_print("\n Select videosource-format (%d ~ %d)\n", min, max);
+                               err = scanf("%d", &index_menu);
+                               bret = streamrecordertest_set_attr_int("videosource-format", index_menu);
+                       }
+                       break;
+
+               case 'A': /* Setting > video framerate setting */
+                       g_print("*video framerate  !\n");
+                       streamrecordertest_get_attr_valid_intrange("video-framerate", &min, &max);
+
+                       if (min >= max) {
+                               g_print("Not supported !! \n");
+                       } else {
+                               flush_stdin();
+                               g_print("\n Select  video-framerate (%d ~ %d)\n", min, max);
+                               err = scanf("%d", &index_menu);
+                               bret = streamrecordertest_set_attr_int("video-framerate", index_menu);
+                       }
+                       break;
+
+               case 'B': /* Setting > video bitrate setting */
+                       g_print("*video bitrate  !\n");
+                       streamrecordertest_get_attr_valid_intrange("video-bitrate", &min, &max);
+
+                       if (min >= max) {
+                               g_print("Not supported !! \n");
+                       } else {
+                               flush_stdin();
+                               g_print("\n Select  video-bitrate (%d ~ %d)\n", min, max);
+                               err = scanf("%d", &index_menu);
+                               bret = streamrecordertest_set_attr_int("video-bitrate", index_menu);
+                       }
+                       break;
+
+               case 'D': /* Setting > audio-source-format setting */
+                       g_print("*audio-source-format !\n");
+                       streamrecordertest_get_attr_valid_intrange("audio-source-format", &min, &max);
+
+                       if (min >= max) {
+                               g_print("Not supported !! \n");
+                       } else {
+                               flush_stdin();
+                               g_print("\n Select  audio-source-format (%d ~ %d)\n", min, max);
+                               err = scanf("%d", &index_menu);
+                               bret = streamrecordertest_set_attr_int("audio-source-format", index_menu);
+                       }
+                       break;
+
+               case 'I': /* Setting > audio-bitrate setting */
+                       g_print("*audio-bitrate !\n");
+                       streamrecordertest_get_attr_valid_intrange("audio-bitrate", &min, &max);
+
+                       if (min >= max) {
+                               g_print("Not supported !! \n");
+                       } else {
+                               flush_stdin();
+                               g_print("\n Select  audio-bitrate (%d ~ %d)\n", min, max);
+                               err = scanf("%d", &index_menu);
+                               bret = streamrecordertest_set_attr_int("audio-bitrate", index_menu);
+                       }
+                       break;
+
+               case 'S': /* Setting > audio-samplerate setting */
+                       g_print("*audio-samplerate !\n");
+                       streamrecordertest_get_attr_valid_intrange("audio-samplerate", &min, &max);
+
+                       if (min >= max) {
+                               g_print("Not supported !! \n");
+                       } else {
+                               flush_stdin();
+                               g_print("\n Select  audio-samplerate (%d ~ %d)\n", min, max);
+                               err = scanf("%d", &index_menu);
+                               bret = streamrecordertest_set_attr_int("audio-samplerate", index_menu);
+                       }
+                       break;
+
+               case 'O': /* Setting > video-encoder setting */
+                       g_print("*video-encoder!\n");
+                       streamrecordertest_get_attr_valid_intrange("video-encoder", &min, &max);
+
+                       if (min >= max) {
+                               g_print("Not supported !! \n");
+                       } else {
+                               flush_stdin();
+                               g_print("\n Select  video-encoder (%d ~ %d)\n", min, max);
+                               err = scanf("%d", &index_menu);
+                               bret = streamrecordertest_set_attr_int("video-encoder", index_menu);
+                       }
+                       break;
+
+               case 'C': /* Setting >audio-encoder setting */
+                       g_print("*audio-encoder!\n");
+                       streamrecordertest_get_attr_valid_intrange("audio-encoder", &min, &max);
+
+                       if (min >= max) {
+                               g_print("Not supported !! \n");
+                       } else {
+                               flush_stdin();
+                               g_print("\n Select  audio-encoder (%d ~ %d)\n", min, max);
+                               err = scanf("%d", &index_menu);
+                               bret = streamrecordertest_set_attr_int("audio-encoder", index_menu);
+                       }
+                       break;
+
+               case 'N': /* Setting >audio-channel-count setting */
+                       g_print("*audio-channel-count!\n");
+                       streamrecordertest_get_attr_valid_intrange("audio-channel-count", &min, &max);
+
+                       if (min >= max) {
+                               g_print("Not supported !! \n");
+                       } else {
+                               flush_stdin();
+                               g_print("\n Select  audio-channel-count(%d ~ %d)\n", min, max);
+                               err = scanf("%d", &index_menu);
+                               bret = streamrecordertest_set_attr_int("audio-channel-count", index_menu);
+                       }
+                       break;
+
+               case 'b': /* back */
+                       hstreamrecorder->menu_state = MENU_STATE_MAIN;
+                       break;
+
+               default:
+                       g_print("\t Invalid input \n");
+                       break;
+               }
+       } else {
+               g_print("\t Invalid mode, back to upper menu \n");
+               hstreamrecorder->menu_state = MENU_STATE_MAIN;
+       }
+}
+
+
+/**
+ * This function is to execute command.
+ *
+ * @param      channel [in]    1st parameter
+ *
+ * @return     This function returns TRUE/FALSE
+ * @remark
+ * @see
+ */
+static gboolean cmd_input(GIOChannel *channel)
+{
+       gchar *buf = NULL;
+       gsize read_size;
+       GError *g_error = NULL;
+
+       debug_msg_t("ENTER");
+
+       g_io_channel_read_line(channel, &buf, &read_size, NULL, &g_error);
+       if (g_error) {
+               debug_msg_t("g_io_channel_read_chars error");
+               g_error_free(g_error);
+               g_error = NULL;
+       }
+
+       if (buf) {
+               g_strstrip(buf);
+
+               debug_msg_t("Menu Status : %d", hstreamrecorder->menu_state);
+               switch (hstreamrecorder->menu_state) {
+               case MENU_STATE_MAIN:
+                       main_menu(buf[0]);
+                       break;
+               case MENU_STATE_SETTING:
+                       setting_menu(buf[0]);
+                       break;
+               default:
+                       break;
+               }
+
+               g_free(buf);
+               buf = NULL;
+
+               print_menu();
+       } else {
+               debug_msg_t("No read input");
+       }
+
+       return TRUE;
+}
+
+/**
+ * This function is to initiate streamrecorder attributes .
+ *
+ * @param      type    [in]    image(capture)/video(recording) mode
+ *
+ * @return     This function returns TRUE/FALSE
+ * @remark
+ * @see                other functions
+ */
+static gboolean init(int type)
+{
+       MMHandleType str_handle = 0;
+
+       char *err_attr_name = NULL;
+       int video_codec = MM_VIDEO_CODEC_INVALID;
+       int audio_codec = MM_AUDIO_CODEC_INVALID;
+       int file_format = MM_FILE_FORMAT_INVALID;
+       int audio_enc = MM_AUDIO_CODEC_INVALID;
+       int channel = 0;
+       int v_bitrate = 0;
+       int a_bitrate = 0;
+       int video_width = 0;
+       int video_height = 0;
+       int video_fps = 0;
+       int audio_samplerate = 0;
+       int audio_src_format = 0;
+       int video_src_format = 0;
+       int rec_mode = 0;
+       const char *filename = "/opt/usr/media/test.mp4";
+
+       if (!hstreamrecorder)
+               return FALSE;
+
+       if (!hstreamrecorder->streamrecorder)
+               return FALSE;
+
+       str_handle = (MMHandleType)(hstreamrecorder->streamrecorder);
+
+       /*================================================================================
+               Video capture mode
+       *=================================================================================*/
+       if (type == MODE_VIDEO_CAPTURE) {
+               video_codec = MM_VIDEO_CODEC_MPEG4;
+               /*audio_codec = MM_AUDIO_CODEC_AAC;*/
+               file_format = MM_FILE_FORMAT_MP4;
+               /*audio_enc = MM_AUDIO_CODEC_PCM;*/
+               /*channel = 1;
+               v_bitrate = 8000000;
+               /*a_bitrate = 64000;*/
+               video_width = 640;
+               video_height = 480;
+               video_fps = 30;
+               /*audio_samplerate = 48000;*/
+               /*audio_src_format = 2;*/
+               rec_mode = 0;
+               video_src_format = MM_STREAMRECORDER_INPUT_FORMAT_NV12;
+               mm_streamrecorder_set_attributes((MMHandleType)str_handle, &err_attr_name,
+                                                               MMSTR_VIDEO_ENABLE,  TRUE,
+                                                               MMSTR_AUDIO_ENABLE,  FALSE,
+                                                               NULL);
+
+               mm_streamrecorder_set_attributes((MMHandleType)str_handle, &err_attr_name,
+                                                               MMSTR_VIDEO_ENCODER, video_codec,
+                                                               /*MMSTR_AUDIO_ENCODER,  audio_codec,*/
+                                                               MMSTR_FILE_FORMAT, file_format,
+                                                               MMSTR_VIDEO_BITRATE, v_bitrate,
+                                                               MMSTR_VIDEO_RESOLUTION_WIDTH , video_width,
+                                                               MMSTR_VIDEO_RESOLUTION_HEIGHT, video_height,
+                                                               MMSTR_VIDEO_FRAMERATE, video_fps,
+                                                               /*MMSTR_AUDIO_CHANNEL, channel,*/
+                                                               /*MMSTR_AUDIO_SAMPLERATE, audio_samplerate,*/
+                                                               /*MMSTR_AUDIO_BITRATE, a_bitrate,*/
+                                                               /*MMSTR_AUDIO_SOURCE_FORMAT, audio_src_format,*/
+                                                               MMSTR_VIDEO_SOURCE_FORMAT, video_src_format,
+                                                               MMSTR_RECORDER_MODE, rec_mode,
+                                                               NULL);
+               mm_streamrecorder_set_attributes((MMHandleType)str_handle, &err_attr_name,
+                                                               MMSTR_FILENAME, filename, strlen(filename), NULL);
+
+
+       }
+       /*================================================================================
+               Audio mode
+       *=================================================================================*/
+       debug_msg_t("Init DONE.");
+
+       return TRUE;
+}
+
+static gboolean init_handle()
+{
+       hstreamrecorder->mode = MODE_VIDEO_CAPTURE;  /* image(capture)/video(recording) mode */
+       hstreamrecorder->isMultishot =  FALSE;
+       hstreamrecorder->stillshot_count = 0;        /* total stillshot count */
+       hstreamrecorder->multishot_count = 0;        /* total multishot count */
+       hstreamrecorder->stillshot_filename = STILL_CAPTURE_FILE_PATH_NAME;  /* stored filename of  stillshot  */
+       hstreamrecorder->multishot_filename = MULTI_CAPTURE_FILE_PATH_NAME;  /* stored filename of  multishot  */
+       hstreamrecorder->menu_state = MENU_STATE_MAIN;
+       hstreamrecorder->isMute = FALSE;
+       hstreamrecorder->elapsed_time = 0;
+       hstreamrecorder->fps = SRC_VIDEO_FRAME_RATE_15; /*SRC_VIDEO_FRAME_RATE_30;*/
+
+       return TRUE;
+}
+/**
+ * This function is to change streamrecorder mode.
+ *
+ * @param      type    [in]    image(capture)/video(recording) mode
+ *
+ * @return     This function returns TRUE/FALSE
+ * @remark
+ * @see                other functions
+ */
+static gboolean mode_change()
+{
+       int err = MM_ERROR_NONE;
+       int state = STREAMRECORDER_NONE;
+       int device_count = 0;
+       int facing_direction = 0;
+       char media_type = '\0';
+       char *evassink_name = NULL;
+       bool check = FALSE;
+
+       state = streamrecorder_get_state();
+       debug_msg_t("MMStreamrecorder State : %d", state);
+       if (state != STREAMRECORDER_NULL) {
+               if ((state == STREAMRECORDER_STARTED)) {
+                       debug_msg_t("mm_streamrecorder_cancel");
+                       err = mm_streamrecorder_cancel(hstreamrecorder->streamrecorder);
+
+                       if (err < 0) {
+                               warn_msg_t("exit mm_streamrecorder_cancel  = %x", err);
+                               return FALSE;
+                       }
+               }
+
+               state = streamrecorder_get_state();
+               if (state == STREAMRECORDER_CREATED) {
+                       debug_msg_t("mm_streamreorder_unrealize");
+                       mm_streamrecorder_unrealize(hstreamrecorder->streamrecorder);
+                       streamrecorder_set_state(STREAMRECORDER_NONE);
+               }
+
+               state = streamrecorder_get_state();
+               if (state == STREAMRECORDER_NONE) {
+                       debug_msg_t("mm_streamrecorder_destroy");
+                       mm_streamrecorder_destroy(hstreamrecorder->streamrecorder);
+
+                       streamrecorder_set_state(STREAMRECORDER_NULL);
+               }
+       }
+
+       init_handle();
+       while (!check) {
+               g_print("\n\t=======================================\n");
+               g_print("\t   MM_STREAMRECORDER_TESTSUIT\n");
+               g_print("\t=======================================\n");
+               g_print("\t   '1' STREAM RECORDER CREATE\n");
+               g_print("\t   'q' Exit\n");
+               g_print("\t=======================================\n");
+
+               g_print("\t  Enter the media type:\n\t");
+
+               err = scanf("%c", &media_type);
+
+               switch (media_type) {
+               case '1':
+                       hstreamrecorder->mode = MODE_VIDEO_CAPTURE;
+                       check = TRUE;
+                       break;
+               case '2':
+                       hstreamrecorder->mode = MODE_VIDEO_CAPTURE;
+                       check = TRUE;
+                       break;
+               case '3':
+                       hstreamrecorder->mode = MODE_AUDIO;
+                       check = TRUE;
+                       break;
+               case '4':
+                       hstreamrecorder->mode = MODE_VIDEO_CAPTURE;
+                       check = TRUE;
+                       break;
+               case 'q':
+                       g_print("\t Quit streamrecorder Testsuite!!\n");
+                       hstreamrecorder->mode = -1;
+                       if (g_main_loop_is_running(g_loop))
+                               g_main_loop_quit(g_loop);
+
+                       return FALSE;
+               default:
+                       g_print("\t Invalid media type(%d)\n", media_type);
+                       continue;
+               }
+       }
+
+       debug_msg_t("mm_streamrecorder_create");
+       g_get_current_time(&previous);
+       g_timer_reset(timer);
+
+       FILE *fp = NULL;
+       size_t nread;
+       fp = fopen("/opt/usr/media/test.nv12", "a+");
+       if (!fp)
+               return -1;
+       nread = fread(&buffer, sizeof(char), sizeof(buffer), fp);
+       time_msg_t("mm_streamrecorder_create()  : nread %d, sizeof(buffer) %d", nread, sizeof(buffer));
+       fclose(fp);
+
+       err = mm_streamrecorder_create(&hstreamrecorder->streamrecorder);
+       time_msg_t("mm_streamrecorder_create()  : %12.6lfs", g_timer_elapsed(timer, NULL));
+
+       if (err != MM_ERROR_NONE) {
+               err_msg_t("mmstreamrecorder_create = %x", err);
+               return -1;
+       } else {
+
+       }
+
+       debug_msg_t("evassink name[%s], device count[%d], facing direction[%d]", evassink_name, device_count, facing_direction);
+
+       if (!init(hstreamrecorder->mode)) {
+               err_msg_t("testsuite init() failed.");
+               return -1;
+       }
+
+       debug_msg_t("mm_streamrecorder_realize");
+
+       g_timer_reset(timer);
+
+       err =  mm_streamrecorder_realize(hstreamrecorder->streamrecorder);
+       streamrecorder_set_state(STREAMRECORDER_CREATED);
+       time_msg_t("mm_streamrecorder_realize()  : %12.6lfs", g_timer_elapsed(timer, NULL));
+       if (err != MM_ERROR_NONE) {
+               err_msg_t("mm_streamrecorder_realize  = %x", err);
+               return -1;
+       }
+
+       g_timer_reset(timer);
+
+       g_get_current_time(&current);
+       timersub(&current, &previous, &result);
+       time_msg_t("streamrecorder Starting Time  : %ld.%lds", result.tv_sec, result.tv_usec);
+
+       return TRUE;
+}
+
+
+/**
+ * This function is the example main function for mmstreamrecorder API.
+ *
+ * @param
+ *
+ * @return     This function returns 0.
+ * @remark
+ * @see                other functions
+ */
+int main(int argc, char **argv)
+{
+       int bret;
+
+       timer = g_timer_new();
+
+       gst_init(&argc, &argv);
+
+       time_msg_t("gst_init() : %12.6lfs", g_timer_elapsed(timer, NULL));
+
+       hstreamrecorder = (streamrecorder_handle_t *) g_malloc0(sizeof(streamrecorder_handle_t));
+
+       g_timer_reset(timer);
+
+       bret = mode_change();
+       if (!bret)
+               return bret;
+
+       print_menu();
+
+       g_loop = g_main_loop_new(NULL, FALSE);
+
+       stdin_channel = g_io_channel_unix_new(fileno(stdin));/* read from stdin */
+       g_io_add_watch(stdin_channel, G_IO_IN, (GIOFunc)cmd_input, NULL);
+
+       debug_msg_t("RUN main loop");
+
+       g_main_loop_run(g_loop);
+
+       debug_msg_t("STOP main loop");
+
+       if (timer) {
+               g_timer_stop(timer);
+               g_timer_destroy(timer);
+               timer = NULL;
+       }
+
+       g_free(hstreamrecorder);
+       g_main_loop_unref(g_loop);
+       g_io_channel_unref(stdin_channel);
+
+       return bret;
+}
+
+/*EOF*/